authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-02 18:15:27+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-02 19:49:32+02:00
logbf25650974933cdb8c1314a85e0838257f6f4471
tree2310ad44ae66ca5b1d0341553841ff67be4cf724
parentf3b328ee8cb9c8340afaec510055d41aa4895583

macho: refactor management of section ordinals

Instead of storing a two-way relation (seg,sect) <=> ordinal we get the latter with `getIndex((seg, sect))`.

3 files changed, 26 insertions(+), 45 deletions(-)

src/link/MachO.zig+18-37
...@@ -168,8 +168,7 @@ strtab_needs_relocation: bool = false,...@@ -168,8 +168,7 @@ strtab_needs_relocation: bool = false,
168has_dices: bool = false,168has_dices: bool = false,
169has_stabs: bool = false,169has_stabs: bool = false,
170170
171section_ordinals: std.ArrayListUnmanaged(MatchingSection) = .{},171section_ordinals: std.AutoArrayHashMapUnmanaged(MatchingSection, void) = .{},
172section_to_ordinal: std.AutoHashMapUnmanaged(MatchingSection, u8) = .{},
173172
174pending_updates: std.ArrayListUnmanaged(struct {173pending_updates: std.ArrayListUnmanaged(struct {
175 kind: enum {174 kind: enum {
...@@ -940,13 +939,6 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {...@@ -940,13 +939,6 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
940 });939 });
941 try self.strtab.append(self.base.allocator, 0);940 try self.strtab.append(self.base.allocator, 0);
942941
943 // Initialize section ordinals with null ordinal pointing at
944 // PAGEZERO segment.
945 try self.section_ordinals.append(self.base.allocator, .{
946 .seg = 0,
947 .sect = 0,
948 });
949
950 try self.populateMetadata();942 try self.populateMetadata();
951 try self.parseInputFiles(positionals.items, self.base.options.sysroot);943 try self.parseInputFiles(positionals.items, self.base.options.sysroot);
952 try self.parseLibs(libs.items, self.base.options.sysroot);944 try self.parseLibs(libs.items, self.base.options.sysroot);
...@@ -1454,7 +1446,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1454,7 +1446,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1454 };1446 };
14551447
1456 if (res) |match| {1448 if (res) |match| {
1457 try self.createSectionOrdinal(match);1449 _ = try self.section_ordinals.getOrPut(self.base.allocator, match);
1458 }1450 }
14591451
1460 return res;1452 return res;
...@@ -1586,32 +1578,29 @@ fn sortSections(self: *MachO) !void {...@@ -1586,32 +1578,29 @@ fn sortSections(self: *MachO) !void {
1586 {1578 {
1587 // Create new section ordinals.1579 // Create new section ordinals.
1588 self.section_ordinals.clearRetainingCapacity();1580 self.section_ordinals.clearRetainingCapacity();
1589 self.section_to_ordinal.clearRetainingCapacity();
1590 // First ordinal is always null
1591 self.section_ordinals.appendAssumeCapacity(.{
1592 .seg = 0,
1593 .sect = 0,
1594 });
1595 const text_seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;1581 const text_seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
1596 for (text_seg.sections.items) |_, sect_id| {1582 for (text_seg.sections.items) |_, sect_id| {
1597 try self.createSectionOrdinal(.{1583 const res = self.section_ordinals.getOrPutAssumeCapacity(.{
1598 .seg = self.text_segment_cmd_index.?,1584 .seg = self.text_segment_cmd_index.?,
1599 .sect = @intCast(u16, sect_id),1585 .sect = @intCast(u16, sect_id),
1600 });1586 });
1587 assert(!res.found_existing);
1601 }1588 }
1602 const data_const_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;1589 const data_const_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
1603 for (data_const_seg.sections.items) |_, sect_id| {1590 for (data_const_seg.sections.items) |_, sect_id| {
1604 try self.createSectionOrdinal(.{1591 const res = self.section_ordinals.getOrPutAssumeCapacity(.{
1605 .seg = self.data_const_segment_cmd_index.?,1592 .seg = self.data_const_segment_cmd_index.?,
1606 .sect = @intCast(u16, sect_id),1593 .sect = @intCast(u16, sect_id),
1607 });1594 });
1595 assert(!res.found_existing);
1608 }1596 }
1609 const data_seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;1597 const data_seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;
1610 for (data_seg.sections.items) |_, sect_id| {1598 for (data_seg.sections.items) |_, sect_id| {
1611 try self.createSectionOrdinal(.{1599 const res = self.section_ordinals.getOrPutAssumeCapacity(.{
1612 .seg = self.data_segment_cmd_index.?,1600 .seg = self.data_segment_cmd_index.?,
1613 .sect = @intCast(u16, sect_id),1601 .sect = @intCast(u16, sect_id),
1614 });1602 });
1603 assert(!res.found_existing);
1615 }1604 }
1616 }1605 }
1617}1606}
...@@ -1740,7 +1729,7 @@ fn allocateTextBlocks(self: *MachO) !void {...@@ -1740,7 +1729,7 @@ fn allocateTextBlocks(self: *MachO) !void {
1740 const sect = seg.sections.items[match.sect];1729 const sect = seg.sections.items[match.sect];
17411730
1742 var base_addr: u64 = sect.addr;1731 var base_addr: u64 = sect.addr;
1743 const n_sect = self.section_to_ordinal.get(match) orelse unreachable;1732 const n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);
17441733
1745 log.debug(" within section {s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) });1734 log.debug(" within section {s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) });
1746 log.debug(" {}", .{sect});1735 log.debug(" {}", .{sect});
...@@ -2262,7 +2251,7 @@ fn resolveSymbols(self: *MachO) !void {...@@ -2262,7 +2251,7 @@ fn resolveSymbols(self: *MachO) !void {
2262 .sect = self.common_section_index.?,2251 .sect = self.common_section_index.?,
2263 };2252 };
2264 };2253 };
2265 try self.createSectionOrdinal(match);2254 _ = try self.section_ordinals.getOrPut(self.base.allocator, match);
22662255
2267 const size = sym.n_value;2256 const size = sym.n_value;
2268 const code = try self.base.allocator.alloc(u8, size);2257 const code = try self.base.allocator.alloc(u8, size);
...@@ -2275,7 +2264,7 @@ fn resolveSymbols(self: *MachO) !void {...@@ -2275,7 +2264,7 @@ fn resolveSymbols(self: *MachO) !void {
2275 var nlist = macho.nlist_64{2264 var nlist = macho.nlist_64{
2276 .n_strx = sym.n_strx,2265 .n_strx = sym.n_strx,
2277 .n_type = macho.N_SECT,2266 .n_type = macho.N_SECT,
2278 .n_sect = self.section_to_ordinal.get(match) orelse unreachable,2267 .n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1),
2279 .n_desc = 0,2268 .n_desc = 0,
2280 .n_value = 0,2269 .n_value = 0,
2281 };2270 };
...@@ -2391,7 +2380,7 @@ fn resolveSymbols(self: *MachO) !void {...@@ -2391,7 +2380,7 @@ fn resolveSymbols(self: *MachO) !void {
2391 var nlist = macho.nlist_64{2380 var nlist = macho.nlist_64{
2392 .n_strx = undef.n_strx,2381 .n_strx = undef.n_strx,
2393 .n_type = macho.N_SECT,2382 .n_type = macho.N_SECT,
2394 .n_sect = self.section_to_ordinal.get(match) orelse unreachable,2383 .n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1),
2395 .n_desc = 0,2384 .n_desc = 0,
2396 .n_value = 0,2385 .n_value = 0,
2397 };2386 };
...@@ -2487,7 +2476,7 @@ fn populateMetadata(self: *MachO) !void {...@@ -2487,7 +2476,7 @@ fn populateMetadata(self: *MachO) !void {
2487 .@"align" = alignment,2476 .@"align" = alignment,
2488 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,2477 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
2489 });2478 });
2490 try self.createSectionOrdinal(.{2479 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
2491 .seg = self.text_segment_cmd_index.?,2480 .seg = self.text_segment_cmd_index.?,
2492 .sect = self.text_section_index.?,2481 .sect = self.text_section_index.?,
2493 });2482 });
...@@ -2511,7 +2500,7 @@ fn populateMetadata(self: *MachO) !void {...@@ -2511,7 +2500,7 @@ fn populateMetadata(self: *MachO) !void {
2511 .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,2500 .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
2512 .reserved2 = stub_size,2501 .reserved2 = stub_size,
2513 });2502 });
2514 try self.createSectionOrdinal(.{2503 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
2515 .seg = self.text_segment_cmd_index.?,2504 .seg = self.text_segment_cmd_index.?,
2516 .sect = self.stubs_section_index.?,2505 .sect = self.stubs_section_index.?,
2517 });2506 });
...@@ -2535,7 +2524,7 @@ fn populateMetadata(self: *MachO) !void {...@@ -2535,7 +2524,7 @@ fn populateMetadata(self: *MachO) !void {
2535 .@"align" = alignment,2524 .@"align" = alignment,
2536 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,2525 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
2537 });2526 });
2538 try self.createSectionOrdinal(.{2527 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
2539 .seg = self.text_segment_cmd_index.?,2528 .seg = self.text_segment_cmd_index.?,
2540 .sect = self.stub_helper_section_index.?,2529 .sect = self.stub_helper_section_index.?,
2541 });2530 });
...@@ -2558,7 +2547,7 @@ fn populateMetadata(self: *MachO) !void {...@@ -2558,7 +2547,7 @@ fn populateMetadata(self: *MachO) !void {
2558 .@"align" = 3, // 2^3 = @sizeOf(u64)2547 .@"align" = 3, // 2^3 = @sizeOf(u64)
2559 .flags = macho.S_NON_LAZY_SYMBOL_POINTERS,2548 .flags = macho.S_NON_LAZY_SYMBOL_POINTERS,
2560 });2549 });
2561 try self.createSectionOrdinal(.{2550 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
2562 .seg = self.data_const_segment_cmd_index.?,2551 .seg = self.data_const_segment_cmd_index.?,
2563 .sect = self.got_section_index.?,2552 .sect = self.got_section_index.?,
2564 });2553 });
...@@ -2581,7 +2570,7 @@ fn populateMetadata(self: *MachO) !void {...@@ -2581,7 +2570,7 @@ fn populateMetadata(self: *MachO) !void {
2581 .@"align" = 3, // 2^3 = @sizeOf(u64)2570 .@"align" = 3, // 2^3 = @sizeOf(u64)
2582 .flags = macho.S_LAZY_SYMBOL_POINTERS,2571 .flags = macho.S_LAZY_SYMBOL_POINTERS,
2583 });2572 });
2584 try self.createSectionOrdinal(.{2573 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
2585 .seg = self.data_segment_cmd_index.?,2574 .seg = self.data_segment_cmd_index.?,
2586 .sect = self.la_symbol_ptr_section_index.?,2575 .sect = self.la_symbol_ptr_section_index.?,
2587 });2576 });
...@@ -2593,7 +2582,7 @@ fn populateMetadata(self: *MachO) !void {...@@ -2593,7 +2582,7 @@ fn populateMetadata(self: *MachO) !void {
2593 try data_seg.addSection(self.base.allocator, "__data", .{2582 try data_seg.addSection(self.base.allocator, "__data", .{
2594 .@"align" = 3, // 2^3 = @sizeOf(u64)2583 .@"align" = 3, // 2^3 = @sizeOf(u64)
2595 });2584 });
2596 try self.createSectionOrdinal(.{2585 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
2597 .seg = self.data_segment_cmd_index.?,2586 .seg = self.data_segment_cmd_index.?,
2598 .sect = self.data_section_index.?,2587 .sect = self.data_section_index.?,
2599 });2588 });
...@@ -3324,7 +3313,6 @@ pub fn deinit(self: *MachO) void {...@@ -3324,7 +3313,6 @@ pub fn deinit(self: *MachO) void {
3324 }3313 }
33253314
3326 self.section_ordinals.deinit(self.base.allocator);3315 self.section_ordinals.deinit(self.base.allocator);
3327 self.section_to_ordinal.deinit(self.base.allocator);
3328 self.pending_updates.deinit(self.base.allocator);3316 self.pending_updates.deinit(self.base.allocator);
3329 self.got_entries.deinit(self.base.allocator);3317 self.got_entries.deinit(self.base.allocator);
3330 self.got_entries_map.deinit(self.base.allocator);3318 self.got_entries_map.deinit(self.base.allocator);
...@@ -5882,13 +5870,6 @@ pub fn findFirst(comptime T: type, haystack: []T, start: usize, predicate: anyty...@@ -5882,13 +5870,6 @@ pub fn findFirst(comptime T: type, haystack: []T, start: usize, predicate: anyty
5882 return i;5870 return i;
5883}5871}
58845872
5885fn createSectionOrdinal(self: *MachO, match: MatchingSection) !void {
5886 if (self.section_to_ordinal.contains(match)) return;
5887 const ordinal = @intCast(u8, self.section_ordinals.items.len);
5888 try self.section_ordinals.append(self.base.allocator, match);
5889 try self.section_to_ordinal.putNoClobber(self.base.allocator, match, ordinal);
5890}
5891
5892fn printSymtabAndTextBlock(self: *MachO) void {5873fn printSymtabAndTextBlock(self: *MachO) void {
5893 log.debug("locals", .{});5874 log.debug("locals", .{});
5894 for (self.locals.items) |sym, id| {5875 for (self.locals.items) |sym, id| {
src/link/MachO/Object.zig+5-5
...@@ -402,7 +402,7 @@ const TextBlockParser = struct {...@@ -402,7 +402,7 @@ const TextBlockParser = struct {
402402
403 const senior_nlist = aliases.pop();403 const senior_nlist = aliases.pop();
404 const senior_sym = &context.macho_file.locals.items[senior_nlist.index];404 const senior_sym = &context.macho_file.locals.items[senior_nlist.index];
405 senior_sym.n_sect = context.macho_file.section_to_ordinal.get(context.match) orelse unreachable;405 senior_sym.n_sect = @intCast(u8, context.macho_file.section_ordinals.getIndex(context.match).? + 1);
406406
407 const start_addr = senior_nlist.nlist.n_value - self.section.addr;407 const start_addr = senior_nlist.nlist.n_value - self.section.addr;
408 const end_addr = if (next_nlist) |n| n.nlist.n_value - self.section.addr else self.section.size;408 const end_addr = if (next_nlist) |n| n.nlist.n_value - self.section.addr else self.section.size;
...@@ -446,7 +446,7 @@ const TextBlockParser = struct {...@@ -446,7 +446,7 @@ const TextBlockParser = struct {
446 for (aliases.items) |alias| {446 for (aliases.items) |alias| {
447 block.aliases.appendAssumeCapacity(alias.index);447 block.aliases.appendAssumeCapacity(alias.index);
448 const sym = &context.macho_file.locals.items[alias.index];448 const sym = &context.macho_file.locals.items[alias.index];
449 sym.n_sect = context.macho_file.section_to_ordinal.get(context.match) orelse unreachable;449 sym.n_sect = @intCast(u8, context.macho_file.section_ordinals.getIndex(context.match).? + 1);
450 }450 }
451451
452 try block.parseRelocs(self.relocs, .{452 try block.parseRelocs(self.relocs, .{
...@@ -588,7 +588,7 @@ pub fn parseTextBlocks(...@@ -588,7 +588,7 @@ pub fn parseTextBlocks(
588 try macho_file.locals.append(allocator, .{588 try macho_file.locals.append(allocator, .{
589 .n_strx = try macho_file.makeString(sym_name),589 .n_strx = try macho_file.makeString(sym_name),
590 .n_type = macho.N_SECT,590 .n_type = macho.N_SECT,
591 .n_sect = macho_file.section_to_ordinal.get(match) orelse unreachable,591 .n_sect = @intCast(u8, macho_file.section_ordinals.getIndex(match).? + 1),
592 .n_desc = 0,592 .n_desc = 0,
593 .n_value = sect.addr,593 .n_value = sect.addr,
594 });594 });
...@@ -733,7 +733,7 @@ pub fn parseTextBlocks(...@@ -733,7 +733,7 @@ pub fn parseTextBlocks(
733 try macho_file.locals.append(allocator, .{733 try macho_file.locals.append(allocator, .{
734 .n_strx = try macho_file.makeString(sym_name),734 .n_strx = try macho_file.makeString(sym_name),
735 .n_type = macho.N_SECT,735 .n_type = macho.N_SECT,
736 .n_sect = macho_file.section_to_ordinal.get(match) orelse unreachable,736 .n_sect = @intCast(u8, macho_file.section_ordinals.getIndex(match).? + 1),
737 .n_desc = 0,737 .n_desc = 0,
738 .n_value = sect.addr,738 .n_value = sect.addr,
739 });739 });
...@@ -781,7 +781,7 @@ pub fn parseTextBlocks(...@@ -781,7 +781,7 @@ pub fn parseTextBlocks(
781 const nlist = nlist_with_index.nlist;781 const nlist = nlist_with_index.nlist;
782 const local_sym_index = self.symbol_mapping.get(nlist_with_index.index) orelse unreachable;782 const local_sym_index = self.symbol_mapping.get(nlist_with_index.index) orelse unreachable;
783 const local = &macho_file.locals.items[local_sym_index];783 const local = &macho_file.locals.items[local_sym_index];
784 local.n_sect = macho_file.section_to_ordinal.get(match) orelse unreachable;784 local.n_sect = @intCast(u8, macho_file.section_ordinals.getIndex(match).? + 1);
785785
786 const stab: ?TextBlock.Stab = if (self.debug_info) |di| blk: {786 const stab: ?TextBlock.Stab = if (self.debug_info) |di| blk: {
787 // TODO there has to be a better to handle this.787 // TODO there has to be a better to handle this.
src/link/MachO/TextBlock.zig+3-3
...@@ -637,7 +637,7 @@ fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Reloc...@@ -637,7 +637,7 @@ fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Reloc
637 try context.macho_file.locals.append(context.allocator, .{637 try context.macho_file.locals.append(context.allocator, .{
638 .n_strx = try context.macho_file.makeString(sym_name),638 .n_strx = try context.macho_file.makeString(sym_name),
639 .n_type = macho.N_SECT,639 .n_type = macho.N_SECT,
640 .n_sect = context.macho_file.section_to_ordinal.get(match) orelse unreachable,640 .n_sect = @intCast(u8, context.macho_file.section_ordinals.getIndex(match).? + 1),
641 .n_desc = 0,641 .n_desc = 0,
642 .n_value = sect.addr,642 .n_value = sect.addr,
643 });643 });
...@@ -844,7 +844,7 @@ pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: R...@@ -844,7 +844,7 @@ pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: R
844 },844 },
845 .local => {845 .local => {
846 const source_sym = context.macho_file.locals.items[self.local_sym_index];846 const source_sym = context.macho_file.locals.items[self.local_sym_index];
847 const match = context.macho_file.section_ordinals.items[source_sym.n_sect];847 const match = context.macho_file.section_ordinals.keys()[source_sym.n_sect - 1];
848 const seg = context.macho_file.load_commands.items[match.seg].Segment;848 const seg = context.macho_file.load_commands.items[match.seg].Segment;
849 const sect = seg.sections.items[match.sect];849 const sect = seg.sections.items[match.sect];
850 const sect_type = commands.sectionType(sect);850 const sect_type = commands.sectionType(sect);
...@@ -1108,7 +1108,7 @@ pub fn resolveRelocs(self: *TextBlock, macho_file: *MachO) !void {...@@ -1108,7 +1108,7 @@ pub fn resolveRelocs(self: *TextBlock, macho_file: *MachO) !void {
1108 const sym = macho_file.locals.items[rel.where_index];1108 const sym = macho_file.locals.items[rel.where_index];
1109 const is_tlv = is_tlv: {1109 const is_tlv = is_tlv: {
1110 const source_sym = macho_file.locals.items[self.local_sym_index];1110 const source_sym = macho_file.locals.items[self.local_sym_index];
1111 const match = macho_file.section_ordinals.items[source_sym.n_sect];1111 const match = macho_file.section_ordinals.keys()[source_sym.n_sect - 1];
1112 const seg = macho_file.load_commands.items[match.seg].Segment;1112 const seg = macho_file.load_commands.items[match.seg].Segment;
1113 const sect = seg.sections.items[match.sect];1113 const sect = seg.sections.items[match.sect];
1114 break :is_tlv commands.sectionType(sect) == macho.S_THREAD_LOCAL_VARIABLES;1114 break :is_tlv commands.sectionType(sect) == macho.S_THREAD_LOCAL_VARIABLES;