diff --git a/src/link/MachO.zig b/src/link/MachO.zig index bfc0ab8ff6..d3412cec3d 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -168,8 +168,7 @@ strtab_needs_relocation: bool = false, has_dices: bool = false, has_stabs: bool = false, -section_ordinals: std.ArrayListUnmanaged(MatchingSection) = .{}, -section_to_ordinal: std.AutoHashMapUnmanaged(MatchingSection, u8) = .{}, +section_ordinals: std.AutoArrayHashMapUnmanaged(MatchingSection, void) = .{}, pending_updates: std.ArrayListUnmanaged(struct { kind: enum { @@ -940,13 +939,6 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void { }); try self.strtab.append(self.base.allocator, 0); - // Initialize section ordinals with null ordinal pointing at - // PAGEZERO segment. - try self.section_ordinals.append(self.base.allocator, .{ - .seg = 0, - .sect = 0, - }); - try self.populateMetadata(); try self.parseInputFiles(positionals.items, self.base.options.sysroot); try self.parseLibs(libs.items, self.base.options.sysroot); @@ -1454,7 +1446,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio }; if (res) |match| { - try self.createSectionOrdinal(match); + _ = try self.section_ordinals.getOrPut(self.base.allocator, match); } return res; @@ -1586,32 +1578,29 @@ fn sortSections(self: *MachO) !void { { // Create new section ordinals. self.section_ordinals.clearRetainingCapacity(); - self.section_to_ordinal.clearRetainingCapacity(); - // First ordinal is always null - self.section_ordinals.appendAssumeCapacity(.{ - .seg = 0, - .sect = 0, - }); const text_seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment; for (text_seg.sections.items) |_, sect_id| { - try self.createSectionOrdinal(.{ + const res = self.section_ordinals.getOrPutAssumeCapacity(.{ .seg = self.text_segment_cmd_index.?, .sect = @intCast(u16, sect_id), }); + assert(!res.found_existing); } const data_const_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; for (data_const_seg.sections.items) |_, sect_id| { - try self.createSectionOrdinal(.{ + const res = self.section_ordinals.getOrPutAssumeCapacity(.{ .seg = self.data_const_segment_cmd_index.?, .sect = @intCast(u16, sect_id), }); + assert(!res.found_existing); } const data_seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; for (data_seg.sections.items) |_, sect_id| { - try self.createSectionOrdinal(.{ + const res = self.section_ordinals.getOrPutAssumeCapacity(.{ .seg = self.data_segment_cmd_index.?, .sect = @intCast(u16, sect_id), }); + assert(!res.found_existing); } } } @@ -1740,7 +1729,7 @@ fn allocateTextBlocks(self: *MachO) !void { const sect = seg.sections.items[match.sect]; var base_addr: u64 = sect.addr; - const n_sect = self.section_to_ordinal.get(match) orelse unreachable; + const n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1); log.debug(" within section {s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) }); log.debug(" {}", .{sect}); @@ -2262,7 +2251,7 @@ fn resolveSymbols(self: *MachO) !void { .sect = self.common_section_index.?, }; }; - try self.createSectionOrdinal(match); + _ = try self.section_ordinals.getOrPut(self.base.allocator, match); const size = sym.n_value; const code = try self.base.allocator.alloc(u8, size); @@ -2275,7 +2264,7 @@ fn resolveSymbols(self: *MachO) !void { var nlist = macho.nlist_64{ .n_strx = sym.n_strx, .n_type = macho.N_SECT, - .n_sect = self.section_to_ordinal.get(match) orelse unreachable, + .n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1), .n_desc = 0, .n_value = 0, }; @@ -2391,7 +2380,7 @@ fn resolveSymbols(self: *MachO) !void { var nlist = macho.nlist_64{ .n_strx = undef.n_strx, .n_type = macho.N_SECT, - .n_sect = self.section_to_ordinal.get(match) orelse unreachable, + .n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1), .n_desc = 0, .n_value = 0, }; @@ -2487,7 +2476,7 @@ fn populateMetadata(self: *MachO) !void { .@"align" = alignment, .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, }); - try self.createSectionOrdinal(.{ + _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ .seg = self.text_segment_cmd_index.?, .sect = self.text_section_index.?, }); @@ -2511,7 +2500,7 @@ fn populateMetadata(self: *MachO) !void { .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, .reserved2 = stub_size, }); - try self.createSectionOrdinal(.{ + _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ .seg = self.text_segment_cmd_index.?, .sect = self.stubs_section_index.?, }); @@ -2535,7 +2524,7 @@ fn populateMetadata(self: *MachO) !void { .@"align" = alignment, .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, }); - try self.createSectionOrdinal(.{ + _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ .seg = self.text_segment_cmd_index.?, .sect = self.stub_helper_section_index.?, }); @@ -2558,7 +2547,7 @@ fn populateMetadata(self: *MachO) !void { .@"align" = 3, // 2^3 = @sizeOf(u64) .flags = macho.S_NON_LAZY_SYMBOL_POINTERS, }); - try self.createSectionOrdinal(.{ + _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ .seg = self.data_const_segment_cmd_index.?, .sect = self.got_section_index.?, }); @@ -2581,7 +2570,7 @@ fn populateMetadata(self: *MachO) !void { .@"align" = 3, // 2^3 = @sizeOf(u64) .flags = macho.S_LAZY_SYMBOL_POINTERS, }); - try self.createSectionOrdinal(.{ + _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ .seg = self.data_segment_cmd_index.?, .sect = self.la_symbol_ptr_section_index.?, }); @@ -2593,7 +2582,7 @@ fn populateMetadata(self: *MachO) !void { try data_seg.addSection(self.base.allocator, "__data", .{ .@"align" = 3, // 2^3 = @sizeOf(u64) }); - try self.createSectionOrdinal(.{ + _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ .seg = self.data_segment_cmd_index.?, .sect = self.data_section_index.?, }); @@ -3324,7 +3313,6 @@ pub fn deinit(self: *MachO) void { } self.section_ordinals.deinit(self.base.allocator); - self.section_to_ordinal.deinit(self.base.allocator); self.pending_updates.deinit(self.base.allocator); self.got_entries.deinit(self.base.allocator); self.got_entries_map.deinit(self.base.allocator); @@ -5882,13 +5870,6 @@ pub fn findFirst(comptime T: type, haystack: []T, start: usize, predicate: anyty return i; } -fn createSectionOrdinal(self: *MachO, match: MatchingSection) !void { - if (self.section_to_ordinal.contains(match)) return; - const ordinal = @intCast(u8, self.section_ordinals.items.len); - try self.section_ordinals.append(self.base.allocator, match); - try self.section_to_ordinal.putNoClobber(self.base.allocator, match, ordinal); -} - fn printSymtabAndTextBlock(self: *MachO) void { log.debug("locals", .{}); for (self.locals.items) |sym, id| { diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index 04071a1cdb..2e6a20ad4b 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -402,7 +402,7 @@ const TextBlockParser = struct { const senior_nlist = aliases.pop(); const senior_sym = &context.macho_file.locals.items[senior_nlist.index]; - senior_sym.n_sect = context.macho_file.section_to_ordinal.get(context.match) orelse unreachable; + senior_sym.n_sect = @intCast(u8, context.macho_file.section_ordinals.getIndex(context.match).? + 1); const start_addr = senior_nlist.nlist.n_value - self.section.addr; 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 { for (aliases.items) |alias| { block.aliases.appendAssumeCapacity(alias.index); const sym = &context.macho_file.locals.items[alias.index]; - sym.n_sect = context.macho_file.section_to_ordinal.get(context.match) orelse unreachable; + sym.n_sect = @intCast(u8, context.macho_file.section_ordinals.getIndex(context.match).? + 1); } try block.parseRelocs(self.relocs, .{ @@ -588,7 +588,7 @@ pub fn parseTextBlocks( try macho_file.locals.append(allocator, .{ .n_strx = try macho_file.makeString(sym_name), .n_type = macho.N_SECT, - .n_sect = macho_file.section_to_ordinal.get(match) orelse unreachable, + .n_sect = @intCast(u8, macho_file.section_ordinals.getIndex(match).? + 1), .n_desc = 0, .n_value = sect.addr, }); @@ -733,7 +733,7 @@ pub fn parseTextBlocks( try macho_file.locals.append(allocator, .{ .n_strx = try macho_file.makeString(sym_name), .n_type = macho.N_SECT, - .n_sect = macho_file.section_to_ordinal.get(match) orelse unreachable, + .n_sect = @intCast(u8, macho_file.section_ordinals.getIndex(match).? + 1), .n_desc = 0, .n_value = sect.addr, }); @@ -781,7 +781,7 @@ pub fn parseTextBlocks( const nlist = nlist_with_index.nlist; const local_sym_index = self.symbol_mapping.get(nlist_with_index.index) orelse unreachable; const local = &macho_file.locals.items[local_sym_index]; - local.n_sect = macho_file.section_to_ordinal.get(match) orelse unreachable; + local.n_sect = @intCast(u8, macho_file.section_ordinals.getIndex(match).? + 1); const stab: ?TextBlock.Stab = if (self.debug_info) |di| blk: { // TODO there has to be a better to handle this. diff --git a/src/link/MachO/TextBlock.zig b/src/link/MachO/TextBlock.zig index ef10d3fe09..55dc2db471 100644 --- a/src/link/MachO/TextBlock.zig +++ b/src/link/MachO/TextBlock.zig @@ -637,7 +637,7 @@ fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Reloc try context.macho_file.locals.append(context.allocator, .{ .n_strx = try context.macho_file.makeString(sym_name), .n_type = macho.N_SECT, - .n_sect = context.macho_file.section_to_ordinal.get(match) orelse unreachable, + .n_sect = @intCast(u8, context.macho_file.section_ordinals.getIndex(match).? + 1), .n_desc = 0, .n_value = sect.addr, }); @@ -844,7 +844,7 @@ pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: R }, .local => { const source_sym = context.macho_file.locals.items[self.local_sym_index]; - const match = context.macho_file.section_ordinals.items[source_sym.n_sect]; + const match = context.macho_file.section_ordinals.keys()[source_sym.n_sect - 1]; const seg = context.macho_file.load_commands.items[match.seg].Segment; const sect = seg.sections.items[match.sect]; const sect_type = commands.sectionType(sect); @@ -1108,7 +1108,7 @@ pub fn resolveRelocs(self: *TextBlock, macho_file: *MachO) !void { const sym = macho_file.locals.items[rel.where_index]; const is_tlv = is_tlv: { const source_sym = macho_file.locals.items[self.local_sym_index]; - const match = macho_file.section_ordinals.items[source_sym.n_sect]; + const match = macho_file.section_ordinals.keys()[source_sym.n_sect - 1]; const seg = macho_file.load_commands.items[match.seg].Segment; const sect = seg.sections.items[match.sect]; break :is_tlv commands.sectionType(sect) == macho.S_THREAD_LOCAL_VARIABLES;