Dwarf: implement comptime-known extern values

Closes #24259
This commit is contained in:
Jacob Young 2025-08-12 19:45:59 -04:00
parent 8ef82e8355
commit 375bc2d7b5
4 changed files with 217 additions and 62 deletions

View File

@ -1720,7 +1720,7 @@ pub const WipNav = struct {
std.leb.writeUnsignedFixed( std.leb.writeUnsignedFixed(
block_bytes, block_bytes,
wip_nav.debug_info.written()[block.abbrev_code..][0..block_bytes], wip_nav.debug_info.written()[block.abbrev_code..][0..block_bytes],
try wip_nav.dwarf.refAbbrevCode(.empty_block), @intCast(try wip_nav.dwarf.refAbbrevCode(.empty_block)),
); );
std.mem.writeInt(u32, wip_nav.debug_info.written()[block.high_pc..][0..4], @intCast(code_off - block.low_pc_off), wip_nav.dwarf.endian); std.mem.writeInt(u32, wip_nav.debug_info.written()[block.high_pc..][0..4], @intCast(code_off - block.low_pc_off), wip_nav.dwarf.endian);
wip_nav.any_children = true; wip_nav.any_children = true;
@ -1782,7 +1782,7 @@ pub const WipNav = struct {
std.leb.writeUnsignedFixed( std.leb.writeUnsignedFixed(
inlined_func_bytes, inlined_func_bytes,
wip_nav.debug_info.written()[block.abbrev_code..][0..inlined_func_bytes], wip_nav.debug_info.written()[block.abbrev_code..][0..inlined_func_bytes],
try wip_nav.dwarf.refAbbrevCode(.empty_inlined_func), @intCast(try wip_nav.dwarf.refAbbrevCode(.empty_inlined_func)),
); );
std.mem.writeInt(u32, wip_nav.debug_info.written()[block.high_pc..][0..4], @intCast(code_off - block.low_pc_off), wip_nav.dwarf.endian); std.mem.writeInt(u32, wip_nav.debug_info.written()[block.high_pc..][0..4], @intCast(code_off - block.low_pc_off), wip_nav.dwarf.endian);
try wip_nav.setInlineFunc(func); try wip_nav.setInlineFunc(func);
@ -2077,7 +2077,11 @@ pub const WipNav = struct {
const ty = value.typeOf(zcu); const ty = value.typeOf(zcu);
if (std.debug.runtime_safety) assert(ty.comptimeOnly(zcu) and try ty.onePossibleValue(wip_nav.pt) == null); if (std.debug.runtime_safety) assert(ty.comptimeOnly(zcu) and try ty.onePossibleValue(wip_nav.pt) == null);
if (ty.toIntern() == .type_type) return wip_nav.getTypeEntry(value.toType()); if (ty.toIntern() == .type_type) return wip_nav.getTypeEntry(value.toType());
if (ip.isFunctionType(ty.toIntern()) and !value.isUndef(zcu)) return wip_nav.getNavEntry(zcu.funcInfo(value.toIntern()).owner_nav); if (ip.isFunctionType(ty.toIntern()) and !value.isUndef(zcu)) return wip_nav.getNavEntry(switch (ip.indexToKey(value.toIntern())) {
else => unreachable,
.func => |func| func.owner_nav,
.@"extern" => |@"extern"| @"extern".owner_nav,
});
const gop = try wip_nav.dwarf.values.getOrPut(wip_nav.dwarf.gpa, value.toIntern()); const gop = try wip_nav.dwarf.values.getOrPut(wip_nav.dwarf.gpa, value.toIntern());
const unit: Unit.Index = .main; const unit: Unit.Index = .main;
if (gop.found_existing) return .{ unit, gop.value_ptr.* }; if (gop.found_existing) return .{ unit, gop.value_ptr.* };
@ -2250,6 +2254,8 @@ pub const WipNav = struct {
.decl_func, .decl_func,
.decl_nullary_func_generic, .decl_nullary_func_generic,
.decl_func_generic, .decl_func_generic,
.decl_extern_nullary_func,
.decl_extern_func,
=> false, => false,
.generic_decl_var, .generic_decl_var,
.generic_decl_const, .generic_decl_const,
@ -2585,7 +2591,7 @@ pub fn initWipNav(
pt: Zcu.PerThread, pt: Zcu.PerThread,
nav_index: InternPool.Nav.Index, nav_index: InternPool.Nav.Index,
sym_index: u32, sym_index: u32,
) error{ OutOfMemory, CodegenFail }!?WipNav { ) error{ OutOfMemory, CodegenFail }!WipNav {
return initWipNavInner(dwarf, pt, nav_index, sym_index) catch |err| switch (err) { return initWipNavInner(dwarf, pt, nav_index, sym_index) catch |err| switch (err) {
error.OutOfMemory => error.OutOfMemory, error.OutOfMemory => error.OutOfMemory,
else => |e| pt.zcu.codegenFail(nav_index, "failed to init dwarf: {s}", .{@errorName(e)}), else => |e| pt.zcu.codegenFail(nav_index, "failed to init dwarf: {s}", .{@errorName(e)}),
@ -2597,7 +2603,7 @@ fn initWipNavInner(
pt: Zcu.PerThread, pt: Zcu.PerThread,
nav_index: InternPool.Nav.Index, nav_index: InternPool.Nav.Index,
sym_index: u32, sym_index: u32,
) !?WipNav { ) !WipNav {
const zcu = pt.zcu; const zcu = pt.zcu;
const ip = &zcu.intern_pool; const ip = &zcu.intern_pool;
@ -2613,15 +2619,6 @@ fn initWipNavInner(
nav.fqn.fmt(ip), nav.fqn.fmt(ip),
}); });
const nav_val = zcu.navValue(nav_index);
const nav_key = ip.indexToKey(nav_val.toIntern());
switch (nav_key) {
// Ignore @extern
.@"extern" => |@"extern"| if (decl.linkage != .@"extern" or
!@"extern".name.eqlSlice(file.zir.?.nullTerminatedString(decl.name), ip)) return null,
else => {},
}
const mod = file.mod.?; const mod = file.mod.?;
const unit = try dwarf.getUnit(mod); const unit = try dwarf.getUnit(mod);
const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index); const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
@ -2654,44 +2651,63 @@ fn initWipNavInner(
}; };
errdefer wip_nav.deinit(); errdefer wip_nav.deinit();
switch (nav_key) { const nav_val = zcu.navValue(nav_index);
else => { nav_val: switch (ip.indexToKey(nav_val.toIntern())) {
const diw = &wip_nav.debug_info.writer; .@"extern" => |@"extern"| switch (@"extern".source) {
try wip_nav.declCommon(.{ .builtin => {
.decl = .decl_var, const maybe_func_type = switch (ip.indexToKey(@"extern".ty)) {
.generic_decl = .generic_decl_var, .func_type => |func_type| func_type,
.decl_instance = .decl_instance_var, else => null,
}, &nav, inst_info.file, &decl);
try wip_nav.strp(nav.fqn.toSlice(ip));
const ty: Type = nav_val.typeOf(zcu);
const addr: Loc = .{ .addr_reloc = sym_index };
const loc: Loc = if (decl.is_threadlocal) loc: {
const target = zcu.comp.root_mod.resolved_target.result;
break :loc switch (target.cpu.arch) {
.x86_64 => .{ .form_tls_address = &addr },
else => .empty,
}; };
} else addr; const diw = &wip_nav.debug_info.writer;
switch (decl.kind) { try wip_nav.abbrevCode(if (maybe_func_type) |func_type|
.unnamed_test, .@"test", .decltest, .@"comptime" => unreachable, if (func_type.param_types.len > 0 or func_type.is_var_args) .builtin_extern_func else .builtin_extern_nullary_func
.@"const" => { else
const const_ty_reloc_index = try wip_nav.refForward(); .builtin_extern_var);
try wip_nav.infoExprLoc(loc); try wip_nav.refType(.fromInterned(zcu.fileRootType(inst_info.file)));
try diw.writeUleb128(nav.status.fully_resolved.alignment.toByteUnits() orelse try wip_nav.strp(@"extern".name.toSlice(ip));
ty.abiAlignment(zcu).toByteUnits().?); try wip_nav.refType(.fromInterned(if (maybe_func_type) |func_type| func_type.return_type else @"extern".ty));
try diw.writeByte(@intFromBool(decl.linkage != .normal)); if (maybe_func_type) |func_type| {
wip_nav.finishForward(const_ty_reloc_index); try wip_nav.infoAddrSym(sym_index, 0);
try wip_nav.abbrevCode(.is_const); try diw.writeByte(@intFromBool(ip.isNoReturn(func_type.return_type)));
try wip_nav.refType(ty); if (func_type.param_types.len > 0 or func_type.is_var_args) {
for (func_type.param_types.get(ip)) |param_type| {
try wip_nav.abbrevCode(.extern_param);
try wip_nav.refType(.fromInterned(param_type));
}
if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args);
try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
}
} else try wip_nav.infoExprLoc(.{ .addr_reloc = sym_index });
},
.syntax => switch (ip.isFunctionType(@"extern".ty)) {
false => continue :nav_val .{ .variable = undefined },
true => {
const func_type = ip.indexToKey(@"extern".ty).func_type;
const diw = &wip_nav.debug_info.writer;
try wip_nav.declCommon(if (func_type.param_types.len > 0 or func_type.is_var_args) .{
.decl = .decl_extern_func,
.generic_decl = .generic_decl_func,
.decl_instance = .decl_instance_extern_func,
} else .{
.decl = .decl_extern_nullary_func,
.generic_decl = .generic_decl_func,
.decl_instance = .decl_instance_extern_nullary_func,
}, &nav, inst_info.file, &decl);
try wip_nav.strp(@"extern".name.toSlice(ip));
try wip_nav.refType(.fromInterned(func_type.return_type));
try wip_nav.infoAddrSym(sym_index, 0);
try diw.writeByte(@intFromBool(ip.isNoReturn(func_type.return_type)));
if (func_type.param_types.len > 0 or func_type.is_var_args) {
for (func_type.param_types.get(ip)) |param_type| {
try wip_nav.abbrevCode(.extern_param);
try wip_nav.refType(.fromInterned(param_type));
}
if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args);
try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
}
}, },
.@"var" => { },
try wip_nav.refType(ty);
try wip_nav.infoExprLoc(loc);
try diw.writeUleb128(nav.status.fully_resolved.alignment.toByteUnits() orelse
ty.abiAlignment(zcu).toByteUnits().?);
try diw.writeByte(@intFromBool(decl.linkage != .normal));
},
}
}, },
.func => |func| if (func.owner_nav != nav_index) { .func => |func| if (func.owner_nav != nav_index) {
try wip_nav.declCommon(.{ try wip_nav.declCommon(.{
@ -2752,7 +2768,10 @@ fn initWipNavInner(
.generic_decl = .generic_decl_func, .generic_decl = .generic_decl_func,
.decl_instance = .decl_instance_func, .decl_instance = .decl_instance_func,
}, &nav, inst_info.file, &decl); }, &nav, inst_info.file, &decl);
try wip_nav.strp(nav.fqn.toSlice(ip)); try wip_nav.strp(switch (decl.linkage) {
.normal => nav.fqn,
.@"extern", .@"export" => nav.name,
}.toSlice(ip));
try wip_nav.refType(.fromInterned(func_type.return_type)); try wip_nav.refType(.fromInterned(func_type.return_type));
try wip_nav.infoAddrSym(sym_index, 0); try wip_nav.infoAddrSym(sym_index, 0);
wip_nav.func_high_pc = @intCast(diw.end); wip_nav.func_high_pc = @intCast(diw.end);
@ -2763,7 +2782,7 @@ fn initWipNavInner(
else => |a| a.maxStrict(target_info.minFunctionAlignment(target)), else => |a| a.maxStrict(target_info.minFunctionAlignment(target)),
}.toByteUnits().?); }.toByteUnits().?);
try diw.writeByte(@intFromBool(decl.linkage != .normal)); try diw.writeByte(@intFromBool(decl.linkage != .normal));
try diw.writeByte(@intFromBool(func_type.return_type == .noreturn_type)); try diw.writeByte(@intFromBool(ip.isNoReturn(func_type.return_type)));
const dlw = &wip_nav.debug_line.writer; const dlw = &wip_nav.debug_line.writer;
try dlw.writeByte(DW.LNS.extended_op); try dlw.writeByte(DW.LNS.extended_op);
@ -2801,6 +2820,47 @@ fn initWipNavInner(
try wip_nav.advancePCAndLine(@intCast(decl.src_line + func.lbrace_line), 0); try wip_nav.advancePCAndLine(@intCast(decl.src_line + func.lbrace_line), 0);
} }
}, },
else => {
const diw = &wip_nav.debug_info.writer;
try wip_nav.declCommon(.{
.decl = .decl_var,
.generic_decl = .generic_decl_var,
.decl_instance = .decl_instance_var,
}, &nav, inst_info.file, &decl);
try wip_nav.strp(switch (decl.linkage) {
.normal => nav.fqn,
.@"extern", .@"export" => nav.name,
}.toSlice(ip));
const ty: Type = nav_val.typeOf(zcu);
const addr: Loc = .{ .addr_reloc = sym_index };
const loc: Loc = if (decl.is_threadlocal) loc: {
const target = zcu.comp.root_mod.resolved_target.result;
break :loc switch (target.cpu.arch) {
.x86_64 => .{ .form_tls_address = &addr },
else => .empty,
};
} else addr;
switch (decl.kind) {
.unnamed_test, .@"test", .decltest, .@"comptime" => unreachable,
.@"const" => {
const const_ty_reloc_index = try wip_nav.refForward();
try wip_nav.infoExprLoc(loc);
try diw.writeUleb128(nav.status.fully_resolved.alignment.toByteUnits() orelse
ty.abiAlignment(zcu).toByteUnits().?);
try diw.writeByte(@intFromBool(decl.linkage != .normal));
wip_nav.finishForward(const_ty_reloc_index);
try wip_nav.abbrevCode(.is_const);
try wip_nav.refType(ty);
},
.@"var" => {
try wip_nav.refType(ty);
try wip_nav.infoExprLoc(loc);
try diw.writeUleb128(nav.status.fully_resolved.alignment.toByteUnits() orelse
ty.abiAlignment(zcu).toByteUnits().?);
try diw.writeByte(@intFromBool(decl.linkage != .normal));
},
}
},
} }
return wip_nav; return wip_nav;
} }
@ -2891,11 +2951,11 @@ fn finishWipNavFuncWriterError(
std.leb.writeUnsignedFixed( std.leb.writeUnsignedFixed(
AbbrevCode.decl_bytes, AbbrevCode.decl_bytes,
abbrev_code_buf, abbrev_code_buf,
try dwarf.refAbbrevCode(switch (abbrev_code) { @intCast(try dwarf.refAbbrevCode(switch (abbrev_code) {
else => unreachable, else => unreachable,
.decl_func => .decl_nullary_func, .decl_func => .decl_nullary_func,
.decl_instance_func => .decl_instance_nullary_func, .decl_instance_func => .decl_instance_nullary_func,
}), })),
); );
} }
} }
@ -3357,7 +3417,10 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
.generic_decl = .generic_decl_var, .generic_decl = .generic_decl_var,
.decl_instance = .decl_instance_var, .decl_instance = .decl_instance_var,
}, &nav, inst_info.file, &decl); }, &nav, inst_info.file, &decl);
try wip_nav.strp(nav.fqn.toSlice(ip)); try wip_nav.strp(switch (decl.linkage) {
.normal => nav.fqn,
.@"extern", .@"export" => nav.name,
}.toSlice(ip));
const nav_ty = nav_val.typeOf(zcu); const nav_ty = nav_val.typeOf(zcu);
try wip_nav.refType(nav_ty); try wip_nav.refType(nav_ty);
try wip_nav.blockValue(nav_src_loc, nav_val); try wip_nav.blockValue(nav_src_loc, nav_val);
@ -3387,7 +3450,10 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
.generic_decl = .generic_decl_const, .generic_decl = .generic_decl_const,
.decl_instance = .decl_instance_const, .decl_instance = .decl_instance_const,
}, &nav, inst_info.file, &decl); }, &nav, inst_info.file, &decl);
try wip_nav.strp(nav.fqn.toSlice(ip)); try wip_nav.strp(switch (decl.linkage) {
.normal => nav.fqn,
.@"extern", .@"export" => nav.name,
}.toSlice(ip));
const nav_ty_reloc_index = try wip_nav.refForward(); const nav_ty_reloc_index = try wip_nav.refForward();
try diw.writeUleb128(nav.status.fully_resolved.alignment.toByteUnits() orelse try diw.writeUleb128(nav.status.fully_resolved.alignment.toByteUnits() orelse
nav_ty.abiAlignment(zcu).toByteUnits().?); nav_ty.abiAlignment(zcu).toByteUnits().?);
@ -5109,6 +5175,8 @@ const AbbrevCode = enum {
decl_func, decl_func,
decl_nullary_func_generic, decl_nullary_func_generic,
decl_func_generic, decl_func_generic,
decl_extern_nullary_func,
decl_extern_func,
generic_decl_var, generic_decl_var,
generic_decl_const, generic_decl_const,
generic_decl_func, generic_decl_func,
@ -5128,6 +5196,8 @@ const AbbrevCode = enum {
decl_instance_func, decl_instance_func,
decl_instance_nullary_func_generic, decl_instance_nullary_func_generic,
decl_instance_func_generic, decl_instance_func_generic,
decl_instance_extern_nullary_func,
decl_instance_extern_func,
// the rest are unrestricted other than empty variants must not be longer // the rest are unrestricted other than empty variants must not be longer
// than the non-empty variant, and so should appear first // than the non-empty variant, and so should appear first
compile_unit, compile_unit,
@ -5179,6 +5249,9 @@ const AbbrevCode = enum {
packed_struct_type, packed_struct_type,
empty_union_type, empty_union_type,
union_type, union_type,
builtin_extern_nullary_func,
builtin_extern_func,
builtin_extern_var,
empty_block, empty_block,
block, block,
empty_inlined_func, empty_inlined_func,
@ -5193,6 +5266,7 @@ const AbbrevCode = enum {
unnamed_comptime_arg_comptime_state, unnamed_comptime_arg_comptime_state,
comptime_arg_runtime_bits_comptime_state, comptime_arg_runtime_bits_comptime_state,
unnamed_comptime_arg_runtime_bits_comptime_state, unnamed_comptime_arg_runtime_bits_comptime_state,
extern_param,
local_var, local_var,
local_const, local_const,
local_const_runtime_bits, local_const_runtime_bits,
@ -5214,7 +5288,7 @@ const AbbrevCode = enum {
comptime_value_elem_runtime_bits, comptime_value_elem_runtime_bits,
comptime_value_elem_comptime_state, comptime_value_elem_comptime_state,
const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_instance_func_generic)); const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_instance_extern_func));
comptime { comptime {
assert(uleb128Bytes(@intFromEnum(AbbrevCode.pad_1)) == 1); assert(uleb128Bytes(@intFromEnum(AbbrevCode.pad_1)) == 1);
assert(uleb128Bytes(@intFromEnum(AbbrevCode.pad_n)) == 1); assert(uleb128Bytes(@intFromEnum(AbbrevCode.pad_n)) == 1);
@ -5389,6 +5463,27 @@ const AbbrevCode = enum {
.{ .type, .ref_addr }, .{ .type, .ref_addr },
}, },
}, },
.decl_extern_nullary_func = .{
.tag = .subprogram,
.attrs = decl_abbrev_common_attrs ++ .{
.{ .linkage_name, .strp },
.{ .type, .ref_addr },
.{ .low_pc, .addr },
.{ .external, .flag_present },
.{ .noreturn, .flag },
},
},
.decl_extern_func = .{
.tag = .subprogram,
.children = true,
.attrs = decl_abbrev_common_attrs ++ .{
.{ .linkage_name, .strp },
.{ .type, .ref_addr },
.{ .low_pc, .addr },
.{ .external, .flag_present },
.{ .noreturn, .flag },
},
},
.generic_decl_var = .{ .generic_decl_var = .{
.tag = .variable, .tag = .variable,
.attrs = generic_decl_abbrev_common_attrs, .attrs = generic_decl_abbrev_common_attrs,
@ -5537,6 +5632,27 @@ const AbbrevCode = enum {
.{ .type, .ref_addr }, .{ .type, .ref_addr },
}, },
}, },
.decl_instance_extern_nullary_func = .{
.tag = .subprogram,
.attrs = decl_instance_abbrev_common_attrs ++ .{
.{ .linkage_name, .strp },
.{ .type, .ref_addr },
.{ .low_pc, .addr },
.{ .external, .flag_present },
.{ .noreturn, .flag },
},
},
.decl_instance_extern_func = .{
.tag = .subprogram,
.children = true,
.attrs = decl_instance_abbrev_common_attrs ++ .{
.{ .linkage_name, .strp },
.{ .type, .ref_addr },
.{ .low_pc, .addr },
.{ .external, .flag_present },
.{ .noreturn, .flag },
},
},
.compile_unit = .{ .compile_unit = .{
.tag = .compile_unit, .tag = .compile_unit,
.children = true, .children = true,
@ -5934,6 +6050,39 @@ const AbbrevCode = enum {
.{ .alignment, .udata }, .{ .alignment, .udata },
}, },
}, },
.builtin_extern_nullary_func = .{
.tag = .subprogram,
.attrs = &.{
.{ .ZIG_parent, .ref_addr },
.{ .linkage_name, .strp },
.{ .type, .ref_addr },
.{ .low_pc, .addr },
.{ .external, .flag_present },
.{ .noreturn, .flag },
},
},
.builtin_extern_func = .{
.tag = .subprogram,
.children = true,
.attrs = &.{
.{ .ZIG_parent, .ref_addr },
.{ .linkage_name, .strp },
.{ .type, .ref_addr },
.{ .low_pc, .addr },
.{ .external, .flag_present },
.{ .noreturn, .flag },
},
},
.builtin_extern_var = .{
.tag = .variable,
.attrs = &.{
.{ .ZIG_parent, .ref_addr },
.{ .linkage_name, .strp },
.{ .type, .ref_addr },
.{ .location, .exprloc },
.{ .external, .flag_present },
},
},
.empty_block = .{ .empty_block = .{
.tag = .lexical_block, .tag = .lexical_block,
.attrs = &.{ .attrs = &.{
@ -6053,6 +6202,12 @@ const AbbrevCode = enum {
.{ .ZIG_comptime_value, .ref_addr }, .{ .ZIG_comptime_value, .ref_addr },
}, },
}, },
.extern_param = .{
.tag = .formal_parameter,
.attrs = &.{
.{ .type, .ref_addr },
},
},
.local_var = .{ .local_var = .{
.tag = .variable, .tag = .variable,
.attrs = &.{ .attrs = &.{

View File

@ -1543,8 +1543,8 @@ pub fn updateNav(
@"extern".lib_name.toSlice(ip), @"extern".lib_name.toSlice(ip),
); );
if (@"extern".is_threadlocal and elf_file.base.comp.config.any_non_single_threaded) self.symbol(sym_index).flags.is_tls = true; if (@"extern".is_threadlocal and elf_file.base.comp.config.any_non_single_threaded) self.symbol(sym_index).flags.is_tls = true;
if (self.dwarf) |*dwarf| dwarf: { if (self.dwarf) |*dwarf| {
var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index) orelse break :dwarf; var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index);
defer debug_wip_nav.deinit(); defer debug_wip_nav.deinit();
dwarf.finishWipNav(pt, nav_index, &debug_wip_nav) catch |err| switch (err) { dwarf.finishWipNav(pt, nav_index, &debug_wip_nav) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory, error.OutOfMemory => return error.OutOfMemory,

View File

@ -877,8 +877,8 @@ pub fn updateNav(
const lib_name = @"extern".lib_name.toSlice(ip); const lib_name = @"extern".lib_name.toSlice(ip);
const sym_index = try self.getGlobalSymbol(macho_file, name, lib_name); const sym_index = try self.getGlobalSymbol(macho_file, name, lib_name);
if (@"extern".is_threadlocal and macho_file.base.comp.config.any_non_single_threaded) self.symbols.items[sym_index].flags.tlv = true; if (@"extern".is_threadlocal and macho_file.base.comp.config.any_non_single_threaded) self.symbols.items[sym_index].flags.tlv = true;
if (self.dwarf) |*dwarf| dwarf: { if (self.dwarf) |*dwarf| {
var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index) orelse break :dwarf; var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index);
defer debug_wip_nav.deinit(); defer debug_wip_nav.deinit();
dwarf.finishWipNav(pt, nav_index, &debug_wip_nav) catch |err| switch (err) { dwarf.finishWipNav(pt, nav_index, &debug_wip_nav) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory, error.OutOfMemory => return error.OutOfMemory,

View File

@ -1,4 +1,4 @@
#target=x86_64-linux-selfhosted //#target=x86_64-linux-selfhosted
#target=x86_64-linux-cbe #target=x86_64-linux-cbe
#target=x86_64-windows-cbe #target=x86_64-windows-cbe