| author | |
| committer | |
| log | 7cfc3f0cfa626abe25c8318a7852977cbc1c723b |
| tree | c17155900c2dcbfc7a929c2e4f213ae17239f76f |
| parent | ed2364a1480f99a7380285cec15ff1962d9df519 |
| parent | 836f007c22e50557dde46c8f766e1150c25271b3 |
| signature |
codegen: lower field_ptr to memory across linking backends9 files changed, 151 insertions(+), 70 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 |
| 2565 | 2565 | |
| 2566 | 2566 | const payload = try self.addExtra(Mir.ImmPair{ |
| 2567 | 2567 | .dest_off = 0, |
| 2568 | .operand = @intCast(u32, imm), | |
| 2568 | // TODO check if this logic is correct | |
| 2569 | .operand = @truncate(u32, imm), | |
| 2569 | 2570 | }); |
| 2570 | 2571 | const flags: u2 = switch (abi_size) { |
| 2571 | 2572 | 1 => 0b00, |
src/codegen.zig+98-37| ... | ... | @@ -142,11 +142,11 @@ pub fn generateFunction( |
| 142 | 142 | |
| 143 | 143 | pub fn generateSymbol( |
| 144 | 144 | bin_file: *link.File, |
| 145 | parent_atom_index: u32, | |
| 146 | 145 | src_loc: Module.SrcLoc, |
| 147 | 146 | typed_value: TypedValue, |
| 148 | 147 | code: *std.ArrayList(u8), |
| 149 | 148 | debug_output: DebugInfoOutput, |
| 149 | reloc_info: RelocInfo, | |
| 150 | 150 | ) GenerateSymbolError!Result { |
| 151 | 151 | const tracy = trace(@src()); |
| 152 | 152 | defer tracy.end(); |
| ... | ... | @@ -178,10 +178,10 @@ pub fn generateSymbol( |
| 178 | 178 | if (typed_value.ty.sentinel()) |sentinel| { |
| 179 | 179 | try code.ensureUnusedCapacity(payload.data.len + 1); |
| 180 | 180 | code.appendSliceAssumeCapacity(payload.data); |
| 181 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ | |
| 181 | switch (try generateSymbol(bin_file, src_loc, .{ | |
| 182 | 182 | .ty = typed_value.ty.elemType(), |
| 183 | 183 | .val = sentinel, |
| 184 | }, code, debug_output)) { | |
| 184 | }, code, debug_output, reloc_info)) { | |
| 185 | 185 | .appended => return Result{ .appended = {} }, |
| 186 | 186 | .externally_managed => |slice| { |
| 187 | 187 | code.appendSliceAssumeCapacity(slice); |
| ... | ... | @@ -198,10 +198,10 @@ pub fn generateSymbol( |
| 198 | 198 | const elem_vals = typed_value.val.castTag(.array).?.data; |
| 199 | 199 | const elem_ty = typed_value.ty.elemType(); |
| 200 | 200 | for (elem_vals) |elem_val| { |
| 201 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ | |
| 201 | switch (try generateSymbol(bin_file, src_loc, .{ | |
| 202 | 202 | .ty = elem_ty, |
| 203 | 203 | .val = elem_val, |
| 204 | }, code, debug_output)) { | |
| 204 | }, code, debug_output, reloc_info)) { | |
| 205 | 205 | .appended => {}, |
| 206 | 206 | .externally_managed => |slice| { |
| 207 | 207 | code.appendSliceAssumeCapacity(slice); |
| ... | ... | @@ -219,10 +219,10 @@ pub fn generateSymbol( |
| 219 | 219 | |
| 220 | 220 | var index: u64 = 0; |
| 221 | 221 | while (index < len) : (index += 1) { |
| 222 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ | |
| 222 | switch (try generateSymbol(bin_file, src_loc, .{ | |
| 223 | 223 | .ty = elem_ty, |
| 224 | 224 | .val = array, |
| 225 | }, code, debug_output)) { | |
| 225 | }, code, debug_output, reloc_info)) { | |
| 226 | 226 | .appended => {}, |
| 227 | 227 | .externally_managed => |slice| { |
| 228 | 228 | code.appendSliceAssumeCapacity(slice); |
| ... | ... | @@ -232,10 +232,10 @@ pub fn generateSymbol( |
| 232 | 232 | } |
| 233 | 233 | |
| 234 | 234 | if (sentinel) |sentinel_val| { |
| 235 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ | |
| 235 | switch (try generateSymbol(bin_file, src_loc, .{ | |
| 236 | 236 | .ty = elem_ty, |
| 237 | 237 | .val = sentinel_val, |
| 238 | }, code, debug_output)) { | |
| 238 | }, code, debug_output, reloc_info)) { | |
| 239 | 239 | .appended => {}, |
| 240 | 240 | .externally_managed => |slice| { |
| 241 | 241 | code.appendSliceAssumeCapacity(slice); |
| ... | ... | @@ -249,10 +249,10 @@ pub fn generateSymbol( |
| 249 | 249 | .empty_array_sentinel => { |
| 250 | 250 | const elem_ty = typed_value.ty.childType(); |
| 251 | 251 | 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, .{ | |
| 253 | 253 | .ty = elem_ty, |
| 254 | 254 | .val = sentinel_val, |
| 255 | }, code, debug_output)) { | |
| 255 | }, code, debug_output, reloc_info)) { | |
| 256 | 256 | .appended => {}, |
| 257 | 257 | .externally_managed => |slice| { |
| 258 | 258 | code.appendSliceAssumeCapacity(slice); |
| ... | ... | @@ -273,11 +273,11 @@ pub fn generateSymbol( |
| 273 | 273 | .Pointer => switch (typed_value.val.tag()) { |
| 274 | 274 | .variable => { |
| 275 | 275 | 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); | |
| 277 | 277 | }, |
| 278 | 278 | .decl_ref => { |
| 279 | 279 | 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); | |
| 281 | 281 | }, |
| 282 | 282 | .slice => { |
| 283 | 283 | const slice = typed_value.val.castTag(.slice).?.data; |
| ... | ... | @@ -285,10 +285,10 @@ pub fn generateSymbol( |
| 285 | 285 | // generate ptr |
| 286 | 286 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 287 | 287 | 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, .{ | |
| 289 | 289 | .ty = slice_ptr_field_type, |
| 290 | 290 | .val = slice.ptr, |
| 291 | }, code, debug_output)) { | |
| 291 | }, code, debug_output, reloc_info)) { | |
| 292 | 292 | .appended => {}, |
| 293 | 293 | .externally_managed => |external_slice| { |
| 294 | 294 | code.appendSliceAssumeCapacity(external_slice); |
| ... | ... | @@ -297,10 +297,10 @@ pub fn generateSymbol( |
| 297 | 297 | } |
| 298 | 298 | |
| 299 | 299 | // generate length |
| 300 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ | |
| 300 | switch (try generateSymbol(bin_file, src_loc, .{ | |
| 301 | 301 | .ty = Type.initTag(.usize), |
| 302 | 302 | .val = slice.len, |
| 303 | }, code, debug_output)) { | |
| 303 | }, code, debug_output, reloc_info)) { | |
| 304 | 304 | .appended => {}, |
| 305 | 305 | .externally_managed => |external_slice| { |
| 306 | 306 | code.appendSliceAssumeCapacity(external_slice); |
| ... | ... | @@ -310,6 +310,58 @@ pub fn generateSymbol( |
| 310 | 310 | |
| 311 | 311 | return Result{ .appended = {} }; |
| 312 | 312 | }, |
| 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 | .field_ptr => { | |
| 343 | switch (try generateSymbol(bin_file, src_loc, .{ | |
| 344 | .ty = typed_value.ty, | |
| 345 | .val = container_ptr, | |
| 346 | }, code, debug_output, reloc_info)) { | |
| 347 | .appended => {}, | |
| 348 | .externally_managed => |external_slice| { | |
| 349 | code.appendSliceAssumeCapacity(external_slice); | |
| 350 | }, | |
| 351 | .fail => |em| return Result{ .fail = em }, | |
| 352 | } | |
| 353 | return Result{ .appended = {} }; | |
| 354 | }, | |
| 355 | else => return Result{ | |
| 356 | .fail = try ErrorMsg.create( | |
| 357 | bin_file.allocator, | |
| 358 | src_loc, | |
| 359 | "TODO implement generateSymbol for pointer type value: '{s}'", | |
| 360 | .{@tagName(typed_value.val.tag())}, | |
| 361 | ), | |
| 362 | }, | |
| 363 | } | |
| 364 | }, | |
| 313 | 365 | else => return Result{ |
| 314 | 366 | .fail = try ErrorMsg.create( |
| 315 | 367 | bin_file.allocator, |
| ... | ... | @@ -441,10 +493,10 @@ pub fn generateSymbol( |
| 441 | 493 | const field_ty = typed_value.ty.structFieldType(index); |
| 442 | 494 | if (!field_ty.hasRuntimeBits()) continue; |
| 443 | 495 | |
| 444 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ | |
| 496 | switch (try generateSymbol(bin_file, src_loc, .{ | |
| 445 | 497 | .ty = field_ty, |
| 446 | 498 | .val = field_val, |
| 447 | }, code, debug_output)) { | |
| 499 | }, code, debug_output, reloc_info)) { | |
| 448 | 500 | .appended => {}, |
| 449 | 501 | .externally_managed => |external_slice| { |
| 450 | 502 | code.appendSliceAssumeCapacity(external_slice); |
| ... | ... | @@ -472,10 +524,10 @@ pub fn generateSymbol( |
| 472 | 524 | const layout = typed_value.ty.unionGetLayout(target); |
| 473 | 525 | |
| 474 | 526 | if (layout.payload_size == 0) { |
| 475 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ | |
| 527 | switch (try generateSymbol(bin_file, src_loc, .{ | |
| 476 | 528 | .ty = typed_value.ty.unionTagType().?, |
| 477 | 529 | .val = union_obj.tag, |
| 478 | }, code, debug_output)) { | |
| 530 | }, code, debug_output, reloc_info)) { | |
| 479 | 531 | .appended => {}, |
| 480 | 532 | .externally_managed => |external_slice| { |
| 481 | 533 | code.appendSliceAssumeCapacity(external_slice); |
| ... | ... | @@ -486,10 +538,10 @@ pub fn generateSymbol( |
| 486 | 538 | |
| 487 | 539 | // Check if we should store the tag first. |
| 488 | 540 | if (layout.tag_align >= layout.payload_align) { |
| 489 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ | |
| 541 | switch (try generateSymbol(bin_file, src_loc, .{ | |
| 490 | 542 | .ty = typed_value.ty.unionTagType().?, |
| 491 | 543 | .val = union_obj.tag, |
| 492 | }, code, debug_output)) { | |
| 544 | }, code, debug_output, reloc_info)) { | |
| 493 | 545 | .appended => {}, |
| 494 | 546 | .externally_managed => |external_slice| { |
| 495 | 547 | code.appendSliceAssumeCapacity(external_slice); |
| ... | ... | @@ -505,10 +557,10 @@ pub fn generateSymbol( |
| 505 | 557 | if (!field_ty.hasRuntimeBits()) { |
| 506 | 558 | try code.writer().writeByteNTimes(0xaa, try math.cast(usize, layout.payload_size)); |
| 507 | 559 | } else { |
| 508 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ | |
| 560 | switch (try generateSymbol(bin_file, src_loc, .{ | |
| 509 | 561 | .ty = field_ty, |
| 510 | 562 | .val = union_obj.val, |
| 511 | }, code, debug_output)) { | |
| 563 | }, code, debug_output, reloc_info)) { | |
| 512 | 564 | .appended => {}, |
| 513 | 565 | .externally_managed => |external_slice| { |
| 514 | 566 | code.appendSliceAssumeCapacity(external_slice); |
| ... | ... | @@ -523,10 +575,10 @@ pub fn generateSymbol( |
| 523 | 575 | } |
| 524 | 576 | |
| 525 | 577 | if (layout.tag_size > 0) { |
| 526 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ | |
| 578 | switch (try generateSymbol(bin_file, src_loc, .{ | |
| 527 | 579 | .ty = union_ty.tag_ty, |
| 528 | 580 | .val = union_obj.tag, |
| 529 | }, code, debug_output)) { | |
| 581 | }, code, debug_output, reloc_info)) { | |
| 530 | 582 | .appended => {}, |
| 531 | 583 | .externally_managed => |external_slice| { |
| 532 | 584 | code.appendSliceAssumeCapacity(external_slice); |
| ... | ... | @@ -555,10 +607,10 @@ pub fn generateSymbol( |
| 555 | 607 | |
| 556 | 608 | const error_val = if (!is_payload) typed_value.val else Value.initTag(.zero); |
| 557 | 609 | const begin = code.items.len; |
| 558 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ | |
| 610 | switch (try generateSymbol(bin_file, src_loc, .{ | |
| 559 | 611 | .ty = error_ty, |
| 560 | 612 | .val = error_val, |
| 561 | }, code, debug_output)) { | |
| 613 | }, code, debug_output, reloc_info)) { | |
| 562 | 614 | .appended => {}, |
| 563 | 615 | .externally_managed => |external_slice| { |
| 564 | 616 | code.appendSliceAssumeCapacity(external_slice); |
| ... | ... | @@ -568,10 +620,10 @@ pub fn generateSymbol( |
| 568 | 620 | |
| 569 | 621 | if (payload_ty.hasRuntimeBits()) { |
| 570 | 622 | 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, .{ | |
| 623 | switch (try generateSymbol(bin_file, src_loc, .{ | |
| 572 | 624 | .ty = payload_ty, |
| 573 | 625 | .val = payload_val, |
| 574 | }, code, debug_output)) { | |
| 626 | }, code, debug_output, reloc_info)) { | |
| 575 | 627 | .appended => {}, |
| 576 | 628 | .externally_managed => |external_slice| { |
| 577 | 629 | code.appendSliceAssumeCapacity(external_slice); |
| ... | ... | @@ -618,23 +670,28 @@ pub fn generateSymbol( |
| 618 | 670 | } |
| 619 | 671 | } |
| 620 | 672 | |
| 673 | const RelocInfo = struct { | |
| 674 | parent_atom_index: u32, | |
| 675 | addend: ?u32 = null, | |
| 676 | }; | |
| 677 | ||
| 621 | 678 | fn lowerDeclRef( |
| 622 | 679 | bin_file: *link.File, |
| 623 | parent_atom_index: u32, | |
| 624 | 680 | src_loc: Module.SrcLoc, |
| 625 | 681 | typed_value: TypedValue, |
| 626 | 682 | decl: *Module.Decl, |
| 627 | 683 | code: *std.ArrayList(u8), |
| 628 | 684 | debug_output: DebugInfoOutput, |
| 685 | reloc_info: RelocInfo, | |
| 629 | 686 | ) GenerateSymbolError!Result { |
| 630 | 687 | if (typed_value.ty.isSlice()) { |
| 631 | 688 | // generate ptr |
| 632 | 689 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 633 | 690 | const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf); |
| 634 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ | |
| 691 | switch (try generateSymbol(bin_file, src_loc, .{ | |
| 635 | 692 | .ty = slice_ptr_field_type, |
| 636 | 693 | .val = typed_value.val, |
| 637 | }, code, debug_output)) { | |
| 694 | }, code, debug_output, reloc_info)) { | |
| 638 | 695 | .appended => {}, |
| 639 | 696 | .externally_managed => |external_slice| { |
| 640 | 697 | code.appendSliceAssumeCapacity(external_slice); |
| ... | ... | @@ -647,10 +704,10 @@ fn lowerDeclRef( |
| 647 | 704 | .base = .{ .tag = .int_u64 }, |
| 648 | 705 | .data = typed_value.val.sliceLen(), |
| 649 | 706 | }; |
| 650 | switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{ | |
| 707 | switch (try generateSymbol(bin_file, src_loc, .{ | |
| 651 | 708 | .ty = Type.usize, |
| 652 | 709 | .val = Value.initPayload(&slice_len.base), |
| 653 | }, code, debug_output)) { | |
| 710 | }, code, debug_output, reloc_info)) { | |
| 654 | 711 | .appended => {}, |
| 655 | 712 | .externally_managed => |external_slice| { |
| 656 | 713 | code.appendSliceAssumeCapacity(external_slice); |
| ... | ... | @@ -670,7 +727,11 @@ fn lowerDeclRef( |
| 670 | 727 | } |
| 671 | 728 | |
| 672 | 729 | decl.markAlive(); |
| 673 | const vaddr = try bin_file.getDeclVAddr(decl, parent_atom_index, code.items.len); | |
| 730 | const vaddr = try bin_file.getDeclVAddr(decl, .{ | |
| 731 | .parent_atom_index = reloc_info.parent_atom_index, | |
| 732 | .offset = code.items.len, | |
| 733 | .addend = reloc_info.addend orelse 0, | |
| 734 | }); | |
| 674 | 735 | const endian = target.cpu.arch.endian(); |
| 675 | 736 | switch (ptr_width) { |
| 676 | 737 | 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 { |
| 685 | 685 | } |
| 686 | 686 | } |
| 687 | 687 | |
| 688 | pub const RelocInfo = struct { | |
| 689 | parent_atom_index: u32, | |
| 690 | offset: u64, | |
| 691 | addend: u32, | |
| 692 | }; | |
| 693 | ||
| 688 | 694 | /// Get allocated `Decl`'s address in virtual memory. |
| 689 | 695 | /// The linker is passed information about the containing atom, `parent_atom_index`, and offset within it's |
| 690 | 696 | /// memory buffer, `offset`, so that it can make a note of potential relocation sites, should the |
| 691 | 697 | /// `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 { | |
| 693 | 699 | 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), | |
| 698 | 704 | .c => unreachable, |
| 699 | 705 | .wasm => unreachable, |
| 700 | 706 | .spirv => unreachable, |
src/link/Coff.zig+6-5| ... | ... | @@ -724,10 +724,12 @@ pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void { |
| 724 | 724 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| 725 | 725 | defer code_buffer.deinit(); |
| 726 | 726 | |
| 727 | const res = try codegen.generateSymbol(&self.base, 0, decl.srcLoc(), .{ | |
| 727 | const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{ | |
| 728 | 728 | .ty = decl.ty, |
| 729 | 729 | .val = decl.val, |
| 730 | }, &code_buffer, .none); | |
| 730 | }, &code_buffer, .none, .{ | |
| 731 | .parent_atom_index = 0, | |
| 732 | }); | |
| 731 | 733 | const code = switch (res) { |
| 732 | 734 | .externally_managed => |x| x, |
| 733 | 735 | .appended => code_buffer.items, |
| ... | ... | @@ -1463,9 +1465,8 @@ fn findLib(self: *Coff, arena: Allocator, name: []const u8) !?[]const u8 { |
| 1463 | 1465 | return null; |
| 1464 | 1466 | } |
| 1465 | 1467 | |
| 1466 | pub fn getDeclVAddr(self: *Coff, decl: *const Module.Decl, parent_atom_index: u32, offset: u64) !u64 { | |
| 1467 | _ = parent_atom_index; | |
| 1468 | _ = offset; | |
| 1468 | pub fn getDeclVAddr(self: *Coff, decl: *const Module.Decl, reloc_info: link.File.RelocInfo) !u64 { | |
| 1469 | _ = reloc_info; | |
| 1469 | 1470 | assert(self.llvm_object == null); |
| 1470 | 1471 | return self.text_section_virtual_address + decl.link.coff.text_offset; |
| 1471 | 1472 | } |
src/link/Elf.zig+12-6| ... | ... | @@ -188,6 +188,7 @@ relocs: RelocTable = .{}, |
| 188 | 188 | const Reloc = struct { |
| 189 | 189 | target: u32, |
| 190 | 190 | offset: u64, |
| 191 | addend: u32, | |
| 191 | 192 | prev_vaddr: u64, |
| 192 | 193 | }; |
| 193 | 194 | |
| ... | ... | @@ -421,20 +422,21 @@ pub fn deinit(self: *Elf) void { |
| 421 | 422 | self.atom_by_index_table.deinit(self.base.allocator); |
| 422 | 423 | } |
| 423 | 424 | |
| 424 | pub fn getDeclVAddr(self: *Elf, decl: *const Module.Decl, parent_atom_index: u32, offset: u64) !u64 { | |
| 425 | pub fn getDeclVAddr(self: *Elf, decl: *const Module.Decl, reloc_info: File.RelocInfo) !u64 { | |
| 425 | 426 | assert(self.llvm_object == null); |
| 426 | 427 | assert(decl.link.elf.local_sym_index != 0); |
| 427 | 428 | |
| 428 | 429 | const target = decl.link.elf.local_sym_index; |
| 429 | 430 | 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).?; | |
| 431 | 432 | const gop = try self.relocs.getOrPut(self.base.allocator, atom); |
| 432 | 433 | if (!gop.found_existing) { |
| 433 | 434 | gop.value_ptr.* = .{}; |
| 434 | 435 | } |
| 435 | 436 | try gop.value_ptr.append(self.base.allocator, .{ |
| 436 | 437 | .target = target, |
| 437 | .offset = offset, | |
| 438 | .offset = reloc_info.offset, | |
| 439 | .addend = reloc_info.addend, | |
| 438 | 440 | .prev_vaddr = vaddr, |
| 439 | 441 | }); |
| 440 | 442 | |
| ... | ... | @@ -1039,7 +1041,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { |
| 1039 | 1041 | |
| 1040 | 1042 | for (relocs.items) |*reloc| { |
| 1041 | 1043 | 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; | |
| 1043 | 1045 | |
| 1044 | 1046 | if (target_vaddr == reloc.prev_vaddr) continue; |
| 1045 | 1047 | |
| ... | ... | @@ -3074,7 +3076,7 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void { |
| 3074 | 3076 | |
| 3075 | 3077 | // TODO implement .debug_info for global variables |
| 3076 | 3078 | 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(), .{ | |
| 3078 | 3080 | .ty = decl.ty, |
| 3079 | 3081 | .val = decl_val, |
| 3080 | 3082 | }, &code_buffer, .{ |
| ... | ... | @@ -3083,6 +3085,8 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void { |
| 3083 | 3085 | .dbg_info = &dbg_info_buffer, |
| 3084 | 3086 | .dbg_info_type_relocs = &dbg_info_type_relocs, |
| 3085 | 3087 | }, |
| 3088 | }, .{ | |
| 3089 | .parent_atom_index = decl.link.elf.local_sym_index, | |
| 3086 | 3090 | }); |
| 3087 | 3091 | const code = switch (res) { |
| 3088 | 3092 | .externally_managed => |x| x, |
| ... | ... | @@ -3130,8 +3134,10 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl: *Module.Decl |
| 3130 | 3134 | atom.local_sym_index = try self.allocateLocalSymbol(); |
| 3131 | 3135 | try self.atom_by_index_table.putNoClobber(self.base.allocator, atom.local_sym_index, atom); |
| 3132 | 3136 | |
| 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, .{ | |
| 3134 | 3138 | .none = .{}, |
| 3139 | }, .{ | |
| 3140 | .parent_atom_index = atom.local_sym_index, | |
| 3135 | 3141 | }); |
| 3136 | 3142 | const code = switch (res) { |
| 3137 | 3143 | .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 |
| 3781 | 3781 | const atom = try self.createEmptyAtom(local_sym_index, @sizeOf(u64), math.log2(required_alignment)); |
| 3782 | 3782 | try self.atom_by_index_table.putNoClobber(self.base.allocator, local_sym_index, atom); |
| 3783 | 3783 | |
| 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, .{ | |
| 3785 | 3785 | .none = .{}, |
| 3786 | }, .{ | |
| 3787 | .parent_atom_index = local_sym_index, | |
| 3786 | 3788 | }); |
| 3787 | 3789 | const code = switch (res) { |
| 3788 | 3790 | .externally_managed => |x| x, |
| ... | ... | @@ -3790,6 +3792,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De |
| 3790 | 3792 | .fail => |em| { |
| 3791 | 3793 | decl.analysis = .codegen_failure; |
| 3792 | 3794 | try module.failed_decls.put(module.gpa, decl, em); |
| 3795 | log.err("{s}", .{em.msg}); | |
| 3793 | 3796 | return error.AnalysisFail; |
| 3794 | 3797 | }, |
| 3795 | 3798 | }; |
| ... | ... | @@ -3860,7 +3863,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { |
| 3860 | 3863 | |
| 3861 | 3864 | const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val; |
| 3862 | 3865 | 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(), .{ | |
| 3864 | 3867 | .ty = decl.ty, |
| 3865 | 3868 | .val = decl_val, |
| 3866 | 3869 | }, &code_buffer, .{ |
| ... | ... | @@ -3869,12 +3872,16 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { |
| 3869 | 3872 | .dbg_info = &dbg.dbg_info_buffer, |
| 3870 | 3873 | .dbg_info_type_relocs = &dbg.dbg_info_type_relocs, |
| 3871 | 3874 | }, |
| 3875 | }, .{ | |
| 3876 | .parent_atom_index = decl.link.macho.local_sym_index, | |
| 3872 | 3877 | }) |
| 3873 | 3878 | else |
| 3874 | try codegen.generateSymbol(&self.base, decl.link.macho.local_sym_index, decl.srcLoc(), .{ | |
| 3879 | try codegen.generateSymbol(&self.base, decl.srcLoc(), .{ | |
| 3875 | 3880 | .ty = decl.ty, |
| 3876 | 3881 | .val = decl_val, |
| 3877 | }, &code_buffer, .none); | |
| 3882 | }, &code_buffer, .none, .{ | |
| 3883 | .parent_atom_index = decl.link.macho.local_sym_index, | |
| 3884 | }); | |
| 3878 | 3885 | |
| 3879 | 3886 | const code = blk: { |
| 3880 | 3887 | switch (res) { |
| ... | ... | @@ -4357,15 +4364,15 @@ pub fn freeDecl(self: *MachO, decl: *Module.Decl) void { |
| 4357 | 4364 | } |
| 4358 | 4365 | } |
| 4359 | 4366 | |
| 4360 | pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl, parent_atom_index: u32, offset: u64) !u64 { | |
| 4367 | pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl, reloc_info: File.RelocInfo) !u64 { | |
| 4361 | 4368 | assert(self.llvm_object == null); |
| 4362 | 4369 | assert(decl.link.macho.local_sym_index != 0); |
| 4363 | 4370 | |
| 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).?; | |
| 4365 | 4372 | try atom.relocs.append(self.base.allocator, .{ |
| 4366 | .offset = @intCast(u32, offset), | |
| 4373 | .offset = @intCast(u32, reloc_info.offset), | |
| 4367 | 4374 | .target = .{ .local = decl.link.macho.local_sym_index }, |
| 4368 | .addend = 0, | |
| 4375 | .addend = reloc_info.addend, | |
| 4369 | 4376 | .subtractor = null, |
| 4370 | 4377 | .pcrel = false, |
| 4371 | 4378 | .length = 3, |
| ... | ... | @@ -4375,7 +4382,7 @@ pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl, parent_atom_index: u |
| 4375 | 4382 | else => unreachable, |
| 4376 | 4383 | }, |
| 4377 | 4384 | }); |
| 4378 | try atom.rebases.append(self.base.allocator, offset); | |
| 4385 | try atom.rebases.append(self.base.allocator, reloc_info.offset); | |
| 4379 | 4386 | |
| 4380 | 4387 | return 0; |
| 4381 | 4388 | } |
src/link/Plan9.zig+6-5| ... | ... | @@ -304,10 +304,12 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl: *Module.Decl) !void { |
| 304 | 304 | const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val; |
| 305 | 305 | // TODO we need the symbol index for symbol in the table of locals for the containing atom |
| 306 | 306 | 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(), .{ | |
| 308 | 308 | .ty = decl.ty, |
| 309 | 309 | .val = decl_val, |
| 310 | }, &code_buffer, .{ .none = .{} }); | |
| 310 | }, &code_buffer, .{ .none = .{} }, .{ | |
| 311 | .parent_atom_index = @intCast(u32, sym_index), | |
| 312 | }); | |
| 311 | 313 | const code = switch (res) { |
| 312 | 314 | .externally_managed => |x| x, |
| 313 | 315 | .appended => code_buffer.items, |
| ... | ... | @@ -752,9 +754,8 @@ pub fn allocateDeclIndexes(self: *Plan9, decl: *Module.Decl) !void { |
| 752 | 754 | _ = self; |
| 753 | 755 | _ = decl; |
| 754 | 756 | } |
| 755 | pub fn getDeclVAddr(self: *Plan9, decl: *const Module.Decl, parent_atom_index: u32, offset: u64) !u64 { | |
| 756 | _ = parent_atom_index; | |
| 757 | _ = offset; | |
| 757 | pub fn getDeclVAddr(self: *Plan9, decl: *const Module.Decl, reloc_info: link.File.RelocInfo) !u64 { | |
| 758 | _ = reloc_info; | |
| 758 | 759 | if (decl.ty.zigTypeTag() == .Fn) { |
| 759 | 760 | var start = self.bases.text; |
| 760 | 761 | var it_file = self.fn_decl_table.iterator(); |
test/behavior/bugs/3046.zig-1| ... | ... | @@ -13,7 +13,6 @@ fn couldFail() anyerror!i32 { |
| 13 | 13 | var some_struct: SomeStruct = undefined; |
| 14 | 14 | |
| 15 | 15 | test "fixed" { |
| 16 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 17 | 16 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 18 | 17 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 19 | 18 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |
test/behavior/struct.zig-1| ... | ... | @@ -780,7 +780,6 @@ test "packed struct with u0 field access" { |
| 780 | 780 | |
| 781 | 781 | test "access to global struct fields" { |
| 782 | 782 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 783 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 784 | 783 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 785 | 784 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 786 | 785 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |