| author | |
| committer | |
| log | 86ab6ca56c4e6d115b017eed40dc62815a6a8e3d |
| tree | 7d429b531800dfe8614ea4789686338d5fd9a5df |
| parent | b6be28ddcc50bd4bf085294ffcb696e31a7a1de5 |
5 files changed, 186 insertions(+), 145 deletions(-)
src/link/MachO/Object.zig+80-98| ... | ... | @@ -43,17 +43,13 @@ dwarf_debug_str_index: ?u16 = null, |
| 43 | 43 | dwarf_debug_line_index: ?u16 = null, |
| 44 | 44 | dwarf_debug_ranges_index: ?u16 = null, |
| 45 | 45 | |
| 46 | symtab: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | |
| 47 | strtab: std.ArrayListUnmanaged(u8) = .{}, | |
| 46 | symbols: std.ArrayListUnmanaged(*Symbol) = .{}, | |
| 47 | initializers: std.ArrayListUnmanaged(*Symbol) = .{}, | |
| 48 | data_in_code_entries: std.ArrayListUnmanaged(macho.data_in_code_entry) = .{}, | |
| 48 | 49 | |
| 49 | locals: std.StringArrayHashMapUnmanaged(Symbol) = .{}, | |
| 50 | stabs: std.ArrayListUnmanaged(Stab) = .{}, | |
| 51 | 50 | tu_path: ?[]const u8 = null, |
| 52 | 51 | tu_mtime: ?u64 = null, |
| 53 | 52 | |
| 54 | initializers: std.ArrayListUnmanaged(CppStatic) = .{}, | |
| 55 | data_in_code_entries: std.ArrayListUnmanaged(macho.data_in_code_entry) = .{}, | |
| 56 | ||
| 57 | 53 | pub const Section = struct { |
| 58 | 54 | inner: macho.section_64, |
| 59 | 55 | code: []u8, |
| ... | ... | @@ -71,23 +67,6 @@ pub const Section = struct { |
| 71 | 67 | } |
| 72 | 68 | }; |
| 73 | 69 | |
| 74 | const CppStatic = struct { | |
| 75 | symbol: u32, | |
| 76 | target_addr: u64, | |
| 77 | }; | |
| 78 | ||
| 79 | const Stab = struct { | |
| 80 | tag: Tag, | |
| 81 | symbol: u32, | |
| 82 | size: ?u64 = null, | |
| 83 | ||
| 84 | const Tag = enum { | |
| 85 | function, | |
| 86 | global, | |
| 87 | static, | |
| 88 | }; | |
| 89 | }; | |
| 90 | ||
| 91 | 70 | const DebugInfo = struct { |
| 92 | 71 | inner: dwarf.DwarfInfo, |
| 93 | 72 | debug_info: []u8, |
| ... | ... | @@ -169,14 +148,12 @@ pub fn deinit(self: *Object) void { |
| 169 | 148 | } |
| 170 | 149 | self.sections.deinit(self.allocator); |
| 171 | 150 | |
| 172 | for (self.locals.items()) |*entry| { | |
| 173 | entry.value.deinit(self.allocator); | |
| 151 | for (self.symbols.items) |sym| { | |
| 152 | sym.deinit(self.allocator); | |
| 153 | self.allocator.destroy(sym); | |
| 174 | 154 | } |
| 175 | self.locals.deinit(self.allocator); | |
| 155 | self.symbols.deinit(self.allocator); | |
| 176 | 156 | |
| 177 | self.symtab.deinit(self.allocator); | |
| 178 | self.strtab.deinit(self.allocator); | |
| 179 | self.stabs.deinit(self.allocator); | |
| 180 | 157 | self.data_in_code_entries.deinit(self.allocator); |
| 181 | 158 | self.initializers.deinit(self.allocator); |
| 182 | 159 | |
| ... | ... | @@ -222,9 +199,9 @@ pub fn parse(self: *Object) !void { |
| 222 | 199 | } |
| 223 | 200 | |
| 224 | 201 | try self.readLoadCommands(reader); |
| 202 | try self.parseSymbols(); | |
| 225 | 203 | try self.parseSections(); |
| 226 | if (self.symtab_cmd_index != null) try self.parseSymtab(); | |
| 227 | if (self.data_in_code_cmd_index != null) try self.readDataInCode(); | |
| 204 | try self.parseDataInCode(); | |
| 228 | 205 | try self.parseInitializers(); |
| 229 | 206 | try self.parseDebugInfo(); |
| 230 | 207 | } |
| ... | ... | @@ -298,9 +275,10 @@ pub fn readLoadCommands(self: *Object, reader: anytype) !void { |
| 298 | 275 | } |
| 299 | 276 | |
| 300 | 277 | pub fn parseSections(self: *Object) !void { |
| 301 | log.debug("parsing sections in {s}", .{self.name.?}); | |
| 302 | 278 | const seg = self.load_commands.items[self.segment_cmd_index.?].Segment; |
| 303 | 279 | |
| 280 | log.debug("parsing sections in {s}", .{self.name.?}); | |
| 281 | ||
| 304 | 282 | try self.sections.ensureCapacity(self.allocator, seg.sections.items.len); |
| 305 | 283 | |
| 306 | 284 | for (seg.sections.items) |sect| { |
| ... | ... | @@ -327,6 +305,7 @@ pub fn parseSections(self: *Object) !void { |
| 327 | 305 | self.arch.?, |
| 328 | 306 | section.code, |
| 329 | 307 | mem.bytesAsSlice(macho.relocation_info, raw_relocs), |
| 308 | self.symbols.items, | |
| 330 | 309 | ); |
| 331 | 310 | } |
| 332 | 311 | |
| ... | ... | @@ -344,60 +323,70 @@ pub fn parseInitializers(self: *Object) !void { |
| 344 | 323 | const relocs = section.relocs orelse unreachable; |
| 345 | 324 | try self.initializers.ensureCapacity(self.allocator, relocs.len); |
| 346 | 325 | for (relocs) |rel| { |
| 347 | self.initializers.appendAssumeCapacity(.{ | |
| 348 | .symbol = rel.target.symbol, | |
| 349 | .target_addr = undefined, | |
| 350 | }); | |
| 326 | self.initializers.appendAssumeCapacity(rel.target.symbol); | |
| 351 | 327 | } |
| 352 | 328 | |
| 353 | mem.reverse(CppStatic, self.initializers.items); | |
| 354 | ||
| 355 | for (self.initializers.items) |initializer| { | |
| 356 | const sym = self.symtab.items[initializer.symbol]; | |
| 357 | const sym_name = self.getString(sym.n_strx); | |
| 358 | log.debug(" | {s}", .{sym_name}); | |
| 359 | } | |
| 329 | mem.reverse(*Symbol, self.initializers.items); | |
| 360 | 330 | } |
| 361 | 331 | |
| 362 | pub fn parseSymtab(self: *Object) !void { | |
| 363 | const symtab_cmd = self.load_commands.items[self.symtab_cmd_index.?].Symtab; | |
| 332 | pub fn parseSymbols(self: *Object) !void { | |
| 333 | const index = self.symtab_cmd_index orelse return; | |
| 334 | const symtab_cmd = self.load_commands.items[index].Symtab; | |
| 364 | 335 | |
| 365 | 336 | var symtab = try self.allocator.alloc(u8, @sizeOf(macho.nlist_64) * symtab_cmd.nsyms); |
| 366 | 337 | defer self.allocator.free(symtab); |
| 367 | ||
| 368 | 338 | _ = try self.file.?.preadAll(symtab, symtab_cmd.symoff); |
| 369 | 339 | const slice = @alignCast(@alignOf(macho.nlist_64), mem.bytesAsSlice(macho.nlist_64, symtab)); |
| 370 | try self.symtab.appendSlice(self.allocator, slice); | |
| 371 | 340 | |
| 372 | 341 | var strtab = try self.allocator.alloc(u8, symtab_cmd.strsize); |
| 373 | 342 | defer self.allocator.free(strtab); |
| 374 | ||
| 375 | 343 | _ = try self.file.?.preadAll(strtab, symtab_cmd.stroff); |
| 376 | try self.strtab.appendSlice(self.allocator, strtab); | |
| 377 | 344 | |
| 378 | for (self.symtab.items) |sym, sym_id| { | |
| 379 | if (Symbol.isStab(sym) or Symbol.isUndef(sym)) continue; | |
| 345 | for (slice) |sym| { | |
| 346 | if (Symbol.isStab(sym)) { | |
| 347 | log.err("TODO handle stabs embedded within object files", .{}); | |
| 348 | return error.HandleStabsInObjects; | |
| 349 | } | |
| 380 | 350 | |
| 381 | const sym_name = self.getString(sym.n_strx); | |
| 382 | const tag: Symbol.Tag = tag: { | |
| 383 | if (Symbol.isLocal(sym)) { | |
| 384 | if (self.arch.? == .aarch64 and mem.startsWith(u8, sym_name, "l")) continue; | |
| 385 | break :tag .local; | |
| 386 | } | |
| 387 | if (Symbol.isWeakDef(sym)) { | |
| 388 | break :tag .weak; | |
| 351 | const sym_name = mem.spanZ(@ptrCast([*:0]const u8, strtab.ptr + sym.n_strx)); | |
| 352 | const name = try self.allocator.dupe(u8, sym_name); | |
| 353 | ||
| 354 | const symbol: *Symbol = symbol: { | |
| 355 | if (Symbol.isSect(sym)) { | |
| 356 | const linkage: Symbol.Regular.Linkage = linkage: { | |
| 357 | if (!Symbol.isExt(sym)) break :linkage .translation_unit; | |
| 358 | if (Symbol.isWeakDef(sym) or Symbol.isPext(sym)) break :linkage .linkage_unit; | |
| 359 | break :linkage .global; | |
| 360 | }; | |
| 361 | const regular = try self.allocator.create(Symbol.Regular); | |
| 362 | errdefer self.allocator.destroy(regular); | |
| 363 | regular.* = .{ | |
| 364 | .base = .{ | |
| 365 | .@"type" = .regular, | |
| 366 | .name = name, | |
| 367 | }, | |
| 368 | .linkage = .translation_unit, | |
| 369 | .address = sym.n_value, | |
| 370 | .section = sym.n_sect - 1, | |
| 371 | .weak_ref = Symbol.isWeakRef(sym), | |
| 372 | .file = self, | |
| 373 | }; | |
| 374 | break :symbol &regular.base; | |
| 389 | 375 | } |
| 390 | break :tag .strong; | |
| 376 | ||
| 377 | const undef = try self.allocator.create(Symbol.Unresolved); | |
| 378 | errdefer self.allocator.destroy(undef); | |
| 379 | undef.* = .{ | |
| 380 | .base = .{ | |
| 381 | .@"type" = .unresolved, | |
| 382 | .name = name, | |
| 383 | }, | |
| 384 | .file = self, | |
| 385 | }; | |
| 386 | break :symbol &undef.base; | |
| 391 | 387 | }; |
| 392 | const name = try self.allocator.dupe(u8, sym_name); | |
| 393 | 388 | |
| 394 | try self.locals.putNoClobber(self.allocator, name, .{ | |
| 395 | .tag = tag, | |
| 396 | .name = name, | |
| 397 | .address = 0, | |
| 398 | .section = 0, | |
| 399 | .index = @intCast(u32, sym_id), | |
| 400 | }); | |
| 389 | try self.symbols.append(self.allocator, symbol); | |
| 401 | 390 | } |
| 402 | 391 | } |
| 403 | 392 | |
| ... | ... | @@ -429,38 +418,31 @@ pub fn parseDebugInfo(self: *Object) !void { |
| 429 | 418 | break :mtime @intCast(u64, @divFloor(stat.mtime, 1_000_000_000)); |
| 430 | 419 | }; |
| 431 | 420 | |
| 432 | for (self.locals.items()) |entry, index| { | |
| 433 | const local = entry.value; | |
| 434 | const source_sym = self.symtab.items[local.index.?]; | |
| 435 | const size = blk: for (debug_info.inner.func_list.items) |func| { | |
| 436 | if (func.pc_range) |range| { | |
| 437 | if (source_sym.n_value >= range.start and source_sym.n_value < range.end) { | |
| 438 | break :blk range.end - range.start; | |
| 421 | for (self.symbols.items) |sym| { | |
| 422 | if (sym.cast(Symbol.Regular)) |reg| { | |
| 423 | const size: u64 = blk: for (debug_info.inner.func_list.items) |func| { | |
| 424 | if (func.pc_range) |range| { | |
| 425 | if (reg.address >= range.start and reg.address < range.end) { | |
| 426 | break :blk range.end - range.start; | |
| 427 | } | |
| 439 | 428 | } |
| 440 | } | |
| 441 | } else null; | |
| 442 | const tag: Stab.Tag = tag: { | |
| 443 | if (size != null) break :tag .function; | |
| 444 | switch (local.tag) { | |
| 445 | .weak, .strong => break :tag .global, | |
| 446 | else => break :tag .static, | |
| 447 | } | |
| 448 | }; | |
| 449 | ||
| 450 | try self.stabs.append(self.allocator, .{ | |
| 451 | .tag = tag, | |
| 452 | .size = size, | |
| 453 | .symbol = @intCast(u32, index), | |
| 454 | }); | |
| 429 | } else 0; | |
| 430 | ||
| 431 | reg.stab = .{ | |
| 432 | .kind = kind: { | |
| 433 | if (size > 0) break :kind .function; | |
| 434 | switch (reg.linkage) { | |
| 435 | .translation_unit => break :kind .static, | |
| 436 | else => break :kind .global, | |
| 437 | } | |
| 438 | }, | |
| 439 | .size = size, | |
| 440 | }; | |
| 441 | } | |
| 455 | 442 | } |
| 456 | 443 | } |
| 457 | 444 | |
| 458 | pub fn getString(self: *const Object, str_off: u32) []const u8 { | |
| 459 | assert(str_off < self.strtab.items.len); | |
| 460 | return mem.spanZ(@ptrCast([*:0]const u8, self.strtab.items.ptr + str_off)); | |
| 461 | } | |
| 462 | ||
| 463 | pub fn readSection(self: Object, allocator: *Allocator, index: u16) ![]u8 { | |
| 445 | fn readSection(self: Object, allocator: *Allocator, index: u16) ![]u8 { | |
| 464 | 446 | const seg = self.load_commands.items[self.segment_cmd_index.?].Segment; |
| 465 | 447 | const sect = seg.sections.items[index]; |
| 466 | 448 | var buffer = try allocator.alloc(u8, sect.size); |
| ... | ... | @@ -468,7 +450,7 @@ pub fn readSection(self: Object, allocator: *Allocator, index: u16) ![]u8 { |
| 468 | 450 | return buffer; |
| 469 | 451 | } |
| 470 | 452 | |
| 471 | pub fn readDataInCode(self: *Object) !void { | |
| 453 | pub fn parseDataInCode(self: *Object) !void { | |
| 472 | 454 | const index = self.data_in_code_cmd_index orelse return; |
| 473 | 455 | const data_in_code = self.load_commands.items[index].LinkeditData; |
| 474 | 456 |
src/link/MachO/Symbol.zig+81-30| ... | ... | @@ -2,31 +2,93 @@ const Symbol = @This(); |
| 2 | 2 | |
| 3 | 3 | const std = @import("std"); |
| 4 | 4 | const macho = std.macho; |
| 5 | const mem = std.mem; | |
| 5 | 6 | |
| 6 | const Allocator = std.mem.Allocator; | |
| 7 | const Allocator = mem.Allocator; | |
| 8 | const Object = @import("Object.zig"); | |
| 7 | 9 | |
| 8 | pub const Tag = enum { | |
| 9 | local, | |
| 10 | weak, | |
| 11 | strong, | |
| 12 | import, | |
| 13 | undef, | |
| 10 | pub const Type = enum { | |
| 11 | regular, | |
| 12 | proxy, | |
| 13 | unresolved, | |
| 14 | 14 | }; |
| 15 | 15 | |
| 16 | tag: Tag, | |
| 16 | /// Symbol type. | |
| 17 | @"type": Type, | |
| 18 | ||
| 19 | /// Symbol name. Owned slice. | |
| 17 | 20 | name: []u8, |
| 18 | address: u64, | |
| 19 | section: u8, | |
| 20 | 21 | |
| 21 | /// Index of file where to locate this symbol. | |
| 22 | /// Depending on context, this is either an object file, or a dylib. | |
| 23 | file: ?u16 = null, | |
| 22 | pub const Regular = struct { | |
| 23 | base: Symbol, | |
| 24 | ||
| 25 | /// Linkage type. | |
| 26 | linkage: Linkage, | |
| 27 | ||
| 28 | /// Symbol address. | |
| 29 | address: u64, | |
| 30 | ||
| 31 | /// Section ID where the symbol resides. | |
| 32 | section: u8, | |
| 33 | ||
| 34 | /// Whether the symbol is a weak ref. | |
| 35 | weak_ref: bool, | |
| 36 | ||
| 37 | /// File where to locate this symbol. | |
| 38 | file: *Object, | |
| 39 | ||
| 40 | /// Debug stab if defined. | |
| 41 | stab: ?struct { | |
| 42 | /// Stab kind | |
| 43 | kind: enum { | |
| 44 | function, | |
| 45 | global, | |
| 46 | static, | |
| 47 | }, | |
| 24 | 48 | |
| 25 | /// Index of this symbol within the file's symbol table. | |
| 26 | index: ?u32 = null, | |
| 49 | /// Size of the stab. | |
| 50 | size: u64, | |
| 51 | } = null, | |
| 27 | 52 | |
| 28 | pub fn deinit(self: *Symbol, allocator: *Allocator) void { | |
| 29 | allocator.free(self.name); | |
| 53 | pub const base_type: Symbol.Type = .regular; | |
| 54 | ||
| 55 | pub const Linkage = enum { | |
| 56 | translation_unit, | |
| 57 | linkage_unit, | |
| 58 | global, | |
| 59 | }; | |
| 60 | }; | |
| 61 | ||
| 62 | pub const Proxy = struct { | |
| 63 | base: Symbol, | |
| 64 | ||
| 65 | /// Dylib ordinal. | |
| 66 | dylib: u16, | |
| 67 | ||
| 68 | pub const base_type: Symbol.Type = .proxy; | |
| 69 | }; | |
| 70 | ||
| 71 | pub const Unresolved = struct { | |
| 72 | base: Symbol, | |
| 73 | ||
| 74 | /// Alias of. | |
| 75 | alias: ?*Symbol = null, | |
| 76 | ||
| 77 | /// File where this symbol was referenced. | |
| 78 | file: *Object, | |
| 79 | ||
| 80 | pub const base_type: Symbol.Type = .unresolved; | |
| 81 | }; | |
| 82 | ||
| 83 | pub fn deinit(base: *Symbol, allocator: *Allocator) void { | |
| 84 | allocator.free(base.name); | |
| 85 | } | |
| 86 | ||
| 87 | pub fn cast(base: *Symbol, comptime T: type) ?*T { | |
| 88 | if (base.@"type" != T.base_type) { | |
| 89 | return null; | |
| 90 | } | |
| 91 | return @fieldParentPtr(T, "base", base); | |
| 30 | 92 | } |
| 31 | 93 | |
| 32 | 94 | pub fn isStab(sym: macho.nlist_64) bool { |
| ... | ... | @@ -55,17 +117,6 @@ pub fn isWeakDef(sym: macho.nlist_64) bool { |
| 55 | 117 | return (sym.n_desc & macho.N_WEAK_DEF) != 0; |
| 56 | 118 | } |
| 57 | 119 | |
| 58 | /// Symbol is local if it is defined and not an extern. | |
| 59 | pub fn isLocal(sym: macho.nlist_64) bool { | |
| 60 | return isSect(sym) and !isExt(sym); | |
| 61 | } | |
| 62 | ||
| 63 | /// Symbol is global if it is defined and an extern. | |
| 64 | pub fn isGlobal(sym: macho.nlist_64) bool { | |
| 65 | return isSect(sym) and isExt(sym); | |
| 66 | } | |
| 67 | ||
| 68 | /// Symbol is undefined if it is not defined and an extern. | |
| 69 | pub fn isUndef(sym: macho.nlist_64) bool { | |
| 70 | return isUndf(sym) and isExt(sym); | |
| 120 | pub fn isWeakRef(sym: macho.nlist_64) bool { | |
| 121 | return (sym.n_desc & macho.N_WEAK_REF) != 0; | |
| 71 | 122 | } |
src/link/MachO/reloc.zig+7-3| ... | ... | @@ -10,6 +10,7 @@ const aarch64 = @import("reloc/aarch64.zig"); |
| 10 | 10 | const x86_64 = @import("reloc/x86_64.zig"); |
| 11 | 11 | |
| 12 | 12 | const Allocator = mem.Allocator; |
| 13 | const Symbol = @import("Symbol.zig"); | |
| 13 | 14 | |
| 14 | 15 | pub const Relocation = struct { |
| 15 | 16 | @"type": Type, |
| ... | ... | @@ -75,12 +76,12 @@ pub const Relocation = struct { |
| 75 | 76 | }; |
| 76 | 77 | |
| 77 | 78 | pub const Target = union(enum) { |
| 78 | symbol: u32, | |
| 79 | symbol: *Symbol, | |
| 79 | 80 | section: u16, |
| 80 | 81 | |
| 81 | pub fn from_reloc(reloc: macho.relocation_info) Target { | |
| 82 | pub fn from_reloc(reloc: macho.relocation_info, symbols: []*Symbol) Target { | |
| 82 | 83 | return if (reloc.r_extern == 1) .{ |
| 83 | .symbol = reloc.r_symbolnum, | |
| 84 | .symbol = symbols[reloc.r_symbolnum], | |
| 84 | 85 | } else .{ |
| 85 | 86 | .section = @intCast(u16, reloc.r_symbolnum - 1), |
| 86 | 87 | }; |
| ... | ... | @@ -136,6 +137,7 @@ pub fn parse( |
| 136 | 137 | arch: std.Target.Cpu.Arch, |
| 137 | 138 | code: []u8, |
| 138 | 139 | relocs: []const macho.relocation_info, |
| 140 | symbols: []*Symbol, | |
| 139 | 141 | ) ![]*Relocation { |
| 140 | 142 | var it = RelocIterator{ |
| 141 | 143 | .buffer = relocs, |
| ... | ... | @@ -148,6 +150,7 @@ pub fn parse( |
| 148 | 150 | .it = &it, |
| 149 | 151 | .code = code, |
| 150 | 152 | .parsed = std.ArrayList(*Relocation).init(allocator), |
| 153 | .symbols = symbols, | |
| 151 | 154 | }; |
| 152 | 155 | defer parser.deinit(); |
| 153 | 156 | try parser.parse(); |
| ... | ... | @@ -160,6 +163,7 @@ pub fn parse( |
| 160 | 163 | .it = &it, |
| 161 | 164 | .code = code, |
| 162 | 165 | .parsed = std.ArrayList(*Relocation).init(allocator), |
| 166 | .symbols = symbols, | |
| 163 | 167 | }; |
| 164 | 168 | defer parser.deinit(); |
| 165 | 169 | try parser.parse(); |
src/link/MachO/reloc/aarch64.zig+9-7| ... | ... | @@ -10,6 +10,7 @@ const reloc = @import("../reloc.zig"); |
| 10 | 10 | |
| 11 | 11 | const Allocator = mem.Allocator; |
| 12 | 12 | const Relocation = reloc.Relocation; |
| 13 | const Symbol = @import("../Symbol.zig"); | |
| 13 | 14 | |
| 14 | 15 | pub const Branch = struct { |
| 15 | 16 | base: Relocation, |
| ... | ... | @@ -188,6 +189,7 @@ pub const Parser = struct { |
| 188 | 189 | it: *reloc.RelocIterator, |
| 189 | 190 | code: []u8, |
| 190 | 191 | parsed: std.ArrayList(*Relocation), |
| 192 | symbols: []*Symbol, | |
| 191 | 193 | addend: ?u32 = null, |
| 192 | 194 | subtractor: ?Relocation.Target = null, |
| 193 | 195 | |
| ... | ... | @@ -273,7 +275,7 @@ pub const Parser = struct { |
| 273 | 275 | var branch = try parser.allocator.create(Branch); |
| 274 | 276 | errdefer parser.allocator.destroy(branch); |
| 275 | 277 | |
| 276 | const target = Relocation.Target.from_reloc(rel); | |
| 278 | const target = Relocation.Target.from_reloc(rel, parser.symbols); | |
| 277 | 279 | |
| 278 | 280 | branch.* = .{ |
| 279 | 281 | .base = .{ |
| ... | ... | @@ -294,7 +296,7 @@ pub const Parser = struct { |
| 294 | 296 | assert(rel.r_length == 2); |
| 295 | 297 | |
| 296 | 298 | const rel_type = @intToEnum(macho.reloc_type_arm64, rel.r_type); |
| 297 | const target = Relocation.Target.from_reloc(rel); | |
| 299 | const target = Relocation.Target.from_reloc(rel, parser.symbols); | |
| 298 | 300 | |
| 299 | 301 | const offset = @intCast(u32, rel.r_address); |
| 300 | 302 | const inst = parser.code[offset..][0..4]; |
| ... | ... | @@ -400,7 +402,7 @@ pub const Parser = struct { |
| 400 | 402 | aarch64.Instruction.load_store_register, |
| 401 | 403 | ), inst) }; |
| 402 | 404 | } |
| 403 | const target = Relocation.Target.from_reloc(rel); | |
| 405 | const target = Relocation.Target.from_reloc(rel, parser.symbols); | |
| 404 | 406 | |
| 405 | 407 | var page_off = try parser.allocator.create(PageOff); |
| 406 | 408 | errdefer parser.allocator.destroy(page_off); |
| ... | ... | @@ -437,7 +439,7 @@ pub const Parser = struct { |
| 437 | 439 | ), inst); |
| 438 | 440 | assert(parsed_inst.size == 3); |
| 439 | 441 | |
| 440 | const target = Relocation.Target.from_reloc(rel); | |
| 442 | const target = Relocation.Target.from_reloc(rel, parser.symbols); | |
| 441 | 443 | |
| 442 | 444 | var page_off = try parser.allocator.create(GotPageOff); |
| 443 | 445 | errdefer parser.allocator.destroy(page_off); |
| ... | ... | @@ -496,7 +498,7 @@ pub const Parser = struct { |
| 496 | 498 | } |
| 497 | 499 | }; |
| 498 | 500 | |
| 499 | const target = Relocation.Target.from_reloc(rel); | |
| 501 | const target = Relocation.Target.from_reloc(rel, parser.symbols); | |
| 500 | 502 | |
| 501 | 503 | var page_off = try parser.allocator.create(TlvpPageOff); |
| 502 | 504 | errdefer parser.allocator.destroy(page_off); |
| ... | ... | @@ -531,7 +533,7 @@ pub const Parser = struct { |
| 531 | 533 | assert(rel.r_pcrel == 0); |
| 532 | 534 | assert(parser.subtractor == null); |
| 533 | 535 | |
| 534 | parser.subtractor = Relocation.Target.from_reloc(rel); | |
| 536 | parser.subtractor = Relocation.Target.from_reloc(rel, parser.symbols); | |
| 535 | 537 | |
| 536 | 538 | // Verify SUBTRACTOR is followed by UNSIGNED. |
| 537 | 539 | const next = @intToEnum(macho.reloc_type_arm64, parser.it.peek().r_type); |
| ... | ... | @@ -554,7 +556,7 @@ pub const Parser = struct { |
| 554 | 556 | var unsigned = try parser.allocator.create(reloc.Unsigned); |
| 555 | 557 | errdefer parser.allocator.destroy(unsigned); |
| 556 | 558 | |
| 557 | const target = Relocation.Target.from_reloc(rel); | |
| 559 | const target = Relocation.Target.from_reloc(rel, parser.symbols); | |
| 558 | 560 | const is_64bit: bool = switch (rel.r_length) { |
| 559 | 561 | 3 => true, |
| 560 | 562 | 2 => false, |
src/link/MachO/reloc/x86_64.zig+9-7| ... | ... | @@ -9,6 +9,7 @@ const reloc = @import("../reloc.zig"); |
| 9 | 9 | |
| 10 | 10 | const Allocator = mem.Allocator; |
| 11 | 11 | const Relocation = reloc.Relocation; |
| 12 | const Symbol = @import("../Symbol.zig"); | |
| 12 | 13 | |
| 13 | 14 | pub const Branch = struct { |
| 14 | 15 | base: Relocation, |
| ... | ... | @@ -95,6 +96,7 @@ pub const Parser = struct { |
| 95 | 96 | it: *reloc.RelocIterator, |
| 96 | 97 | code: []u8, |
| 97 | 98 | parsed: std.ArrayList(*Relocation), |
| 99 | symbols: []*Symbol, | |
| 98 | 100 | subtractor: ?Relocation.Target = null, |
| 99 | 101 | |
| 100 | 102 | pub fn deinit(parser: *Parser) void { |
| ... | ... | @@ -145,7 +147,7 @@ pub const Parser = struct { |
| 145 | 147 | var branch = try parser.allocator.create(Branch); |
| 146 | 148 | errdefer parser.allocator.destroy(branch); |
| 147 | 149 | |
| 148 | const target = Relocation.Target.from_reloc(rel); | |
| 150 | const target = Relocation.Target.from_reloc(rel, parser.symbols); | |
| 149 | 151 | |
| 150 | 152 | branch.* = .{ |
| 151 | 153 | .base = .{ |
| ... | ... | @@ -165,7 +167,7 @@ pub const Parser = struct { |
| 165 | 167 | assert(rel.r_length == 2); |
| 166 | 168 | |
| 167 | 169 | const rel_type = @intToEnum(macho.reloc_type_x86_64, rel.r_type); |
| 168 | const target = Relocation.Target.from_reloc(rel); | |
| 170 | const target = Relocation.Target.from_reloc(rel, parser.symbols); | |
| 169 | 171 | const is_extern = rel.r_extern == 1; |
| 170 | 172 | |
| 171 | 173 | const offset = @intCast(u32, rel.r_address); |
| ... | ... | @@ -211,7 +213,7 @@ pub const Parser = struct { |
| 211 | 213 | |
| 212 | 214 | const offset = @intCast(u32, rel.r_address); |
| 213 | 215 | const inst = parser.code[offset..][0..4]; |
| 214 | const target = Relocation.Target.from_reloc(rel); | |
| 216 | const target = Relocation.Target.from_reloc(rel, parser.symbols); | |
| 215 | 217 | |
| 216 | 218 | var got_load = try parser.allocator.create(GotLoad); |
| 217 | 219 | errdefer parser.allocator.destroy(got_load); |
| ... | ... | @@ -237,7 +239,7 @@ pub const Parser = struct { |
| 237 | 239 | |
| 238 | 240 | const offset = @intCast(u32, rel.r_address); |
| 239 | 241 | const inst = parser.code[offset..][0..4]; |
| 240 | const target = Relocation.Target.from_reloc(rel); | |
| 242 | const target = Relocation.Target.from_reloc(rel, parser.symbols); | |
| 241 | 243 | |
| 242 | 244 | var got = try parser.allocator.create(Got); |
| 243 | 245 | errdefer parser.allocator.destroy(got); |
| ... | ... | @@ -263,7 +265,7 @@ pub const Parser = struct { |
| 263 | 265 | |
| 264 | 266 | const offset = @intCast(u32, rel.r_address); |
| 265 | 267 | const inst = parser.code[offset..][0..4]; |
| 266 | const target = Relocation.Target.from_reloc(rel); | |
| 268 | const target = Relocation.Target.from_reloc(rel, parser.symbols); | |
| 267 | 269 | |
| 268 | 270 | var tlv = try parser.allocator.create(Tlv); |
| 269 | 271 | errdefer parser.allocator.destroy(tlv); |
| ... | ... | @@ -288,7 +290,7 @@ pub const Parser = struct { |
| 288 | 290 | assert(rel.r_pcrel == 0); |
| 289 | 291 | assert(parser.subtractor == null); |
| 290 | 292 | |
| 291 | parser.subtractor = Relocation.Target.from_reloc(rel); | |
| 293 | parser.subtractor = Relocation.Target.from_reloc(rel, parser.symbols); | |
| 292 | 294 | |
| 293 | 295 | // Verify SUBTRACTOR is followed by UNSIGNED. |
| 294 | 296 | const next = @intToEnum(macho.reloc_type_x86_64, parser.it.peek().r_type); |
| ... | ... | @@ -311,7 +313,7 @@ pub const Parser = struct { |
| 311 | 313 | var unsigned = try parser.allocator.create(reloc.Unsigned); |
| 312 | 314 | errdefer parser.allocator.destroy(unsigned); |
| 313 | 315 | |
| 314 | const target = Relocation.Target.from_reloc(rel); | |
| 316 | const target = Relocation.Target.from_reloc(rel, parser.symbols); | |
| 315 | 317 | const is_64bit: bool = switch (rel.r_length) { |
| 316 | 318 | 3 => true, |
| 317 | 319 | 2 => false, |