mirror of
https://github.com/ziglang/zig.git
synced 2026-01-07 14:03:26 +00:00
parent
c71b78eb01
commit
fe8bdf6f04
@ -1705,7 +1705,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
|
||||
lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)),
|
||||
error.Overflow => {
|
||||
error.Overflow, error.RelocationNotByteAligned => {
|
||||
try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
|
||||
gpa,
|
||||
zcu.navSrcLoc(nav_index),
|
||||
@ -3131,7 +3131,7 @@ pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error
|
||||
lf.updateNav(pt, nav_index) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)),
|
||||
error.Overflow => {
|
||||
error.Overflow, error.RelocationNotByteAligned => {
|
||||
try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
|
||||
gpa,
|
||||
zcu.navSrcLoc(nav_index),
|
||||
|
||||
@ -23,10 +23,7 @@ const Zir = std.zig.Zir;
|
||||
const Alignment = InternPool.Alignment;
|
||||
const dev = @import("dev.zig");
|
||||
|
||||
pub const CodeGenError = error{
|
||||
OutOfMemory,
|
||||
/// Compiler was asked to operate on a number larger than supported.
|
||||
Overflow,
|
||||
pub const CodeGenError = GenerateSymbolError || error{
|
||||
/// Indicates the error is already stored in Zcu `failed_codegen`.
|
||||
CodegenFail,
|
||||
};
|
||||
@ -177,6 +174,8 @@ pub const GenerateSymbolError = error{
|
||||
OutOfMemory,
|
||||
/// Compiler was asked to operate on a number larger than supported.
|
||||
Overflow,
|
||||
/// Compiler was asked to produce a non-byte-aligned relocation.
|
||||
RelocationNotByteAligned,
|
||||
};
|
||||
|
||||
pub fn generateSymbol(
|
||||
@ -481,12 +480,18 @@ pub fn generateSymbol(
|
||||
// pointer may point to a decl which must be marked used
|
||||
// but can also result in a relocation. Therefore we handle those separately.
|
||||
if (Type.fromInterned(field_ty).zigTypeTag(zcu) == .pointer) {
|
||||
const field_size = math.cast(usize, Type.fromInterned(field_ty).abiSize(zcu)) orelse
|
||||
return error.Overflow;
|
||||
var tmp_list = try std.ArrayListUnmanaged(u8).initCapacity(gpa, field_size);
|
||||
defer tmp_list.deinit(gpa);
|
||||
try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, reloc_parent);
|
||||
@memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items);
|
||||
const field_offset = std.math.divExact(u16, bits, 8) catch |err| switch (err) {
|
||||
error.DivisionByZero => unreachable,
|
||||
error.UnexpectedRemainder => return error.RelocationNotByteAligned,
|
||||
};
|
||||
code.items.len = current_pos + field_offset;
|
||||
// TODO: code.lockPointers();
|
||||
defer {
|
||||
assert(code.items.len == current_pos + field_offset + @divExact(target.ptrBitWidth(), 8));
|
||||
// TODO: code.unlockPointers();
|
||||
code.items.len = current_pos + abi_size;
|
||||
}
|
||||
try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent);
|
||||
} else {
|
||||
Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), pt, code.items[current_pos..], bits) catch unreachable;
|
||||
}
|
||||
|
||||
11
src/link.zig
11
src/link.zig
@ -26,6 +26,7 @@ const Package = @import("Package.zig");
|
||||
const dev = @import("dev.zig");
|
||||
const ThreadSafeQueue = @import("ThreadSafeQueue.zig").ThreadSafeQueue;
|
||||
const target_util = @import("target.zig");
|
||||
const codegen = @import("codegen.zig");
|
||||
|
||||
pub const LdScript = @import("link/LdScript.zig");
|
||||
|
||||
@ -683,13 +684,7 @@ pub const File = struct {
|
||||
|
||||
/// Note that `LinkFailure` is not a member of this error set because the error message
|
||||
/// must be attached to `Zcu.failed_codegen` rather than `Compilation.link_diags`.
|
||||
pub const UpdateNavError = error{
|
||||
Overflow,
|
||||
OutOfMemory,
|
||||
/// Indicates the error is already reported and stored in
|
||||
/// `failed_codegen` on the Zcu.
|
||||
CodegenFail,
|
||||
};
|
||||
pub const UpdateNavError = codegen.CodeGenError;
|
||||
|
||||
/// Called from within CodeGen to retrieve the symbol index of a global symbol.
|
||||
/// If no symbol exists yet with this name, a new undefined global symbol will
|
||||
@ -920,7 +915,7 @@ pub const File = struct {
|
||||
decl_val: InternPool.Index,
|
||||
decl_align: InternPool.Alignment,
|
||||
src_loc: Zcu.LazySrcLoc,
|
||||
) !@import("codegen.zig").GenResult {
|
||||
) !codegen.GenResult {
|
||||
switch (base.tag) {
|
||||
.c => unreachable,
|
||||
.spirv => unreachable,
|
||||
|
||||
@ -1134,7 +1134,7 @@ pub fn updateFunc(
|
||||
) catch |err| switch (err) {
|
||||
error.CodegenFail => return error.CodegenFail,
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.Overflow => |e| {
|
||||
error.Overflow, error.RelocationNotByteAligned => |e| {
|
||||
try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create(
|
||||
gpa,
|
||||
zcu.navSrcLoc(nav_index),
|
||||
|
||||
@ -23,12 +23,11 @@ debug_str: StringSection,
|
||||
pub const UpdateError = error{
|
||||
ReinterpretDeclRef,
|
||||
Unimplemented,
|
||||
OutOfMemory,
|
||||
EndOfStream,
|
||||
Overflow,
|
||||
Underflow,
|
||||
UnexpectedEndOfFile,
|
||||
} ||
|
||||
codegen.GenerateSymbolError ||
|
||||
std.fs.File.OpenError ||
|
||||
std.fs.File.SetEndPosError ||
|
||||
std.fs.File.CopyRangeError ||
|
||||
|
||||
@ -1090,7 +1090,9 @@ fn updateLazySymbolAtom(
|
||||
) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.CodegenFail => return error.LinkFailure,
|
||||
error.Overflow => return diags.fail("codegen failure: encountered number too big for compiler", .{}),
|
||||
error.Overflow,
|
||||
error.RelocationNotByteAligned,
|
||||
=> return diags.fail("unable to codegen: {s}", .{@errorName(err)}),
|
||||
};
|
||||
const code = code_buffer.items;
|
||||
// duped_code is freed when the atom is freed
|
||||
|
||||
@ -14,14 +14,7 @@ const link = @import("link.zig");
|
||||
|
||||
const log = std.log.scoped(.register_manager);
|
||||
|
||||
pub const AllocationError = error{
|
||||
OutOfRegisters,
|
||||
OutOfMemory,
|
||||
/// Compiler was asked to operate on a number larger than supported.
|
||||
Overflow,
|
||||
/// Indicates the error is already stored in `failed_codegen` on the Zcu.
|
||||
CodegenFail,
|
||||
};
|
||||
pub const AllocationError = @import("codegen.zig").CodeGenError || error{OutOfRegisters};
|
||||
|
||||
pub fn RegisterManager(
|
||||
comptime Function: type,
|
||||
|
||||
@ -1349,3 +1349,17 @@ test "assign packed struct initialized with RLS to packed struct literal field"
|
||||
try expect(outer.inner.x == x);
|
||||
try expect(outer.x == x);
|
||||
}
|
||||
|
||||
test "byte-aligned packed relocation" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
var global: u8 align(2) = 0;
|
||||
var packed_value: packed struct { x: u8, y: *align(2) u8 } = .{ .x = 111, .y = &global };
|
||||
};
|
||||
try expect(S.packed_value.x == 111);
|
||||
try expect(S.packed_value.y == &S.global);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user