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,
168168has_dices: bool = false,
169169has_stabs: bool = false,
170170
171section_ordinals: std.ArrayListUnmanaged(MatchingSection) = .{},
172section_to_ordinal: std.AutoHashMapUnmanaged(MatchingSection, u8) = .{},
171section_ordinals: std.AutoArrayHashMapUnmanaged(MatchingSection, void) = .{},
173172
174173pending_updates: std.ArrayListUnmanaged(struct {
175174 kind: enum {
......@@ -940,13 +939,6 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
940939 });
941940 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
950942 try self.populateMetadata();
951943 try self.parseInputFiles(positionals.items, self.base.options.sysroot);
952944 try self.parseLibs(libs.items, self.base.options.sysroot);
......@@ -1454,7 +1446,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
14541446 };
14551447
14561448 if (res) |match| {
1457 try self.createSectionOrdinal(match);
1449 _ = try self.section_ordinals.getOrPut(self.base.allocator, match);
14581450 }
14591451
14601452 return res;
......@@ -1586,32 +1578,29 @@ fn sortSections(self: *MachO) !void {
15861578 {
15871579 // Create new section ordinals.
15881580 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 });
15951581 const text_seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
15961582 for (text_seg.sections.items) |_, sect_id| {
1597 try self.createSectionOrdinal(.{
1583 const res = self.section_ordinals.getOrPutAssumeCapacity(.{
15981584 .seg = self.text_segment_cmd_index.?,
15991585 .sect = @intCast(u16, sect_id),
16001586 });
1587 assert(!res.found_existing);
16011588 }
16021589 const data_const_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
16031590 for (data_const_seg.sections.items) |_, sect_id| {
1604 try self.createSectionOrdinal(.{
1591 const res = self.section_ordinals.getOrPutAssumeCapacity(.{
16051592 .seg = self.data_const_segment_cmd_index.?,
16061593 .sect = @intCast(u16, sect_id),
16071594 });
1595 assert(!res.found_existing);
16081596 }
16091597 const data_seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;
16101598 for (data_seg.sections.items) |_, sect_id| {
1611 try self.createSectionOrdinal(.{
1599 const res = self.section_ordinals.getOrPutAssumeCapacity(.{
16121600 .seg = self.data_segment_cmd_index.?,
16131601 .sect = @intCast(u16, sect_id),
16141602 });
1603 assert(!res.found_existing);
16151604 }
16161605 }
16171606}
......@@ -1740,7 +1729,7 @@ fn allocateTextBlocks(self: *MachO) !void {
17401729 const sect = seg.sections.items[match.sect];
17411730
17421731 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
17451734 log.debug(" within section {s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) });
17461735 log.debug(" {}", .{sect});
......@@ -2262,7 +2251,7 @@ fn resolveSymbols(self: *MachO) !void {
22622251 .sect = self.common_section_index.?,
22632252 };
22642253 };
2265 try self.createSectionOrdinal(match);
2254 _ = try self.section_ordinals.getOrPut(self.base.allocator, match);
22662255
22672256 const size = sym.n_value;
22682257 const code = try self.base.allocator.alloc(u8, size);
......@@ -2275,7 +2264,7 @@ fn resolveSymbols(self: *MachO) !void {
22752264 var nlist = macho.nlist_64{
22762265 .n_strx = sym.n_strx,
22772266 .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),
22792268 .n_desc = 0,
22802269 .n_value = 0,
22812270 };
......@@ -2391,7 +2380,7 @@ fn resolveSymbols(self: *MachO) !void {
23912380 var nlist = macho.nlist_64{
23922381 .n_strx = undef.n_strx,
23932382 .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),
23952384 .n_desc = 0,
23962385 .n_value = 0,
23972386 };
......@@ -2487,7 +2476,7 @@ fn populateMetadata(self: *MachO) !void {
24872476 .@"align" = alignment,
24882477 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
24892478 });
2490 try self.createSectionOrdinal(.{
2479 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
24912480 .seg = self.text_segment_cmd_index.?,
24922481 .sect = self.text_section_index.?,
24932482 });
......@@ -2511,7 +2500,7 @@ fn populateMetadata(self: *MachO) !void {
25112500 .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
25122501 .reserved2 = stub_size,
25132502 });
2514 try self.createSectionOrdinal(.{
2503 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
25152504 .seg = self.text_segment_cmd_index.?,
25162505 .sect = self.stubs_section_index.?,
25172506 });
......@@ -2535,7 +2524,7 @@ fn populateMetadata(self: *MachO) !void {
25352524 .@"align" = alignment,
25362525 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
25372526 });
2538 try self.createSectionOrdinal(.{
2527 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
25392528 .seg = self.text_segment_cmd_index.?,
25402529 .sect = self.stub_helper_section_index.?,
25412530 });
......@@ -2558,7 +2547,7 @@ fn populateMetadata(self: *MachO) !void {
25582547 .@"align" = 3, // 2^3 = @sizeOf(u64)
25592548 .flags = macho.S_NON_LAZY_SYMBOL_POINTERS,
25602549 });
2561 try self.createSectionOrdinal(.{
2550 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
25622551 .seg = self.data_const_segment_cmd_index.?,
25632552 .sect = self.got_section_index.?,
25642553 });
......@@ -2581,7 +2570,7 @@ fn populateMetadata(self: *MachO) !void {
25812570 .@"align" = 3, // 2^3 = @sizeOf(u64)
25822571 .flags = macho.S_LAZY_SYMBOL_POINTERS,
25832572 });
2584 try self.createSectionOrdinal(.{
2573 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
25852574 .seg = self.data_segment_cmd_index.?,
25862575 .sect = self.la_symbol_ptr_section_index.?,
25872576 });
......@@ -2593,7 +2582,7 @@ fn populateMetadata(self: *MachO) !void {
25932582 try data_seg.addSection(self.base.allocator, "__data", .{
25942583 .@"align" = 3, // 2^3 = @sizeOf(u64)
25952584 });
2596 try self.createSectionOrdinal(.{
2585 _ = try self.section_ordinals.getOrPut(self.base.allocator, .{
25972586 .seg = self.data_segment_cmd_index.?,
25982587 .sect = self.data_section_index.?,
25992588 });
......@@ -3324,7 +3313,6 @@ pub fn deinit(self: *MachO) void {
33243313 }
33253314
33263315 self.section_ordinals.deinit(self.base.allocator);
3327 self.section_to_ordinal.deinit(self.base.allocator);
33283316 self.pending_updates.deinit(self.base.allocator);
33293317 self.got_entries.deinit(self.base.allocator);
33303318 self.got_entries_map.deinit(self.base.allocator);
......@@ -5882,13 +5870,6 @@ pub fn findFirst(comptime T: type, haystack: []T, start: usize, predicate: anyty
58825870 return i;
58835871}
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
58925873fn printSymtabAndTextBlock(self: *MachO) void {
58935874 log.debug("locals", .{});
58945875 for (self.locals.items) |sym, id| {
src/link/MachO/Object.zig+5-5
......@@ -402,7 +402,7 @@ const TextBlockParser = struct {
402402
403403 const senior_nlist = aliases.pop();
404404 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
407407 const start_addr = senior_nlist.nlist.n_value - self.section.addr;
408408 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 {
446446 for (aliases.items) |alias| {
447447 block.aliases.appendAssumeCapacity(alias.index);
448448 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);
450450 }
451451
452452 try block.parseRelocs(self.relocs, .{
......@@ -588,7 +588,7 @@ pub fn parseTextBlocks(
588588 try macho_file.locals.append(allocator, .{
589589 .n_strx = try macho_file.makeString(sym_name),
590590 .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),
592592 .n_desc = 0,
593593 .n_value = sect.addr,
594594 });
......@@ -733,7 +733,7 @@ pub fn parseTextBlocks(
733733 try macho_file.locals.append(allocator, .{
734734 .n_strx = try macho_file.makeString(sym_name),
735735 .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),
737737 .n_desc = 0,
738738 .n_value = sect.addr,
739739 });
......@@ -781,7 +781,7 @@ pub fn parseTextBlocks(
781781 const nlist = nlist_with_index.nlist;
782782 const local_sym_index = self.symbol_mapping.get(nlist_with_index.index) orelse unreachable;
783783 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
786786 const stab: ?TextBlock.Stab = if (self.debug_info) |di| blk: {
787787 // 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
637637 try context.macho_file.locals.append(context.allocator, .{
638638 .n_strx = try context.macho_file.makeString(sym_name),
639639 .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),
641641 .n_desc = 0,
642642 .n_value = sect.addr,
643643 });
......@@ -844,7 +844,7 @@ pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: R
844844 },
845845 .local => {
846846 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];
848848 const seg = context.macho_file.load_commands.items[match.seg].Segment;
849849 const sect = seg.sections.items[match.sect];
850850 const sect_type = commands.sectionType(sect);
......@@ -1108,7 +1108,7 @@ pub fn resolveRelocs(self: *TextBlock, macho_file: *MachO) !void {
11081108 const sym = macho_file.locals.items[rel.where_index];
11091109 const is_tlv = is_tlv: {
11101110 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];
11121112 const seg = macho_file.load_commands.items[match.seg].Segment;
11131113 const sect = seg.sections.items[match.sect];
11141114 break :is_tlv commands.sectionType(sect) == macho.S_THREAD_LOCAL_VARIABLES;