diff options
| author | antlilja <liljaanton2001@gmail.com> | 2023-07-31 16:49:19 +0200 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-07-31 15:14:31 -0700 |
| commit | 928d43f61a9b08fd9c83964c34a29cca85839226 (patch) | |
| tree | 41285239ba4d29f2d75aaf44029876d4b212c15c /src/codegen.zig | |
| parent | 33e4cbb20f7cac71e5feaeeeb4c7576ab4708697 (diff) | |
| download | zig-928d43f61a9b08fd9c83964c34a29cca85839226.tar.gz zig-928d43f61a9b08fd9c83964c34a29cca85839226.zip | |
Fix integer overflow in field padding calculation
The old code was iterating and generating symbols
for fields in their declared order instead of the
memory optimized order while getting offsets in
the memory optimized order.
Diffstat (limited to 'src/codegen.zig')
| -rw-r--r-- | src/codegen.zig | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/src/codegen.zig b/src/codegen.zig index 1d83d452b9..c1a956a765 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -513,19 +513,27 @@ pub fn generateSymbol( } } else { const struct_begin = code.items.len; - for (struct_obj.fields.values(), 0..) |field, index| { - const field_ty = field.ty; + const fields = struct_obj.fields.values(); + + var it = typed_value.ty.iterateStructOffsets(mod); + + while (it.next()) |field_offset| { + const field_ty = fields[field_offset.field].ty; + if (!field_ty.hasRuntimeBits(mod)) continue; const field_val = switch (mod.intern_pool.indexToKey(typed_value.val.toIntern()).aggregate.storage) { .bytes => |bytes| try mod.intern_pool.get(mod.gpa, .{ .int = .{ .ty = field_ty.toIntern(), - .storage = .{ .u64 = bytes[index] }, + .storage = .{ .u64 = bytes[field_offset.field] }, } }), - .elems => |elems| elems[index], + .elems => |elems| elems[field_offset.field], .repeated_elem => |elem| elem, }; + const padding = math.cast(usize, field_offset.offset - (code.items.len - struct_begin)) orelse return error.Overflow; + if (padding > 0) try code.appendNTimes(0, padding); + switch (try generateSymbol(bin_file, src_loc, .{ .ty = field_ty, .val = field_val.toValue(), @@ -533,16 +541,10 @@ pub fn generateSymbol( .ok => {}, .fail => |em| return Result{ .fail = em }, } - const unpadded_field_end = code.items.len - struct_begin; - - // Pad struct members if required - const padded_field_end = typed_value.ty.structFieldOffset(index + 1, mod); - const padding = math.cast(usize, padded_field_end - unpadded_field_end) orelse return error.Overflow; - - if (padding > 0) { - try code.appendNTimes(0, padding); - } } + + const padding = math.cast(usize, std.mem.alignForward(u64, it.offset, @max(it.big_align, 1)) - (code.items.len - struct_begin)) orelse return error.Overflow; + if (padding > 0) try code.appendNTimes(0, padding); } }, else => unreachable, |
