authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-22 13:57:43+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-22 15:13:17+01:00
logc984201ddb10d2977290c6f1d6857e78573a2dff
tree438b3484fc41bb253da66c24e6618e995f4a6eb6
parent8bffe87e9eeaf602d06eec60dffc955a86228fbd

macho+zld: refactor parsing of relocation target


7 files changed, 198 insertions(+), 160 deletions(-)

src/link/MachO/Object.zig+12-14
......@@ -735,13 +735,12 @@ fn parseEhFrameSection(self: *Object, zld: *Zld, object_id: u32) !void {
735735 assert(rel_pos.len > 0); // TODO convert to an error as the FDE eh frame is malformed
736736 // Find function symbol that this record describes
737737 const rel = relocs[rel_pos.start..][rel_pos.len - 1];
738 const target = UnwindInfo.parseRelocTarget(
739 zld,
740 object_id,
741 rel,
742 it.data[offset..],
743 @intCast(i32, offset),
744 );
738 const target = Atom.parseRelocTarget(zld, .{
739 .object_id = object_id,
740 .rel = rel,
741 .code = it.data[offset..],
742 .base_offset = @intCast(i32, offset),
743 });
745744 break :blk target;
746745 },
747746 .x86_64 => {
......@@ -825,13 +824,12 @@ fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void {
825824
826825 // Find function symbol that this record describes
827826 const rel = relocs[rel_pos.start..][rel_pos.len - 1];
828 const target = UnwindInfo.parseRelocTarget(
829 zld,
830 object_id,
831 rel,
832 mem.asBytes(&record),
833 @intCast(i32, offset),
834 );
827 const target = Atom.parseRelocTarget(zld, .{
828 .object_id = object_id,
829 .rel = rel,
830 .code = mem.asBytes(&record),
831 .base_offset = @intCast(i32, offset),
832 });
835833 log.debug("unwind record {d} tracks {s}", .{ record_id, zld.getSymbolName(target) });
836834 if (target.getFile() != object_id) {
837835 self.unwind_relocs_lookup[record_id].dead = true;
src/link/MachO/UnwindInfo.zig+18-56
......@@ -218,13 +218,12 @@ pub fn scanRelocs(zld: *Zld) !void {
218218 record_id,
219219 )) |rel| {
220220 // Personality function; add GOT pointer.
221 const target = parseRelocTarget(
222 zld,
223 @intCast(u32, object_id),
224 rel,
225 mem.asBytes(&record),
226 @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)),
227 );
221 const target = Atom.parseRelocTarget(zld, .{
222 .object_id = @intCast(u32, object_id),
223 .rel = rel,
224 .code = mem.asBytes(&record),
225 .base_offset = @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)),
226 });
228227 try Atom.addGotEntry(zld, target);
229228 }
230229 }
......@@ -266,13 +265,12 @@ pub fn collect(info: *UnwindInfo, zld: *Zld) !void {
266265 @intCast(u32, object_id),
267266 record_id,
268267 )) |rel| {
269 const target = parseRelocTarget(
270 zld,
271 @intCast(u32, object_id),
272 rel,
273 mem.asBytes(&record),
274 @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)),
275 );
268 const target = Atom.parseRelocTarget(zld, .{
269 .object_id = @intCast(u32, object_id),
270 .rel = rel,
271 .code = mem.asBytes(&record),
272 .base_offset = @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)),
273 });
276274 const personality_index = info.getPersonalityFunction(target) orelse inner: {
277275 const personality_index = info.personalities_count;
278276 info.personalities[personality_index] = target;
......@@ -285,13 +283,12 @@ pub fn collect(info: *UnwindInfo, zld: *Zld) !void {
285283 }
286284
287285 if (getLsdaReloc(zld, @intCast(u32, object_id), record_id)) |rel| {
288 const target = parseRelocTarget(
289 zld,
290 @intCast(u32, object_id),
291 rel,
292 mem.asBytes(&record),
293 @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)),
294 );
286 const target = Atom.parseRelocTarget(zld, .{
287 .object_id = @intCast(u32, object_id),
288 .rel = rel,
289 .code = mem.asBytes(&record),
290 .base_offset = @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)),
291 });
295292 record.lsda = @bitCast(u64, target);
296293 }
297294 }
......@@ -668,41 +665,6 @@ pub fn write(info: *UnwindInfo, zld: *Zld) !void {
668665 try zld.file.pwriteAll(buffer.items, sect.offset);
669666}
670667
671pub fn parseRelocTarget(
672 zld: *Zld,
673 object_id: u32,
674 rel: macho.relocation_info,
675 code: []const u8,
676 base_offset: i32,
677) SymbolWithLoc {
678 const tracy = trace(@src());
679 defer tracy.end();
680
681 const object = &zld.objects.items[object_id];
682
683 const sym_index = if (rel.r_extern == 0) blk: {
684 const sect_id = @intCast(u8, rel.r_symbolnum - 1);
685 const rel_offset = @intCast(u32, rel.r_address - base_offset);
686 assert(rel.r_pcrel == 0 and rel.r_length == 3);
687 const address_in_section = mem.readIntLittle(u64, code[rel_offset..][0..8]);
688 const sym_index = object.getSymbolByAddress(address_in_section, sect_id);
689 break :blk sym_index;
690 } else object.reverse_symtab_lookup[rel.r_symbolnum];
691
692 const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = object_id + 1 };
693 const sym = zld.getSymbol(sym_loc);
694
695 if (sym.sect() and !sym.ext()) {
696 // Make sure we are not dealing with a local alias.
697 const atom_index = object.getAtomIndexForSymbol(sym_index) orelse
698 return sym_loc;
699 const atom = zld.getAtom(atom_index);
700 return atom.getSymbolWithLoc();
701 } else if (object.getGlobal(sym_index)) |global_index| {
702 return zld.globals.items[global_index];
703 } else return sym_loc;
704}
705
706668fn getRelocs(zld: *Zld, object_id: u32, record_id: usize) []const macho.relocation_info {
707669 const object = &zld.objects.items[object_id];
708670 assert(object.hasUnwindRecords());
src/link/MachO/ZldAtom.zig+74-33
......@@ -15,6 +15,7 @@ const macho = std.macho;
1515const math = std.math;
1616const mem = std.mem;
1717const meta = std.meta;
18const trace = @import("../../tracy.zig").trace;
1819
1920const Allocator = mem.Allocator;
2021const Arch = std.Target.Cpu.Arch;
......@@ -163,7 +164,7 @@ pub fn scanAtomRelocs(zld: *Zld, atom_index: AtomIndex, relocs: []align(1) const
163164}
164165
165166const RelocContext = struct {
166 base_addr: u64 = 0,
167 base_addr: i64 = 0,
167168 base_offset: i32 = 0,
168169};
169170
......@@ -175,7 +176,7 @@ pub fn getRelocContext(zld: *Zld, atom_index: AtomIndex) RelocContext {
175176 if (object.getSourceSymbol(atom.sym_index)) |source_sym| {
176177 const source_sect = object.getSourceSection(source_sym.n_sect - 1);
177178 return .{
178 .base_addr = source_sect.addr,
179 .base_addr = @intCast(i64, source_sect.addr),
179180 .base_offset = @intCast(i32, source_sym.n_value - source_sect.addr),
180181 };
181182 }
......@@ -183,55 +184,71 @@ pub fn getRelocContext(zld: *Zld, atom_index: AtomIndex) RelocContext {
183184 const sect_id = @intCast(u8, atom.sym_index - nbase);
184185 const source_sect = object.getSourceSection(sect_id);
185186 return .{
186 .base_addr = source_sect.addr,
187 .base_addr = @intCast(i64, source_sect.addr),
187188 .base_offset = 0,
188189 };
189190}
190191
191pub fn parseRelocTarget(zld: *Zld, atom_index: AtomIndex, rel: macho.relocation_info) SymbolWithLoc {
192 const atom = zld.getAtom(atom_index);
193 const object = &zld.objects.items[atom.getFile().?];
192pub fn parseRelocTarget(zld: *Zld, ctx: struct {
193 object_id: u32,
194 rel: macho.relocation_info,
195 code: []const u8,
196 base_addr: i64 = 0,
197 base_offset: i32 = 0,
198}) SymbolWithLoc {
199 const tracy = trace(@src());
200 defer tracy.end();
201
202 const object = &zld.objects.items[ctx.object_id];
203 log.debug("parsing reloc target in object({d}) '{s}' ", .{ ctx.object_id, object.name });
194204
195 const sym_index = if (rel.r_extern == 0) sym_index: {
196 const sect_id = @intCast(u8, rel.r_symbolnum - 1);
197 const ctx = getRelocContext(zld, atom_index);
198 const atom_code = getAtomCode(zld, atom_index);
199 const rel_offset = @intCast(u32, rel.r_address - ctx.base_offset);
205 const sym_index = if (ctx.rel.r_extern == 0) sym_index: {
206 const sect_id = @intCast(u8, ctx.rel.r_symbolnum - 1);
207 const rel_offset = @intCast(u32, ctx.rel.r_address - ctx.base_offset);
200208
201 const address_in_section = if (rel.r_pcrel == 0) blk: {
202 break :blk if (rel.r_length == 3)
203 mem.readIntLittle(u64, atom_code[rel_offset..][0..8])
209 const address_in_section = if (ctx.rel.r_pcrel == 0) blk: {
210 break :blk if (ctx.rel.r_length == 3)
211 mem.readIntLittle(u64, ctx.code[rel_offset..][0..8])
204212 else
205 mem.readIntLittle(u32, atom_code[rel_offset..][0..4]);
213 mem.readIntLittle(u32, ctx.code[rel_offset..][0..4]);
206214 } else blk: {
207 const correction: u3 = switch (@intToEnum(macho.reloc_type_x86_64, rel.r_type)) {
215 assert(zld.options.target.cpu.arch == .x86_64);
216 const correction: u3 = switch (@intToEnum(macho.reloc_type_x86_64, ctx.rel.r_type)) {
208217 .X86_64_RELOC_SIGNED => 0,
209218 .X86_64_RELOC_SIGNED_1 => 1,
210219 .X86_64_RELOC_SIGNED_2 => 2,
211220 .X86_64_RELOC_SIGNED_4 => 4,
212221 else => unreachable,
213222 };
214 const addend = mem.readIntLittle(i32, atom_code[rel_offset..][0..4]);
215 const target_address = @intCast(i64, ctx.base_addr) + rel.r_address + 4 + correction + addend;
223 const addend = mem.readIntLittle(i32, ctx.code[rel_offset..][0..4]);
224 const target_address = @intCast(i64, ctx.base_addr) + ctx.rel.r_address + 4 + correction + addend;
216225 break :blk @intCast(u64, target_address);
217226 };
218227
219228 // Find containing atom
229 log.debug(" | locating symbol by address @{x} in section {d}", .{ address_in_section, sect_id });
220230 const sym_index = object.getSymbolByAddress(address_in_section, sect_id);
221231 break :sym_index sym_index;
222 } else object.reverse_symtab_lookup[rel.r_symbolnum];
232 } else object.reverse_symtab_lookup[ctx.rel.r_symbolnum];
223233
224 const sym_loc = SymbolWithLoc{
225 .sym_index = sym_index,
226 .file = atom.file,
227 };
234 const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = ctx.object_id + 1 };
228235 const sym = zld.getSymbol(sym_loc);
229
230 if (sym.sect() and !sym.ext()) {
231 return sym_loc;
232 } else if (object.getGlobal(sym_index)) |global_index| {
233 return zld.globals.items[global_index];
234 } else return sym_loc;
236 const target = target: {
237 if (sym.sect() and !sym.ext()) {
238 // Make sure we are not dealing with a local alias.
239 const atom_index = object.getAtomIndexForSymbol(sym_index) orelse break :target sym_loc;
240 const atom = zld.getAtom(atom_index);
241 break :target atom.getSymbolWithLoc();
242 } else if (object.getGlobal(sym_index)) |global_index| {
243 break :target zld.globals.items[global_index];
244 } else break :target sym_loc;
245 };
246 log.debug(" | target %{d} ('{s}') in object({?d})", .{
247 target.sym_index,
248 zld.getSymbolName(target),
249 target.getFile(),
250 });
251 return target;
235252}
236253
237254pub fn getRelocTargetAtomIndex(zld: *Zld, target: SymbolWithLoc, is_via_got: bool) ?AtomIndex {
......@@ -499,13 +516,25 @@ fn resolveRelocsArm64(
499516 atom.getFile(),
500517 });
501518
502 subtractor = parseRelocTarget(zld, atom_index, rel);
519 subtractor = parseRelocTarget(zld, .{
520 .object_id = atom.getFile().?,
521 .rel = rel,
522 .code = atom_code,
523 .base_addr = context.base_addr,
524 .base_offset = context.base_offset,
525 });
503526 continue;
504527 },
505528 else => {},
506529 }
507530
508 const target = parseRelocTarget(zld, atom_index, rel);
531 const target = parseRelocTarget(zld, .{
532 .object_id = atom.getFile().?,
533 .rel = rel,
534 .code = atom_code,
535 .base_addr = context.base_addr,
536 .base_offset = context.base_offset,
537 });
509538 const rel_offset = @intCast(u32, rel.r_address - context.base_offset);
510539
511540 log.debug(" RELA({s}) @ {x} => %{d} ('{s}') in object({?})", .{
......@@ -781,13 +810,25 @@ fn resolveRelocsX86(
781810 atom.getFile(),
782811 });
783812
784 subtractor = parseRelocTarget(zld, atom_index, rel);
813 subtractor = parseRelocTarget(zld, .{
814 .object_id = atom.getFile().?,
815 .rel = rel,
816 .code = atom_code,
817 .base_addr = context.base_addr,
818 .base_offset = context.base_offset,
819 });
785820 continue;
786821 },
787822 else => {},
788823 }
789824
790 const target = parseRelocTarget(zld, atom_index, rel);
825 const target = parseRelocTarget(zld, .{
826 .object_id = atom.getFile().?,
827 .rel = rel,
828 .code = atom_code,
829 .base_addr = context.base_addr,
830 .base_offset = context.base_offset,
831 });
791832 const rel_offset = @intCast(u32, rel.r_address - context.base_offset);
792833
793834 log.debug(" RELA({s}) @ {x} => %{d} ('{s}') in object({?})", .{
src/link/MachO/dead_strip.zig+52-25
......@@ -130,14 +130,29 @@ fn markLive(zld: *Zld, atom_index: AtomIndex, alive: *AtomTable) void {
130130 const header = zld.sections.items(.header)[sym.n_sect - 1];
131131 if (header.isZerofill()) return;
132132
133 const code = Atom.getAtomCode(zld, atom_index);
133134 const relocs = Atom.getAtomRelocs(zld, atom_index);
135 const ctx = Atom.getRelocContext(zld, atom_index);
136
134137 for (relocs) |rel| {
135138 const target = switch (cpu_arch) {
136139 .aarch64 => switch (@intToEnum(macho.reloc_type_arm64, rel.r_type)) {
137140 .ARM64_RELOC_ADDEND => continue,
138 else => Atom.parseRelocTarget(zld, atom_index, rel),
141 else => Atom.parseRelocTarget(zld, .{
142 .object_id = atom.getFile().?,
143 .rel = rel,
144 .code = code,
145 .base_offset = ctx.base_offset,
146 .base_addr = ctx.base_addr,
147 }),
139148 },
140 .x86_64 => Atom.parseRelocTarget(zld, atom_index, rel),
149 .x86_64 => Atom.parseRelocTarget(zld, .{
150 .object_id = atom.getFile().?,
151 .rel = rel,
152 .code = code,
153 .base_offset = ctx.base_offset,
154 .base_addr = ctx.base_addr,
155 }),
141156 else => unreachable,
142157 };
143158 const target_sym = zld.getSymbol(target);
......@@ -175,14 +190,29 @@ fn refersLive(zld: *Zld, atom_index: AtomIndex, alive: AtomTable) bool {
175190 const header = zld.sections.items(.header)[sym.n_sect - 1];
176191 assert(!header.isZerofill());
177192
193 const code = Atom.getAtomCode(zld, atom_index);
178194 const relocs = Atom.getAtomRelocs(zld, atom_index);
195 const ctx = Atom.getRelocContext(zld, atom_index);
196
179197 for (relocs) |rel| {
180198 const target = switch (cpu_arch) {
181199 .aarch64 => switch (@intToEnum(macho.reloc_type_arm64, rel.r_type)) {
182200 .ARM64_RELOC_ADDEND => continue,
183 else => Atom.parseRelocTarget(zld, atom_index, rel),
201 else => Atom.parseRelocTarget(zld, .{
202 .object_id = atom.getFile().?,
203 .rel = rel,
204 .code = code,
205 .base_offset = ctx.base_offset,
206 .base_addr = ctx.base_addr,
207 }),
184208 },
185 .x86_64 => Atom.parseRelocTarget(zld, atom_index, rel),
209 .x86_64 => Atom.parseRelocTarget(zld, .{
210 .object_id = atom.getFile().?,
211 .rel = rel,
212 .code = code,
213 .base_offset = ctx.base_offset,
214 .base_addr = ctx.base_addr,
215 }),
186216 else => unreachable,
187217 };
188218
......@@ -283,13 +313,12 @@ fn markUnwindRecords(zld: *Zld, object_id: u32, alive: *AtomTable) !void {
283313 try markEhFrameRecord(zld, object_id, atom_index, alive);
284314 } else {
285315 if (UnwindInfo.getPersonalityFunctionReloc(zld, object_id, record_id)) |rel| {
286 const target = UnwindInfo.parseRelocTarget(
287 zld,
288 object_id,
289 rel,
290 mem.asBytes(&record),
291 @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)),
292 );
316 const target = Atom.parseRelocTarget(zld, .{
317 .object_id = object_id,
318 .rel = rel,
319 .code = mem.asBytes(&record),
320 .base_offset = @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)),
321 });
293322 const target_sym = zld.getSymbol(target);
294323 if (!target_sym.undf()) {
295324 const target_object = zld.objects.items[target.getFile().?];
......@@ -299,13 +328,12 @@ fn markUnwindRecords(zld: *Zld, object_id: u32, alive: *AtomTable) !void {
299328 }
300329
301330 if (UnwindInfo.getLsdaReloc(zld, object_id, record_id)) |rel| {
302 const target = UnwindInfo.parseRelocTarget(
303 zld,
304 object_id,
305 rel,
306 mem.asBytes(&record),
307 @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)),
308 );
331 const target = Atom.parseRelocTarget(zld, .{
332 .object_id = object_id,
333 .rel = rel,
334 .code = mem.asBytes(&record),
335 .base_offset = @intCast(i32, record_id * @sizeOf(macho.compact_unwind_entry)),
336 });
309337 const target_object = zld.objects.items[target.getFile().?];
310338 const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index).?;
311339 markLive(zld, target_atom_index, alive);
......@@ -333,13 +361,12 @@ fn markEhFrameRecord(zld: *Zld, object_id: u32, atom_index: AtomIndex, alive: *A
333361 // Mark FDE references which should include any referenced LSDA record
334362 const relocs = eh_frame.getRelocs(zld, object_id, fde_offset);
335363 for (relocs) |rel| {
336 const target = UnwindInfo.parseRelocTarget(
337 zld,
338 object_id,
339 rel,
340 fde.data,
341 @intCast(i32, fde_offset) + 4,
342 );
364 const target = Atom.parseRelocTarget(zld, .{
365 .object_id = object_id,
366 .rel = rel,
367 .code = fde.data,
368 .base_offset = @intCast(i32, fde_offset) + 4,
369 });
343370 const target_sym = zld.getSymbol(target);
344371 if (!target_sym.undf()) blk: {
345372 const target_object = zld.objects.items[target.getFile().?];
src/link/MachO/eh_frame.zig+12-14
......@@ -308,13 +308,12 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
308308 },
309309 else => unreachable,
310310 }
311 const target = UnwindInfo.parseRelocTarget(
312 zld,
313 object_id,
314 rel,
315 rec.data,
316 @intCast(i32, source_offset) + 4,
317 );
311 const target = Atom.parseRelocTarget(zld, .{
312 .object_id = object_id,
313 .rel = rel,
314 .code = rec.data,
315 .base_offset = @intCast(i32, source_offset) + 4,
316 });
318317 return target;
319318 }
320319 return null;
......@@ -331,13 +330,12 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
331330 const relocs = getRelocs(zld, object_id, ctx.source_offset);
332331
333332 for (relocs) |rel| {
334 const target = UnwindInfo.parseRelocTarget(
335 zld,
336 object_id,
337 rel,
338 rec.data,
339 @intCast(i32, ctx.source_offset) + 4,
340 );
333 const target = Atom.parseRelocTarget(zld, .{
334 .object_id = object_id,
335 .rel = rel,
336 .code = rec.data,
337 .base_offset = @intCast(i32, ctx.source_offset) + 4,
338 });
341339 const rel_offset = @intCast(u32, rel.r_address - @intCast(i32, ctx.source_offset) - 4);
342340 const source_addr = ctx.sect_addr + rel_offset + ctx.out_offset + 4;
343341
src/link/MachO/thunks.zig+10-1
......@@ -225,11 +225,20 @@ fn scanRelocs(
225225 break :blk @intCast(i32, source_sym.n_value - source_sect.addr);
226226 } else 0;
227227
228 const code = Atom.getAtomCode(zld, atom_index);
228229 const relocs = Atom.getAtomRelocs(zld, atom_index);
230 const ctx = Atom.getRelocContext(zld, atom_index);
231
229232 for (relocs) |rel| {
230233 if (!relocNeedsThunk(rel)) continue;
231234
232 const target = Atom.parseRelocTarget(zld, atom_index, rel);
235 const target = Atom.parseRelocTarget(zld, .{
236 .object_id = atom.getFile().?,
237 .rel = rel,
238 .code = code,
239 .base_offset = ctx.base_offset,
240 .base_addr = ctx.base_addr,
241 });
233242 if (isReachable(zld, atom_index, rel, base_offset, target, allocated)) continue;
234243
235244 log.debug("{x}: source = {s}@{x}, target = {s}@{x} unreachable", .{
src/link/MachO/zld.zig+20-17
......@@ -1884,13 +1884,9 @@ pub const Zld = struct {
18841884 if (should_rebase) {
18851885 log.debug(" ATOM({d}, %{d}, '{s}')", .{ atom_index, atom.sym_index, self.getSymbolName(atom.getSymbolWithLoc()) });
18861886
1887 const object = self.objects.items[atom.getFile().?];
1888 const base_rel_offset: i32 = blk: {
1889 const source_sym = object.getSourceSymbol(atom.sym_index) orelse break :blk 0;
1890 const source_sect = object.getSourceSection(source_sym.n_sect - 1);
1891 break :blk @intCast(i32, source_sym.n_value - source_sect.addr);
1892 };
1887 const code = Atom.getAtomCode(self, atom_index);
18931888 const relocs = Atom.getAtomRelocs(self, atom_index);
1889 const ctx = Atom.getRelocContext(self, atom_index);
18941890
18951891 for (relocs) |rel| {
18961892 switch (cpu_arch) {
......@@ -1906,12 +1902,18 @@ pub const Zld = struct {
19061902 },
19071903 else => unreachable,
19081904 }
1909 const target = Atom.parseRelocTarget(self, atom_index, rel);
1905 const target = Atom.parseRelocTarget(self, .{
1906 .object_id = atom.getFile().?,
1907 .rel = rel,
1908 .code = code,
1909 .base_offset = ctx.base_offset,
1910 .base_addr = ctx.base_addr,
1911 });
19101912 const target_sym = self.getSymbol(target);
19111913 if (target_sym.undf()) continue;
19121914
19131915 const base_offset = @intCast(i32, sym.n_value - segment.vmaddr);
1914 const rel_offset = rel.r_address - base_rel_offset;
1916 const rel_offset = rel.r_address - ctx.base_offset;
19151917 const offset = @intCast(u64, base_offset + rel_offset);
19161918 log.debug(" | rebase at {x}", .{offset});
19171919
......@@ -2021,13 +2023,9 @@ pub const Zld = struct {
20212023 };
20222024
20232025 if (should_bind) {
2024 const object = self.objects.items[atom.getFile().?];
2025 const base_rel_offset: i32 = blk: {
2026 const source_sym = object.getSourceSymbol(atom.sym_index) orelse break :blk 0;
2027 const source_sect = object.getSourceSection(source_sym.n_sect - 1);
2028 break :blk @intCast(i32, source_sym.n_value - source_sect.addr);
2029 };
2026 const code = Atom.getAtomCode(self, atom_index);
20302027 const relocs = Atom.getAtomRelocs(self, atom_index);
2028 const ctx = Atom.getRelocContext(self, atom_index);
20312029
20322030 for (relocs) |rel| {
20332031 switch (cpu_arch) {
......@@ -2044,15 +2042,20 @@ pub const Zld = struct {
20442042 else => unreachable,
20452043 }
20462044
2047 const global = Atom.parseRelocTarget(self, atom_index, rel);
2045 const global = Atom.parseRelocTarget(self, .{
2046 .object_id = atom.getFile().?,
2047 .rel = rel,
2048 .code = code,
2049 .base_offset = ctx.base_offset,
2050 .base_addr = ctx.base_addr,
2051 });
20482052 const bind_sym_name = self.getSymbolName(global);
20492053 const bind_sym = self.getSymbol(global);
20502054 if (!bind_sym.undf()) continue;
20512055
20522056 const base_offset = sym.n_value - segment.vmaddr;
2053 const rel_offset = @intCast(u32, rel.r_address - base_rel_offset);
2057 const rel_offset = @intCast(u32, rel.r_address - ctx.base_offset);
20542058 const offset = @intCast(u64, base_offset + rel_offset);
2055 const code = Atom.getAtomCode(self, atom_index);
20562059 const addend = mem.readIntLittle(i64, code[rel_offset..][0..8]);
20572060
20582061 const dylib_ordinal = @divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER);