authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-03-01 22:03:18+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-03-01 22:03:18+01:00
loge8eb9778cccd2f2d23027d9e0d73d7053bf92efe
treea658c7381f29593222e059ad541d006afd9e310c
parent543bee0adf2d3b036654fa0983c16ff7023f504c

codegen: lower field_ptr to memory across linking backends

This requires generating an addend for the target relocation as the field pointer might point at a field inner to the container.

8 files changed, 138 insertions(+), 69 deletions(-)

src/arch/x86_64/CodeGen.zig+2-1
......@@ -2565,7 +2565,8 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
25652565
25662566 const payload = try self.addExtra(Mir.ImmPair{
25672567 .dest_off = 0,
2568 .operand = @intCast(u32, imm),
2568 // TODO check if this logic is correct
2569 .operand = @truncate(u32, imm),
25692570 });
25702571 const flags: u2 = switch (abi_size) {
25712572 1 => 0b00,
src/codegen.zig+85-37
......@@ -142,11 +142,11 @@ pub fn generateFunction(
142142
143143pub fn generateSymbol(
144144 bin_file: *link.File,
145 parent_atom_index: u32,
146145 src_loc: Module.SrcLoc,
147146 typed_value: TypedValue,
148147 code: *std.ArrayList(u8),
149148 debug_output: DebugInfoOutput,
149 reloc_info: RelocInfo,
150150) GenerateSymbolError!Result {
151151 const tracy = trace(@src());
152152 defer tracy.end();
......@@ -178,10 +178,10 @@ pub fn generateSymbol(
178178 if (typed_value.ty.sentinel()) |sentinel| {
179179 try code.ensureUnusedCapacity(payload.data.len + 1);
180180 code.appendSliceAssumeCapacity(payload.data);
181 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
181 switch (try generateSymbol(bin_file, src_loc, .{
182182 .ty = typed_value.ty.elemType(),
183183 .val = sentinel,
184 }, code, debug_output)) {
184 }, code, debug_output, reloc_info)) {
185185 .appended => return Result{ .appended = {} },
186186 .externally_managed => |slice| {
187187 code.appendSliceAssumeCapacity(slice);
......@@ -198,10 +198,10 @@ pub fn generateSymbol(
198198 const elem_vals = typed_value.val.castTag(.array).?.data;
199199 const elem_ty = typed_value.ty.elemType();
200200 for (elem_vals) |elem_val| {
201 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
201 switch (try generateSymbol(bin_file, src_loc, .{
202202 .ty = elem_ty,
203203 .val = elem_val,
204 }, code, debug_output)) {
204 }, code, debug_output, reloc_info)) {
205205 .appended => {},
206206 .externally_managed => |slice| {
207207 code.appendSliceAssumeCapacity(slice);
......@@ -219,10 +219,10 @@ pub fn generateSymbol(
219219
220220 var index: u64 = 0;
221221 while (index < len) : (index += 1) {
222 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
222 switch (try generateSymbol(bin_file, src_loc, .{
223223 .ty = elem_ty,
224224 .val = array,
225 }, code, debug_output)) {
225 }, code, debug_output, reloc_info)) {
226226 .appended => {},
227227 .externally_managed => |slice| {
228228 code.appendSliceAssumeCapacity(slice);
......@@ -232,10 +232,10 @@ pub fn generateSymbol(
232232 }
233233
234234 if (sentinel) |sentinel_val| {
235 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
235 switch (try generateSymbol(bin_file, src_loc, .{
236236 .ty = elem_ty,
237237 .val = sentinel_val,
238 }, code, debug_output)) {
238 }, code, debug_output, reloc_info)) {
239239 .appended => {},
240240 .externally_managed => |slice| {
241241 code.appendSliceAssumeCapacity(slice);
......@@ -249,10 +249,10 @@ pub fn generateSymbol(
249249 .empty_array_sentinel => {
250250 const elem_ty = typed_value.ty.childType();
251251 const sentinel_val = typed_value.ty.sentinel().?;
252 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
252 switch (try generateSymbol(bin_file, src_loc, .{
253253 .ty = elem_ty,
254254 .val = sentinel_val,
255 }, code, debug_output)) {
255 }, code, debug_output, reloc_info)) {
256256 .appended => {},
257257 .externally_managed => |slice| {
258258 code.appendSliceAssumeCapacity(slice);
......@@ -273,11 +273,11 @@ pub fn generateSymbol(
273273 .Pointer => switch (typed_value.val.tag()) {
274274 .variable => {
275275 const decl = typed_value.val.castTag(.variable).?.data.owner_decl;
276 return lowerDeclRef(bin_file, parent_atom_index, src_loc, typed_value, decl, code, debug_output);
276 return lowerDeclRef(bin_file, src_loc, typed_value, decl, code, debug_output, reloc_info);
277277 },
278278 .decl_ref => {
279279 const decl = typed_value.val.castTag(.decl_ref).?.data;
280 return lowerDeclRef(bin_file, parent_atom_index, src_loc, typed_value, decl, code, debug_output);
280 return lowerDeclRef(bin_file, src_loc, typed_value, decl, code, debug_output, reloc_info);
281281 },
282282 .slice => {
283283 const slice = typed_value.val.castTag(.slice).?.data;
......@@ -285,10 +285,10 @@ pub fn generateSymbol(
285285 // generate ptr
286286 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
287287 const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf);
288 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
288 switch (try generateSymbol(bin_file, src_loc, .{
289289 .ty = slice_ptr_field_type,
290290 .val = slice.ptr,
291 }, code, debug_output)) {
291 }, code, debug_output, reloc_info)) {
292292 .appended => {},
293293 .externally_managed => |external_slice| {
294294 code.appendSliceAssumeCapacity(external_slice);
......@@ -297,10 +297,10 @@ pub fn generateSymbol(
297297 }
298298
299299 // generate length
300 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
300 switch (try generateSymbol(bin_file, src_loc, .{
301301 .ty = Type.initTag(.usize),
302302 .val = slice.len,
303 }, code, debug_output)) {
303 }, code, debug_output, reloc_info)) {
304304 .appended => {},
305305 .externally_managed => |external_slice| {
306306 code.appendSliceAssumeCapacity(external_slice);
......@@ -310,6 +310,45 @@ pub fn generateSymbol(
310310
311311 return Result{ .appended = {} };
312312 },
313 .field_ptr => {
314 const target = bin_file.options.target;
315 const field_ptr = typed_value.val.castTag(.field_ptr).?.data;
316 const container_ptr = field_ptr.container_ptr;
317
318 switch (container_ptr.tag()) {
319 .decl_ref => {
320 const decl = container_ptr.castTag(.decl_ref).?.data;
321 const addend = blk: {
322 switch (decl.ty.tag()) {
323 .@"struct" => {
324 const addend = decl.ty.structFieldOffset(field_ptr.field_index, target);
325 break :blk @intCast(u32, addend);
326 },
327 else => return Result{
328 .fail = try ErrorMsg.create(
329 bin_file.allocator,
330 src_loc,
331 "TODO implement generateSymbol for pointer type value: '{s}'",
332 .{@tagName(typed_value.val.tag())},
333 ),
334 },
335 }
336 };
337 return lowerDeclRef(bin_file, src_loc, typed_value, decl, code, debug_output, .{
338 .parent_atom_index = reloc_info.parent_atom_index,
339 .addend = (reloc_info.addend orelse 0) + addend,
340 });
341 },
342 else => return Result{
343 .fail = try ErrorMsg.create(
344 bin_file.allocator,
345 src_loc,
346 "TODO implement generateSymbol for pointer type value: '{s}'",
347 .{@tagName(typed_value.val.tag())},
348 ),
349 },
350 }
351 },
313352 else => return Result{
314353 .fail = try ErrorMsg.create(
315354 bin_file.allocator,
......@@ -441,10 +480,10 @@ pub fn generateSymbol(
441480 const field_ty = typed_value.ty.structFieldType(index);
442481 if (!field_ty.hasRuntimeBits()) continue;
443482
444 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
483 switch (try generateSymbol(bin_file, src_loc, .{
445484 .ty = field_ty,
446485 .val = field_val,
447 }, code, debug_output)) {
486 }, code, debug_output, reloc_info)) {
448487 .appended => {},
449488 .externally_managed => |external_slice| {
450489 code.appendSliceAssumeCapacity(external_slice);
......@@ -472,10 +511,10 @@ pub fn generateSymbol(
472511 const layout = typed_value.ty.unionGetLayout(target);
473512
474513 if (layout.payload_size == 0) {
475 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
514 switch (try generateSymbol(bin_file, src_loc, .{
476515 .ty = typed_value.ty.unionTagType().?,
477516 .val = union_obj.tag,
478 }, code, debug_output)) {
517 }, code, debug_output, reloc_info)) {
479518 .appended => {},
480519 .externally_managed => |external_slice| {
481520 code.appendSliceAssumeCapacity(external_slice);
......@@ -486,10 +525,10 @@ pub fn generateSymbol(
486525
487526 // Check if we should store the tag first.
488527 if (layout.tag_align >= layout.payload_align) {
489 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
528 switch (try generateSymbol(bin_file, src_loc, .{
490529 .ty = typed_value.ty.unionTagType().?,
491530 .val = union_obj.tag,
492 }, code, debug_output)) {
531 }, code, debug_output, reloc_info)) {
493532 .appended => {},
494533 .externally_managed => |external_slice| {
495534 code.appendSliceAssumeCapacity(external_slice);
......@@ -505,10 +544,10 @@ pub fn generateSymbol(
505544 if (!field_ty.hasRuntimeBits()) {
506545 try code.writer().writeByteNTimes(0xaa, try math.cast(usize, layout.payload_size));
507546 } else {
508 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
547 switch (try generateSymbol(bin_file, src_loc, .{
509548 .ty = field_ty,
510549 .val = union_obj.val,
511 }, code, debug_output)) {
550 }, code, debug_output, reloc_info)) {
512551 .appended => {},
513552 .externally_managed => |external_slice| {
514553 code.appendSliceAssumeCapacity(external_slice);
......@@ -523,10 +562,10 @@ pub fn generateSymbol(
523562 }
524563
525564 if (layout.tag_size > 0) {
526 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
565 switch (try generateSymbol(bin_file, src_loc, .{
527566 .ty = union_ty.tag_ty,
528567 .val = union_obj.tag,
529 }, code, debug_output)) {
568 }, code, debug_output, reloc_info)) {
530569 .appended => {},
531570 .externally_managed => |external_slice| {
532571 code.appendSliceAssumeCapacity(external_slice);
......@@ -555,10 +594,10 @@ pub fn generateSymbol(
555594
556595 const error_val = if (!is_payload) typed_value.val else Value.initTag(.zero);
557596 const begin = code.items.len;
558 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
597 switch (try generateSymbol(bin_file, src_loc, .{
559598 .ty = error_ty,
560599 .val = error_val,
561 }, code, debug_output)) {
600 }, code, debug_output, reloc_info)) {
562601 .appended => {},
563602 .externally_managed => |external_slice| {
564603 code.appendSliceAssumeCapacity(external_slice);
......@@ -568,10 +607,10 @@ pub fn generateSymbol(
568607
569608 if (payload_ty.hasRuntimeBits()) {
570609 const payload_val = if (typed_value.val.castTag(.eu_payload)) |val| val.data else Value.initTag(.undef);
571 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
610 switch (try generateSymbol(bin_file, src_loc, .{
572611 .ty = payload_ty,
573612 .val = payload_val,
574 }, code, debug_output)) {
613 }, code, debug_output, reloc_info)) {
575614 .appended => {},
576615 .externally_managed => |external_slice| {
577616 code.appendSliceAssumeCapacity(external_slice);
......@@ -618,23 +657,28 @@ pub fn generateSymbol(
618657 }
619658}
620659
660const RelocInfo = struct {
661 parent_atom_index: u32,
662 addend: ?u32 = null,
663};
664
621665fn lowerDeclRef(
622666 bin_file: *link.File,
623 parent_atom_index: u32,
624667 src_loc: Module.SrcLoc,
625668 typed_value: TypedValue,
626669 decl: *Module.Decl,
627670 code: *std.ArrayList(u8),
628671 debug_output: DebugInfoOutput,
672 reloc_info: RelocInfo,
629673) GenerateSymbolError!Result {
630674 if (typed_value.ty.isSlice()) {
631675 // generate ptr
632676 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
633677 const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf);
634 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
678 switch (try generateSymbol(bin_file, src_loc, .{
635679 .ty = slice_ptr_field_type,
636680 .val = typed_value.val,
637 }, code, debug_output)) {
681 }, code, debug_output, reloc_info)) {
638682 .appended => {},
639683 .externally_managed => |external_slice| {
640684 code.appendSliceAssumeCapacity(external_slice);
......@@ -647,10 +691,10 @@ fn lowerDeclRef(
647691 .base = .{ .tag = .int_u64 },
648692 .data = typed_value.val.sliceLen(),
649693 };
650 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
694 switch (try generateSymbol(bin_file, src_loc, .{
651695 .ty = Type.usize,
652696 .val = Value.initPayload(&slice_len.base),
653 }, code, debug_output)) {
697 }, code, debug_output, reloc_info)) {
654698 .appended => {},
655699 .externally_managed => |external_slice| {
656700 code.appendSliceAssumeCapacity(external_slice);
......@@ -670,7 +714,11 @@ fn lowerDeclRef(
670714 }
671715
672716 decl.markAlive();
673 const vaddr = try bin_file.getDeclVAddr(decl, parent_atom_index, code.items.len);
717 const vaddr = try bin_file.getDeclVAddr(decl, .{
718 .parent_atom_index = reloc_info.parent_atom_index,
719 .offset = code.items.len,
720 .addend = reloc_info.addend orelse 0,
721 });
674722 const endian = target.cpu.arch.endian();
675723 switch (ptr_width) {
676724 16 => mem.writeInt(u16, try code.addManyAsArray(2), @intCast(u16, vaddr), endian),
src/link.zig+11-5
......@@ -685,16 +685,22 @@ pub const File = struct {
685685 }
686686 }
687687
688 pub const RelocInfo = struct {
689 parent_atom_index: u32,
690 offset: u64,
691 addend: u32,
692 };
693
688694 /// Get allocated `Decl`'s address in virtual memory.
689695 /// The linker is passed information about the containing atom, `parent_atom_index`, and offset within it's
690696 /// memory buffer, `offset`, so that it can make a note of potential relocation sites, should the
691697 /// `Decl`'s address was not yet resolved, or the containing atom gets moved in virtual memory.
692 pub fn getDeclVAddr(base: *File, decl: *const Module.Decl, parent_atom_index: u32, offset: u64) !u64 {
698 pub fn getDeclVAddr(base: *File, decl: *const Module.Decl, reloc_info: RelocInfo) !u64 {
693699 switch (base.tag) {
694 .coff => return @fieldParentPtr(Coff, "base", base).getDeclVAddr(decl, parent_atom_index, offset),
695 .elf => return @fieldParentPtr(Elf, "base", base).getDeclVAddr(decl, parent_atom_index, offset),
696 .macho => return @fieldParentPtr(MachO, "base", base).getDeclVAddr(decl, parent_atom_index, offset),
697 .plan9 => return @fieldParentPtr(Plan9, "base", base).getDeclVAddr(decl, parent_atom_index, offset),
700 .coff => return @fieldParentPtr(Coff, "base", base).getDeclVAddr(decl, reloc_info),
701 .elf => return @fieldParentPtr(Elf, "base", base).getDeclVAddr(decl, reloc_info),
702 .macho => return @fieldParentPtr(MachO, "base", base).getDeclVAddr(decl, reloc_info),
703 .plan9 => return @fieldParentPtr(Plan9, "base", base).getDeclVAddr(decl, reloc_info),
698704 .c => unreachable,
699705 .wasm => unreachable,
700706 .spirv => unreachable,
src/link/Coff.zig+6-5
......@@ -724,10 +724,12 @@ pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void {
724724 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
725725 defer code_buffer.deinit();
726726
727 const res = try codegen.generateSymbol(&self.base, 0, decl.srcLoc(), .{
727 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
728728 .ty = decl.ty,
729729 .val = decl.val,
730 }, &code_buffer, .none);
730 }, &code_buffer, .none, .{
731 .parent_atom_index = 0,
732 });
731733 const code = switch (res) {
732734 .externally_managed => |x| x,
733735 .appended => code_buffer.items,
......@@ -1463,9 +1465,8 @@ fn findLib(self: *Coff, arena: Allocator, name: []const u8) !?[]const u8 {
14631465 return null;
14641466}
14651467
1466pub fn getDeclVAddr(self: *Coff, decl: *const Module.Decl, parent_atom_index: u32, offset: u64) !u64 {
1467 _ = parent_atom_index;
1468 _ = offset;
1468pub fn getDeclVAddr(self: *Coff, decl: *const Module.Decl, reloc_info: link.File.RelocInfo) !u64 {
1469 _ = reloc_info;
14691470 assert(self.llvm_object == null);
14701471 return self.text_section_virtual_address + decl.link.coff.text_offset;
14711472}
src/link/Elf.zig+12-6
......@@ -188,6 +188,7 @@ relocs: RelocTable = .{},
188188const Reloc = struct {
189189 target: u32,
190190 offset: u64,
191 addend: u32,
191192 prev_vaddr: u64,
192193};
193194
......@@ -421,20 +422,21 @@ pub fn deinit(self: *Elf) void {
421422 self.atom_by_index_table.deinit(self.base.allocator);
422423}
423424
424pub fn getDeclVAddr(self: *Elf, decl: *const Module.Decl, parent_atom_index: u32, offset: u64) !u64 {
425pub fn getDeclVAddr(self: *Elf, decl: *const Module.Decl, reloc_info: File.RelocInfo) !u64 {
425426 assert(self.llvm_object == null);
426427 assert(decl.link.elf.local_sym_index != 0);
427428
428429 const target = decl.link.elf.local_sym_index;
429430 const vaddr = self.local_symbols.items[target].st_value;
430 const atom = self.atom_by_index_table.get(parent_atom_index).?;
431 const atom = self.atom_by_index_table.get(reloc_info.parent_atom_index).?;
431432 const gop = try self.relocs.getOrPut(self.base.allocator, atom);
432433 if (!gop.found_existing) {
433434 gop.value_ptr.* = .{};
434435 }
435436 try gop.value_ptr.append(self.base.allocator, .{
436437 .target = target,
437 .offset = offset,
438 .offset = reloc_info.offset,
439 .addend = reloc_info.addend,
438440 .prev_vaddr = vaddr,
439441 });
440442
......@@ -1039,7 +1041,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
10391041
10401042 for (relocs.items) |*reloc| {
10411043 const target_sym = self.local_symbols.items[reloc.target];
1042 const target_vaddr = target_sym.st_value;
1044 const target_vaddr = target_sym.st_value + reloc.addend;
10431045
10441046 if (target_vaddr == reloc.prev_vaddr) continue;
10451047
......@@ -3074,7 +3076,7 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
30743076
30753077 // TODO implement .debug_info for global variables
30763078 const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val;
3077 const res = try codegen.generateSymbol(&self.base, decl.link.elf.local_sym_index, decl.srcLoc(), .{
3079 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
30783080 .ty = decl.ty,
30793081 .val = decl_val,
30803082 }, &code_buffer, .{
......@@ -3083,6 +3085,8 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
30833085 .dbg_info = &dbg_info_buffer,
30843086 .dbg_info_type_relocs = &dbg_info_type_relocs,
30853087 },
3088 }, .{
3089 .parent_atom_index = decl.link.elf.local_sym_index,
30863090 });
30873091 const code = switch (res) {
30883092 .externally_managed => |x| x,
......@@ -3130,8 +3134,10 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl: *Module.Decl
31303134 atom.local_sym_index = try self.allocateLocalSymbol();
31313135 try self.atom_by_index_table.putNoClobber(self.base.allocator, atom.local_sym_index, atom);
31323136
3133 const res = try codegen.generateSymbol(&self.base, atom.local_sym_index, decl.srcLoc(), typed_value, &code_buffer, .{
3137 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), typed_value, &code_buffer, .{
31343138 .none = .{},
3139 }, .{
3140 .parent_atom_index = atom.local_sym_index,
31353141 });
31363142 const code = switch (res) {
31373143 .externally_managed => |x| x,
src/link/MachO.zig+16-9
......@@ -3781,8 +3781,10 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De
37813781 const atom = try self.createEmptyAtom(local_sym_index, @sizeOf(u64), math.log2(required_alignment));
37823782 try self.atom_by_index_table.putNoClobber(self.base.allocator, local_sym_index, atom);
37833783
3784 const res = try codegen.generateSymbol(&self.base, local_sym_index, decl.srcLoc(), typed_value, &code_buffer, .{
3784 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), typed_value, &code_buffer, .{
37853785 .none = .{},
3786 }, .{
3787 .parent_atom_index = local_sym_index,
37863788 });
37873789 const code = switch (res) {
37883790 .externally_managed => |x| x,
......@@ -3790,6 +3792,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De
37903792 .fail => |em| {
37913793 decl.analysis = .codegen_failure;
37923794 try module.failed_decls.put(module.gpa, decl, em);
3795 log.err("{s}", .{em.msg});
37933796 return error.AnalysisFail;
37943797 },
37953798 };
......@@ -3860,7 +3863,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
38603863
38613864 const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val;
38623865 const res = if (debug_buffers) |dbg|
3863 try codegen.generateSymbol(&self.base, decl.link.macho.local_sym_index, decl.srcLoc(), .{
3866 try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
38643867 .ty = decl.ty,
38653868 .val = decl_val,
38663869 }, &code_buffer, .{
......@@ -3869,12 +3872,16 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
38693872 .dbg_info = &dbg.dbg_info_buffer,
38703873 .dbg_info_type_relocs = &dbg.dbg_info_type_relocs,
38713874 },
3875 }, .{
3876 .parent_atom_index = decl.link.macho.local_sym_index,
38723877 })
38733878 else
3874 try codegen.generateSymbol(&self.base, decl.link.macho.local_sym_index, decl.srcLoc(), .{
3879 try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
38753880 .ty = decl.ty,
38763881 .val = decl_val,
3877 }, &code_buffer, .none);
3882 }, &code_buffer, .none, .{
3883 .parent_atom_index = decl.link.macho.local_sym_index,
3884 });
38783885
38793886 const code = blk: {
38803887 switch (res) {
......@@ -4357,15 +4364,15 @@ pub fn freeDecl(self: *MachO, decl: *Module.Decl) void {
43574364 }
43584365}
43594366
4360pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl, parent_atom_index: u32, offset: u64) !u64 {
4367pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl, reloc_info: File.RelocInfo) !u64 {
43614368 assert(self.llvm_object == null);
43624369 assert(decl.link.macho.local_sym_index != 0);
43634370
4364 const atom = self.atom_by_index_table.get(parent_atom_index).?;
4371 const atom = self.atom_by_index_table.get(reloc_info.parent_atom_index).?;
43654372 try atom.relocs.append(self.base.allocator, .{
4366 .offset = @intCast(u32, offset),
4373 .offset = @intCast(u32, reloc_info.offset),
43674374 .target = .{ .local = decl.link.macho.local_sym_index },
4368 .addend = 0,
4375 .addend = reloc_info.addend,
43694376 .subtractor = null,
43704377 .pcrel = false,
43714378 .length = 3,
......@@ -4375,7 +4382,7 @@ pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl, parent_atom_index: u
43754382 else => unreachable,
43764383 },
43774384 });
4378 try atom.rebases.append(self.base.allocator, offset);
4385 try atom.rebases.append(self.base.allocator, reloc_info.offset);
43794386
43804387 return 0;
43814388}
src/link/Plan9.zig+6-5
......@@ -304,10 +304,12 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl: *Module.Decl) !void {
304304 const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val;
305305 // TODO we need the symbol index for symbol in the table of locals for the containing atom
306306 const sym_index = decl.link.plan9.sym_index orelse 0;
307 const res = try codegen.generateSymbol(&self.base, @intCast(u32, sym_index), decl.srcLoc(), .{
307 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
308308 .ty = decl.ty,
309309 .val = decl_val,
310 }, &code_buffer, .{ .none = .{} });
310 }, &code_buffer, .{ .none = .{} }, .{
311 .parent_atom_index = @intCast(u32, sym_index),
312 });
311313 const code = switch (res) {
312314 .externally_managed => |x| x,
313315 .appended => code_buffer.items,
......@@ -752,9 +754,8 @@ pub fn allocateDeclIndexes(self: *Plan9, decl: *Module.Decl) !void {
752754 _ = self;
753755 _ = decl;
754756}
755pub fn getDeclVAddr(self: *Plan9, decl: *const Module.Decl, parent_atom_index: u32, offset: u64) !u64 {
756 _ = parent_atom_index;
757 _ = offset;
757pub fn getDeclVAddr(self: *Plan9, decl: *const Module.Decl, reloc_info: link.File.RelocInfo) !u64 {
758 _ = reloc_info;
758759 if (decl.ty.zigTypeTag() == .Fn) {
759760 var start = self.bases.text;
760761 var it_file = self.fn_decl_table.iterator();
test/behavior/bugs/3046.zig-1
......@@ -13,7 +13,6 @@ fn couldFail() anyerror!i32 {
1313var some_struct: SomeStruct = undefined;
1414
1515test "fixed" {
16 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1716 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1817 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1918 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;