mirror of
https://github.com/ziglang/zig.git
synced 2026-01-25 16:55:22 +00:00
Merge pull request #2079 from Sahnvour/issue-2050
Fixes c_ABI tests on windows
This commit is contained in:
commit
2fdf69bc40
@ -6699,10 +6699,28 @@ Error file_fetch(CodeGen *g, Buf *resolved_path, Buf *contents) {
|
||||
}
|
||||
}
|
||||
|
||||
X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty) {
|
||||
size_t ty_size = type_size(g, ty);
|
||||
if (get_codegen_ptr_type(ty) != nullptr)
|
||||
return X64CABIClass_INTEGER;
|
||||
static X64CABIClass type_windows_abi_x86_64_class(CodeGen *g, ZigType *ty, size_t ty_size) {
|
||||
// https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017
|
||||
switch (ty->id) {
|
||||
case ZigTypeIdEnum:
|
||||
case ZigTypeIdInt:
|
||||
case ZigTypeIdBool:
|
||||
return X64CABIClass_INTEGER;
|
||||
case ZigTypeIdFloat:
|
||||
case ZigTypeIdVector:
|
||||
return X64CABIClass_SSE;
|
||||
case ZigTypeIdStruct:
|
||||
case ZigTypeIdUnion: {
|
||||
if (ty_size <= 8)
|
||||
return X64CABIClass_INTEGER;
|
||||
return X64CABIClass_MEMORY;
|
||||
}
|
||||
default:
|
||||
return X64CABIClass_Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
static X64CABIClass type_system_V_abi_x86_64_class(CodeGen *g, ZigType *ty, size_t ty_size) {
|
||||
switch (ty->id) {
|
||||
case ZigTypeIdEnum:
|
||||
case ZigTypeIdInt:
|
||||
@ -6770,6 +6788,18 @@ X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty) {
|
||||
}
|
||||
}
|
||||
|
||||
X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty) {
|
||||
const size_t ty_size = type_size(g, ty);
|
||||
if (get_codegen_ptr_type(ty) != nullptr)
|
||||
return X64CABIClass_INTEGER;
|
||||
|
||||
if (g->zig_target->os == OsWindows || g->zig_target->os == OsUefi) {
|
||||
return type_windows_abi_x86_64_class(g, ty, ty_size);
|
||||
} else {
|
||||
return type_system_V_abi_x86_64_class(g, ty, ty_size);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE this does not depend on x86_64
|
||||
bool type_is_c_abi_int(CodeGen *g, ZigType *ty) {
|
||||
return (ty->id == ZigTypeIdInt ||
|
||||
|
||||
@ -372,18 +372,20 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres
|
||||
const frag_vaddr_start = coff_section.header.virtual_address + line_hdr.RelocOffset;
|
||||
const frag_vaddr_end = frag_vaddr_start + line_hdr.CodeSize;
|
||||
|
||||
// There is an unknown number of LineBlockFragmentHeaders (and their accompanying line and column records)
|
||||
// from now on. We will iterate through them, and eventually find a LineInfo that we're interested in,
|
||||
// breaking out to :subsections. If not, we will make sure to not read anything outside of this subsection.
|
||||
const subsection_end_index = sect_offset + subsect_hdr.Length;
|
||||
while (line_index < subsection_end_index) {
|
||||
const block_hdr = @ptrCast(*pdb.LineBlockFragmentHeader, &subsect_info[line_index]);
|
||||
line_index += @sizeOf(pdb.LineBlockFragmentHeader);
|
||||
const start_line_index = line_index;
|
||||
if (relative_address >= frag_vaddr_start and relative_address < frag_vaddr_end) {
|
||||
// There is an unknown number of LineBlockFragmentHeaders (and their accompanying line and column records)
|
||||
// from now on. We will iterate through them, and eventually find a LineInfo that we're interested in,
|
||||
// breaking out to :subsections. If not, we will make sure to not read anything outside of this subsection.
|
||||
|
||||
const has_column = line_hdr.Flags.LF_HaveColumns;
|
||||
const subsection_end_index = sect_offset + subsect_hdr.Length;
|
||||
|
||||
while (line_index < subsection_end_index) {
|
||||
const block_hdr = @ptrCast(*pdb.LineBlockFragmentHeader, &subsect_info[line_index]);
|
||||
line_index += @sizeOf(pdb.LineBlockFragmentHeader);
|
||||
const start_line_index = line_index;
|
||||
|
||||
const has_column = line_hdr.Flags.LF_HaveColumns;
|
||||
|
||||
if (relative_address >= frag_vaddr_start and relative_address < frag_vaddr_end) {
|
||||
// All line entries are stored inside their line block by ascending start address.
|
||||
// Heuristic: we want to find the last line entry that has a vaddr_start <= relative_address.
|
||||
// This is done with a simple linear search.
|
||||
@ -427,11 +429,11 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Checking that we are not reading garbage after the (possibly) multiple block fragments.
|
||||
if (line_index != subsection_end_index) {
|
||||
return error.InvalidDebugInfo;
|
||||
// Checking that we are not reading garbage after the (possibly) multiple block fragments.
|
||||
if (line_index != subsection_end_index) {
|
||||
return error.InvalidDebugInfo;
|
||||
}
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
@ -476,6 +478,11 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres
|
||||
}
|
||||
} else |err| switch (err) {
|
||||
error.EndOfFile => {},
|
||||
error.FileNotFound => {
|
||||
setTtyColor(TtyColor.Dim);
|
||||
try out_stream.write("file not found\n\n");
|
||||
setTtyColor(TtyColor.White);
|
||||
},
|
||||
else => return err,
|
||||
}
|
||||
} else {
|
||||
@ -565,11 +572,12 @@ fn populateModule(di: *DebugInfo, mod: *Module) !void {
|
||||
return;
|
||||
const allocator = getDebugInfoAllocator();
|
||||
|
||||
if (mod.mod_info.C11ByteSize != 0)
|
||||
// At most one can be non-zero.
|
||||
if (mod.mod_info.C11ByteSize != 0 and mod.mod_info.C13ByteSize != 0)
|
||||
return error.InvalidDebugInfo;
|
||||
|
||||
if (mod.mod_info.C13ByteSize == 0)
|
||||
return error.MissingDebugInfo;
|
||||
return;
|
||||
|
||||
const modi = di.pdb.getStreamById(mod.mod_info.ModuleSymStream) orelse return error.MissingDebugInfo;
|
||||
|
||||
@ -881,8 +889,9 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {
|
||||
const obj_file_name = try dbi.readNullTermString(allocator);
|
||||
this_record_len += obj_file_name.len + 1;
|
||||
|
||||
const march_forward_bytes = this_record_len % 4;
|
||||
if (march_forward_bytes != 0) {
|
||||
if (this_record_len % 4 != 0) {
|
||||
const round_to_next_4 = (this_record_len | 0x3) + 1;
|
||||
const march_forward_bytes = round_to_next_4 - this_record_len;
|
||||
try dbi.seekForward(march_forward_bytes);
|
||||
this_record_len += march_forward_bytes;
|
||||
}
|
||||
|
||||
@ -25,9 +25,7 @@ pub fn addCases(cases: *tests.BuildExamplesContext) void {
|
||||
cases.addBuildFile("test/standalone/load_dynamic_library/build.zig");
|
||||
}
|
||||
|
||||
if (!is_windows // TODO support compiling C files on windows with zig build system
|
||||
and builtin.arch == builtin.Arch.x86_64 // TODO add C ABI support for other architectures
|
||||
) {
|
||||
if (builtin.arch == builtin.Arch.x86_64) { // TODO add C ABI support for other architectures
|
||||
cases.addBuildFile("test/stage1/c_abi/build.zig");
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,9 +18,11 @@ void zig_i8(int8_t);
|
||||
void zig_i16(int16_t);
|
||||
void zig_i32(int32_t);
|
||||
void zig_i64(int64_t);
|
||||
void zig_five_integers(int32_t, int32_t, int32_t, int32_t, int32_t);
|
||||
|
||||
void zig_f32(float);
|
||||
void zig_f64(double);
|
||||
void zig_five_floats(float, float, float, float, float);
|
||||
|
||||
void zig_ptr(void *);
|
||||
|
||||
@ -71,9 +73,11 @@ void run_c_tests(void) {
|
||||
zig_i16(-2);
|
||||
zig_i32(-3);
|
||||
zig_i64(-4);
|
||||
zig_five_integers(12, 34, 56, 78, 90);
|
||||
|
||||
zig_f32(12.34f);
|
||||
zig_f64(56.78);
|
||||
zig_five_floats(1.0f, 2.0f, 3.0f, 4.0f, 5.0f);
|
||||
|
||||
zig_ptr((void*)0xdeadbeefL);
|
||||
|
||||
@ -156,6 +160,22 @@ void c_bool(bool x) {
|
||||
assert_or_panic(x);
|
||||
}
|
||||
|
||||
void c_five_integers(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e) {
|
||||
assert_or_panic(a == 12);
|
||||
assert_or_panic(b == 34);
|
||||
assert_or_panic(c == 56);
|
||||
assert_or_panic(d == 78);
|
||||
assert_or_panic(e == 90);
|
||||
}
|
||||
|
||||
void c_five_floats(float a, float b, float c, float d, float e) {
|
||||
assert_or_panic(a == 1.0);
|
||||
assert_or_panic(b == 2.0);
|
||||
assert_or_panic(c == 3.0);
|
||||
assert_or_panic(d == 4.0);
|
||||
assert_or_panic(e == 5.0);
|
||||
}
|
||||
|
||||
void c_array(uint8_t x[10]) {
|
||||
assert_or_panic(x[0] == '1');
|
||||
assert_or_panic(x[1] == '2');
|
||||
|
||||
@ -20,6 +20,17 @@ extern fn c_i16(i16) void;
|
||||
extern fn c_i32(i32) void;
|
||||
extern fn c_i64(i64) void;
|
||||
|
||||
// On windows x64, the first 4 are passed via registers, others on the stack.
|
||||
extern fn c_five_integers(i32, i32, i32, i32, i32) void;
|
||||
|
||||
export fn zig_five_integers(a: i32, b: i32, c: i32, d: i32, e: i32) void {
|
||||
expect(a == 12);
|
||||
expect(b == 34);
|
||||
expect(c == 56);
|
||||
expect(d == 78);
|
||||
expect(e == 90);
|
||||
}
|
||||
|
||||
test "C ABI integers" {
|
||||
c_u8(0xff);
|
||||
c_u16(0xfffe);
|
||||
@ -30,6 +41,7 @@ test "C ABI integers" {
|
||||
c_i16(-2);
|
||||
c_i32(-3);
|
||||
c_i64(-4);
|
||||
c_five_integers(12, 34, 56, 78, 90);
|
||||
}
|
||||
|
||||
export fn zig_u8(x: u8) void {
|
||||
@ -60,9 +72,21 @@ export fn zig_i64(x: i64) void {
|
||||
extern fn c_f32(f32) void;
|
||||
extern fn c_f64(f64) void;
|
||||
|
||||
// On windows x64, the first 4 are passed via registers, others on the stack.
|
||||
extern fn c_five_floats(f32, f32, f32, f32, f32) void;
|
||||
|
||||
export fn zig_five_floats(a: f32, b: f32, c: f32, d: f32, e: f32) void {
|
||||
expect(a == 1.0);
|
||||
expect(b == 2.0);
|
||||
expect(c == 3.0);
|
||||
expect(d == 4.0);
|
||||
expect(e == 5.0);
|
||||
}
|
||||
|
||||
test "C ABI floats" {
|
||||
c_f32(12.34);
|
||||
c_f64(56.78);
|
||||
c_five_floats(1.0, 2.0, 3.0, 4.0, 5.0);
|
||||
}
|
||||
|
||||
export fn zig_f32(x: f32) void {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user