authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-05-02 23:40:08+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-05-04 13:09:32+02:00
log86ab6ca56c4e6d115b017eed40dc62815a6a8e3d
tree7d429b531800dfe8614ea4789686338d5fd9a5df
parentb6be28ddcc50bd4bf085294ffcb696e31a7a1de5

zld: rewrite Object to include pointers to Symbols


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