authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-07-31 10:26:21+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-01 09:06:56+02:00
logc30cc4dbbfe3e1494160ffac18ce6a9f9a5e5224
tree7c152b08e974f3769180a7aee9838470288b0060
parent1f95c50d9a0c4c057780d387d57ac2ac40df1720

macho: don't store allocator in Object

instead, pass it in functions that require it. Also, when parsing relocs, make Object part of the context struct where we pass in additional goodies such as `*MachO` or `*Allocator`.

4 files changed, 215 insertions(+), 222 deletions(-)

src/link/MachO.zig+11-11
......@@ -2004,21 +2004,21 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
20042004 if (symbolIsStab(sym)) {
20052005 log.err("unhandled symbol type: stab", .{});
20062006 log.err(" symbol '{s}'", .{sym_name});
2007 log.err(" first definition in '{s}'", .{object.name.?});
2007 log.err(" first definition in '{s}'", .{object.name});
20082008 return error.UnhandledSymbolType;
20092009 }
20102010
20112011 if (symbolIsIndr(sym)) {
20122012 log.err("unhandled symbol type: indirect", .{});
20132013 log.err(" symbol '{s}'", .{sym_name});
2014 log.err(" first definition in '{s}'", .{object.name.?});
2014 log.err(" first definition in '{s}'", .{object.name});
20152015 return error.UnhandledSymbolType;
20162016 }
20172017
20182018 if (symbolIsAbs(sym)) {
20192019 log.err("unhandled symbol type: absolute", .{});
20202020 log.err(" symbol '{s}'", .{sym_name});
2021 log.err(" first definition in '{s}'", .{object.name.?});
2021 log.err(" first definition in '{s}'", .{object.name});
20222022 return error.UnhandledSymbolType;
20232023 }
20242024
......@@ -2068,8 +2068,8 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
20682068 !(symbolIsWeakDef(global.*) or symbolIsPext(global.*)))
20692069 {
20702070 log.err("symbol '{s}' defined multiple times", .{sym_name});
2071 log.err(" first definition in '{s}'", .{self.objects.items[resolv.file].name.?});
2072 log.err(" next definition in '{s}'", .{object.name.?});
2071 log.err(" first definition in '{s}'", .{self.objects.items[resolv.file].name});
2072 log.err(" next definition in '{s}'", .{object.name});
20732073 return error.MultipleSymbolDefinitions;
20742074 }
20752075
......@@ -2448,7 +2448,7 @@ fn resolveSymbols(self: *MachO) !void {
24482448 const resolv = self.symbol_resolver.get(sym.n_strx) orelse unreachable;
24492449
24502450 log.err("undefined reference to symbol '{s}'", .{sym_name});
2451 log.err(" first referenced in '{s}'", .{self.objects.items[resolv.file].name.?});
2451 log.err(" first referenced in '{s}'", .{self.objects.items[resolv.file].name});
24522452 has_undefined = true;
24532453 }
24542454
......@@ -2457,7 +2457,7 @@ fn resolveSymbols(self: *MachO) !void {
24572457
24582458fn parseTextBlocks(self: *MachO) !void {
24592459 for (self.objects.items) |object| {
2460 try object.parseTextBlocks(self);
2460 try object.parseTextBlocks(self.base.allocator, self);
24612461 }
24622462}
24632463
......@@ -3190,7 +3190,7 @@ fn writeSymbolTable(self: *MachO) !void {
31903190 .n_value = 0,
31913191 });
31923192 locals.appendAssumeCapacity(.{
3193 .n_strx = try self.makeString(object.name.?),
3193 .n_strx = try self.makeString(object.name),
31943194 .n_type = macho.N_OSO,
31953195 .n_sect = 0,
31963196 .n_desc = 1,
......@@ -3334,7 +3334,7 @@ pub fn deinit(self: *MachO) void {
33343334 self.symbol_resolver.deinit(self.base.allocator);
33353335
33363336 for (self.objects.items) |object| {
3337 object.deinit();
3337 object.deinit(self.base.allocator);
33383338 self.base.allocator.destroy(object);
33393339 }
33403340 self.objects.deinit(self.base.allocator);
......@@ -3372,7 +3372,7 @@ pub fn deinit(self: *MachO) void {
33723372
33733373pub fn closeFiles(self: MachO) void {
33743374 for (self.objects.items) |object| {
3375 object.closeFile();
3375 object.file.close();
33763376 }
33773377 for (self.archives.items) |archive| {
33783378 archive.closeFile();
......@@ -5913,7 +5913,7 @@ fn printSymtabAndTextBlock(self: *MachO) void {
59135913
59145914 log.debug("mappings", .{});
59155915 for (self.objects.items) |object| {
5916 log.debug(" in object {s}", .{object.name.?});
5916 log.debug(" in object {s}", .{object.name});
59175917 for (object.symtab.items) |sym, sym_id| {
59185918 if (object.symbol_mapping.get(@intCast(u32, sym_id))) |local_id| {
59195919 log.debug(" | {d} => {d}", .{ sym_id, local_id });
src/link/MachO/Archive.zig+1-3
......@@ -264,14 +264,12 @@ pub fn parseObject(self: Archive, offset: u32) !*Object {
264264 errdefer self.allocator.destroy(object);
265265
266266 object.* = .{
267 .allocator = self.allocator,
268 .arch = self.arch.?,
269267 .file = try fs.cwd().openFile(self.name.?, .{}),
270268 .name = name,
271269 .file_offset = @intCast(u32, try reader.context.getPos()),
272270 .mtime = try self.header.?.date(),
273271 };
274 try object.parse();
272 try object.parse(self.allocator, self.arch.?);
275273 try reader.context.seekTo(0);
276274
277275 return object;
src/link/MachO/Object.zig+138-140
......@@ -10,20 +10,22 @@ const macho = std.macho;
1010const math = std.math;
1111const mem = std.mem;
1212const sort = std.sort;
13const commands = @import("commands.zig");
14const segmentName = commands.segmentName;
15const sectionName = commands.sectionName;
1316
1417const Allocator = mem.Allocator;
1518const Arch = std.Target.Cpu.Arch;
19const LoadCommand = commands.LoadCommand;
1620const MachO = @import("../MachO.zig");
1721const TextBlock = @import("TextBlock.zig");
1822
19usingnamespace @import("commands.zig");
23file: fs.File,
24name: []const u8,
2025
21allocator: *Allocator,
22arch: ?Arch = null,
23header: ?macho.mach_header_64 = null,
24file: ?fs.File = null,
2526file_offset: ?u32 = null,
26name: ?[]const u8 = null,
27
28header: ?macho.mach_header_64 = null,
2729
2830load_commands: std.ArrayListUnmanaged(LoadCommand) = .{},
2931
......@@ -139,15 +141,13 @@ pub fn createAndParseFromPath(allocator: *Allocator, arch: Arch, path: []const u
139141 errdefer allocator.free(name);
140142
141143 object.* = .{
142 .allocator = allocator,
143 .arch = arch,
144144 .name = name,
145145 .file = file,
146146 };
147147
148 object.parse() catch |err| switch (err) {
148 object.parse(allocator, arch) catch |err| switch (err) {
149149 error.EndOfStream, error.NotObject => {
150 object.deinit();
150 object.deinit(allocator);
151151 allocator.destroy(object);
152152 return null;
153153 },
......@@ -157,44 +157,35 @@ pub fn createAndParseFromPath(allocator: *Allocator, arch: Arch, path: []const u
157157 return object;
158158}
159159
160pub fn deinit(self: *Object) void {
160pub fn deinit(self: *Object, allocator: *Allocator) void {
161161 for (self.load_commands.items) |*lc| {
162 lc.deinit(self.allocator);
162 lc.deinit(allocator);
163163 }
164 self.load_commands.deinit(self.allocator);
165 self.data_in_code_entries.deinit(self.allocator);
166 self.symtab.deinit(self.allocator);
167 self.strtab.deinit(self.allocator);
168 self.text_blocks.deinit(self.allocator);
169 self.sections_as_symbols.deinit(self.allocator);
170 self.symbol_mapping.deinit(self.allocator);
171 self.reverse_symbol_mapping.deinit(self.allocator);
164 self.load_commands.deinit(allocator);
165 self.data_in_code_entries.deinit(allocator);
166 self.symtab.deinit(allocator);
167 self.strtab.deinit(allocator);
168 self.text_blocks.deinit(allocator);
169 self.sections_as_symbols.deinit(allocator);
170 self.symbol_mapping.deinit(allocator);
171 self.reverse_symbol_mapping.deinit(allocator);
172 allocator.free(self.name);
172173
173174 if (self.debug_info) |*db| {
174 db.deinit(self.allocator);
175 db.deinit(allocator);
175176 }
176177
177178 if (self.tu_name) |n| {
178 self.allocator.free(n);
179 allocator.free(n);
179180 }
180181
181182 if (self.tu_comp_dir) |n| {
182 self.allocator.free(n);
183 }
184
185 if (self.name) |n| {
186 self.allocator.free(n);
187 }
188}
189
190pub fn closeFile(self: Object) void {
191 if (self.file) |f| {
192 f.close();
183 allocator.free(n);
193184 }
194185}
195186
196pub fn parse(self: *Object) !void {
197 var reader = self.file.?.reader();
187pub fn parse(self: *Object, allocator: *Allocator, arch: Arch) !void {
188 var reader = self.file.reader();
198189 if (self.file_offset) |offset| {
199190 try reader.context.seekTo(offset);
200191 }
......@@ -214,26 +205,28 @@ pub fn parse(self: *Object) !void {
214205 return error.UnsupportedCpuArchitecture;
215206 },
216207 };
217 if (this_arch != self.arch.?) {
218 log.err("mismatched cpu architecture: expected {s}, found {s}", .{ self.arch.?, this_arch });
208 if (this_arch != arch) {
209 log.err("mismatched cpu architecture: expected {s}, found {s}", .{ arch, this_arch });
219210 return error.MismatchedCpuArchitecture;
220211 }
221212
222213 self.header = header;
223214
224 try self.readLoadCommands(reader);
225 try self.parseSymtab();
226 try self.parseDataInCode();
227 try self.parseDebugInfo();
215 try self.readLoadCommands(allocator, reader);
216 try self.parseSymtab(allocator);
217 try self.parseDataInCode(allocator);
218 try self.parseDebugInfo(allocator);
228219}
229220
230pub fn readLoadCommands(self: *Object, reader: anytype) !void {
221pub fn readLoadCommands(self: *Object, allocator: *Allocator, reader: anytype) !void {
222 const header = self.header orelse unreachable; // Unreachable here signifies a fatal unexplored condition.
231223 const offset = self.file_offset orelse 0;
232 try self.load_commands.ensureCapacity(self.allocator, self.header.?.ncmds);
224
225 try self.load_commands.ensureCapacity(allocator, header.ncmds);
233226
234227 var i: u16 = 0;
235 while (i < self.header.?.ncmds) : (i += 1) {
236 var cmd = try LoadCommand.read(self.allocator, reader);
228 while (i < header.ncmds) : (i += 1) {
229 var cmd = try LoadCommand.read(allocator, reader);
237230 switch (cmd.cmd()) {
238231 macho.LC_SEGMENT_64 => {
239232 self.segment_cmd_index = i;
......@@ -347,26 +340,25 @@ fn filterDice(dices: []macho.data_in_code_entry, start_addr: u64, end_addr: u64)
347340 return dices[start..end];
348341}
349342
350const TextBlockParser = struct {
343const Context = struct {
351344 allocator: *Allocator,
345 object: *Object,
346 macho_file: *MachO,
347 match: MachO.MatchingSection,
348};
349
350const TextBlockParser = struct {
352351 section: macho.section_64,
353352 code: []u8,
354353 relocs: []macho.relocation_info,
355 object: *Object,
356 macho_file: *MachO,
357354 nlists: []NlistWithIndex,
358355 index: u32 = 0,
359 match: MachO.MatchingSection,
360356
361 fn peek(self: *TextBlockParser) ?NlistWithIndex {
357 fn peek(self: TextBlockParser) ?NlistWithIndex {
362358 return if (self.index + 1 < self.nlists.len) self.nlists[self.index + 1] else null;
363359 }
364360
365 const SeniorityContext = struct {
366 object: *Object,
367 };
368
369 fn lessThanBySeniority(context: SeniorityContext, lhs: NlistWithIndex, rhs: NlistWithIndex) bool {
361 fn lessThanBySeniority(context: Context, lhs: NlistWithIndex, rhs: NlistWithIndex) bool {
370362 if (!MachO.symbolIsExt(rhs.nlist)) {
371363 return MachO.symbolIsTemp(lhs.nlist, context.object.getString(lhs.nlist.n_strx));
372364 } else if (MachO.symbolIsPext(rhs.nlist) or MachO.symbolIsWeakDef(rhs.nlist)) {
......@@ -376,10 +368,10 @@ const TextBlockParser = struct {
376368 }
377369 }
378370
379 pub fn next(self: *TextBlockParser) !?*TextBlock {
371 pub fn next(self: *TextBlockParser, context: Context) !?*TextBlock {
380372 if (self.index == self.nlists.len) return null;
381373
382 var aliases = std.ArrayList(NlistWithIndex).init(self.allocator);
374 var aliases = std.ArrayList(NlistWithIndex).init(context.allocator);
383375 defer aliases.deinit();
384376
385377 const next_nlist: ?NlistWithIndex = blk: while (true) {
......@@ -397,7 +389,7 @@ const TextBlockParser = struct {
397389 } else null;
398390
399391 for (aliases.items) |*nlist_with_index| {
400 nlist_with_index.index = self.object.symbol_mapping.get(nlist_with_index.index) orelse unreachable;
392 nlist_with_index.index = context.object.symbol_mapping.get(nlist_with_index.index) orelse unreachable;
401393 }
402394
403395 if (aliases.items.len > 1) {
......@@ -405,14 +397,14 @@ const TextBlockParser = struct {
405397 sort.sort(
406398 NlistWithIndex,
407399 aliases.items,
408 SeniorityContext{ .object = self.object },
400 context,
409401 TextBlockParser.lessThanBySeniority,
410402 );
411403 }
412404
413405 const senior_nlist = aliases.pop();
414 const senior_sym = &self.macho_file.locals.items[senior_nlist.index];
415 senior_sym.n_sect = self.macho_file.section_to_ordinal.get(self.match) orelse unreachable;
406 const senior_sym = &context.macho_file.locals.items[senior_nlist.index];
407 senior_sym.n_sect = context.macho_file.section_to_ordinal.get(context.match) orelse unreachable;
416408
417409 const start_addr = senior_nlist.nlist.n_value - self.section.addr;
418410 const end_addr = if (next_nlist) |n| n.nlist.n_value - self.section.addr else self.section.size;
......@@ -426,7 +418,7 @@ const TextBlockParser = struct {
426418 else
427419 max_align;
428420
429 const stab: ?TextBlock.Stab = if (self.object.debug_info) |di| blk: {
421 const stab: ?TextBlock.Stab = if (context.object.debug_info) |di| blk: {
430422 // TODO there has to be a better to handle this.
431423 for (di.inner.func_list.items) |func| {
432424 if (func.pc_range) |range| {
......@@ -442,35 +434,37 @@ const TextBlockParser = struct {
442434 break :blk .static;
443435 } else null;
444436
445 const block = try self.macho_file.base.allocator.create(TextBlock);
437 const block = try context.allocator.create(TextBlock);
446438 block.* = TextBlock.empty;
447439 block.local_sym_index = senior_nlist.index;
448440 block.stab = stab;
449441 block.size = size;
450442 block.alignment = actual_align;
451 try self.macho_file.managed_blocks.append(self.macho_file.base.allocator, block);
443 try context.macho_file.managed_blocks.append(context.allocator, block);
452444
453 try block.code.appendSlice(self.macho_file.base.allocator, code);
445 try block.code.appendSlice(context.allocator, code);
454446
455 try block.aliases.ensureTotalCapacity(self.macho_file.base.allocator, aliases.items.len);
447 try block.aliases.ensureTotalCapacity(context.allocator, aliases.items.len);
456448 for (aliases.items) |alias| {
457449 block.aliases.appendAssumeCapacity(alias.index);
458 const sym = &self.macho_file.locals.items[alias.index];
459 sym.n_sect = self.macho_file.section_to_ordinal.get(self.match) orelse unreachable;
450 const sym = &context.macho_file.locals.items[alias.index];
451 sym.n_sect = context.macho_file.section_to_ordinal.get(context.match) orelse unreachable;
460452 }
461453
462 try block.parseRelocsFromObject(self.macho_file.base.allocator, self.relocs, self.object, .{
454 try block.parseRelocs(self.relocs, .{
463455 .base_addr = start_addr,
464 .macho_file = self.macho_file,
456 .allocator = context.allocator,
457 .object = context.object,
458 .macho_file = context.macho_file,
465459 });
466460
467 if (self.macho_file.has_dices) {
461 if (context.macho_file.has_dices) {
468462 const dices = filterDice(
469 self.object.data_in_code_entries.items,
463 context.object.data_in_code_entries.items,
470464 senior_nlist.nlist.n_value,
471465 senior_nlist.nlist.n_value + size,
472466 );
473 try block.dices.ensureTotalCapacity(self.macho_file.base.allocator, dices.len);
467 try block.dices.ensureTotalCapacity(context.allocator, dices.len);
474468
475469 for (dices) |dice| {
476470 block.dices.appendAssumeCapacity(.{
......@@ -487,16 +481,16 @@ const TextBlockParser = struct {
487481 }
488482};
489483
490pub fn parseTextBlocks(self: *Object, macho_file: *MachO) !void {
484pub fn parseTextBlocks(self: *Object, allocator: *Allocator, macho_file: *MachO) !void {
491485 const seg = self.load_commands.items[self.segment_cmd_index.?].Segment;
492486
493 log.debug("analysing {s}", .{self.name.?});
487 log.debug("analysing {s}", .{self.name});
494488
495489 // You would expect that the symbol table is at least pre-sorted based on symbol's type:
496490 // local < extern defined < undefined. Unfortunately, this is not guaranteed! For instance,
497491 // the GO compiler does not necessarily respect that therefore we sort immediately by type
498492 // and address within.
499 var sorted_all_nlists = std.ArrayList(NlistWithIndex).init(self.allocator);
493 var sorted_all_nlists = std.ArrayList(NlistWithIndex).init(allocator);
500494 defer sorted_all_nlists.deinit();
501495 try sorted_all_nlists.ensureTotalCapacity(self.symtab.items.len);
502496
......@@ -540,14 +534,14 @@ pub fn parseTextBlocks(self: *Object, macho_file: *MachO) !void {
540534 };
541535
542536 // Read section's code
543 var code = try self.allocator.alloc(u8, @intCast(usize, sect.size));
544 defer self.allocator.free(code);
545 _ = try self.file.?.preadAll(code, sect.offset);
537 var code = try allocator.alloc(u8, @intCast(usize, sect.size));
538 defer allocator.free(code);
539 _ = try self.file.preadAll(code, sect.offset);
546540
547541 // Read section's list of relocations
548 var raw_relocs = try self.allocator.alloc(u8, sect.nreloc * @sizeOf(macho.relocation_info));
549 defer self.allocator.free(raw_relocs);
550 _ = try self.file.?.preadAll(raw_relocs, sect.reloff);
542 var raw_relocs = try allocator.alloc(u8, sect.nreloc * @sizeOf(macho.relocation_info));
543 defer allocator.free(raw_relocs);
544 _ = try self.file.preadAll(raw_relocs, sect.reloff);
551545 const relocs = mem.bytesAsSlice(macho.relocation_info, raw_relocs);
552546
553547 // Symbols within this section only.
......@@ -579,46 +573,48 @@ pub fn parseTextBlocks(self: *Object, macho_file: *MachO) !void {
579573 // as a temporary symbol and insert the matching TextBlock.
580574 const first_nlist = filtered_nlists[0].nlist;
581575 if (first_nlist.n_value > sect.addr) {
582 const sym_name = try std.fmt.allocPrint(self.allocator, "l_{s}_{s}_{s}", .{
583 self.name.?,
576 const sym_name = try std.fmt.allocPrint(allocator, "l_{s}_{s}_{s}", .{
577 self.name,
584578 segmentName(sect),
585579 sectionName(sect),
586580 });
587 defer self.allocator.free(sym_name);
581 defer allocator.free(sym_name);
588582
589583 const block_local_sym_index = self.sections_as_symbols.get(sect_id) orelse blk: {
590584 const block_local_sym_index = @intCast(u32, macho_file.locals.items.len);
591 try macho_file.locals.append(macho_file.base.allocator, .{
585 try macho_file.locals.append(allocator, .{
592586 .n_strx = try macho_file.makeString(sym_name),
593587 .n_type = macho.N_SECT,
594588 .n_sect = macho_file.section_to_ordinal.get(match) orelse unreachable,
595589 .n_desc = 0,
596590 .n_value = sect.addr,
597591 });
598 try self.sections_as_symbols.putNoClobber(self.allocator, sect_id, block_local_sym_index);
592 try self.sections_as_symbols.putNoClobber(allocator, sect_id, block_local_sym_index);
599593 break :blk block_local_sym_index;
600594 };
601595
602596 const block_code = code[0 .. first_nlist.n_value - sect.addr];
603597 const block_size = block_code.len;
604598
605 const block = try macho_file.base.allocator.create(TextBlock);
599 const block = try allocator.create(TextBlock);
606600 block.* = TextBlock.empty;
607601 block.local_sym_index = block_local_sym_index;
608602 block.size = block_size;
609603 block.alignment = sect.@"align";
610 try macho_file.managed_blocks.append(macho_file.base.allocator, block);
604 try macho_file.managed_blocks.append(allocator, block);
611605
612 try block.code.appendSlice(macho_file.base.allocator, block_code);
606 try block.code.appendSlice(allocator, block_code);
613607
614 try block.parseRelocsFromObject(self.allocator, relocs, self, .{
608 try block.parseRelocs(relocs, .{
615609 .base_addr = 0,
610 .allocator = allocator,
611 .object = self,
616612 .macho_file = macho_file,
617613 });
618614
619615 if (macho_file.has_dices) {
620616 const dices = filterDice(self.data_in_code_entries.items, sect.addr, sect.addr + block_size);
621 try block.dices.ensureTotalCapacity(macho_file.base.allocator, dices.len);
617 try block.dices.ensureTotalCapacity(allocator, dices.len);
622618
623619 for (dices) |dice| {
624620 block.dices.appendAssumeCapacity(.{
......@@ -645,24 +641,25 @@ pub fn parseTextBlocks(self: *Object, macho_file: *MachO) !void {
645641 block.prev = last.*;
646642 last.* = block;
647643 } else {
648 try macho_file.blocks.putNoClobber(macho_file.base.allocator, match, block);
644 try macho_file.blocks.putNoClobber(allocator, match, block);
649645 }
650646
651 try self.text_blocks.append(self.allocator, block);
647 try self.text_blocks.append(allocator, block);
652648 }
653649
654650 var parser = TextBlockParser{
655 .allocator = self.allocator,
656651 .section = sect,
657652 .code = code,
658653 .relocs = relocs,
659 .object = self,
660 .macho_file = macho_file,
661654 .nlists = filtered_nlists,
662 .match = match,
663655 };
664656
665 while (try parser.next()) |block| {
657 while (try parser.next(.{
658 .allocator = allocator,
659 .object = self,
660 .macho_file = macho_file,
661 .match = match,
662 })) |block| {
666663 const sym = macho_file.locals.items[block.local_sym_index];
667664 const is_ext = blk: {
668665 const orig_sym_id = self.reverse_symbol_mapping.get(block.local_sym_index) orelse unreachable;
......@@ -675,9 +672,9 @@ pub fn parseTextBlocks(self: *Object, macho_file: *MachO) !void {
675672 if (global_object != self) {
676673 log.debug("deduping definition of {s} in {s}", .{
677674 macho_file.getString(sym.n_strx),
678 self.name.?,
675 self.name,
679676 });
680 log.debug(" already defined in {s}", .{global_object.name.?});
677 log.debug(" already defined in {s}", .{global_object.name});
681678 continue;
682679 }
683680 }
......@@ -688,7 +685,7 @@ pub fn parseTextBlocks(self: *Object, macho_file: *MachO) !void {
688685 // In x86_64 relocs, it can so happen that the compiler refers to the same
689686 // atom by both the actual assigned symbol and the start of the section. In this
690687 // case, we need to link the two together so add an alias.
691 try block.aliases.append(macho_file.base.allocator, alias);
688 try block.aliases.append(allocator, alias);
692689 }
693690 }
694691
......@@ -708,10 +705,10 @@ pub fn parseTextBlocks(self: *Object, macho_file: *MachO) !void {
708705 block.prev = last.*;
709706 last.* = block;
710707 } else {
711 try macho_file.blocks.putNoClobber(macho_file.base.allocator, match, block);
708 try macho_file.blocks.putNoClobber(allocator, match, block);
712709 }
713710
714 try self.text_blocks.append(self.allocator, block);
711 try self.text_blocks.append(allocator, block);
715712 }
716713
717714 break :next;
......@@ -720,43 +717,45 @@ pub fn parseTextBlocks(self: *Object, macho_file: *MachO) !void {
720717 // Since there is no symbol to refer to this block, we create
721718 // a temp one, unless we already did that when working out the relocations
722719 // of other text blocks.
723 const sym_name = try std.fmt.allocPrint(self.allocator, "l_{s}_{s}_{s}", .{
724 self.name.?,
720 const sym_name = try std.fmt.allocPrint(allocator, "l_{s}_{s}_{s}", .{
721 self.name,
725722 segmentName(sect),
726723 sectionName(sect),
727724 });
728 defer self.allocator.free(sym_name);
725 defer allocator.free(sym_name);
729726
730727 const block_local_sym_index = self.sections_as_symbols.get(sect_id) orelse blk: {
731728 const block_local_sym_index = @intCast(u32, macho_file.locals.items.len);
732 try macho_file.locals.append(macho_file.base.allocator, .{
729 try macho_file.locals.append(allocator, .{
733730 .n_strx = try macho_file.makeString(sym_name),
734731 .n_type = macho.N_SECT,
735732 .n_sect = macho_file.section_to_ordinal.get(match) orelse unreachable,
736733 .n_desc = 0,
737734 .n_value = sect.addr,
738735 });
739 try self.sections_as_symbols.putNoClobber(self.allocator, sect_id, block_local_sym_index);
736 try self.sections_as_symbols.putNoClobber(allocator, sect_id, block_local_sym_index);
740737 break :blk block_local_sym_index;
741738 };
742739
743 const block = try macho_file.base.allocator.create(TextBlock);
740 const block = try allocator.create(TextBlock);
744741 block.* = TextBlock.empty;
745742 block.local_sym_index = block_local_sym_index;
746743 block.size = sect.size;
747744 block.alignment = sect.@"align";
748 try macho_file.managed_blocks.append(macho_file.base.allocator, block);
745 try macho_file.managed_blocks.append(allocator, block);
749746
750 try block.code.appendSlice(macho_file.base.allocator, code);
747 try block.code.appendSlice(allocator, code);
751748
752 try block.parseRelocsFromObject(self.allocator, relocs, self, .{
749 try block.parseRelocs(relocs, .{
753750 .base_addr = 0,
751 .allocator = allocator,
752 .object = self,
754753 .macho_file = macho_file,
755754 });
756755
757756 if (macho_file.has_dices) {
758757 const dices = filterDice(self.data_in_code_entries.items, sect.addr, sect.addr + sect.size);
759 try block.dices.ensureTotalCapacity(macho_file.base.allocator, dices.len);
758 try block.dices.ensureTotalCapacity(allocator, dices.len);
760759
761760 for (dices) |dice| {
762761 block.dices.appendAssumeCapacity(.{
......@@ -772,7 +771,7 @@ pub fn parseTextBlocks(self: *Object, macho_file: *MachO) !void {
772771 // the filtered symbols and note which symbol is contained within so that
773772 // we can properly allocate addresses down the line.
774773 // While we're at it, we need to update segment,section mapping of each symbol too.
775 try block.contained.ensureTotalCapacity(self.allocator, filtered_nlists.len);
774 try block.contained.ensureTotalCapacity(allocator, filtered_nlists.len);
776775
777776 for (filtered_nlists) |nlist_with_index| {
778777 const nlist = nlist_with_index.nlist;
......@@ -819,35 +818,35 @@ pub fn parseTextBlocks(self: *Object, macho_file: *MachO) !void {
819818 block.prev = last.*;
820819 last.* = block;
821820 } else {
822 try macho_file.blocks.putNoClobber(macho_file.base.allocator, match, block);
821 try macho_file.blocks.putNoClobber(allocator, match, block);
823822 }
824823
825 try self.text_blocks.append(self.allocator, block);
824 try self.text_blocks.append(allocator, block);
826825 }
827826 }
828827}
829828
830fn parseSymtab(self: *Object) !void {
829fn parseSymtab(self: *Object, allocator: *Allocator) !void {
831830 const index = self.symtab_cmd_index orelse return;
832831 const symtab_cmd = self.load_commands.items[index].Symtab;
833832
834 var symtab = try self.allocator.alloc(u8, @sizeOf(macho.nlist_64) * symtab_cmd.nsyms);
835 defer self.allocator.free(symtab);
836 _ = try self.file.?.preadAll(symtab, symtab_cmd.symoff);
833 var symtab = try allocator.alloc(u8, @sizeOf(macho.nlist_64) * symtab_cmd.nsyms);
834 defer allocator.free(symtab);
835 _ = try self.file.preadAll(symtab, symtab_cmd.symoff);
837836 const slice = @alignCast(@alignOf(macho.nlist_64), mem.bytesAsSlice(macho.nlist_64, symtab));
838 try self.symtab.appendSlice(self.allocator, slice);
837 try self.symtab.appendSlice(allocator, slice);
839838
840 var strtab = try self.allocator.alloc(u8, symtab_cmd.strsize);
841 defer self.allocator.free(strtab);
842 _ = try self.file.?.preadAll(strtab, symtab_cmd.stroff);
843 try self.strtab.appendSlice(self.allocator, strtab);
839 var strtab = try allocator.alloc(u8, symtab_cmd.strsize);
840 defer allocator.free(strtab);
841 _ = try self.file.preadAll(strtab, symtab_cmd.stroff);
842 try self.strtab.appendSlice(allocator, strtab);
844843}
845844
846pub fn parseDebugInfo(self: *Object) !void {
847 log.debug("parsing debug info in '{s}'", .{self.name.?});
845pub fn parseDebugInfo(self: *Object, allocator: *Allocator) !void {
846 log.debug("parsing debug info in '{s}'", .{self.name});
848847
849848 var debug_info = blk: {
850 var di = try DebugInfo.parseFromObject(self.allocator, self);
849 var di = try DebugInfo.parseFromObject(allocator, self);
851850 break :blk di orelse return;
852851 };
853852
......@@ -855,7 +854,7 @@ pub fn parseDebugInfo(self: *Object) !void {
855854 const compile_unit = debug_info.inner.findCompileUnit(0x0) catch |err| switch (err) {
856855 error.MissingDebugInfo => {
857856 // TODO audit cases with missing debug info and audit our dwarf.zig module.
858 log.debug("invalid or missing debug info in {s}; skipping", .{self.name.?});
857 log.debug("invalid or missing debug info in {s}; skipping", .{self.name});
859858 return;
860859 },
861860 else => |e| return e,
......@@ -864,26 +863,25 @@ pub fn parseDebugInfo(self: *Object) !void {
864863 const comp_dir = try compile_unit.die.getAttrString(&debug_info.inner, dwarf.AT_comp_dir);
865864
866865 self.debug_info = debug_info;
867 self.tu_name = try self.allocator.dupe(u8, name);
868 self.tu_comp_dir = try self.allocator.dupe(u8, comp_dir);
866 self.tu_name = try allocator.dupe(u8, name);
867 self.tu_comp_dir = try allocator.dupe(u8, comp_dir);
869868
870869 if (self.mtime == null) {
871870 self.mtime = mtime: {
872 const file = self.file orelse break :mtime 0;
873 const stat = file.stat() catch break :mtime 0;
871 const stat = self.file.stat() catch break :mtime 0;
874872 break :mtime @intCast(u64, @divFloor(stat.mtime, 1_000_000_000));
875873 };
876874 }
877875}
878876
879pub fn parseDataInCode(self: *Object) !void {
877pub fn parseDataInCode(self: *Object, allocator: *Allocator) !void {
880878 const index = self.data_in_code_cmd_index orelse return;
881879 const data_in_code = self.load_commands.items[index].LinkeditData;
882880
883 var buffer = try self.allocator.alloc(u8, data_in_code.datasize);
884 defer self.allocator.free(buffer);
881 var buffer = try allocator.alloc(u8, data_in_code.datasize);
882 defer allocator.free(buffer);
885883
886 _ = try self.file.?.preadAll(buffer, data_in_code.dataoff);
884 _ = try self.file.preadAll(buffer, data_in_code.dataoff);
887885
888886 var stream = io.fixedBufferStream(buffer);
889887 var reader = stream.reader();
......@@ -892,7 +890,7 @@ pub fn parseDataInCode(self: *Object) !void {
892890 error.EndOfStream => break,
893891 else => |e| return e,
894892 };
895 try self.data_in_code_entries.append(self.allocator, dice);
893 try self.data_in_code_entries.append(allocator, dice);
896894 }
897895}
898896
......@@ -900,7 +898,7 @@ fn readSection(self: Object, allocator: *Allocator, index: u16) ![]u8 {
900898 const seg = self.load_commands.items[self.segment_cmd_index.?].Segment;
901899 const sect = seg.sections.items[index];
902900 var buffer = try allocator.alloc(u8, @intCast(usize, sect.size));
903 _ = try self.file.?.preadAll(buffer, sect.offset);
901 _ = try self.file.preadAll(buffer, sect.offset);
904902 return buffer;
905903}
906904
src/link/MachO/TextBlock.zig+65-68
......@@ -606,12 +606,14 @@ pub fn freeListEligible(self: TextBlock, macho_file: MachO) bool {
606606
607607const RelocContext = struct {
608608 base_addr: u64 = 0,
609 allocator: *Allocator,
610 object: *Object,
609611 macho_file: *MachO,
610612};
611613
612fn initRelocFromObject(rel: macho.relocation_info, object: *Object, ctx: RelocContext) !Relocation {
614fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Relocation {
613615 var parsed_rel = Relocation{
614 .offset = @intCast(u32, @intCast(u64, rel.r_address) - ctx.base_addr),
616 .offset = @intCast(u32, @intCast(u64, rel.r_address) - context.base_addr),
615617 .where = undefined,
616618 .where_index = undefined,
617619 .payload = undefined,
......@@ -620,44 +622,44 @@ fn initRelocFromObject(rel: macho.relocation_info, object: *Object, ctx: RelocCo
620622 if (rel.r_extern == 0) {
621623 const sect_id = @intCast(u16, rel.r_symbolnum - 1);
622624
623 const local_sym_index = object.sections_as_symbols.get(sect_id) orelse blk: {
624 const seg = object.load_commands.items[object.segment_cmd_index.?].Segment;
625 const local_sym_index = context.object.sections_as_symbols.get(sect_id) orelse blk: {
626 const seg = context.object.load_commands.items[context.object.segment_cmd_index.?].Segment;
625627 const sect = seg.sections.items[sect_id];
626 const match = (try ctx.macho_file.getMatchingSection(sect)) orelse unreachable;
627 const local_sym_index = @intCast(u32, ctx.macho_file.locals.items.len);
628 const sym_name = try std.fmt.allocPrint(ctx.macho_file.base.allocator, "l_{s}_{s}_{s}", .{
629 object.name.?,
628 const match = (try context.macho_file.getMatchingSection(sect)) orelse unreachable;
629 const local_sym_index = @intCast(u32, context.macho_file.locals.items.len);
630 const sym_name = try std.fmt.allocPrint(context.allocator, "l_{s}_{s}_{s}", .{
631 context.object.name,
630632 commands.segmentName(sect),
631633 commands.sectionName(sect),
632634 });
633 defer ctx.macho_file.base.allocator.free(sym_name);
635 defer context.allocator.free(sym_name);
634636
635 try ctx.macho_file.locals.append(ctx.macho_file.base.allocator, .{
636 .n_strx = try ctx.macho_file.makeString(sym_name),
637 try context.macho_file.locals.append(context.allocator, .{
638 .n_strx = try context.macho_file.makeString(sym_name),
637639 .n_type = macho.N_SECT,
638 .n_sect = ctx.macho_file.section_to_ordinal.get(match) orelse unreachable,
640 .n_sect = context.macho_file.section_to_ordinal.get(match) orelse unreachable,
639641 .n_desc = 0,
640642 .n_value = sect.addr,
641643 });
642 try object.sections_as_symbols.putNoClobber(object.allocator, sect_id, local_sym_index);
644 try context.object.sections_as_symbols.putNoClobber(context.allocator, sect_id, local_sym_index);
643645 break :blk local_sym_index;
644646 };
645647
646648 parsed_rel.where = .local;
647649 parsed_rel.where_index = local_sym_index;
648650 } else {
649 const sym = object.symtab.items[rel.r_symbolnum];
650 const sym_name = object.getString(sym.n_strx);
651 const sym = context.object.symtab.items[rel.r_symbolnum];
652 const sym_name = context.object.getString(sym.n_strx);
651653
652654 if (MachO.symbolIsSect(sym) and !MachO.symbolIsExt(sym)) {
653 const where_index = object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;
655 const where_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;
654656 parsed_rel.where = .local;
655657 parsed_rel.where_index = where_index;
656658 } else {
657 const n_strx = ctx.macho_file.strtab_dir.getAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
658 .strtab = &ctx.macho_file.strtab,
659 const n_strx = context.macho_file.strtab_dir.getAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
660 .strtab = &context.macho_file.strtab,
659661 }) orelse unreachable;
660 const resolv = ctx.macho_file.symbol_resolver.get(n_strx) orelse unreachable;
662 const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;
661663 switch (resolv.where) {
662664 .global => {
663665 parsed_rel.where = .local;
......@@ -675,29 +677,24 @@ fn initRelocFromObject(rel: macho.relocation_info, object: *Object, ctx: RelocCo
675677 return parsed_rel;
676678}
677679
678pub fn parseRelocsFromObject(
679 self: *TextBlock,
680 allocator: *Allocator,
681 relocs: []macho.relocation_info,
682 object: *Object,
683 ctx: RelocContext,
684) !void {
685 const filtered_relocs = filterRelocs(relocs, ctx.base_addr, ctx.base_addr + self.size);
680pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: RelocContext) !void {
681 const filtered_relocs = filterRelocs(relocs, context.base_addr, context.base_addr + self.size);
686682 var it = RelocIterator{
687683 .buffer = filtered_relocs,
688684 };
689685
690686 var addend: u32 = 0;
691687 var subtractor: ?u32 = null;
688 const arch = context.macho_file.base.options.target.cpu.arch;
692689
693690 while (it.next()) |rel| {
694 if (isAddend(rel, object.arch.?)) {
691 if (isAddend(rel, arch)) {
695692 // Addend is not a relocation with effect on the TextBlock, so
696693 // parse it and carry on.
697694 assert(addend == 0); // Oh no, addend was not reset!
698695 addend = rel.r_symbolnum;
699696
700 // Verify ADDEND is followed by a load.
697 // Verify ADDEND is followed by a PAGE21 or PAGEOFF12.
701698 const next = @intToEnum(macho.reloc_type_arm64, it.peek().r_type);
702699 switch (next) {
703700 .ARM64_RELOC_PAGE21, .ARM64_RELOC_PAGEOFF12 => {},
......@@ -709,28 +706,28 @@ pub fn parseRelocsFromObject(
709706 continue;
710707 }
711708
712 if (isSubtractor(rel, object.arch.?)) {
709 if (isSubtractor(rel, arch)) {
713710 // Subtractor is not a relocation with effect on the TextBlock, so
714711 // parse it and carry on.
715712 assert(subtractor == null); // Oh no, subtractor was not reset!
716713 assert(rel.r_extern == 1);
717 const sym = object.symtab.items[rel.r_symbolnum];
718 const sym_name = object.getString(sym.n_strx);
714 const sym = context.object.symtab.items[rel.r_symbolnum];
715 const sym_name = context.object.getString(sym.n_strx);
719716
720717 if (MachO.symbolIsSect(sym) and !MachO.symbolIsExt(sym)) {
721 const where_index = object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;
718 const where_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;
722719 subtractor = where_index;
723720 } else {
724 const n_strx = ctx.macho_file.strtab_dir.getAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
725 .strtab = &ctx.macho_file.strtab,
721 const n_strx = context.macho_file.strtab_dir.getAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{
722 .strtab = &context.macho_file.strtab,
726723 }) orelse unreachable;
727 const resolv = ctx.macho_file.symbol_resolver.get(n_strx) orelse unreachable;
724 const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable;
728725 assert(resolv.where == .global);
729726 subtractor = resolv.local_sym_index;
730727 }
731728
732729 // Verify SUBTRACTOR is followed by UNSIGNED.
733 switch (object.arch.?) {
730 switch (arch) {
734731 .aarch64 => {
735732 const next = @intToEnum(macho.reloc_type_arm64, it.peek().r_type);
736733 if (next != .ARM64_RELOC_UNSIGNED) {
......@@ -750,19 +747,19 @@ pub fn parseRelocsFromObject(
750747 continue;
751748 }
752749
753 var parsed_rel = try initRelocFromObject(rel, object, ctx);
750 var parsed_rel = try initRelocFromObject(rel, context);
754751
755 switch (object.arch.?) {
752 switch (arch) {
756753 .aarch64 => {
757754 const rel_type = @intToEnum(macho.reloc_type_arm64, rel.r_type);
758755 switch (rel_type) {
759756 .ARM64_RELOC_ADDEND => unreachable,
760757 .ARM64_RELOC_SUBTRACTOR => unreachable,
761758 .ARM64_RELOC_BRANCH26 => {
762 self.parseBranch(rel, &parsed_rel, ctx);
759 self.parseBranch(rel, &parsed_rel, context);
763760 },
764761 .ARM64_RELOC_UNSIGNED => {
765 self.parseUnsigned(rel, &parsed_rel, subtractor, ctx);
762 self.parseUnsigned(rel, &parsed_rel, subtractor, context);
766763 subtractor = null;
767764 },
768765 .ARM64_RELOC_PAGE21,
......@@ -790,10 +787,10 @@ pub fn parseRelocsFromObject(
790787 switch (@intToEnum(macho.reloc_type_x86_64, rel.r_type)) {
791788 .X86_64_RELOC_SUBTRACTOR => unreachable,
792789 .X86_64_RELOC_BRANCH => {
793 self.parseBranch(rel, &parsed_rel, ctx);
790 self.parseBranch(rel, &parsed_rel, context);
794791 },
795792 .X86_64_RELOC_UNSIGNED => {
796 self.parseUnsigned(rel, &parsed_rel, subtractor, ctx);
793 self.parseUnsigned(rel, &parsed_rel, subtractor, context);
797794 subtractor = null;
798795 },
799796 .X86_64_RELOC_SIGNED,
......@@ -801,7 +798,7 @@ pub fn parseRelocsFromObject(
801798 .X86_64_RELOC_SIGNED_2,
802799 .X86_64_RELOC_SIGNED_4,
803800 => {
804 self.parseSigned(rel, &parsed_rel, ctx);
801 self.parseSigned(rel, &parsed_rel, context);
805802 },
806803 .X86_64_RELOC_GOT_LOAD,
807804 .X86_64_RELOC_GOT,
......@@ -814,7 +811,7 @@ pub fn parseRelocsFromObject(
814811 else => unreachable,
815812 }
816813
817 try self.relocs.append(allocator, parsed_rel);
814 try self.relocs.append(context.allocator, parsed_rel);
818815
819816 const is_via_got = switch (parsed_rel.payload) {
820817 .pointer_to_got => true,
......@@ -832,23 +829,23 @@ pub fn parseRelocsFromObject(
832829 },
833830 .where_index = parsed_rel.where_index,
834831 };
835 if (ctx.macho_file.got_entries_map.contains(key)) break :blk;
832 if (context.macho_file.got_entries_map.contains(key)) break :blk;
836833
837 const got_index = @intCast(u32, ctx.macho_file.got_entries.items.len);
838 try ctx.macho_file.got_entries.append(ctx.macho_file.base.allocator, key);
839 try ctx.macho_file.got_entries_map.putNoClobber(ctx.macho_file.base.allocator, key, got_index);
834 const got_index = @intCast(u32, context.macho_file.got_entries.items.len);
835 try context.macho_file.got_entries.append(context.allocator, key);
836 try context.macho_file.got_entries_map.putNoClobber(context.allocator, key, got_index);
840837 } else if (parsed_rel.payload == .unsigned) {
841838 switch (parsed_rel.where) {
842839 .import => {
843 try self.bindings.append(allocator, .{
840 try self.bindings.append(context.allocator, .{
844841 .local_sym_index = parsed_rel.where_index,
845842 .offset = parsed_rel.offset,
846843 });
847844 },
848845 .local => {
849 const source_sym = ctx.macho_file.locals.items[self.local_sym_index];
850 const match = ctx.macho_file.section_ordinals.items[source_sym.n_sect];
851 const seg = ctx.macho_file.load_commands.items[match.seg].Segment;
846 const source_sym = context.macho_file.locals.items[self.local_sym_index];
847 const match = context.macho_file.section_ordinals.items[source_sym.n_sect];
848 const seg = context.macho_file.load_commands.items[match.seg].Segment;
852849 const sect = seg.sections.items[match.sect];
853850 const sect_type = commands.sectionType(sect);
854851
......@@ -858,12 +855,12 @@ pub fn parseRelocsFromObject(
858855 // TODO actually, a check similar to what dyld is doing, that is, verifying
859856 // that the segment is writable should be enough here.
860857 const is_right_segment = blk: {
861 if (ctx.macho_file.data_segment_cmd_index) |idx| {
858 if (context.macho_file.data_segment_cmd_index) |idx| {
862859 if (match.seg == idx) {
863860 break :blk true;
864861 }
865862 }
866 if (ctx.macho_file.data_const_segment_cmd_index) |idx| {
863 if (context.macho_file.data_const_segment_cmd_index) |idx| {
867864 if (match.seg == idx) {
868865 break :blk true;
869866 }
......@@ -884,17 +881,17 @@ pub fn parseRelocsFromObject(
884881 };
885882
886883 if (should_rebase) {
887 try self.rebases.append(allocator, parsed_rel.offset);
884 try self.rebases.append(context.allocator, parsed_rel.offset);
888885 }
889886 },
890887 }
891888 } else if (parsed_rel.payload == .branch) blk: {
892889 if (parsed_rel.where != .import) break :blk;
893 if (ctx.macho_file.stubs_map.contains(parsed_rel.where_index)) break :blk;
890 if (context.macho_file.stubs_map.contains(parsed_rel.where_index)) break :blk;
894891
895 const stubs_index = @intCast(u32, ctx.macho_file.stubs.items.len);
896 try ctx.macho_file.stubs.append(ctx.macho_file.base.allocator, parsed_rel.where_index);
897 try ctx.macho_file.stubs_map.putNoClobber(ctx.macho_file.base.allocator, parsed_rel.where_index, stubs_index);
892 const stubs_index = @intCast(u32, context.macho_file.stubs.items.len);
893 try context.macho_file.stubs.append(context.allocator, parsed_rel.where_index);
894 try context.macho_file.stubs_map.putNoClobber(context.allocator, parsed_rel.where_index, stubs_index);
898895 }
899896 }
900897}
......@@ -917,7 +914,7 @@ fn parseUnsigned(
917914 rel: macho.relocation_info,
918915 out: *Relocation,
919916 subtractor: ?u32,
920 ctx: RelocContext,
917 context: RelocContext,
921918) void {
922919 assert(rel.r_pcrel == 0);
923920
......@@ -934,7 +931,7 @@ fn parseUnsigned(
934931
935932 if (rel.r_extern == 0) {
936933 assert(out.where == .local);
937 const target_sym = ctx.macho_file.locals.items[out.where_index];
934 const target_sym = context.macho_file.locals.items[out.where_index];
938935 addend -= @intCast(i64, target_sym.n_value);
939936 }
940937
......@@ -947,14 +944,14 @@ fn parseUnsigned(
947944 };
948945}
949946
950fn parseBranch(self: TextBlock, rel: macho.relocation_info, out: *Relocation, ctx: RelocContext) void {
947fn parseBranch(self: TextBlock, rel: macho.relocation_info, out: *Relocation, context: RelocContext) void {
951948 _ = self;
952949 assert(rel.r_pcrel == 1);
953950 assert(rel.r_length == 2);
954951
955952 out.payload = .{
956953 .branch = .{
957 .arch = ctx.macho_file.base.options.target.cpu.arch,
954 .arch = context.macho_file.base.options.target.cpu.arch,
958955 },
959956 };
960957}
......@@ -1015,7 +1012,7 @@ fn parsePointerToGot(self: TextBlock, rel: macho.relocation_info, out: *Relocati
10151012 };
10161013}
10171014
1018fn parseSigned(self: TextBlock, rel: macho.relocation_info, out: *Relocation, ctx: RelocContext) void {
1015fn parseSigned(self: TextBlock, rel: macho.relocation_info, out: *Relocation, context: RelocContext) void {
10191016 assert(rel.r_pcrel == 1);
10201017 assert(rel.r_length == 2);
10211018
......@@ -1030,10 +1027,10 @@ fn parseSigned(self: TextBlock, rel: macho.relocation_info, out: *Relocation, ct
10301027 var addend: i64 = mem.readIntLittle(i32, self.code.items[out.offset..][0..4]) + correction;
10311028
10321029 if (rel.r_extern == 0) {
1033 const source_sym = ctx.macho_file.locals.items[self.local_sym_index];
1030 const source_sym = context.macho_file.locals.items[self.local_sym_index];
10341031 const target_sym = switch (out.where) {
1035 .local => ctx.macho_file.locals.items[out.where_index],
1036 .import => ctx.macho_file.imports.items[out.where_index],
1032 .local => context.macho_file.locals.items[out.where_index],
1033 .import => context.macho_file.imports.items[out.where_index],
10371034 };
10381035 addend = @intCast(i64, source_sym.n_value + out.offset + 4) + addend - @intCast(i64, target_sym.n_value);
10391036 }