| ... | @@ -167,6 +167,9 @@ strtab_needs_relocation: bool = false, | ... | @@ -167,6 +167,9 @@ strtab_needs_relocation: bool = false, |
| 167 | has_dices: bool = false, | 167 | has_dices: bool = false, |
| 168 | has_stabs: bool = false, | 168 | has_stabs: bool = false, |
| 169 | | 169 | |
| | 170 | section_ordinals: std.ArrayListUnmanaged(MatchingSection) = .{}, |
| | 171 | section_to_ordinal: std.AutoHashMapUnmanaged(MatchingSection, u8) = .{}, |
| | 172 | |
| 170 | pending_updates: std.ArrayListUnmanaged(struct { | 173 | pending_updates: std.ArrayListUnmanaged(struct { |
| 171 | kind: enum { | 174 | kind: enum { |
| 172 | got, | 175 | got, |
| ... | @@ -925,6 +928,13 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void { | ... | @@ -925,6 +928,13 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void { |
| 925 | else => unreachable, | 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 | try self.populateMetadata(); | 938 | try self.populateMetadata(); |
| 929 | try self.parseInputFiles(positionals.items, self.base.options.sysroot); | 939 | try self.parseInputFiles(positionals.items, self.base.options.sysroot); |
| 930 | try self.parseLibs(libs.items, self.base.options.sysroot); | 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,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 | return res; | 1499 | return res; |
| 1486 | } | 1500 | } |
| 1487 | | 1501 | |
| ... | @@ -1606,6 +1620,38 @@ fn sortSections(self: *MachO) !void { | ... | @@ -1606,6 +1620,38 @@ fn sortSections(self: *MachO) !void { |
| 1606 | self.blocks.deinit(self.base.allocator); | 1620 | self.blocks.deinit(self.base.allocator); |
| 1607 | self.blocks = transient; | 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 | fn allocateTextSegment(self: *MachO) !void { | 1657 | fn allocateTextSegment(self: *MachO) !void { |
| ... | @@ -1732,7 +1778,7 @@ fn allocateTextBlocks(self: *MachO) !void { | ... | @@ -1732,7 +1778,7 @@ fn allocateTextBlocks(self: *MachO) !void { |
| 1732 | const sect = seg.sections.items[match.sect]; | 1778 | const sect = seg.sections.items[match.sect]; |
| 1733 | | 1779 | |
| 1734 | var base_addr: u64 = sect.addr; | 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 | log.debug(" within section {s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) }); | 1783 | log.debug(" within section {s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) }); |
| 1738 | log.debug(" {}", .{sect}); | 1784 | log.debug(" {}", .{sect}); |
| ... | @@ -2260,6 +2306,7 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2260,6 +2306,7 @@ fn resolveSymbols(self: *MachO) !void { |
| 2260 | .sect = self.common_section_index.?, | 2306 | .sect = self.common_section_index.?, |
| 2261 | }; | 2307 | }; |
| 2262 | }; | 2308 | }; |
| | 2309 | try self.createSectionOrdinal(match); |
| 2263 | | 2310 | |
| 2264 | const size = sym.n_value; | 2311 | const size = sym.n_value; |
| 2265 | const code = try self.base.allocator.alloc(u8, size); | 2312 | const code = try self.base.allocator.alloc(u8, size); |
| ... | @@ -2272,7 +2319,7 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2272,7 +2319,7 @@ fn resolveSymbols(self: *MachO) !void { |
| 2272 | var nlist = macho.nlist_64{ | 2319 | var nlist = macho.nlist_64{ |
| 2273 | .n_strx = sym.n_strx, | 2320 | .n_strx = sym.n_strx, |
| 2274 | .n_type = macho.N_SECT, | 2321 | .n_type = macho.N_SECT, |
| 2275 | .n_sect = self.sectionId(match), | 2322 | .n_sect = self.section_to_ordinal.get(match) orelse unreachable, |
| 2276 | .n_desc = 0, | 2323 | .n_desc = 0, |
| 2277 | .n_value = 0, | 2324 | .n_value = 0, |
| 2278 | }; | 2325 | }; |
| ... | @@ -2402,7 +2449,7 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2402,7 +2449,7 @@ fn resolveSymbols(self: *MachO) !void { |
| 2402 | var nlist = macho.nlist_64{ | 2449 | var nlist = macho.nlist_64{ |
| 2403 | .n_strx = undef.n_strx, | 2450 | .n_strx = undef.n_strx, |
| 2404 | .n_type = macho.N_SECT, | 2451 | .n_type = macho.N_SECT, |
| 2405 | .n_sect = self.sectionId(match), | 2452 | .n_sect = self.section_to_ordinal.get(match) orelse unreachable, |
| 2406 | .n_desc = 0, | 2453 | .n_desc = 0, |
| 2407 | .n_value = 0, | 2454 | .n_value = 0, |
| 2408 | }; | 2455 | }; |
| ... | @@ -2498,6 +2545,10 @@ fn populateMetadata(self: *MachO) !void { | ... | @@ -2498,6 +2545,10 @@ fn populateMetadata(self: *MachO) !void { |
| 2498 | .@"align" = alignment, | 2545 | .@"align" = alignment, |
| 2499 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, | 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 | if (self.stubs_section_index == null) { | 2554 | if (self.stubs_section_index == null) { |
| ... | @@ -2518,6 +2569,10 @@ fn populateMetadata(self: *MachO) !void { | ... | @@ -2518,6 +2569,10 @@ fn populateMetadata(self: *MachO) !void { |
| 2518 | .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, | 2569 | .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 2519 | .reserved2 = stub_size, | 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 | if (self.stub_helper_section_index == null) { | 2578 | if (self.stub_helper_section_index == null) { |
| ... | @@ -2538,6 +2593,10 @@ fn populateMetadata(self: *MachO) !void { | ... | @@ -2538,6 +2593,10 @@ fn populateMetadata(self: *MachO) !void { |
| 2538 | .@"align" = alignment, | 2593 | .@"align" = alignment, |
| 2539 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, | 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 | if (self.data_const_segment_cmd_index == null) { | 2602 | if (self.data_const_segment_cmd_index == null) { |
| ... | @@ -2557,6 +2616,10 @@ fn populateMetadata(self: *MachO) !void { | ... | @@ -2557,6 +2616,10 @@ fn populateMetadata(self: *MachO) !void { |
| 2557 | .@"align" = 3, // 2^3 = @sizeOf(u64) | 2616 | .@"align" = 3, // 2^3 = @sizeOf(u64) |
| 2558 | .flags = macho.S_NON_LAZY_SYMBOL_POINTERS, | 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 | if (self.data_segment_cmd_index == null) { | 2625 | if (self.data_segment_cmd_index == null) { |
| ... | @@ -2576,6 +2639,10 @@ fn populateMetadata(self: *MachO) !void { | ... | @@ -2576,6 +2639,10 @@ fn populateMetadata(self: *MachO) !void { |
| 2576 | .@"align" = 3, // 2^3 = @sizeOf(u64) | 2639 | .@"align" = 3, // 2^3 = @sizeOf(u64) |
| 2577 | .flags = macho.S_LAZY_SYMBOL_POINTERS, | 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 | if (self.data_section_index == null) { | 2648 | if (self.data_section_index == null) { |
| ... | @@ -2584,6 +2651,10 @@ fn populateMetadata(self: *MachO) !void { | ... | @@ -2584,6 +2651,10 @@ fn populateMetadata(self: *MachO) !void { |
| 2584 | try data_seg.addSection(self.base.allocator, "__data", .{ | 2651 | try data_seg.addSection(self.base.allocator, "__data", .{ |
| 2585 | .@"align" = 3, // 2^3 = @sizeOf(u64) | 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 | if (self.linkedit_segment_cmd_index == null) { | 2660 | if (self.linkedit_segment_cmd_index == null) { |
| ... | @@ -3290,6 +3361,8 @@ pub fn deinit(self: *MachO) void { | ... | @@ -3290,6 +3361,8 @@ pub fn deinit(self: *MachO) void { |
| 3290 | ds.deinit(self.base.allocator); | 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 | self.pending_updates.deinit(self.base.allocator); | 3366 | self.pending_updates.deinit(self.base.allocator); |
| 3294 | self.got_entries.deinit(self.base.allocator); | 3367 | self.got_entries.deinit(self.base.allocator); |
| 3295 | self.got_entries_map.deinit(self.base.allocator); | 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,37 +5889,6 @@ pub fn symbolIsTemp(sym: macho.nlist_64, sym_name: []const u8) bool { |
| 5816 | return mem.startsWith(u8, sym_name, "l") or mem.startsWith(u8, sym_name, "L"); | 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 | fn packDylibOrdinal(ordinal: u16) u16 { | 5892 | fn packDylibOrdinal(ordinal: u16) u16 { |
| 5851 | return ordinal * macho.N_SYMBOL_RESOLVER; | 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,3 +5909,10 @@ pub fn findFirst(comptime T: type, haystack: []T, start: usize, predicate: anyty |
| 5867 | } | 5909 | } |
| 5868 | return i; | 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 | } |