| author | |
| committer | |
| log | c4fcf0e22a0a0bab19ac9d1335b10decbfb2f137 |
| tree | ab9d2b9228c6dfd927cdc5a6536811412d03c62b |
| parent | dd402f6d83071535fffac055fabe72ebcb0db994 |
7 files changed, 73 insertions(+), 57 deletions(-)
src/arch/wasm/CodeGen.zig+2-5| ... | ... | @@ -3153,11 +3153,8 @@ fn lowerAnonDeclRef( |
| 3153 | 3153 | return WValue{ .imm32 = 0xaaaaaaaa }; |
| 3154 | 3154 | } |
| 3155 | 3155 | |
| 3156 | const alignment = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment; | |
| 3157 | if (alignment != .none) { | |
| 3158 | @panic("TODO how to make this anon decl be aligned?"); | |
| 3159 | } | |
| 3160 | const res = try func.bin_file.lowerAnonDecl(decl_val, func.decl.srcLoc(mod)); | |
| 3156 | const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment; | |
| 3157 | const res = try func.bin_file.lowerAnonDecl(decl_val, decl_align, func.decl.srcLoc(mod)); | |
| 3161 | 3158 | switch (res) { |
| 3162 | 3159 | .ok => {}, |
| 3163 | 3160 | .fail => |em| { |
src/codegen.zig+2-5| ... | ... | @@ -731,16 +731,13 @@ fn lowerAnonDeclRef( |
| 731 | 731 | return Result.ok; |
| 732 | 732 | } |
| 733 | 733 | |
| 734 | const res = try bin_file.lowerAnonDecl(decl_val, src_loc); | |
| 734 | const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment; | |
| 735 | const res = try bin_file.lowerAnonDecl(decl_val, decl_align, src_loc); | |
| 735 | 736 | switch (res) { |
| 736 | 737 | .ok => {}, |
| 737 | 738 | .fail => |em| return .{ .fail = em }, |
| 738 | 739 | } |
| 739 | 740 | |
| 740 | const alignment = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment; | |
| 741 | if (alignment != .none) { | |
| 742 | @panic("TODO how to make this anon decl be aligned?"); | |
| 743 | } | |
| 744 | 741 | const vaddr = try bin_file.getAnonDeclVAddr(decl_val, .{ |
| 745 | 742 | .parent_atom_index = reloc_info.parent_atom_index, |
| 746 | 743 | .offset = code.items.len, |
src/link.zig+5-5| ... | ... | @@ -940,15 +940,15 @@ pub const File = struct { |
| 940 | 940 | |
| 941 | 941 | pub const LowerResult = @import("codegen.zig").Result; |
| 942 | 942 | |
| 943 | pub fn lowerAnonDecl(base: *File, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !LowerResult { | |
| 943 | pub fn lowerAnonDecl(base: *File, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !LowerResult { | |
| 944 | 944 | if (build_options.only_c) unreachable; |
| 945 | 945 | switch (base.tag) { |
| 946 | .coff => return @fieldParentPtr(Coff, "base", base).lowerAnonDecl(decl_val, src_loc), | |
| 947 | .elf => return @fieldParentPtr(Elf, "base", base).lowerAnonDecl(decl_val, src_loc), | |
| 948 | .macho => return @fieldParentPtr(MachO, "base", base).lowerAnonDecl(decl_val, src_loc), | |
| 946 | .coff => return @fieldParentPtr(Coff, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc), | |
| 947 | .elf => return @fieldParentPtr(Elf, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc), | |
| 948 | .macho => return @fieldParentPtr(MachO, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc), | |
| 949 | 949 | .plan9 => return @fieldParentPtr(Plan9, "base", base).lowerAnonDecl(decl_val, src_loc), |
| 950 | 950 | .c => unreachable, |
| 951 | .wasm => return @fieldParentPtr(Wasm, "base", base).lowerAnonDecl(decl_val, src_loc), | |
| 951 | .wasm => return @fieldParentPtr(Wasm, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc), | |
| 952 | 952 | .spirv => unreachable, |
| 953 | 953 | .nvptx => unreachable, |
| 954 | 954 | } |
src/link/Coff.zig+18-10| ... | ... | @@ -1091,7 +1091,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In |
| 1091 | 1091 | const index = unnamed_consts.items.len; |
| 1092 | 1092 | const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index }); |
| 1093 | 1093 | defer gpa.free(sym_name); |
| 1094 | const atom_index = switch (try self.lowerConst(sym_name, tv, self.rdata_section_index.?, decl.srcLoc(mod))) { | |
| 1094 | const atom_index = switch (try self.lowerConst(sym_name, tv, tv.ty.abiAlignment(mod), self.rdata_section_index.?, decl.srcLoc(mod))) { | |
| 1095 | 1095 | .ok => |atom_index| atom_index, |
| 1096 | 1096 | .fail => |em| { |
| 1097 | 1097 | decl.analysis = .codegen_failure; |
| ... | ... | @@ -1109,13 +1109,12 @@ const LowerConstResult = union(enum) { |
| 1109 | 1109 | fail: *Module.ErrorMsg, |
| 1110 | 1110 | }; |
| 1111 | 1111 | |
| 1112 | fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, sect_id: u16, src_loc: Module.SrcLoc) !LowerConstResult { | |
| 1112 | fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, required_alignment: InternPool.Alignment, sect_id: u16, src_loc: Module.SrcLoc) !LowerConstResult { | |
| 1113 | 1113 | const gpa = self.base.allocator; |
| 1114 | 1114 | |
| 1115 | 1115 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 1116 | 1116 | defer code_buffer.deinit(); |
| 1117 | 1117 | |
| 1118 | const mod = self.base.options.module.?; | |
| 1119 | 1118 | const atom_index = try self.createAtom(); |
| 1120 | 1119 | const sym = self.getAtom(atom_index).getSymbolPtr(self); |
| 1121 | 1120 | try self.setSymbolName(sym, name); |
| ... | ... | @@ -1129,10 +1128,13 @@ fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, sect_id: u16, src_l |
| 1129 | 1128 | .fail => |em| return .{ .fail = em }, |
| 1130 | 1129 | }; |
| 1131 | 1130 | |
| 1132 | const required_alignment: u32 = @intCast(tv.ty.abiAlignment(mod).toByteUnits(0)); | |
| 1133 | 1131 | const atom = self.getAtomPtr(atom_index); |
| 1134 | 1132 | atom.size = @as(u32, @intCast(code.len)); |
| 1135 | atom.getSymbolPtr(self).value = try self.allocateAtom(atom_index, atom.size, required_alignment); | |
| 1133 | atom.getSymbolPtr(self).value = try self.allocateAtom( | |
| 1134 | atom_index, | |
| 1135 | atom.size, | |
| 1136 | @intCast(required_alignment.toByteUnitsOptional().?), | |
| 1137 | ); | |
| 1136 | 1138 | errdefer self.freeAtom(atom_index); |
| 1137 | 1139 | |
| 1138 | 1140 | log.debug("allocated atom for {s} at 0x{x}", .{ name, atom.getSymbol(self).value }); |
| ... | ... | @@ -1736,7 +1738,7 @@ pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link |
| 1736 | 1738 | return 0; |
| 1737 | 1739 | } |
| 1738 | 1740 | |
| 1739 | pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result { | |
| 1741 | pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result { | |
| 1740 | 1742 | // This is basically the same as lowerUnnamedConst. |
| 1741 | 1743 | // example: |
| 1742 | 1744 | // const ty = mod.intern_pool.typeOf(decl_val).toType(); |
| ... | ... | @@ -1747,15 +1749,21 @@ pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, src_loc: Module.Sr |
| 1747 | 1749 | // to put it in some location. |
| 1748 | 1750 | // ... |
| 1749 | 1751 | const gpa = self.base.allocator; |
| 1752 | const mod = self.base.options.module.?; | |
| 1753 | const ty = mod.intern_pool.typeOf(decl_val).toType(); | |
| 1750 | 1754 | const gop = try self.anon_decls.getOrPut(gpa, decl_val); |
| 1751 | if (!gop.found_existing) { | |
| 1752 | const mod = self.base.options.module.?; | |
| 1753 | const ty = mod.intern_pool.typeOf(decl_val).toType(); | |
| 1755 | const required_alignment = switch (decl_align) { | |
| 1756 | .none => ty.abiAlignment(mod), | |
| 1757 | else => decl_align, | |
| 1758 | }; | |
| 1759 | if (!gop.found_existing or | |
| 1760 | !required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).value)) | |
| 1761 | { | |
| 1754 | 1762 | const val = decl_val.toValue(); |
| 1755 | 1763 | const tv = TypedValue{ .ty = ty, .val = val }; |
| 1756 | 1764 | const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)}); |
| 1757 | 1765 | defer gpa.free(name); |
| 1758 | const res = self.lowerConst(name, tv, self.rdata_section_index.?, src_loc) catch |err| switch (err) { | |
| 1766 | const res = self.lowerConst(name, tv, required_alignment, self.rdata_section_index.?, src_loc) catch |err| switch (err) { | |
| 1759 | 1767 | else => { |
| 1760 | 1768 | // TODO improve error message |
| 1761 | 1769 | const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{ |
src/link/Elf.zig+13-8| ... | ... | @@ -473,7 +473,7 @@ pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link. |
| 473 | 473 | return vaddr; |
| 474 | 474 | } |
| 475 | 475 | |
| 476 | pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result { | |
| 476 | pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result { | |
| 477 | 477 | // This is basically the same as lowerUnnamedConst. |
| 478 | 478 | // example: |
| 479 | 479 | // const ty = mod.intern_pool.typeOf(decl_val).toType(); |
| ... | ... | @@ -484,15 +484,21 @@ pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, src_loc: Module.Src |
| 484 | 484 | // to put it in some location. |
| 485 | 485 | // ... |
| 486 | 486 | const gpa = self.base.allocator; |
| 487 | const mod = self.base.options.module.?; | |
| 488 | const ty = mod.intern_pool.typeOf(decl_val).toType(); | |
| 487 | 489 | const gop = try self.anon_decls.getOrPut(gpa, decl_val); |
| 488 | if (!gop.found_existing) { | |
| 489 | const mod = self.base.options.module.?; | |
| 490 | const ty = mod.intern_pool.typeOf(decl_val).toType(); | |
| 490 | const required_alignment = switch (decl_align) { | |
| 491 | .none => ty.abiAlignment(mod), | |
| 492 | else => decl_align, | |
| 493 | }; | |
| 494 | if (!gop.found_existing or | |
| 495 | required_alignment.order(self.symbol(gop.value_ptr.*).atom(self).?.alignment).compare(.gt)) | |
| 496 | { | |
| 491 | 497 | const val = decl_val.toValue(); |
| 492 | 498 | const tv = TypedValue{ .ty = ty, .val = val }; |
| 493 | 499 | const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)}); |
| 494 | 500 | defer gpa.free(name); |
| 495 | const res = self.lowerConst(name, tv, self.zig_rodata_section_index.?, src_loc) catch |err| switch (err) { | |
| 501 | const res = self.lowerConst(name, tv, required_alignment, self.zig_rodata_section_index.?, src_loc) catch |err| switch (err) { | |
| 496 | 502 | else => { |
| 497 | 503 | // TODO improve error message |
| 498 | 504 | const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{ |
| ... | ... | @@ -3479,7 +3485,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module |
| 3479 | 3485 | const index = unnamed_consts.items.len; |
| 3480 | 3486 | const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index }); |
| 3481 | 3487 | defer gpa.free(name); |
| 3482 | const sym_index = switch (try self.lowerConst(name, typed_value, self.zig_rodata_section_index.?, decl.srcLoc(mod))) { | |
| 3488 | const sym_index = switch (try self.lowerConst(name, typed_value, typed_value.ty.abiAlignment(mod), self.zig_rodata_section_index.?, decl.srcLoc(mod))) { | |
| 3483 | 3489 | .ok => |sym_index| sym_index, |
| 3484 | 3490 | .fail => |em| { |
| 3485 | 3491 | decl.analysis = .codegen_failure; |
| ... | ... | @@ -3502,6 +3508,7 @@ fn lowerConst( |
| 3502 | 3508 | self: *Elf, |
| 3503 | 3509 | name: []const u8, |
| 3504 | 3510 | tv: TypedValue, |
| 3511 | required_alignment: InternPool.Alignment, | |
| 3505 | 3512 | output_section_index: u16, |
| 3506 | 3513 | src_loc: Module.SrcLoc, |
| 3507 | 3514 | ) !LowerConstResult { |
| ... | ... | @@ -3510,7 +3517,6 @@ fn lowerConst( |
| 3510 | 3517 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 3511 | 3518 | defer code_buffer.deinit(); |
| 3512 | 3519 | |
| 3513 | const mod = self.base.options.module.?; | |
| 3514 | 3520 | const zig_module = self.file(self.zig_module_index.?).?.zig_module; |
| 3515 | 3521 | const sym_index = try zig_module.addAtom(self); |
| 3516 | 3522 | |
| ... | ... | @@ -3524,7 +3530,6 @@ fn lowerConst( |
| 3524 | 3530 | .fail => |em| return .{ .fail = em }, |
| 3525 | 3531 | }; |
| 3526 | 3532 | |
| 3527 | const required_alignment = tv.ty.abiAlignment(mod); | |
| 3528 | 3533 | const phdr_index = self.phdr_to_shdr_table.get(output_section_index).?; |
| 3529 | 3534 | const local_sym = self.symbol(sym_index); |
| 3530 | 3535 | const name_str_index = try self.strtab.insert(gpa, name); |
src/link/MachO.zig+13-9| ... | ... | @@ -2196,7 +2196,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu |
| 2196 | 2196 | const index = unnamed_consts.items.len; |
| 2197 | 2197 | const name = try std.fmt.allocPrint(gpa, "___unnamed_{s}_{d}", .{ decl_name, index }); |
| 2198 | 2198 | defer gpa.free(name); |
| 2199 | const atom_index = switch (try self.lowerConst(name, typed_value, self.data_const_section_index.?, decl.srcLoc(mod))) { | |
| 2199 | const atom_index = switch (try self.lowerConst(name, typed_value, typed_value.ty.abiAlignment(mod), self.data_const_section_index.?, decl.srcLoc(mod))) { | |
| 2200 | 2200 | .ok => |atom_index| atom_index, |
| 2201 | 2201 | .fail => |em| { |
| 2202 | 2202 | decl.analysis = .codegen_failure; |
| ... | ... | @@ -2219,6 +2219,7 @@ fn lowerConst( |
| 2219 | 2219 | self: *MachO, |
| 2220 | 2220 | name: []const u8, |
| 2221 | 2221 | tv: TypedValue, |
| 2222 | required_alignment: InternPool.Alignment, | |
| 2222 | 2223 | sect_id: u8, |
| 2223 | 2224 | src_loc: Module.SrcLoc, |
| 2224 | 2225 | ) !LowerConstResult { |
| ... | ... | @@ -2227,8 +2228,6 @@ fn lowerConst( |
| 2227 | 2228 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 2228 | 2229 | defer code_buffer.deinit(); |
| 2229 | 2230 | |
| 2230 | const mod = self.base.options.module.?; | |
| 2231 | ||
| 2232 | 2231 | log.debug("allocating symbol indexes for {s}", .{name}); |
| 2233 | 2232 | |
| 2234 | 2233 | const sym_index = try self.allocateSymbol(); |
| ... | ... | @@ -2243,7 +2242,6 @@ fn lowerConst( |
| 2243 | 2242 | .fail => |em| return .{ .fail = em }, |
| 2244 | 2243 | }; |
| 2245 | 2244 | |
| 2246 | const required_alignment = tv.ty.abiAlignment(mod); | |
| 2247 | 2245 | const atom = self.getAtomPtr(atom_index); |
| 2248 | 2246 | atom.size = code.len; |
| 2249 | 2247 | // TODO: work out logic for disambiguating functions from function pointers |
| ... | ... | @@ -2868,7 +2866,7 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil |
| 2868 | 2866 | return 0; |
| 2869 | 2867 | } |
| 2870 | 2868 | |
| 2871 | pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result { | |
| 2869 | pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result { | |
| 2872 | 2870 | // This is basically the same as lowerUnnamedConst. |
| 2873 | 2871 | // example: |
| 2874 | 2872 | // const ty = mod.intern_pool.typeOf(decl_val).toType(); |
| ... | ... | @@ -2879,15 +2877,21 @@ pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, src_loc: Module.S |
| 2879 | 2877 | // to put it in some location. |
| 2880 | 2878 | // ... |
| 2881 | 2879 | const gpa = self.base.allocator; |
| 2880 | const mod = self.base.options.module.?; | |
| 2881 | const ty = mod.intern_pool.typeOf(decl_val).toType(); | |
| 2882 | 2882 | const gop = try self.anon_decls.getOrPut(gpa, decl_val); |
| 2883 | if (!gop.found_existing) { | |
| 2884 | const mod = self.base.options.module.?; | |
| 2885 | const ty = mod.intern_pool.typeOf(decl_val).toType(); | |
| 2883 | const required_alignment = switch (decl_align) { | |
| 2884 | .none => ty.abiAlignment(mod), | |
| 2885 | else => decl_align, | |
| 2886 | }; | |
| 2887 | if (!gop.found_existing or | |
| 2888 | !required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).n_value)) | |
| 2889 | { | |
| 2886 | 2890 | const val = decl_val.toValue(); |
| 2887 | 2891 | const tv = TypedValue{ .ty = ty, .val = val }; |
| 2888 | 2892 | const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)}); |
| 2889 | 2893 | defer gpa.free(name); |
| 2890 | const res = self.lowerConst(name, tv, self.data_const_section_index.?, src_loc) catch |err| switch (err) { | |
| 2894 | const res = self.lowerConst(name, tv, required_alignment, self.data_const_section_index.?, src_loc) catch |err| switch (err) { | |
| 2891 | 2895 | else => { |
| 2892 | 2896 | // TODO improve error message |
| 2893 | 2897 | const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{ |
src/link/Wasm.zig+20-15| ... | ... | @@ -1702,25 +1702,30 @@ pub fn getDeclVAddr( |
| 1702 | 1702 | return target_symbol_index; |
| 1703 | 1703 | } |
| 1704 | 1704 | |
| 1705 | pub fn lowerAnonDecl(wasm: *Wasm, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result { | |
| 1705 | pub fn lowerAnonDecl(wasm: *Wasm, decl_val: InternPool.Index, decl_align: Alignment, src_loc: Module.SrcLoc) !codegen.Result { | |
| 1706 | 1706 | const gop = try wasm.anon_decls.getOrPut(wasm.base.allocator, decl_val); |
| 1707 | if (gop.found_existing) { | |
| 1708 | return .ok; | |
| 1709 | } | |
| 1707 | if (!gop.found_existing) { | |
| 1708 | const mod = wasm.base.options.module.?; | |
| 1709 | const ty = mod.intern_pool.typeOf(decl_val).toType(); | |
| 1710 | const tv: TypedValue = .{ .ty = ty, .val = decl_val.toValue() }; | |
| 1711 | const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__anon_{d}", .{@intFromEnum(decl_val)}); | |
| 1712 | defer wasm.base.allocator.free(name); | |
| 1710 | 1713 | |
| 1711 | const mod = wasm.base.options.module.?; | |
| 1712 | const ty = mod.intern_pool.typeOf(decl_val).toType(); | |
| 1713 | const tv: TypedValue = .{ .ty = ty, .val = decl_val.toValue() }; | |
| 1714 | const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__anon_{d}", .{@intFromEnum(decl_val)}); | |
| 1715 | defer wasm.base.allocator.free(name); | |
| 1714 | switch (try wasm.lowerConst(name, tv, src_loc)) { | |
| 1715 | .ok => |atom_index| gop.value_ptr.* = atom_index, | |
| 1716 | .fail => |em| return .{ .fail = em }, | |
| 1717 | } | |
| 1718 | } | |
| 1716 | 1719 | |
| 1717 | switch (try wasm.lowerConst(name, tv, src_loc)) { | |
| 1718 | .ok => |atom_index| { | |
| 1719 | gop.value_ptr.* = atom_index; | |
| 1720 | return .ok; | |
| 1720 | const atom = wasm.getAtomPtr(gop.value_ptr.*); | |
| 1721 | atom.alignment = switch (atom.alignment) { | |
| 1722 | .none => decl_align, | |
| 1723 | else => switch (decl_align) { | |
| 1724 | .none => atom.alignment, | |
| 1725 | else => atom.alignment.maxStrict(decl_align), | |
| 1721 | 1726 | }, |
| 1722 | .fail => |em| return .{ .fail = em }, | |
| 1723 | } | |
| 1727 | }; | |
| 1728 | return .ok; | |
| 1724 | 1729 | } |
| 1725 | 1730 | |
| 1726 | 1731 | pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { |