From 15ff891f044102ba6515cb07f40805452420ea24 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 2 Feb 2022 00:20:41 +0100 Subject: stage2: pad out (non-packed) struct fields when lowering to bytes * pad out (non-packed) struct fields when lowering to bytes to be saved in the binary - prior to this change, fields would be saved at non-aligned addresses leading to wrong accesses * add a matching test case to `behavior/struct.zig` tests * fix offset to field calculation in `struct_field_ptr` on `x86_64` --- src/codegen.zig | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'src/codegen.zig') diff --git a/src/codegen.zig b/src/codegen.zig index faafe79c13..bcd36358b1 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -373,11 +373,24 @@ pub fn generateSymbol( }, .Struct => { // TODO debug info - // TODO padding of struct members + const struct_obj = typed_value.ty.castTag(.@"struct").?.data; + if (struct_obj.layout == .Packed) { + return Result{ + .fail = try ErrorMsg.create( + bin_file.allocator, + src_loc, + "TODO implement generateSymbol for packed struct", + .{}, + ), + }; + } + + const struct_begin = code.items.len; const field_vals = typed_value.val.castTag(.@"struct").?.data; for (field_vals) |field_val, index| { const field_ty = typed_value.ty.structFieldType(index); if (!field_ty.hasRuntimeBits()) continue; + switch (try generateSymbol(bin_file, src_loc, .{ .ty = field_ty, .val = field_val, @@ -388,6 +401,16 @@ pub fn generateSymbol( }, .fail => |em| return Result{ .fail = em }, } + const unpadded_field_end = code.items.len - struct_begin; + + // Pad struct members if required + const target = bin_file.options.target; + const padded_field_end = typed_value.ty.structFieldOffset(index + 1, target); + const padding = try math.cast(usize, padded_field_end - unpadded_field_end); + + if (padding > 0) { + try code.writer().writeByteNTimes(0, padding); + } } return Result{ .appended = {} }; -- cgit v1.2.3