x86_64: increase passing test coverage on windows
Now that codegen has no references to linker state this is much easier. Closes #24153
This commit is contained in:
193
src/codegen.zig
193
src/codegen.zig
@@ -810,7 +810,7 @@ fn lowerUavRef(
|
||||
|
||||
const uav_align = ip.indexToKey(uav.orig_ty).ptr_type.flags.alignment;
|
||||
switch (try lf.lowerUav(pt, uav_val, uav_align, src_loc)) {
|
||||
.mcv => {},
|
||||
.sym_index => {},
|
||||
.fail => |em| std.debug.panic("TODO rework lowerUav. internal error: {s}", .{em.msg}),
|
||||
}
|
||||
|
||||
@@ -920,6 +920,90 @@ pub const LinkerLoad = struct {
|
||||
sym_index: u32,
|
||||
};
|
||||
|
||||
pub const SymbolResult = union(enum) { sym_index: u32, fail: *ErrorMsg };
|
||||
|
||||
pub fn genNavRef(
|
||||
lf: *link.File,
|
||||
pt: Zcu.PerThread,
|
||||
src_loc: Zcu.LazySrcLoc,
|
||||
nav_index: InternPool.Nav.Index,
|
||||
target: *const std.Target,
|
||||
) CodeGenError!SymbolResult {
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const nav = ip.getNav(nav_index);
|
||||
log.debug("genNavRef({})", .{nav.fqn.fmt(ip)});
|
||||
|
||||
const lib_name, const linkage, const is_threadlocal = if (nav.getExtern(ip)) |e|
|
||||
.{ e.lib_name, e.linkage, e.is_threadlocal and zcu.comp.config.any_non_single_threaded }
|
||||
else
|
||||
.{ .none, .internal, false };
|
||||
if (lf.cast(.elf)) |elf_file| {
|
||||
const zo = elf_file.zigObjectPtr().?;
|
||||
switch (linkage) {
|
||||
.internal => {
|
||||
const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index);
|
||||
if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
|
||||
return .{ .sym_index = sym_index };
|
||||
},
|
||||
.strong, .weak => {
|
||||
const sym_index = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
|
||||
switch (linkage) {
|
||||
.internal => unreachable,
|
||||
.strong => {},
|
||||
.weak => zo.symbol(sym_index).flags.weak = true,
|
||||
.link_once => unreachable,
|
||||
}
|
||||
if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
|
||||
return .{ .sym_index = sym_index };
|
||||
},
|
||||
.link_once => unreachable,
|
||||
}
|
||||
} else if (lf.cast(.macho)) |macho_file| {
|
||||
const zo = macho_file.getZigObject().?;
|
||||
switch (linkage) {
|
||||
.internal => {
|
||||
const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index);
|
||||
if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
|
||||
return .{ .sym_index = sym_index };
|
||||
},
|
||||
.strong, .weak => {
|
||||
const sym_index = try macho_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
|
||||
switch (linkage) {
|
||||
.internal => unreachable,
|
||||
.strong => {},
|
||||
.weak => zo.symbols.items[sym_index].flags.weak = true,
|
||||
.link_once => unreachable,
|
||||
}
|
||||
if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
|
||||
return .{ .sym_index = sym_index };
|
||||
},
|
||||
.link_once => unreachable,
|
||||
}
|
||||
} else if (lf.cast(.coff)) |coff_file| {
|
||||
// TODO audit this
|
||||
switch (linkage) {
|
||||
.internal => {
|
||||
const atom_index = try coff_file.getOrCreateAtomForNav(nav_index);
|
||||
const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
|
||||
return .{ .sym_index = sym_index };
|
||||
},
|
||||
.strong, .weak => {
|
||||
const global_index = try coff_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
|
||||
try coff_file.need_got_table.put(zcu.gpa, global_index, {}); // needs GOT
|
||||
return .{ .sym_index = global_index };
|
||||
},
|
||||
.link_once => unreachable,
|
||||
}
|
||||
} else if (lf.cast(.plan9)) |p9| {
|
||||
return .{ .sym_index = try p9.seeNav(pt, nav_index) };
|
||||
} else {
|
||||
const msg = try ErrorMsg.create(zcu.gpa, src_loc, "TODO genNavRef for target {}", .{target});
|
||||
return .{ .fail = msg };
|
||||
}
|
||||
}
|
||||
|
||||
/// deprecated legacy type
|
||||
pub const GenResult = union(enum) {
|
||||
mcv: MCValue,
|
||||
fail: *ErrorMsg,
|
||||
@@ -951,89 +1035,6 @@ pub const GenResult = union(enum) {
|
||||
};
|
||||
};
|
||||
|
||||
pub fn genNavRef(
|
||||
lf: *link.File,
|
||||
pt: Zcu.PerThread,
|
||||
src_loc: Zcu.LazySrcLoc,
|
||||
nav_index: InternPool.Nav.Index,
|
||||
target: *const std.Target,
|
||||
) CodeGenError!GenResult {
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const nav = ip.getNav(nav_index);
|
||||
log.debug("genNavRef({})", .{nav.fqn.fmt(ip)});
|
||||
|
||||
const lib_name, const linkage, const is_threadlocal = if (nav.getExtern(ip)) |e|
|
||||
.{ e.lib_name, e.linkage, e.is_threadlocal and zcu.comp.config.any_non_single_threaded }
|
||||
else
|
||||
.{ .none, .internal, false };
|
||||
if (lf.cast(.elf)) |elf_file| {
|
||||
const zo = elf_file.zigObjectPtr().?;
|
||||
switch (linkage) {
|
||||
.internal => {
|
||||
const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index);
|
||||
if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
|
||||
return .{ .mcv = .{ .lea_symbol = sym_index } };
|
||||
},
|
||||
.strong, .weak => {
|
||||
const sym_index = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
|
||||
switch (linkage) {
|
||||
.internal => unreachable,
|
||||
.strong => {},
|
||||
.weak => zo.symbol(sym_index).flags.weak = true,
|
||||
.link_once => unreachable,
|
||||
}
|
||||
if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
|
||||
return .{ .mcv = .{ .lea_symbol = sym_index } };
|
||||
},
|
||||
.link_once => unreachable,
|
||||
}
|
||||
} else if (lf.cast(.macho)) |macho_file| {
|
||||
const zo = macho_file.getZigObject().?;
|
||||
switch (linkage) {
|
||||
.internal => {
|
||||
const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index);
|
||||
if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
|
||||
return .{ .mcv = .{ .lea_symbol = sym_index } };
|
||||
},
|
||||
.strong, .weak => {
|
||||
const sym_index = try macho_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
|
||||
switch (linkage) {
|
||||
.internal => unreachable,
|
||||
.strong => {},
|
||||
.weak => zo.symbols.items[sym_index].flags.weak = true,
|
||||
.link_once => unreachable,
|
||||
}
|
||||
if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
|
||||
return .{ .mcv = .{ .lea_symbol = sym_index } };
|
||||
},
|
||||
.link_once => unreachable,
|
||||
}
|
||||
} else if (lf.cast(.coff)) |coff_file| {
|
||||
// TODO audit this
|
||||
switch (linkage) {
|
||||
.internal => {
|
||||
const atom_index = try coff_file.getOrCreateAtomForNav(nav_index);
|
||||
const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
|
||||
return .{ .mcv = .{ .lea_symbol = sym_index } };
|
||||
},
|
||||
.strong, .weak => {
|
||||
const global_index = try coff_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
|
||||
try coff_file.need_got_table.put(zcu.gpa, global_index, {}); // needs GOT
|
||||
return .{ .mcv = .{ .lea_symbol = global_index } };
|
||||
},
|
||||
.link_once => unreachable,
|
||||
}
|
||||
} else if (lf.cast(.plan9)) |p9| {
|
||||
const atom_index = try p9.seeNav(pt, nav_index);
|
||||
const atom = p9.getAtom(atom_index);
|
||||
return .{ .mcv = .{ .memory = atom.getOffsetTableAddress(p9) } };
|
||||
} else {
|
||||
const msg = try ErrorMsg.create(zcu.gpa, src_loc, "TODO genNavRef for target {}", .{target});
|
||||
return .{ .fail = msg };
|
||||
}
|
||||
}
|
||||
|
||||
/// deprecated legacy code path
|
||||
pub fn genTypedValue(
|
||||
lf: *link.File,
|
||||
@@ -1042,30 +1043,28 @@ pub fn genTypedValue(
|
||||
val: Value,
|
||||
target: *const std.Target,
|
||||
) CodeGenError!GenResult {
|
||||
return switch (try lowerValue(pt, val, target)) {
|
||||
const res = try lowerValue(pt, val, target);
|
||||
return switch (res) {
|
||||
.none => .{ .mcv = .none },
|
||||
.undef => .{ .mcv = .undef },
|
||||
.immediate => |imm| .{ .mcv = .{ .immediate = imm } },
|
||||
.lea_nav => |nav| genNavRef(lf, pt, src_loc, nav, target),
|
||||
.lea_uav => |uav| switch (try lf.lowerUav(
|
||||
.lea_nav => |nav| switch (try genNavRef(lf, pt, src_loc, nav, target)) {
|
||||
.sym_index => |sym_index| .{ .mcv = .{ .lea_symbol = sym_index } },
|
||||
.fail => |em| .{ .fail = em },
|
||||
},
|
||||
.load_uav, .lea_uav => |uav| switch (try lf.lowerUav(
|
||||
pt,
|
||||
uav.val,
|
||||
Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu),
|
||||
src_loc,
|
||||
)) {
|
||||
.mcv => |mcv| .{ .mcv = switch (mcv) {
|
||||
.sym_index => |sym_index| .{ .mcv = switch (res) {
|
||||
else => unreachable,
|
||||
.load_direct => |sym_index| .{ .lea_direct = sym_index },
|
||||
.load_symbol => |sym_index| .{ .lea_symbol = sym_index },
|
||||
.load_uav => .{ .load_symbol = sym_index },
|
||||
.lea_uav => .{ .lea_symbol = sym_index },
|
||||
} },
|
||||
.fail => |em| .{ .fail = em },
|
||||
},
|
||||
.load_uav => |uav| lf.lowerUav(
|
||||
pt,
|
||||
uav.val,
|
||||
Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu),
|
||||
src_loc,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1076,8 +1075,8 @@ const LowerResult = union(enum) {
|
||||
/// such as ARM, the immediate will never exceed 32-bits.
|
||||
immediate: u64,
|
||||
lea_nav: InternPool.Nav.Index,
|
||||
lea_uav: InternPool.Key.Ptr.BaseAddr.Uav,
|
||||
load_uav: InternPool.Key.Ptr.BaseAddr.Uav,
|
||||
lea_uav: InternPool.Key.Ptr.BaseAddr.Uav,
|
||||
};
|
||||
|
||||
pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allocator.Error!LowerResult {
|
||||
|
||||
Reference in New Issue
Block a user