diff options
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 7 | ||||
| -rw-r--r-- | src/codegen.zig | 7 | ||||
| -rw-r--r-- | src/link.zig | 10 | ||||
| -rw-r--r-- | src/link/Coff.zig | 28 | ||||
| -rw-r--r-- | src/link/Elf.zig | 21 | ||||
| -rw-r--r-- | src/link/MachO.zig | 22 | ||||
| -rw-r--r-- | src/link/Wasm.zig | 35 |
7 files changed, 73 insertions, 57 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 639af3d8c4..83ab118ac5 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -3153,11 +3153,8 @@ fn lowerAnonDeclRef( return WValue{ .imm32 = 0xaaaaaaaa }; } - const alignment = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment; - if (alignment != .none) { - @panic("TODO how to make this anon decl be aligned?"); - } - const res = try func.bin_file.lowerAnonDecl(decl_val, func.decl.srcLoc(mod)); + const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment; + const res = try func.bin_file.lowerAnonDecl(decl_val, decl_align, func.decl.srcLoc(mod)); switch (res) { .ok => {}, .fail => |em| { diff --git a/src/codegen.zig b/src/codegen.zig index d7a5666986..fe948d18bd 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -731,16 +731,13 @@ fn lowerAnonDeclRef( return Result.ok; } - const res = try bin_file.lowerAnonDecl(decl_val, src_loc); + const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment; + const res = try bin_file.lowerAnonDecl(decl_val, decl_align, src_loc); switch (res) { .ok => {}, .fail => |em| return .{ .fail = em }, } - const alignment = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment; - if (alignment != .none) { - @panic("TODO how to make this anon decl be aligned?"); - } const vaddr = try bin_file.getAnonDeclVAddr(decl_val, .{ .parent_atom_index = reloc_info.parent_atom_index, .offset = code.items.len, diff --git a/src/link.zig b/src/link.zig index 9c79de290d..6e5c809f62 100644 --- a/src/link.zig +++ b/src/link.zig @@ -940,15 +940,15 @@ pub const File = struct { pub const LowerResult = @import("codegen.zig").Result; - pub fn lowerAnonDecl(base: *File, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !LowerResult { + pub fn lowerAnonDecl(base: *File, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !LowerResult { if (build_options.only_c) unreachable; switch (base.tag) { - .coff => return @fieldParentPtr(Coff, "base", base).lowerAnonDecl(decl_val, src_loc), - .elf => return @fieldParentPtr(Elf, "base", base).lowerAnonDecl(decl_val, src_loc), - .macho => return @fieldParentPtr(MachO, "base", base).lowerAnonDecl(decl_val, src_loc), + .coff => return @fieldParentPtr(Coff, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc), + .elf => return @fieldParentPtr(Elf, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc), + .macho => return @fieldParentPtr(MachO, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc), .plan9 => return @fieldParentPtr(Plan9, "base", base).lowerAnonDecl(decl_val, src_loc), .c => unreachable, - .wasm => return @fieldParentPtr(Wasm, "base", base).lowerAnonDecl(decl_val, src_loc), + .wasm => return @fieldParentPtr(Wasm, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc), .spirv => unreachable, .nvptx => unreachable, } diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 94b3c63741..35f0b84411 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -1091,7 +1091,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In const index = unnamed_consts.items.len; const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index }); defer gpa.free(sym_name); - const atom_index = switch (try self.lowerConst(sym_name, tv, self.rdata_section_index.?, decl.srcLoc(mod))) { + const atom_index = switch (try self.lowerConst(sym_name, tv, tv.ty.abiAlignment(mod), self.rdata_section_index.?, decl.srcLoc(mod))) { .ok => |atom_index| atom_index, .fail => |em| { decl.analysis = .codegen_failure; @@ -1109,13 +1109,12 @@ const LowerConstResult = union(enum) { fail: *Module.ErrorMsg, }; -fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, sect_id: u16, src_loc: Module.SrcLoc) !LowerConstResult { +fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, required_alignment: InternPool.Alignment, sect_id: u16, src_loc: Module.SrcLoc) !LowerConstResult { const gpa = self.base.allocator; var code_buffer = std.ArrayList(u8).init(gpa); defer code_buffer.deinit(); - const mod = self.base.options.module.?; const atom_index = try self.createAtom(); const sym = self.getAtom(atom_index).getSymbolPtr(self); try self.setSymbolName(sym, name); @@ -1129,10 +1128,13 @@ fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, sect_id: u16, src_l .fail => |em| return .{ .fail = em }, }; - const required_alignment: u32 = @intCast(tv.ty.abiAlignment(mod).toByteUnits(0)); const atom = self.getAtomPtr(atom_index); atom.size = @as(u32, @intCast(code.len)); - atom.getSymbolPtr(self).value = try self.allocateAtom(atom_index, atom.size, required_alignment); + atom.getSymbolPtr(self).value = try self.allocateAtom( + atom_index, + atom.size, + @intCast(required_alignment.toByteUnitsOptional().?), + ); errdefer self.freeAtom(atom_index); log.debug("allocated atom for {s} at 0x{x}", .{ name, atom.getSymbol(self).value }); @@ -1736,7 +1738,7 @@ pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link return 0; } -pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result { +pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result { // This is basically the same as lowerUnnamedConst. // example: // const ty = mod.intern_pool.typeOf(decl_val).toType(); @@ -1747,15 +1749,21 @@ pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, src_loc: Module.Sr // to put it in some location. // ... const gpa = self.base.allocator; + const mod = self.base.options.module.?; + const ty = mod.intern_pool.typeOf(decl_val).toType(); const gop = try self.anon_decls.getOrPut(gpa, decl_val); - if (!gop.found_existing) { - const mod = self.base.options.module.?; - const ty = mod.intern_pool.typeOf(decl_val).toType(); + const required_alignment = switch (decl_align) { + .none => ty.abiAlignment(mod), + else => decl_align, + }; + if (!gop.found_existing or + !required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).value)) + { const val = decl_val.toValue(); const tv = TypedValue{ .ty = ty, .val = val }; const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)}); defer gpa.free(name); - const res = self.lowerConst(name, tv, self.rdata_section_index.?, src_loc) catch |err| switch (err) { + const res = self.lowerConst(name, tv, required_alignment, self.rdata_section_index.?, src_loc) catch |err| switch (err) { else => { // TODO improve error message const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{ diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 2d16cd03e9..738d648ebe 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -473,7 +473,7 @@ pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link. return vaddr; } -pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result { +pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result { // This is basically the same as lowerUnnamedConst. // example: // const ty = mod.intern_pool.typeOf(decl_val).toType(); @@ -484,15 +484,21 @@ pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, src_loc: Module.Src // to put it in some location. // ... const gpa = self.base.allocator; + const mod = self.base.options.module.?; + const ty = mod.intern_pool.typeOf(decl_val).toType(); const gop = try self.anon_decls.getOrPut(gpa, decl_val); - if (!gop.found_existing) { - const mod = self.base.options.module.?; - const ty = mod.intern_pool.typeOf(decl_val).toType(); + const required_alignment = switch (decl_align) { + .none => ty.abiAlignment(mod), + else => decl_align, + }; + if (!gop.found_existing or + required_alignment.order(self.symbol(gop.value_ptr.*).atom(self).?.alignment).compare(.gt)) + { const val = decl_val.toValue(); const tv = TypedValue{ .ty = ty, .val = val }; const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)}); defer gpa.free(name); - const res = self.lowerConst(name, tv, self.zig_rodata_section_index.?, src_loc) catch |err| switch (err) { + const res = self.lowerConst(name, tv, required_alignment, self.zig_rodata_section_index.?, src_loc) catch |err| switch (err) { else => { // TODO improve error message const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{ @@ -3479,7 +3485,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module const index = unnamed_consts.items.len; const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index }); defer gpa.free(name); - const sym_index = switch (try self.lowerConst(name, typed_value, self.zig_rodata_section_index.?, decl.srcLoc(mod))) { + const sym_index = switch (try self.lowerConst(name, typed_value, typed_value.ty.abiAlignment(mod), self.zig_rodata_section_index.?, decl.srcLoc(mod))) { .ok => |sym_index| sym_index, .fail => |em| { decl.analysis = .codegen_failure; @@ -3502,6 +3508,7 @@ fn lowerConst( self: *Elf, name: []const u8, tv: TypedValue, + required_alignment: InternPool.Alignment, output_section_index: u16, src_loc: Module.SrcLoc, ) !LowerConstResult { @@ -3510,7 +3517,6 @@ fn lowerConst( var code_buffer = std.ArrayList(u8).init(gpa); defer code_buffer.deinit(); - const mod = self.base.options.module.?; const zig_module = self.file(self.zig_module_index.?).?.zig_module; const sym_index = try zig_module.addAtom(self); @@ -3524,7 +3530,6 @@ fn lowerConst( .fail => |em| return .{ .fail = em }, }; - const required_alignment = tv.ty.abiAlignment(mod); const phdr_index = self.phdr_to_shdr_table.get(output_section_index).?; const local_sym = self.symbol(sym_index); const name_str_index = try self.strtab.insert(gpa, name); diff --git a/src/link/MachO.zig b/src/link/MachO.zig index cc537cdd72..eb82de7374 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -2196,7 +2196,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu const index = unnamed_consts.items.len; const name = try std.fmt.allocPrint(gpa, "___unnamed_{s}_{d}", .{ decl_name, index }); defer gpa.free(name); - const atom_index = switch (try self.lowerConst(name, typed_value, self.data_const_section_index.?, decl.srcLoc(mod))) { + const atom_index = switch (try self.lowerConst(name, typed_value, typed_value.ty.abiAlignment(mod), self.data_const_section_index.?, decl.srcLoc(mod))) { .ok => |atom_index| atom_index, .fail => |em| { decl.analysis = .codegen_failure; @@ -2219,6 +2219,7 @@ fn lowerConst( self: *MachO, name: []const u8, tv: TypedValue, + required_alignment: InternPool.Alignment, sect_id: u8, src_loc: Module.SrcLoc, ) !LowerConstResult { @@ -2227,8 +2228,6 @@ fn lowerConst( var code_buffer = std.ArrayList(u8).init(gpa); defer code_buffer.deinit(); - const mod = self.base.options.module.?; - log.debug("allocating symbol indexes for {s}", .{name}); const sym_index = try self.allocateSymbol(); @@ -2243,7 +2242,6 @@ fn lowerConst( .fail => |em| return .{ .fail = em }, }; - const required_alignment = tv.ty.abiAlignment(mod); const atom = self.getAtomPtr(atom_index); atom.size = code.len; // TODO: work out logic for disambiguating functions from function pointers @@ -2868,7 +2866,7 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil return 0; } -pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result { +pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result { // This is basically the same as lowerUnnamedConst. // example: // const ty = mod.intern_pool.typeOf(decl_val).toType(); @@ -2879,15 +2877,21 @@ pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, src_loc: Module.S // to put it in some location. // ... const gpa = self.base.allocator; + const mod = self.base.options.module.?; + const ty = mod.intern_pool.typeOf(decl_val).toType(); const gop = try self.anon_decls.getOrPut(gpa, decl_val); - if (!gop.found_existing) { - const mod = self.base.options.module.?; - const ty = mod.intern_pool.typeOf(decl_val).toType(); + const required_alignment = switch (decl_align) { + .none => ty.abiAlignment(mod), + else => decl_align, + }; + if (!gop.found_existing or + !required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).n_value)) + { const val = decl_val.toValue(); const tv = TypedValue{ .ty = ty, .val = val }; const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)}); defer gpa.free(name); - const res = self.lowerConst(name, tv, self.data_const_section_index.?, src_loc) catch |err| switch (err) { + const res = self.lowerConst(name, tv, required_alignment, self.data_const_section_index.?, src_loc) catch |err| switch (err) { else => { // TODO improve error message const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{ diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index fc827b23eb..f138cdc3e2 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -1702,25 +1702,30 @@ pub fn getDeclVAddr( return target_symbol_index; } -pub fn lowerAnonDecl(wasm: *Wasm, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result { +pub fn lowerAnonDecl(wasm: *Wasm, decl_val: InternPool.Index, decl_align: Alignment, src_loc: Module.SrcLoc) !codegen.Result { const gop = try wasm.anon_decls.getOrPut(wasm.base.allocator, decl_val); - if (gop.found_existing) { - return .ok; - } + if (!gop.found_existing) { + const mod = wasm.base.options.module.?; + const ty = mod.intern_pool.typeOf(decl_val).toType(); + const tv: TypedValue = .{ .ty = ty, .val = decl_val.toValue() }; + const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__anon_{d}", .{@intFromEnum(decl_val)}); + defer wasm.base.allocator.free(name); - const mod = wasm.base.options.module.?; - const ty = mod.intern_pool.typeOf(decl_val).toType(); - const tv: TypedValue = .{ .ty = ty, .val = decl_val.toValue() }; - const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__anon_{d}", .{@intFromEnum(decl_val)}); - defer wasm.base.allocator.free(name); + switch (try wasm.lowerConst(name, tv, src_loc)) { + .ok => |atom_index| gop.value_ptr.* = atom_index, + .fail => |em| return .{ .fail = em }, + } + } - switch (try wasm.lowerConst(name, tv, src_loc)) { - .ok => |atom_index| { - gop.value_ptr.* = atom_index; - return .ok; + const atom = wasm.getAtomPtr(gop.value_ptr.*); + atom.alignment = switch (atom.alignment) { + .none => decl_align, + else => switch (decl_align) { + .none => atom.alignment, + else => atom.alignment.maxStrict(decl_align), }, - .fail => |em| return .{ .fail = em }, - } + }; + return .ok; } pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { |
