| author | |
| committer | |
| log | 2c2ff4558f83cdf1aacb0a4865389e93af60d2d5 |
| tree | c325b95fbb4d14dce911a8195b037271f07fa6d0 |
| parent | 5edb8e0b8ff8ec16fc38af0c9653eee3d4534db0 |
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 { |
| 316 | 316 | object_id, |
| 317 | 317 | sym_index, |
| 318 | 318 | 0, |
| 319 | 0, | |
| 319 | 320 | sect.size, |
| 320 | 321 | sect.@"align", |
| 321 | 322 | out_sect_id, |
| ... | ... | @@ -392,6 +393,7 @@ pub fn splitIntoAtoms(self: *Object, zld: *Zld, object_id: u31) !void { |
| 392 | 393 | object_id, |
| 393 | 394 | sym_index, |
| 394 | 395 | 0, |
| 396 | 0, | |
| 395 | 397 | atom_size, |
| 396 | 398 | sect.@"align", |
| 397 | 399 | out_sect_id, |
| ... | ... | @@ -429,6 +431,7 @@ pub fn splitIntoAtoms(self: *Object, zld: *Zld, object_id: u31) !void { |
| 429 | 431 | zld, |
| 430 | 432 | object_id, |
| 431 | 433 | atom_sym_index, |
| 434 | atom_sym_index + 1, | |
| 432 | 435 | nsyms_trailing, |
| 433 | 436 | atom_size, |
| 434 | 437 | atom_align, |
| ... | ... | @@ -447,19 +450,17 @@ pub fn splitIntoAtoms(self: *Object, zld: *Zld, object_id: u31) !void { |
| 447 | 450 | zld.addAtomToSection(atom_index); |
| 448 | 451 | } |
| 449 | 452 | } else { |
| 450 | const sym_index = self.getSectionAliasSymbolIndex(sect_id); | |
| 453 | const alias_index = self.getSectionAliasSymbolIndex(sect_id); | |
| 451 | 454 | const atom_index = try self.createAtomFromSubsection( |
| 452 | 455 | zld, |
| 453 | 456 | object_id, |
| 454 | sym_index, | |
| 455 | 0, | |
| 457 | alias_index, | |
| 458 | sect_start_index, | |
| 459 | sect_loc.len, | |
| 456 | 460 | sect.size, |
| 457 | 461 | sect.@"align", |
| 458 | 462 | out_sect_id, |
| 459 | 463 | ); |
| 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. | |
| 463 | 464 | zld.addAtomToSection(atom_index); |
| 464 | 465 | } |
| 465 | 466 | } |
| ... | ... | @@ -470,7 +471,8 @@ fn createAtomFromSubsection( |
| 470 | 471 | zld: *Zld, |
| 471 | 472 | object_id: u31, |
| 472 | 473 | sym_index: u32, |
| 473 | nsyms_trailing: u32, | |
| 474 | inner_sym_index: u32, | |
| 475 | inner_nsyms_trailing: u32, | |
| 474 | 476 | size: u64, |
| 475 | 477 | alignment: u32, |
| 476 | 478 | out_sect_id: u8, |
| ... | ... | @@ -478,7 +480,8 @@ fn createAtomFromSubsection( |
| 478 | 480 | const gpa = zld.gpa; |
| 479 | 481 | const atom_index = try zld.createEmptyAtom(sym_index, size, alignment); |
| 480 | 482 | 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; | |
| 482 | 485 | atom.file = object_id; |
| 483 | 486 | self.symtab[sym_index].n_sect = out_sect_id + 1; |
| 484 | 487 |
src/link/MachO/ZldAtom.zig+30-23| ... | ... | @@ -28,7 +28,8 @@ sym_index: u32, |
| 28 | 28 | /// If this Atom references a subsection in an Object file, `nsyms_trailing` |
| 29 | 29 | /// tells how many symbols trailing `sym_index` fall within this Atom's address |
| 30 | 30 | /// range. |
| 31 | nsyms_trailing: u32, | |
| 31 | inner_sym_index: u32, | |
| 32 | inner_nsyms_trailing: u32, | |
| 32 | 33 | |
| 33 | 34 | /// -1 means symbol defined by the linker. |
| 34 | 35 | /// Otherwise, it is the index into appropriate object file. |
| ... | ... | @@ -52,7 +53,8 @@ prev_index: ?AtomIndex, |
| 52 | 53 | |
| 53 | 54 | pub const empty = Atom{ |
| 54 | 55 | .sym_index = 0, |
| 55 | .nsyms_trailing = 0, | |
| 56 | .inner_sym_index = 0, | |
| 57 | .inner_nsyms_trailing = 0, | |
| 56 | 58 | .file = -1, |
| 57 | 59 | .size = 0, |
| 58 | 60 | .alignment = 0, |
| ... | ... | @@ -81,9 +83,10 @@ const InnerSymIterator = struct { |
| 81 | 83 | |
| 82 | 84 | pub fn next(it: *@This()) ?SymbolWithLoc { |
| 83 | 85 | if (it.count == 0) return null; |
| 86 | const res = SymbolWithLoc{ .sym_index = it.sym_index, .file = it.file }; | |
| 84 | 87 | it.sym_index += 1; |
| 85 | 88 | it.count -= 1; |
| 86 | return SymbolWithLoc{ .sym_index = it.sym_index, .file = it.file }; | |
| 89 | return res; | |
| 87 | 90 | } |
| 88 | 91 | }; |
| 89 | 92 | |
| ... | ... | @@ -91,8 +94,8 @@ pub fn getInnerSymbolsIterator(zld: *Zld, atom_index: AtomIndex) InnerSymIterato |
| 91 | 94 | const atom = zld.getAtom(atom_index); |
| 92 | 95 | assert(atom.getFile() != null); |
| 93 | 96 | 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, | |
| 96 | 99 | .file = atom.file, |
| 97 | 100 | }; |
| 98 | 101 | } |
| ... | ... | @@ -123,9 +126,16 @@ pub fn calcInnerSymbolOffset(zld: *Zld, atom_index: AtomIndex, sym_index: u32) u |
| 123 | 126 | if (atom.sym_index == sym_index) return 0; |
| 124 | 127 | |
| 125 | 128 | const object = zld.objects.items[atom.getFile().?]; |
| 126 | const source_atom_sym = object.getSourceSymbol(atom.sym_index).?; | |
| 127 | 129 | 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; | |
| 129 | 139 | } |
| 130 | 140 | |
| 131 | 141 | pub fn scanAtomRelocs( |
| ... | ... | @@ -383,13 +393,13 @@ pub fn resolveRelocs( |
| 383 | 393 | .base_offset = @intCast(i32, source_sym.n_value - source_sect.addr), |
| 384 | 394 | }; |
| 385 | 395 | } |
| 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 | }; | |
| 393 | 403 | }; |
| 394 | 404 | |
| 395 | 405 | log.debug("resolving relocations in ATOM(%{d}, '{s}')", .{ |
| ... | ... | @@ -918,11 +928,9 @@ pub fn getAtomCode(zld: *Zld, atom_index: AtomIndex) []const u8 { |
| 918 | 928 | // If there was no matching symbol present in the source symtab, this means |
| 919 | 929 | // we are dealing with either an entire section, or part of it, but also |
| 920 | 930 | // 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); | |
| 926 | 934 | assert(!source_sect.isZerofill()); |
| 927 | 935 | const code = object.getSectionContents(source_sect); |
| 928 | 936 | const code_len = @intCast(usize, atom.size); |
| ... | ... | @@ -949,10 +957,9 @@ pub fn getAtomRelocs(zld: *Zld, atom_index: AtomIndex) []align(1) const macho.re |
| 949 | 957 | // If there was no matching symbol present in the source symtab, this means |
| 950 | 958 | // we are dealing with either an entire section, or part of it, but also |
| 951 | 959 | // 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); | |
| 956 | 963 | assert(!source_sect.isZerofill()); |
| 957 | 964 | break :blk source_sect; |
| 958 | 965 | }; |
src/link/MachO/dead_strip.zig+17-4| ... | ... | @@ -77,8 +77,15 @@ fn collectRoots(zld: *Zld, roots: *AtomTable) !void { |
| 77 | 77 | for (zld.objects.items) |object| { |
| 78 | 78 | for (object.atoms.items) |atom_index| { |
| 79 | 79 | 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); | |
| 82 | 89 | const is_gc_root = blk: { |
| 83 | 90 | if (source_sect.isDontDeadStrip()) break :blk true; |
| 84 | 91 | 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 |
| 220 | 227 | if (alive.contains(atom_index)) continue; |
| 221 | 228 | |
| 222 | 229 | 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); | |
| 225 | 238 | |
| 226 | 239 | if (source_sect.isDontDeadStripIfReferencesLive()) { |
| 227 | 240 | if (try refersLive(zld, atom_index, alive.*, reverse_lookups)) { |
src/link/MachO/zld.zig+15-9| ... | ... | @@ -1911,7 +1911,7 @@ pub const Zld = struct { |
| 1911 | 1911 | sym.n_value, |
| 1912 | 1912 | }); |
| 1913 | 1913 | |
| 1914 | if (atom.getFile()) |_| { | |
| 1914 | if (atom.getFile() != null) { | |
| 1915 | 1915 | // Update each symbol contained within the atom |
| 1916 | 1916 | var it = Atom.getInnerSymbolsIterator(self, atom_index); |
| 1917 | 1917 | while (it.next()) |sym_loc| { |
| ... | ... | @@ -2160,8 +2160,11 @@ pub const Zld = struct { |
| 2160 | 2160 | log.debug(" ATOM({d}, %{d}, '{s}')", .{ atom_index, atom.sym_index, self.getSymbolName(atom.getSymbolWithLoc()) }); |
| 2161 | 2161 | |
| 2162 | 2162 | 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 | }; | |
| 2165 | 2168 | const relocs = Atom.getAtomRelocs(self, atom_index); |
| 2166 | 2169 | |
| 2167 | 2170 | for (relocs) |rel| { |
| ... | ... | @@ -2180,7 +2183,7 @@ pub const Zld = struct { |
| 2180 | 2183 | } |
| 2181 | 2184 | |
| 2182 | 2185 | 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; | |
| 2184 | 2187 | const offset = @intCast(u64, base_offset + rel_offset); |
| 2185 | 2188 | log.debug(" | rebase at {x}", .{offset}); |
| 2186 | 2189 | |
| ... | ... | @@ -2288,8 +2291,11 @@ pub const Zld = struct { |
| 2288 | 2291 | |
| 2289 | 2292 | if (should_bind) { |
| 2290 | 2293 | 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 | }; | |
| 2293 | 2299 | const relocs = Atom.getAtomRelocs(self, atom_index); |
| 2294 | 2300 | |
| 2295 | 2301 | for (relocs) |rel| { |
| ... | ... | @@ -2313,7 +2319,7 @@ pub const Zld = struct { |
| 2313 | 2319 | if (!bind_sym.undf()) continue; |
| 2314 | 2320 | |
| 2315 | 2321 | 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; | |
| 2317 | 2323 | const offset = @intCast(u64, base_offset + rel_offset); |
| 2318 | 2324 | |
| 2319 | 2325 | const dylib_ordinal = @divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER); |
| ... | ... | @@ -3491,7 +3497,7 @@ pub const Zld = struct { |
| 3491 | 3497 | }); |
| 3492 | 3498 | } |
| 3493 | 3499 | } |
| 3494 | scoped_log.debug(" object(null)", .{}); | |
| 3500 | scoped_log.debug(" object(-1)", .{}); | |
| 3495 | 3501 | for (self.locals.items) |sym, sym_id| { |
| 3496 | 3502 | if (sym.undf()) continue; |
| 3497 | 3503 | scoped_log.debug(" %{d}: {s} @{x} in sect({d}), {s}", .{ |
| ... | ... | @@ -3635,7 +3641,7 @@ pub const Zld = struct { |
| 3635 | 3641 | sym.n_sect, |
| 3636 | 3642 | }); |
| 3637 | 3643 | |
| 3638 | if (atom.getFile()) |_| { | |
| 3644 | if (atom.getFile() != null) { | |
| 3639 | 3645 | var it = Atom.getInnerSymbolsIterator(self, atom_index); |
| 3640 | 3646 | while (it.next()) |sym_loc| { |
| 3641 | 3647 | const inner = self.getSymbol(sym_loc); |