authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-10-20 14:34:09+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-10-22 07:59:24+02:00
log2c2ff4558f83cdf1aacb0a4865389e93af60d2d5
treec325b95fbb4d14dce911a8195b037271f07fa6d0
parent5edb8e0b8ff8ec16fc38af0c9653eee3d4534db0

macho: fix handling of lack of subsections and tracking of inner symbols


4 files changed, 73 insertions(+), 44 deletions(-)

src/link/MachO/Object.zig+11-8
......@@ -316,6 +316,7 @@ pub fn splitIntoAtoms(self: *Object, zld: *Zld, object_id: u31) !void {
316316 object_id,
317317 sym_index,
318318 0,
319 0,
319320 sect.size,
320321 sect.@"align",
321322 out_sect_id,
......@@ -392,6 +393,7 @@ pub fn splitIntoAtoms(self: *Object, zld: *Zld, object_id: u31) !void {
392393 object_id,
393394 sym_index,
394395 0,
396 0,
395397 atom_size,
396398 sect.@"align",
397399 out_sect_id,
......@@ -429,6 +431,7 @@ pub fn splitIntoAtoms(self: *Object, zld: *Zld, object_id: u31) !void {
429431 zld,
430432 object_id,
431433 atom_sym_index,
434 atom_sym_index + 1,
432435 nsyms_trailing,
433436 atom_size,
434437 atom_align,
......@@ -447,19 +450,17 @@ pub fn splitIntoAtoms(self: *Object, zld: *Zld, object_id: u31) !void {
447450 zld.addAtomToSection(atom_index);
448451 }
449452 } else {
450 const sym_index = self.getSectionAliasSymbolIndex(sect_id);
453 const alias_index = self.getSectionAliasSymbolIndex(sect_id);
451454 const atom_index = try self.createAtomFromSubsection(
452455 zld,
453456 object_id,
454 sym_index,
455 0,
457 alias_index,
458 sect_start_index,
459 sect_loc.len,
456460 sect.size,
457461 sect.@"align",
458462 out_sect_id,
459463 );
460 // If there is no symbol to refer to this atom, we create
461 // a temp one, unless we already did that when working out the relocations
462 // of other atoms.
463464 zld.addAtomToSection(atom_index);
464465 }
465466 }
......@@ -470,7 +471,8 @@ fn createAtomFromSubsection(
470471 zld: *Zld,
471472 object_id: u31,
472473 sym_index: u32,
473 nsyms_trailing: u32,
474 inner_sym_index: u32,
475 inner_nsyms_trailing: u32,
474476 size: u64,
475477 alignment: u32,
476478 out_sect_id: u8,
......@@ -478,7 +480,8 @@ fn createAtomFromSubsection(
478480 const gpa = zld.gpa;
479481 const atom_index = try zld.createEmptyAtom(sym_index, size, alignment);
480482 const atom = zld.getAtomPtr(atom_index);
481 atom.nsyms_trailing = nsyms_trailing;
483 atom.inner_sym_index = inner_sym_index;
484 atom.inner_nsyms_trailing = inner_nsyms_trailing;
482485 atom.file = object_id;
483486 self.symtab[sym_index].n_sect = out_sect_id + 1;
484487
src/link/MachO/ZldAtom.zig+30-23
......@@ -28,7 +28,8 @@ sym_index: u32,
2828/// If this Atom references a subsection in an Object file, `nsyms_trailing`
2929/// tells how many symbols trailing `sym_index` fall within this Atom's address
3030/// range.
31nsyms_trailing: u32,
31inner_sym_index: u32,
32inner_nsyms_trailing: u32,
3233
3334/// -1 means symbol defined by the linker.
3435/// Otherwise, it is the index into appropriate object file.
......@@ -52,7 +53,8 @@ prev_index: ?AtomIndex,
5253
5354pub const empty = Atom{
5455 .sym_index = 0,
55 .nsyms_trailing = 0,
56 .inner_sym_index = 0,
57 .inner_nsyms_trailing = 0,
5658 .file = -1,
5759 .size = 0,
5860 .alignment = 0,
......@@ -81,9 +83,10 @@ const InnerSymIterator = struct {
8183
8284 pub fn next(it: *@This()) ?SymbolWithLoc {
8385 if (it.count == 0) return null;
86 const res = SymbolWithLoc{ .sym_index = it.sym_index, .file = it.file };
8487 it.sym_index += 1;
8588 it.count -= 1;
86 return SymbolWithLoc{ .sym_index = it.sym_index, .file = it.file };
89 return res;
8790 }
8891};
8992
......@@ -91,8 +94,8 @@ pub fn getInnerSymbolsIterator(zld: *Zld, atom_index: AtomIndex) InnerSymIterato
9194 const atom = zld.getAtom(atom_index);
9295 assert(atom.getFile() != null);
9396 return .{
94 .sym_index = atom.sym_index,
95 .count = atom.nsyms_trailing,
97 .sym_index = atom.inner_sym_index,
98 .count = atom.inner_nsyms_trailing,
9699 .file = atom.file,
97100 };
98101}
......@@ -123,9 +126,16 @@ pub fn calcInnerSymbolOffset(zld: *Zld, atom_index: AtomIndex, sym_index: u32) u
123126 if (atom.sym_index == sym_index) return 0;
124127
125128 const object = zld.objects.items[atom.getFile().?];
126 const source_atom_sym = object.getSourceSymbol(atom.sym_index).?;
127129 const source_sym = object.getSourceSymbol(sym_index).?;
128 return source_sym.n_value - source_atom_sym.n_value;
130 const base_addr = if (object.getSourceSymbol(atom.sym_index)) |sym|
131 sym.n_value
132 else blk: {
133 const nbase = @intCast(u32, object.in_symtab.?.len);
134 const sect_id = @intCast(u16, atom.sym_index - nbase);
135 const source_sect = object.getSourceSection(sect_id);
136 break :blk source_sect.addr;
137 };
138 return source_sym.n_value - base_addr;
129139}
130140
131141pub fn scanAtomRelocs(
......@@ -383,13 +393,13 @@ pub fn resolveRelocs(
383393 .base_offset = @intCast(i32, source_sym.n_value - source_sect.addr),
384394 };
385395 }
386 for (object.getSourceSections()) |source_sect, i| {
387 const sym_index = object.getSectionAliasSymbolIndex(@intCast(u8, i));
388 if (sym_index == atom.sym_index) break :blk .{
389 .base_addr = source_sect.addr,
390 .base_offset = 0,
391 };
392 } else unreachable;
396 const nbase = @intCast(u32, object.in_symtab.?.len);
397 const sect_id = @intCast(u16, atom.sym_index - nbase);
398 const source_sect = object.getSourceSection(sect_id);
399 break :blk .{
400 .base_addr = source_sect.addr,
401 .base_offset = 0,
402 };
393403 };
394404
395405 log.debug("resolving relocations in ATOM(%{d}, '{s}')", .{
......@@ -918,11 +928,9 @@ pub fn getAtomCode(zld: *Zld, atom_index: AtomIndex) []const u8 {
918928 // If there was no matching symbol present in the source symtab, this means
919929 // we are dealing with either an entire section, or part of it, but also
920930 // starting at the beginning.
921 const source_sect = for (object.getSourceSections()) |source_sect, sect_id| {
922 const sym_index = object.getSectionAliasSymbolIndex(@intCast(u8, sect_id));
923 if (sym_index == atom.sym_index) break source_sect;
924 } else unreachable;
925
931 const nbase = @intCast(u32, object.in_symtab.?.len);
932 const sect_id = @intCast(u16, atom.sym_index - nbase);
933 const source_sect = object.getSourceSection(sect_id);
926934 assert(!source_sect.isZerofill());
927935 const code = object.getSectionContents(source_sect);
928936 const code_len = @intCast(usize, atom.size);
......@@ -949,10 +957,9 @@ pub fn getAtomRelocs(zld: *Zld, atom_index: AtomIndex) []align(1) const macho.re
949957 // If there was no matching symbol present in the source symtab, this means
950958 // we are dealing with either an entire section, or part of it, but also
951959 // starting at the beginning.
952 const source_sect = for (object.getSourceSections()) |source_sect, sect_id| {
953 const sym_index = object.getSectionAliasSymbolIndex(@intCast(u8, sect_id));
954 if (sym_index == atom.sym_index) break source_sect;
955 } else unreachable;
960 const nbase = @intCast(u32, object.in_symtab.?.len);
961 const sect_id = @intCast(u16, atom.sym_index - nbase);
962 const source_sect = object.getSourceSection(sect_id);
956963 assert(!source_sect.isZerofill());
957964 break :blk source_sect;
958965 };
src/link/MachO/dead_strip.zig+17-4
......@@ -77,8 +77,15 @@ fn collectRoots(zld: *Zld, roots: *AtomTable) !void {
7777 for (zld.objects.items) |object| {
7878 for (object.atoms.items) |atom_index| {
7979 const atom = zld.getAtom(atom_index);
80 const source_sym = object.getSourceSymbol(atom.sym_index) orelse continue;
81 const source_sect = object.getSourceSection(source_sym.n_sect - 1);
80
81 const sect_id = if (object.getSourceSymbol(atom.sym_index)) |source_sym|
82 source_sym.n_sect - 1
83 else blk: {
84 const nbase = @intCast(u32, object.in_symtab.?.len);
85 const sect_id = @intCast(u16, atom.sym_index - nbase);
86 break :blk sect_id;
87 };
88 const source_sect = object.getSourceSection(sect_id);
8289 const is_gc_root = blk: {
8390 if (source_sect.isDontDeadStrip()) break :blk true;
8491 if (mem.eql(u8, "__StaticInit", source_sect.sectName())) break :blk true;
......@@ -220,8 +227,14 @@ fn mark(zld: *Zld, roots: AtomTable, alive: *AtomTable, reverse_lookups: [][]u32
220227 if (alive.contains(atom_index)) continue;
221228
222229 const atom = zld.getAtom(atom_index);
223 const source_sym = object.getSourceSymbol(atom.sym_index) orelse continue;
224 const source_sect = object.getSourceSection(source_sym.n_sect - 1);
230 const sect_id = if (object.getSourceSymbol(atom.sym_index)) |source_sym|
231 source_sym.n_sect - 1
232 else blk: {
233 const nbase = @intCast(u32, object.in_symtab.?.len);
234 const sect_id = @intCast(u16, atom.sym_index - nbase);
235 break :blk sect_id;
236 };
237 const source_sect = object.getSourceSection(sect_id);
225238
226239 if (source_sect.isDontDeadStripIfReferencesLive()) {
227240 if (try refersLive(zld, atom_index, alive.*, reverse_lookups)) {
src/link/MachO/zld.zig+15-9
......@@ -1911,7 +1911,7 @@ pub const Zld = struct {
19111911 sym.n_value,
19121912 });
19131913
1914 if (atom.getFile()) |_| {
1914 if (atom.getFile() != null) {
19151915 // Update each symbol contained within the atom
19161916 var it = Atom.getInnerSymbolsIterator(self, atom_index);
19171917 while (it.next()) |sym_loc| {
......@@ -2160,8 +2160,11 @@ pub const Zld = struct {
21602160 log.debug(" ATOM({d}, %{d}, '{s}')", .{ atom_index, atom.sym_index, self.getSymbolName(atom.getSymbolWithLoc()) });
21612161
21622162 const object = self.objects.items[atom.getFile().?];
2163 const source_sym = object.getSourceSymbol(atom.sym_index).?;
2164 const source_sect = object.getSourceSection(source_sym.n_sect - 1);
2163 const base_rel_offset: i32 = blk: {
2164 const source_sym = object.getSourceSymbol(atom.sym_index) orelse break :blk 0;
2165 const source_sect = object.getSourceSection(source_sym.n_sect - 1);
2166 break :blk @intCast(i32, source_sym.n_value - source_sect.addr);
2167 };
21652168 const relocs = Atom.getAtomRelocs(self, atom_index);
21662169
21672170 for (relocs) |rel| {
......@@ -2180,7 +2183,7 @@ pub const Zld = struct {
21802183 }
21812184
21822185 const base_offset = @intCast(i32, sym.n_value - segment.vmaddr);
2183 const rel_offset = rel.r_address - @intCast(i32, source_sym.n_value - source_sect.addr);
2186 const rel_offset = rel.r_address - base_rel_offset;
21842187 const offset = @intCast(u64, base_offset + rel_offset);
21852188 log.debug(" | rebase at {x}", .{offset});
21862189
......@@ -2288,8 +2291,11 @@ pub const Zld = struct {
22882291
22892292 if (should_bind) {
22902293 const object = self.objects.items[atom.getFile().?];
2291 const source_sym = object.getSourceSymbol(atom.sym_index).?;
2292 const source_sect = object.getSourceSection(source_sym.n_sect - 1);
2294 const base_rel_offset: i32 = blk: {
2295 const source_sym = object.getSourceSymbol(atom.sym_index) orelse break :blk 0;
2296 const source_sect = object.getSourceSection(source_sym.n_sect - 1);
2297 break :blk @intCast(i32, source_sym.n_value - source_sect.addr);
2298 };
22932299 const relocs = Atom.getAtomRelocs(self, atom_index);
22942300
22952301 for (relocs) |rel| {
......@@ -2313,7 +2319,7 @@ pub const Zld = struct {
23132319 if (!bind_sym.undf()) continue;
23142320
23152321 const base_offset = @intCast(i32, sym.n_value - segment.vmaddr);
2316 const rel_offset = rel.r_address - @intCast(i32, source_sym.n_value - source_sect.addr);
2322 const rel_offset = rel.r_address - base_rel_offset;
23172323 const offset = @intCast(u64, base_offset + rel_offset);
23182324
23192325 const dylib_ordinal = @divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER);
......@@ -3491,7 +3497,7 @@ pub const Zld = struct {
34913497 });
34923498 }
34933499 }
3494 scoped_log.debug(" object(null)", .{});
3500 scoped_log.debug(" object(-1)", .{});
34953501 for (self.locals.items) |sym, sym_id| {
34963502 if (sym.undf()) continue;
34973503 scoped_log.debug(" %{d}: {s} @{x} in sect({d}), {s}", .{
......@@ -3635,7 +3641,7 @@ pub const Zld = struct {
36353641 sym.n_sect,
36363642 });
36373643
3638 if (atom.getFile()) |_| {
3644 if (atom.getFile() != null) {
36393645 var it = Atom.getInnerSymbolsIterator(self, atom_index);
36403646 while (it.next()) |sym_loc| {
36413647 const inner = self.getSymbol(sym_loc);