| ... | ... | @@ -167,6 +167,9 @@ strtab_needs_relocation: bool = false, |
| 167 | 167 | has_dices: bool = false, |
| 168 | 168 | has_stabs: bool = false, |
| 169 | 169 | |
| 170 | section_ordinals: std.ArrayListUnmanaged(MatchingSection) = .{}, |
| 171 | section_to_ordinal: std.AutoHashMapUnmanaged(MatchingSection, u8) = .{}, |
| 172 | |
| 170 | 173 | pending_updates: std.ArrayListUnmanaged(struct { |
| 171 | 174 | kind: enum { |
| 172 | 175 | got, |
| ... | ... | @@ -925,6 +928,13 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void { |
| 925 | 928 | else => unreachable, |
| 926 | 929 | }; |
| 927 | 930 | |
| 931 | // Initialize section ordinals with null ordinal pointing at |
| 932 | // PAGEZERO segment. |
| 933 | try self.section_ordinals.append(self.base.allocator, .{ |
| 934 | .seg = 0, |
| 935 | .sect = 0, |
| 936 | }); |
| 937 | |
| 928 | 938 | try self.populateMetadata(); |
| 929 | 939 | try self.parseInputFiles(positionals.items, self.base.options.sysroot); |
| 930 | 940 | try self.parseLibs(libs.items, self.base.options.sysroot); |
| ... | ... | @@ -1482,6 +1492,10 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1482 | 1492 | } |
| 1483 | 1493 | }; |
| 1484 | 1494 | |
| 1495 | if (res) |match| { |
| 1496 | try self.createSectionOrdinal(match); |
| 1497 | } |
| 1498 | |
| 1485 | 1499 | return res; |
| 1486 | 1500 | } |
| 1487 | 1501 | |
| ... | ... | @@ -1606,6 +1620,38 @@ fn sortSections(self: *MachO) !void { |
| 1606 | 1620 | self.blocks.deinit(self.base.allocator); |
| 1607 | 1621 | self.blocks = transient; |
| 1608 | 1622 | } |
| 1623 | |
| 1624 | { |
| 1625 | // Create new section ordinals. |
| 1626 | self.section_ordinals.clearRetainingCapacity(); |
| 1627 | self.section_to_ordinal.clearRetainingCapacity(); |
| 1628 | // First ordinal is always null |
| 1629 | self.section_ordinals.appendAssumeCapacity(.{ |
| 1630 | .seg = 0, |
| 1631 | .sect = 0, |
| 1632 | }); |
| 1633 | const text_seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 1634 | for (text_seg.sections.items) |_, sect_id| { |
| 1635 | try self.createSectionOrdinal(.{ |
| 1636 | .seg = self.text_segment_cmd_index.?, |
| 1637 | .sect = @intCast(u16, sect_id), |
| 1638 | }); |
| 1639 | } |
| 1640 | const data_const_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 1641 | for (data_const_seg.sections.items) |_, sect_id| { |
| 1642 | try self.createSectionOrdinal(.{ |
| 1643 | .seg = self.data_const_segment_cmd_index.?, |
| 1644 | .sect = @intCast(u16, sect_id), |
| 1645 | }); |
| 1646 | } |
| 1647 | const data_seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 1648 | for (data_seg.sections.items) |_, sect_id| { |
| 1649 | try self.createSectionOrdinal(.{ |
| 1650 | .seg = self.data_segment_cmd_index.?, |
| 1651 | .sect = @intCast(u16, sect_id), |
| 1652 | }); |
| 1653 | } |
| 1654 | } |
| 1609 | 1655 | } |
| 1610 | 1656 | |
| 1611 | 1657 | fn allocateTextSegment(self: *MachO) !void { |
| ... | ... | @@ -1732,7 +1778,7 @@ fn allocateTextBlocks(self: *MachO) !void { |
| 1732 | 1778 | const sect = seg.sections.items[match.sect]; |
| 1733 | 1779 | |
| 1734 | 1780 | var base_addr: u64 = sect.addr; |
| 1735 | | const n_sect = self.sectionId(match); |
| 1781 | const n_sect = self.section_to_ordinal.get(match) orelse unreachable; |
| 1736 | 1782 | |
| 1737 | 1783 | log.debug(" within section {s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) }); |
| 1738 | 1784 | log.debug(" {}", .{sect}); |
| ... | ... | @@ -2260,6 +2306,7 @@ fn resolveSymbols(self: *MachO) !void { |
| 2260 | 2306 | .sect = self.common_section_index.?, |
| 2261 | 2307 | }; |
| 2262 | 2308 | }; |
| 2309 | try self.createSectionOrdinal(match); |
| 2263 | 2310 | |
| 2264 | 2311 | const size = sym.n_value; |
| 2265 | 2312 | const code = try self.base.allocator.alloc(u8, size); |
| ... | ... | @@ -2272,7 +2319,7 @@ fn resolveSymbols(self: *MachO) !void { |
| 2272 | 2319 | var nlist = macho.nlist_64{ |
| 2273 | 2320 | .n_strx = sym.n_strx, |
| 2274 | 2321 | .n_type = macho.N_SECT, |
| 2275 | | .n_sect = self.sectionId(match), |
| 2322 | .n_sect = self.section_to_ordinal.get(match) orelse unreachable, |
| 2276 | 2323 | .n_desc = 0, |
| 2277 | 2324 | .n_value = 0, |
| 2278 | 2325 | }; |
| ... | ... | @@ -2402,7 +2449,7 @@ fn resolveSymbols(self: *MachO) !void { |
| 2402 | 2449 | var nlist = macho.nlist_64{ |
| 2403 | 2450 | .n_strx = undef.n_strx, |
| 2404 | 2451 | .n_type = macho.N_SECT, |
| 2405 | | .n_sect = self.sectionId(match), |
| 2452 | .n_sect = self.section_to_ordinal.get(match) orelse unreachable, |
| 2406 | 2453 | .n_desc = 0, |
| 2407 | 2454 | .n_value = 0, |
| 2408 | 2455 | }; |
| ... | ... | @@ -2498,6 +2545,10 @@ fn populateMetadata(self: *MachO) !void { |
| 2498 | 2545 | .@"align" = alignment, |
| 2499 | 2546 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 2500 | 2547 | }); |
| 2548 | try self.createSectionOrdinal(.{ |
| 2549 | .seg = self.text_segment_cmd_index.?, |
| 2550 | .sect = self.text_section_index.?, |
| 2551 | }); |
| 2501 | 2552 | } |
| 2502 | 2553 | |
| 2503 | 2554 | if (self.stubs_section_index == null) { |
| ... | ... | @@ -2518,6 +2569,10 @@ fn populateMetadata(self: *MachO) !void { |
| 2518 | 2569 | .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 2519 | 2570 | .reserved2 = stub_size, |
| 2520 | 2571 | }); |
| 2572 | try self.createSectionOrdinal(.{ |
| 2573 | .seg = self.text_segment_cmd_index.?, |
| 2574 | .sect = self.stubs_section_index.?, |
| 2575 | }); |
| 2521 | 2576 | } |
| 2522 | 2577 | |
| 2523 | 2578 | if (self.stub_helper_section_index == null) { |
| ... | ... | @@ -2538,6 +2593,10 @@ fn populateMetadata(self: *MachO) !void { |
| 2538 | 2593 | .@"align" = alignment, |
| 2539 | 2594 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 2540 | 2595 | }); |
| 2596 | try self.createSectionOrdinal(.{ |
| 2597 | .seg = self.text_segment_cmd_index.?, |
| 2598 | .sect = self.stub_helper_section_index.?, |
| 2599 | }); |
| 2541 | 2600 | } |
| 2542 | 2601 | |
| 2543 | 2602 | if (self.data_const_segment_cmd_index == null) { |
| ... | ... | @@ -2557,6 +2616,10 @@ fn populateMetadata(self: *MachO) !void { |
| 2557 | 2616 | .@"align" = 3, // 2^3 = @sizeOf(u64) |
| 2558 | 2617 | .flags = macho.S_NON_LAZY_SYMBOL_POINTERS, |
| 2559 | 2618 | }); |
| 2619 | try self.createSectionOrdinal(.{ |
| 2620 | .seg = self.data_const_segment_cmd_index.?, |
| 2621 | .sect = self.got_section_index.?, |
| 2622 | }); |
| 2560 | 2623 | } |
| 2561 | 2624 | |
| 2562 | 2625 | if (self.data_segment_cmd_index == null) { |
| ... | ... | @@ -2576,6 +2639,10 @@ fn populateMetadata(self: *MachO) !void { |
| 2576 | 2639 | .@"align" = 3, // 2^3 = @sizeOf(u64) |
| 2577 | 2640 | .flags = macho.S_LAZY_SYMBOL_POINTERS, |
| 2578 | 2641 | }); |
| 2642 | try self.createSectionOrdinal(.{ |
| 2643 | .seg = self.data_segment_cmd_index.?, |
| 2644 | .sect = self.la_symbol_ptr_section_index.?, |
| 2645 | }); |
| 2579 | 2646 | } |
| 2580 | 2647 | |
| 2581 | 2648 | if (self.data_section_index == null) { |
| ... | ... | @@ -2584,6 +2651,10 @@ fn populateMetadata(self: *MachO) !void { |
| 2584 | 2651 | try data_seg.addSection(self.base.allocator, "__data", .{ |
| 2585 | 2652 | .@"align" = 3, // 2^3 = @sizeOf(u64) |
| 2586 | 2653 | }); |
| 2654 | try self.createSectionOrdinal(.{ |
| 2655 | .seg = self.data_segment_cmd_index.?, |
| 2656 | .sect = self.data_section_index.?, |
| 2657 | }); |
| 2587 | 2658 | } |
| 2588 | 2659 | |
| 2589 | 2660 | if (self.linkedit_segment_cmd_index == null) { |
| ... | ... | @@ -3290,6 +3361,8 @@ pub fn deinit(self: *MachO) void { |
| 3290 | 3361 | ds.deinit(self.base.allocator); |
| 3291 | 3362 | } |
| 3292 | 3363 | |
| 3364 | self.section_ordinals.deinit(self.base.allocator); |
| 3365 | self.section_to_ordinal.deinit(self.base.allocator); |
| 3293 | 3366 | self.pending_updates.deinit(self.base.allocator); |
| 3294 | 3367 | self.got_entries.deinit(self.base.allocator); |
| 3295 | 3368 | self.got_entries_map.deinit(self.base.allocator); |
| ... | ... | @@ -5816,37 +5889,6 @@ pub fn symbolIsTemp(sym: macho.nlist_64, sym_name: []const u8) bool { |
| 5816 | 5889 | return mem.startsWith(u8, sym_name, "l") or mem.startsWith(u8, sym_name, "L"); |
| 5817 | 5890 | } |
| 5818 | 5891 | |
| 5819 | | pub fn sectionId(self: MachO, match: MatchingSection) u8 { |
| 5820 | | // TODO there might be a more generic way of doing this. |
| 5821 | | var section: u8 = 0; |
| 5822 | | for (self.load_commands.items) |cmd, cmd_id| { |
| 5823 | | if (cmd != .Segment) break; |
| 5824 | | if (cmd_id == match.seg) { |
| 5825 | | section += @intCast(u8, match.sect) + 1; |
| 5826 | | break; |
| 5827 | | } |
| 5828 | | section += @intCast(u8, cmd.Segment.sections.items.len); |
| 5829 | | } |
| 5830 | | return section; |
| 5831 | | } |
| 5832 | | |
| 5833 | | pub fn unpackSectionId(self: MachO, section_id: u8) MatchingSection { |
| 5834 | | var match: MatchingSection = undefined; |
| 5835 | | var section: u8 = 0; |
| 5836 | | outer: for (self.load_commands.items) |cmd, cmd_id| { |
| 5837 | | assert(cmd == .Segment); |
| 5838 | | for (cmd.Segment.sections.items) |_, sect_id| { |
| 5839 | | section += 1; |
| 5840 | | if (section_id == section) { |
| 5841 | | match.seg = @intCast(u16, cmd_id); |
| 5842 | | match.sect = @intCast(u16, sect_id); |
| 5843 | | break :outer; |
| 5844 | | } |
| 5845 | | } |
| 5846 | | } |
| 5847 | | return match; |
| 5848 | | } |
| 5849 | | |
| 5850 | 5892 | fn packDylibOrdinal(ordinal: u16) u16 { |
| 5851 | 5893 | return ordinal * macho.N_SYMBOL_RESOLVER; |
| 5852 | 5894 | } |
| ... | ... | @@ -5867,3 +5909,10 @@ pub fn findFirst(comptime T: type, haystack: []T, start: usize, predicate: anyty |
| 5867 | 5909 | } |
| 5868 | 5910 | return i; |
| 5869 | 5911 | } |
| 5912 | |
| 5913 | fn createSectionOrdinal(self: *MachO, match: MatchingSection) !void { |
| 5914 | if (self.section_to_ordinal.contains(match)) return; |
| 5915 | const ordinal = @intCast(u8, self.section_ordinals.items.len); |
| 5916 | try self.section_ordinals.append(self.base.allocator, match); |
| 5917 | try self.section_to_ordinal.putNoClobber(self.base.allocator, match, ordinal); |
| 5918 | } |