| author | |
| committer | |
| log | c984201ddb10d2977290c6f1d6857e78573a2dff |
| tree | 438b3484fc41bb253da66c24e6618e995f4a6eb6 |
| parent | 8bffe87e9eeaf602d06eec60dffc955a86228fbd |
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 { |
| 735 | 735 | assert(rel_pos.len > 0); // TODO convert to an error as the FDE eh frame is malformed |
| 736 | 736 | // Find function symbol that this record describes |
| 737 | 737 | 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 | }); | |
| 745 | 744 | break :blk target; |
| 746 | 745 | }, |
| 747 | 746 | .x86_64 => { |
| ... | ... | @@ -825,13 +824,12 @@ fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void { |
| 825 | 824 | |
| 826 | 825 | // Find function symbol that this record describes |
| 827 | 826 | 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 | }); | |
| 835 | 833 | log.debug("unwind record {d} tracks {s}", .{ record_id, zld.getSymbolName(target) }); |
| 836 | 834 | if (target.getFile() != object_id) { |
| 837 | 835 | 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 { |
| 218 | 218 | record_id, |
| 219 | 219 | )) |rel| { |
| 220 | 220 | // 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 | }); | |
| 228 | 227 | try Atom.addGotEntry(zld, target); |
| 229 | 228 | } |
| 230 | 229 | } |
| ... | ... | @@ -266,13 +265,12 @@ pub fn collect(info: *UnwindInfo, zld: *Zld) !void { |
| 266 | 265 | @intCast(u32, object_id), |
| 267 | 266 | record_id, |
| 268 | 267 | )) |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 | }); | |
| 276 | 274 | const personality_index = info.getPersonalityFunction(target) orelse inner: { |
| 277 | 275 | const personality_index = info.personalities_count; |
| 278 | 276 | info.personalities[personality_index] = target; |
| ... | ... | @@ -285,13 +283,12 @@ pub fn collect(info: *UnwindInfo, zld: *Zld) !void { |
| 285 | 283 | } |
| 286 | 284 | |
| 287 | 285 | 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 | }); | |
| 295 | 292 | record.lsda = @bitCast(u64, target); |
| 296 | 293 | } |
| 297 | 294 | } |
| ... | ... | @@ -668,41 +665,6 @@ pub fn write(info: *UnwindInfo, zld: *Zld) !void { |
| 668 | 665 | try zld.file.pwriteAll(buffer.items, sect.offset); |
| 669 | 666 | } |
| 670 | 667 | |
| 671 | pub 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 | ||
| 706 | 668 | fn getRelocs(zld: *Zld, object_id: u32, record_id: usize) []const macho.relocation_info { |
| 707 | 669 | const object = &zld.objects.items[object_id]; |
| 708 | 670 | assert(object.hasUnwindRecords()); |
src/link/MachO/ZldAtom.zig+74-33| ... | ... | @@ -15,6 +15,7 @@ const macho = std.macho; |
| 15 | 15 | const math = std.math; |
| 16 | 16 | const mem = std.mem; |
| 17 | 17 | const meta = std.meta; |
| 18 | const trace = @import("../../tracy.zig").trace; | |
| 18 | 19 | |
| 19 | 20 | const Allocator = mem.Allocator; |
| 20 | 21 | const Arch = std.Target.Cpu.Arch; |
| ... | ... | @@ -163,7 +164,7 @@ pub fn scanAtomRelocs(zld: *Zld, atom_index: AtomIndex, relocs: []align(1) const |
| 163 | 164 | } |
| 164 | 165 | |
| 165 | 166 | const RelocContext = struct { |
| 166 | base_addr: u64 = 0, | |
| 167 | base_addr: i64 = 0, | |
| 167 | 168 | base_offset: i32 = 0, |
| 168 | 169 | }; |
| 169 | 170 | |
| ... | ... | @@ -175,7 +176,7 @@ pub fn getRelocContext(zld: *Zld, atom_index: AtomIndex) RelocContext { |
| 175 | 176 | if (object.getSourceSymbol(atom.sym_index)) |source_sym| { |
| 176 | 177 | const source_sect = object.getSourceSection(source_sym.n_sect - 1); |
| 177 | 178 | return .{ |
| 178 | .base_addr = source_sect.addr, | |
| 179 | .base_addr = @intCast(i64, source_sect.addr), | |
| 179 | 180 | .base_offset = @intCast(i32, source_sym.n_value - source_sect.addr), |
| 180 | 181 | }; |
| 181 | 182 | } |
| ... | ... | @@ -183,55 +184,71 @@ pub fn getRelocContext(zld: *Zld, atom_index: AtomIndex) RelocContext { |
| 183 | 184 | const sect_id = @intCast(u8, atom.sym_index - nbase); |
| 184 | 185 | const source_sect = object.getSourceSection(sect_id); |
| 185 | 186 | return .{ |
| 186 | .base_addr = source_sect.addr, | |
| 187 | .base_addr = @intCast(i64, source_sect.addr), | |
| 187 | 188 | .base_offset = 0, |
| 188 | 189 | }; |
| 189 | 190 | } |
| 190 | 191 | |
| 191 | pub 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().?]; | |
| 192 | pub 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 }); | |
| 194 | 204 | |
| 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); | |
| 200 | 208 | |
| 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]) | |
| 204 | 212 | else |
| 205 | mem.readIntLittle(u32, atom_code[rel_offset..][0..4]); | |
| 213 | mem.readIntLittle(u32, ctx.code[rel_offset..][0..4]); | |
| 206 | 214 | } 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)) { | |
| 208 | 217 | .X86_64_RELOC_SIGNED => 0, |
| 209 | 218 | .X86_64_RELOC_SIGNED_1 => 1, |
| 210 | 219 | .X86_64_RELOC_SIGNED_2 => 2, |
| 211 | 220 | .X86_64_RELOC_SIGNED_4 => 4, |
| 212 | 221 | else => unreachable, |
| 213 | 222 | }; |
| 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; | |
| 216 | 225 | break :blk @intCast(u64, target_address); |
| 217 | 226 | }; |
| 218 | 227 | |
| 219 | 228 | // Find containing atom |
| 229 | log.debug(" | locating symbol by address @{x} in section {d}", .{ address_in_section, sect_id }); | |
| 220 | 230 | const sym_index = object.getSymbolByAddress(address_in_section, sect_id); |
| 221 | 231 | break :sym_index sym_index; |
| 222 | } else object.reverse_symtab_lookup[rel.r_symbolnum]; | |
| 232 | } else object.reverse_symtab_lookup[ctx.rel.r_symbolnum]; | |
| 223 | 233 | |
| 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 }; | |
| 228 | 235 | 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; | |
| 235 | 252 | } |
| 236 | 253 | |
| 237 | 254 | pub fn getRelocTargetAtomIndex(zld: *Zld, target: SymbolWithLoc, is_via_got: bool) ?AtomIndex { |
| ... | ... | @@ -499,13 +516,25 @@ fn resolveRelocsArm64( |
| 499 | 516 | atom.getFile(), |
| 500 | 517 | }); |
| 501 | 518 | |
| 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 | }); | |
| 503 | 526 | continue; |
| 504 | 527 | }, |
| 505 | 528 | else => {}, |
| 506 | 529 | } |
| 507 | 530 | |
| 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 | }); | |
| 509 | 538 | const rel_offset = @intCast(u32, rel.r_address - context.base_offset); |
| 510 | 539 | |
| 511 | 540 | log.debug(" RELA({s}) @ {x} => %{d} ('{s}') in object({?})", .{ |
| ... | ... | @@ -781,13 +810,25 @@ fn resolveRelocsX86( |
| 781 | 810 | atom.getFile(), |
| 782 | 811 | }); |
| 783 | 812 | |
| 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 | }); | |
| 785 | 820 | continue; |
| 786 | 821 | }, |
| 787 | 822 | else => {}, |
| 788 | 823 | } |
| 789 | 824 | |
| 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 | }); | |
| 791 | 832 | const rel_offset = @intCast(u32, rel.r_address - context.base_offset); |
| 792 | 833 | |
| 793 | 834 | 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 { |
| 130 | 130 | const header = zld.sections.items(.header)[sym.n_sect - 1]; |
| 131 | 131 | if (header.isZerofill()) return; |
| 132 | 132 | |
| 133 | const code = Atom.getAtomCode(zld, atom_index); | |
| 133 | 134 | const relocs = Atom.getAtomRelocs(zld, atom_index); |
| 135 | const ctx = Atom.getRelocContext(zld, atom_index); | |
| 136 | ||
| 134 | 137 | for (relocs) |rel| { |
| 135 | 138 | const target = switch (cpu_arch) { |
| 136 | 139 | .aarch64 => switch (@intToEnum(macho.reloc_type_arm64, rel.r_type)) { |
| 137 | 140 | .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 | }), | |
| 139 | 148 | }, |
| 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 | }), | |
| 141 | 156 | else => unreachable, |
| 142 | 157 | }; |
| 143 | 158 | const target_sym = zld.getSymbol(target); |
| ... | ... | @@ -175,14 +190,29 @@ fn refersLive(zld: *Zld, atom_index: AtomIndex, alive: AtomTable) bool { |
| 175 | 190 | const header = zld.sections.items(.header)[sym.n_sect - 1]; |
| 176 | 191 | assert(!header.isZerofill()); |
| 177 | 192 | |
| 193 | const code = Atom.getAtomCode(zld, atom_index); | |
| 178 | 194 | const relocs = Atom.getAtomRelocs(zld, atom_index); |
| 195 | const ctx = Atom.getRelocContext(zld, atom_index); | |
| 196 | ||
| 179 | 197 | for (relocs) |rel| { |
| 180 | 198 | const target = switch (cpu_arch) { |
| 181 | 199 | .aarch64 => switch (@intToEnum(macho.reloc_type_arm64, rel.r_type)) { |
| 182 | 200 | .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 | }), | |
| 184 | 208 | }, |
| 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 | }), | |
| 186 | 216 | else => unreachable, |
| 187 | 217 | }; |
| 188 | 218 | |
| ... | ... | @@ -283,13 +313,12 @@ fn markUnwindRecords(zld: *Zld, object_id: u32, alive: *AtomTable) !void { |
| 283 | 313 | try markEhFrameRecord(zld, object_id, atom_index, alive); |
| 284 | 314 | } else { |
| 285 | 315 | 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 | }); | |
| 293 | 322 | const target_sym = zld.getSymbol(target); |
| 294 | 323 | if (!target_sym.undf()) { |
| 295 | 324 | const target_object = zld.objects.items[target.getFile().?]; |
| ... | ... | @@ -299,13 +328,12 @@ fn markUnwindRecords(zld: *Zld, object_id: u32, alive: *AtomTable) !void { |
| 299 | 328 | } |
| 300 | 329 | |
| 301 | 330 | 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 | }); | |
| 309 | 337 | const target_object = zld.objects.items[target.getFile().?]; |
| 310 | 338 | const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index).?; |
| 311 | 339 | markLive(zld, target_atom_index, alive); |
| ... | ... | @@ -333,13 +361,12 @@ fn markEhFrameRecord(zld: *Zld, object_id: u32, atom_index: AtomIndex, alive: *A |
| 333 | 361 | // Mark FDE references which should include any referenced LSDA record |
| 334 | 362 | const relocs = eh_frame.getRelocs(zld, object_id, fde_offset); |
| 335 | 363 | 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 | }); | |
| 343 | 370 | const target_sym = zld.getSymbol(target); |
| 344 | 371 | if (!target_sym.undf()) blk: { |
| 345 | 372 | 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 { |
| 308 | 308 | }, |
| 309 | 309 | else => unreachable, |
| 310 | 310 | } |
| 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 | }); | |
| 318 | 317 | return target; |
| 319 | 318 | } |
| 320 | 319 | return null; |
| ... | ... | @@ -331,13 +330,12 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type { |
| 331 | 330 | const relocs = getRelocs(zld, object_id, ctx.source_offset); |
| 332 | 331 | |
| 333 | 332 | 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 | }); | |
| 341 | 339 | const rel_offset = @intCast(u32, rel.r_address - @intCast(i32, ctx.source_offset) - 4); |
| 342 | 340 | const source_addr = ctx.sect_addr + rel_offset + ctx.out_offset + 4; |
| 343 | 341 |
src/link/MachO/thunks.zig+10-1| ... | ... | @@ -225,11 +225,20 @@ fn scanRelocs( |
| 225 | 225 | break :blk @intCast(i32, source_sym.n_value - source_sect.addr); |
| 226 | 226 | } else 0; |
| 227 | 227 | |
| 228 | const code = Atom.getAtomCode(zld, atom_index); | |
| 228 | 229 | const relocs = Atom.getAtomRelocs(zld, atom_index); |
| 230 | const ctx = Atom.getRelocContext(zld, atom_index); | |
| 231 | ||
| 229 | 232 | for (relocs) |rel| { |
| 230 | 233 | if (!relocNeedsThunk(rel)) continue; |
| 231 | 234 | |
| 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 | }); | |
| 233 | 242 | if (isReachable(zld, atom_index, rel, base_offset, target, allocated)) continue; |
| 234 | 243 | |
| 235 | 244 | 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 { |
| 1884 | 1884 | if (should_rebase) { |
| 1885 | 1885 | log.debug(" ATOM({d}, %{d}, '{s}')", .{ atom_index, atom.sym_index, self.getSymbolName(atom.getSymbolWithLoc()) }); |
| 1886 | 1886 | |
| 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); | |
| 1893 | 1888 | const relocs = Atom.getAtomRelocs(self, atom_index); |
| 1889 | const ctx = Atom.getRelocContext(self, atom_index); | |
| 1894 | 1890 | |
| 1895 | 1891 | for (relocs) |rel| { |
| 1896 | 1892 | switch (cpu_arch) { |
| ... | ... | @@ -1906,12 +1902,18 @@ pub const Zld = struct { |
| 1906 | 1902 | }, |
| 1907 | 1903 | else => unreachable, |
| 1908 | 1904 | } |
| 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 | }); | |
| 1910 | 1912 | const target_sym = self.getSymbol(target); |
| 1911 | 1913 | if (target_sym.undf()) continue; |
| 1912 | 1914 | |
| 1913 | 1915 | 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; | |
| 1915 | 1917 | const offset = @intCast(u64, base_offset + rel_offset); |
| 1916 | 1918 | log.debug(" | rebase at {x}", .{offset}); |
| 1917 | 1919 | |
| ... | ... | @@ -2021,13 +2023,9 @@ pub const Zld = struct { |
| 2021 | 2023 | }; |
| 2022 | 2024 | |
| 2023 | 2025 | 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); | |
| 2030 | 2027 | const relocs = Atom.getAtomRelocs(self, atom_index); |
| 2028 | const ctx = Atom.getRelocContext(self, atom_index); | |
| 2031 | 2029 | |
| 2032 | 2030 | for (relocs) |rel| { |
| 2033 | 2031 | switch (cpu_arch) { |
| ... | ... | @@ -2044,15 +2042,20 @@ pub const Zld = struct { |
| 2044 | 2042 | else => unreachable, |
| 2045 | 2043 | } |
| 2046 | 2044 | |
| 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 | }); | |
| 2048 | 2052 | const bind_sym_name = self.getSymbolName(global); |
| 2049 | 2053 | const bind_sym = self.getSymbol(global); |
| 2050 | 2054 | if (!bind_sym.undf()) continue; |
| 2051 | 2055 | |
| 2052 | 2056 | 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); | |
| 2054 | 2058 | const offset = @intCast(u64, base_offset + rel_offset); |
| 2055 | const code = Atom.getAtomCode(self, atom_index); | |
| 2056 | 2059 | const addend = mem.readIntLittle(i64, code[rel_offset..][0..8]); |
| 2057 | 2060 | |
| 2058 | 2061 | const dylib_ordinal = @divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER); |