authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-21 22:17:34+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-29 11:39:34+02:00
loge1e0ccb0c7ac32024aeb079a6cb57e237f941473
tree1c64dcaf809555250eda5e606257935935b70053
parent05c9d6c00babc4ccc7949b3eb0224f70719d12a5

macho: unify Section concept across drivers


5 files changed, 27 insertions(+), 46 deletions(-)

src/link/MachO.zig+2-4
...@@ -69,12 +69,10 @@ pub const Mode = enum {...@@ -69,12 +69,10 @@ pub const Mode = enum {
69 zld,69 zld,
70};70};
7171
72const Section = struct {72pub const Section = struct {
73 header: macho.section_64,73 header: macho.section_64,
74 segment_index: u8,74 segment_index: u8,
7575 first_atom_index: ?Atom.Index = null,
76 // TODO is null here necessary, or can we do away with tracking via section
77 // size in incremental context?
78 last_atom_index: ?Atom.Index = null,76 last_atom_index: ?Atom.Index = null,
7977
80 /// A list of atoms that have surplus capacity. This list can have false78 /// A list of atoms that have surplus capacity. This list can have false
src/link/MachO/Object.zig+4-6
...@@ -55,7 +55,7 @@ source_section_index_lookup: []Entry = undefined,...@@ -55,7 +55,7 @@ source_section_index_lookup: []Entry = undefined,
55/// Can be undefined as set together with in_symtab.55/// Can be undefined as set together with in_symtab.
56strtab_lookup: []u32 = undefined,56strtab_lookup: []u32 = undefined,
57/// Can be undefined as set together with in_symtab.57/// Can be undefined as set together with in_symtab.
58atom_by_index_table: []AtomIndex = undefined,58atom_by_index_table: []?AtomIndex = undefined,
59/// Can be undefined as set together with in_symtab.59/// Can be undefined as set together with in_symtab.
60globals_lookup: []i64 = undefined,60globals_lookup: []i64 = undefined,
61/// Can be undefined as set together with in_symtab.61/// Can be undefined as set together with in_symtab.
...@@ -156,7 +156,7 @@ pub fn parse(self: *Object, allocator: Allocator) !void {...@@ -156,7 +156,7 @@ pub fn parse(self: *Object, allocator: Allocator) !void {
156 self.reverse_symtab_lookup = try allocator.alloc(u32, self.in_symtab.?.len);156 self.reverse_symtab_lookup = try allocator.alloc(u32, self.in_symtab.?.len);
157 self.strtab_lookup = try allocator.alloc(u32, self.in_symtab.?.len);157 self.strtab_lookup = try allocator.alloc(u32, self.in_symtab.?.len);
158 self.globals_lookup = try allocator.alloc(i64, self.in_symtab.?.len);158 self.globals_lookup = try allocator.alloc(i64, self.in_symtab.?.len);
159 self.atom_by_index_table = try allocator.alloc(AtomIndex, self.in_symtab.?.len + nsects);159 self.atom_by_index_table = try allocator.alloc(?AtomIndex, self.in_symtab.?.len + nsects);
160 self.relocs_lookup = try allocator.alloc(Entry, self.in_symtab.?.len + nsects);160 self.relocs_lookup = try allocator.alloc(Entry, self.in_symtab.?.len + nsects);
161 // This is wasteful but we need to be able to lookup source symbol address after stripping and161 // This is wasteful but we need to be able to lookup source symbol address after stripping and
162 // allocating of sections.162 // allocating of sections.
...@@ -174,7 +174,7 @@ pub fn parse(self: *Object, allocator: Allocator) !void {...@@ -174,7 +174,7 @@ pub fn parse(self: *Object, allocator: Allocator) !void {
174 }174 }
175175
176 @memset(self.globals_lookup, -1);176 @memset(self.globals_lookup, -1);
177 @memset(self.atom_by_index_table, 0);177 @memset(self.atom_by_index_table, null);
178 @memset(self.source_section_index_lookup, .{});178 @memset(self.source_section_index_lookup, .{});
179 @memset(self.relocs_lookup, .{});179 @memset(self.relocs_lookup, .{});
180180
...@@ -1060,9 +1060,7 @@ pub fn getGlobal(self: Object, sym_index: u32) ?u32 {...@@ -1060,9 +1060,7 @@ pub fn getGlobal(self: Object, sym_index: u32) ?u32 {
1060}1060}
10611061
1062pub fn getAtomIndexForSymbol(self: Object, sym_index: u32) ?AtomIndex {1062pub fn getAtomIndexForSymbol(self: Object, sym_index: u32) ?AtomIndex {
1063 const atom_index = self.atom_by_index_table[sym_index];1063 return self.atom_by_index_table[sym_index];
1064 if (atom_index == 0) return null;
1065 return atom_index;
1066}1064}
10671065
1068pub fn hasUnwindRecords(self: Object) bool {1066pub fn hasUnwindRecords(self: Object) bool {
src/link/MachO/dead_strip.zig+2-2
...@@ -466,8 +466,8 @@ fn prune(zld: *Zld, alive: AtomTable) void {...@@ -466,8 +466,8 @@ fn prune(zld: *Zld, alive: AtomTable) void {
466 section.last_atom_index = prev_index;466 section.last_atom_index = prev_index;
467 } else {467 } else {
468 assert(section.header.size == 0);468 assert(section.header.size == 0);
469 section.first_atom_index = 0;469 section.first_atom_index = null;
470 section.last_atom_index = 0;470 section.last_atom_index = null;
471 }471 }
472 }472 }
473473
src/link/MachO/thunks.zig+1-1
...@@ -75,7 +75,7 @@ pub fn createThunks(zld: *Zld, sect_id: u8) !void {...@@ -75,7 +75,7 @@ pub fn createThunks(zld: *Zld, sect_id: u8) !void {
75 if (header.size == 0) return;75 if (header.size == 0) return;
7676
77 const gpa = zld.gpa;77 const gpa = zld.gpa;
78 const first_atom_index = zld.sections.items(.first_atom_index)[sect_id];78 const first_atom_index = zld.sections.items(.first_atom_index)[sect_id].?;
7979
80 header.size = 0;80 header.size = 0;
81 header.@"align" = 0;81 header.@"align" = 0;
src/link/MachO/zld.zig+18-33
...@@ -31,6 +31,7 @@ const MachO = @import("../MachO.zig");...@@ -31,6 +31,7 @@ const MachO = @import("../MachO.zig");
31const Md5 = std.crypto.hash.Md5;31const Md5 = std.crypto.hash.Md5;
32const LibStub = @import("../tapi.zig").LibStub;32const LibStub = @import("../tapi.zig").LibStub;
33const Object = @import("Object.zig");33const Object = @import("Object.zig");
34const Section = MachO.Section;
34const StringTable = @import("../strtab.zig").StringTable;35const StringTable = @import("../strtab.zig").StringTable;
35const SymbolWithLoc = MachO.SymbolWithLoc;36const SymbolWithLoc = MachO.SymbolWithLoc;
36const SymbolResolver = MachO.SymbolResolver;37const SymbolResolver = MachO.SymbolResolver;
...@@ -231,7 +232,7 @@ pub const Zld = struct {...@@ -231,7 +232,7 @@ pub const Zld = struct {
231 const sym = self.getSymbol(atom.getSymbolWithLoc());232 const sym = self.getSymbol(atom.getSymbolWithLoc());
232 var section = self.sections.get(sym.n_sect - 1);233 var section = self.sections.get(sym.n_sect - 1);
233 if (section.header.size > 0) {234 if (section.header.size > 0) {
234 const last_atom = self.getAtomPtr(section.last_atom_index);235 const last_atom = self.getAtomPtr(section.last_atom_index.?);
235 last_atom.next_index = atom_index;236 last_atom.next_index = atom_index;
236 atom.prev_index = section.last_atom_index;237 atom.prev_index = section.last_atom_index;
237 } else {238 } else {
...@@ -445,7 +446,7 @@ pub const Zld = struct {...@@ -445,7 +446,7 @@ pub const Zld = struct {
445 fn writeLazyPointer(self: *Zld, stub_helper_index: u32, writer: anytype) !void {446 fn writeLazyPointer(self: *Zld, stub_helper_index: u32, writer: anytype) !void {
446 const target_addr = blk: {447 const target_addr = blk: {
447 const sect_id = self.getSectionByName("__TEXT", "__stub_helper").?;448 const sect_id = self.getSectionByName("__TEXT", "__stub_helper").?;
448 var atom_index = self.sections.items(.first_atom_index)[sect_id];449 var atom_index = self.sections.items(.first_atom_index)[sect_id].?;
449 var count: u32 = 0;450 var count: u32 = 0;
450 while (count < stub_helper_index + 1) : (count += 1) {451 while (count < stub_helper_index + 1) : (count += 1) {
451 const atom = self.getAtom(atom_index);452 const atom = self.getAtom(atom_index);
...@@ -497,7 +498,7 @@ pub const Zld = struct {...@@ -497,7 +498,7 @@ pub const Zld = struct {
497 const target_addr = blk: {498 const target_addr = blk: {
498 // TODO: cache this at stub atom creation; they always go in pairs anyhow499 // TODO: cache this at stub atom creation; they always go in pairs anyhow
499 const la_sect_id = self.getSectionByName("__DATA", "__la_symbol_ptr").?;500 const la_sect_id = self.getSectionByName("__DATA", "__la_symbol_ptr").?;
500 var la_atom_index = self.sections.items(.first_atom_index)[la_sect_id];501 var la_atom_index = self.sections.items(.first_atom_index)[la_sect_id].?;
501 var count: u32 = 0;502 var count: u32 = 0;
502 while (count < stub_index) : (count += 1) {503 while (count < stub_index) : (count += 1) {
503 const la_atom = self.getAtom(la_atom_index);504 const la_atom = self.getAtom(la_atom_index);
...@@ -1012,11 +1013,10 @@ pub const Zld = struct {...@@ -1012,11 +1013,10 @@ pub const Zld = struct {
10121013
1013 for (slice.items(.first_atom_index), 0..) |first_atom_index, sect_id| {1014 for (slice.items(.first_atom_index), 0..) |first_atom_index, sect_id| {
1014 const header = slice.items(.header)[sect_id];1015 const header = slice.items(.header)[sect_id];
1015 var atom_index = first_atom_index;
1016
1017 if (atom_index == 0) continue;
1018 if (header.isZerofill()) continue;1016 if (header.isZerofill()) continue;
10191017
1018 var atom_index = first_atom_index orelse continue;
1019
1020 var buffer = std.ArrayList(u8).init(gpa);1020 var buffer = std.ArrayList(u8).init(gpa);
1021 defer buffer.deinit();1021 defer buffer.deinit();
1022 try buffer.ensureTotalCapacity(math.cast(usize, header.size) orelse return error.Overflow);1022 try buffer.ensureTotalCapacity(math.cast(usize, header.size) orelse return error.Overflow);
...@@ -1129,7 +1129,7 @@ pub const Zld = struct {...@@ -1129,7 +1129,7 @@ pub const Zld = struct {
1129 while (i < slice.len) : (i += 1) {1129 while (i < slice.len) : (i += 1) {
1130 const section = self.sections.get(i);1130 const section = self.sections.get(i);
1131 if (section.header.size == 0) {1131 if (section.header.size == 0) {
1132 log.debug("pruning section {s},{s} {d}", .{1132 log.debug("pruning section {s},{s} {?d}", .{
1133 section.header.segName(),1133 section.header.segName(),
1134 section.header.sectName(),1134 section.header.sectName(),
1135 section.first_atom_index,1135 section.first_atom_index,
...@@ -1156,8 +1156,7 @@ pub const Zld = struct {...@@ -1156,8 +1156,7 @@ pub const Zld = struct {
1156 if (header.isCode() and !(header.type() == macho.S_SYMBOL_STUBS) and !mem.eql(u8, header.sectName(), "__stub_helper")) continue;1156 if (header.isCode() and !(header.type() == macho.S_SYMBOL_STUBS) and !mem.eql(u8, header.sectName(), "__stub_helper")) continue;
1157 }1157 }
11581158
1159 var atom_index = slice.items(.first_atom_index)[sect_id];1159 var atom_index = slice.items(.first_atom_index)[sect_id] orelse continue;
1160 if (atom_index == 0) continue;
11611160
1162 header.size = 0;1161 header.size = 0;
1163 header.@"align" = 0;1162 header.@"align" = 0;
...@@ -1195,8 +1194,7 @@ pub const Zld = struct {...@@ -1195,8 +1194,7 @@ pub const Zld = struct {
1195 // We need to do this since our unwind info synthesiser relies on1194 // We need to do this since our unwind info synthesiser relies on
1196 // traversing the symbols when synthesising unwind info and DWARF CFI records.1195 // traversing the symbols when synthesising unwind info and DWARF CFI records.
1197 for (slice.items(.first_atom_index)) |first_atom_index| {1196 for (slice.items(.first_atom_index)) |first_atom_index| {
1198 if (first_atom_index == 0) continue;1197 var atom_index = first_atom_index orelse continue;
1199 var atom_index = first_atom_index;
12001198
1201 while (true) {1199 while (true) {
1202 const atom = self.getAtom(atom_index);1200 const atom = self.getAtom(atom_index);
...@@ -1278,8 +1276,9 @@ pub const Zld = struct {...@@ -1278,8 +1276,9 @@ pub const Zld = struct {
1278 @as(u32, @intCast(segment.fileoff + start_aligned));1276 @as(u32, @intCast(segment.fileoff + start_aligned));
1279 header.addr = segment.vmaddr + start_aligned;1277 header.addr = segment.vmaddr + start_aligned;
12801278
1281 var atom_index = slice.items(.first_atom_index)[indexes.start + sect_id];1279 if (slice.items(.first_atom_index)[indexes.start + sect_id]) |first_atom_index| {
1282 if (atom_index > 0) {1280 var atom_index = first_atom_index;
1281
1283 log.debug("allocating local symbols in sect({d}, '{s},{s}')", .{1282 log.debug("allocating local symbols in sect({d}, '{s},{s}')", .{
1284 n_sect,1283 n_sect,
1285 header.segName(),1284 header.segName(),
...@@ -1362,8 +1361,6 @@ pub const Zld = struct {...@@ -1362,8 +1361,6 @@ pub const Zld = struct {
1362 .reserved1 = opts.reserved1,1361 .reserved1 = opts.reserved1,
1363 .reserved2 = opts.reserved2,1362 .reserved2 = opts.reserved2,
1364 },1363 },
1365 .first_atom_index = 0,
1366 .last_atom_index = 0,
1367 });1364 });
1368 return index;1365 return index;
1369 }1366 }
...@@ -1491,7 +1488,7 @@ pub const Zld = struct {...@@ -1491,7 +1488,7 @@ pub const Zld = struct {
1491 if (self.getSectionByName("__DATA", "__la_symbol_ptr")) |sect_id| {1488 if (self.getSectionByName("__DATA", "__la_symbol_ptr")) |sect_id| {
1492 const segment_index = slice.items(.segment_index)[sect_id];1489 const segment_index = slice.items(.segment_index)[sect_id];
1493 const seg = self.getSegment(sect_id);1490 const seg = self.getSegment(sect_id);
1494 var atom_index = slice.items(.first_atom_index)[sect_id];1491 var atom_index = slice.items(.first_atom_index)[sect_id].?;
14951492
1496 try rebase.entries.ensureUnusedCapacity(self.gpa, self.stubs.items.len);1493 try rebase.entries.ensureUnusedCapacity(self.gpa, self.stubs.items.len);
14971494
...@@ -1531,8 +1528,7 @@ pub const Zld = struct {...@@ -1531,8 +1528,7 @@ pub const Zld = struct {
1531 log.debug("{s},{s}", .{ header.segName(), header.sectName() });1528 log.debug("{s},{s}", .{ header.segName(), header.sectName() });
15321529
1533 const cpu_arch = self.options.target.cpu.arch;1530 const cpu_arch = self.options.target.cpu.arch;
1534 var atom_index = slice.items(.first_atom_index)[sect_id];1531 var atom_index = slice.items(.first_atom_index)[sect_id] orelse continue;
1535 if (atom_index == 0) continue;
15361532
1537 while (true) {1533 while (true) {
1538 const atom = self.getAtom(atom_index);1534 const atom = self.getAtom(atom_index);
...@@ -1668,8 +1664,7 @@ pub const Zld = struct {...@@ -1668,8 +1664,7 @@ pub const Zld = struct {
1668 if (segment.maxprot & macho.PROT.WRITE == 0) continue;1664 if (segment.maxprot & macho.PROT.WRITE == 0) continue;
16691665
1670 const cpu_arch = self.options.target.cpu.arch;1666 const cpu_arch = self.options.target.cpu.arch;
1671 var atom_index = slice.items(.first_atom_index)[sect_id];1667 var atom_index = slice.items(.first_atom_index)[sect_id] orelse continue;
1672 if (atom_index == 0) continue;
16731668
1674 log.debug("{s},{s}", .{ header.segName(), header.sectName() });1669 log.debug("{s},{s}", .{ header.segName(), header.sectName() });
16751670
...@@ -1757,7 +1752,7 @@ pub const Zld = struct {...@@ -1757,7 +1752,7 @@ pub const Zld = struct {
1757 const slice = self.sections.slice();1752 const slice = self.sections.slice();
1758 const segment_index = slice.items(.segment_index)[sect_id];1753 const segment_index = slice.items(.segment_index)[sect_id];
1759 const seg = self.getSegment(sect_id);1754 const seg = self.getSegment(sect_id);
1760 var atom_index = slice.items(.first_atom_index)[sect_id];1755 var atom_index = slice.items(.first_atom_index)[sect_id].?;
17611756
1762 // TODO: we actually don't need to store lazy pointer atoms as they are synthetically generated by the linker1757 // TODO: we actually don't need to store lazy pointer atoms as they are synthetically generated by the linker
1763 try lazy_bind.entries.ensureUnusedCapacity(self.gpa, self.stubs.items.len);1758 try lazy_bind.entries.ensureUnusedCapacity(self.gpa, self.stubs.items.len);
...@@ -1920,7 +1915,7 @@ pub const Zld = struct {...@@ -1920,7 +1915,7 @@ pub const Zld = struct {
1920 const section = self.sections.get(stub_helper_section_index);1915 const section = self.sections.get(stub_helper_section_index);
1921 const stub_offset = stub_helpers.calcStubOffsetInStubHelper(self.options.target.cpu.arch);1916 const stub_offset = stub_helpers.calcStubOffsetInStubHelper(self.options.target.cpu.arch);
1922 const header = section.header;1917 const header = section.header;
1923 var atom_index = section.first_atom_index;1918 var atom_index = section.first_atom_index.?;
1924 atom_index = self.getAtom(atom_index).next_index.?; // skip preamble1919 atom_index = self.getAtom(atom_index).next_index.?; // skip preamble
19251920
1926 var index: usize = 0;1921 var index: usize = 0;
...@@ -2923,9 +2918,7 @@ pub const Zld = struct {...@@ -2923,9 +2918,7 @@ pub const Zld = struct {
2923 log.debug("atoms:", .{});2918 log.debug("atoms:", .{});
2924 const slice = self.sections.slice();2919 const slice = self.sections.slice();
2925 for (slice.items(.first_atom_index), 0..) |first_atom_index, sect_id| {2920 for (slice.items(.first_atom_index), 0..) |first_atom_index, sect_id| {
2926 var atom_index = first_atom_index;2921 var atom_index = first_atom_index orelse continue;
2927 if (atom_index == 0) continue;
2928
2929 const header = slice.items(.header)[sect_id];2922 const header = slice.items(.header)[sect_id];
29302923
2931 log.debug("{s},{s}", .{ header.segName(), header.sectName() });2924 log.debug("{s},{s}", .{ header.segName(), header.sectName() });
...@@ -2990,13 +2983,6 @@ pub const Zld = struct {...@@ -2990,13 +2983,6 @@ pub const Zld = struct {
29902983
2991pub const N_DEAD: u16 = @as(u16, @bitCast(@as(i16, -1)));2984pub const N_DEAD: u16 = @as(u16, @bitCast(@as(i16, -1)));
29922985
2993const Section = struct {
2994 header: macho.section_64,
2995 segment_index: u8,
2996 first_atom_index: AtomIndex,
2997 last_atom_index: AtomIndex,
2998};
2999
3000pub const AtomIndex = u32;2986pub const AtomIndex = u32;
30012987
3002const IndirectPointer = struct {2988const IndirectPointer = struct {
...@@ -3183,7 +3169,6 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr...@@ -3183,7 +3169,6 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
3183 };3169 };
3184 defer zld.deinit();3170 defer zld.deinit();
31853171
3186 try zld.atoms.append(gpa, Atom.empty); // AtomIndex at 0 is reserved as null atom
3187 try zld.strtab.buffer.append(gpa, 0);3172 try zld.strtab.buffer.append(gpa, 0);
31883173
3189 // Positional arguments to the linker such as object files and static archives.3174 // Positional arguments to the linker such as object files and static archives.