| author | |
| committer | |
| log | 98646e5cf8a59e5a7d47eaf863d57ad26313c61c |
| tree | 2798cabc394f95dfd1b4ae569b3bbb0baaf3cec8 |
| parent | b6d904624296dc5c60c34d8613d6c261e60328cf |
| parent | bcf387f0b9e3911ade500313dc1624b67a011619 |
| signature |
link: support static archives that are linker scripts6 files changed, 103 insertions(+), 102 deletions(-)
src/link.zig+11-11| ... | @@ -2294,9 +2294,10 @@ fn resolvePathInputLib( | ... | @@ -2294,9 +2294,10 @@ fn resolvePathInputLib( |
| 2294 | const test_path: Path = pq.path; | 2294 | const test_path: Path = pq.path; |
| 2295 | // In the case of shared libraries, they might actually be "linker scripts" | 2295 | // In the case of shared libraries, they might actually be "linker scripts" |
| 2296 | // that contain references to other libraries. | 2296 | // that contain references to other libraries. |
| 2297 | if (pq.query.allow_so_scripts and target.ofmt == .elf and | 2297 | if (pq.query.allow_so_scripts and target.ofmt == .elf and switch (Compilation.classifyFileExt(test_path.sub_path)) { |
| 2298 | Compilation.classifyFileExt(test_path.sub_path) == .shared_library) | 2298 | .static_library, .shared_library => true, |
| 2299 | { | 2299 | else => false, |
| 2300 | }) { | ||
| 2300 | var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) { | 2301 | var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) { |
| 2301 | error.FileNotFound => return .no_match, | 2302 | error.FileNotFound => return .no_match, |
| 2302 | else => |e| fatal("unable to search for {s} library '{'}': {s}", .{ | 2303 | else => |e| fatal("unable to search for {s} library '{'}': {s}", .{ |
| ... | @@ -2304,14 +2305,13 @@ fn resolvePathInputLib( | ... | @@ -2304,14 +2305,13 @@ fn resolvePathInputLib( |
| 2304 | }), | 2305 | }), |
| 2305 | }; | 2306 | }; |
| 2306 | errdefer file.close(); | 2307 | errdefer file.close(); |
| 2307 | try ld_script_bytes.resize(gpa, @sizeOf(std.elf.Elf64_Ehdr)); | 2308 | try ld_script_bytes.resize(gpa, @max(std.elf.MAGIC.len, std.elf.ARMAG.len)); |
| 2308 | const n = file.preadAll(ld_script_bytes.items, 0) catch |err| fatal("failed to read '{'}': {s}", .{ | 2309 | const n = file.preadAll(ld_script_bytes.items, 0) catch |err| fatal("failed to read '{'}': {s}", .{ |
| 2309 | test_path, @errorName(err), | 2310 | test_path, @errorName(err), |
| 2310 | }); | 2311 | }); |
| 2311 | elf_file: { | 2312 | const buf = ld_script_bytes.items[0..n]; |
| 2312 | if (n != ld_script_bytes.items.len) break :elf_file; | 2313 | if (mem.startsWith(u8, buf, std.elf.MAGIC) or mem.startsWith(u8, buf, std.elf.ARMAG)) { |
| 2313 | if (!mem.eql(u8, ld_script_bytes.items[0..4], "\x7fELF")) break :elf_file; | 2314 | // Appears to be an ELF or archive file. |
| 2314 | // Appears to be an ELF file. | ||
| 2315 | return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query); | 2315 | return finishResolveLibInput(resolved_inputs, test_path, file, link_mode, pq.query); |
| 2316 | } | 2316 | } |
| 2317 | const stat = file.stat() catch |err| | 2317 | const stat = file.stat() catch |err| |
| ... | @@ -2319,10 +2319,10 @@ fn resolvePathInputLib( | ... | @@ -2319,10 +2319,10 @@ fn resolvePathInputLib( |
| 2319 | const size = std.math.cast(u32, stat.size) orelse | 2319 | const size = std.math.cast(u32, stat.size) orelse |
| 2320 | fatal("{}: linker script too big", .{test_path}); | 2320 | fatal("{}: linker script too big", .{test_path}); |
| 2321 | try ld_script_bytes.resize(gpa, size); | 2321 | try ld_script_bytes.resize(gpa, size); |
| 2322 | const buf = ld_script_bytes.items[n..]; | 2322 | const buf2 = ld_script_bytes.items[n..]; |
| 2323 | const n2 = file.preadAll(buf, n) catch |err| | 2323 | const n2 = file.preadAll(buf2, n) catch |err| |
| 2324 | fatal("failed to read {}: {s}", .{ test_path, @errorName(err) }); | 2324 | fatal("failed to read {}: {s}", .{ test_path, @errorName(err) }); |
| 2325 | if (n2 != buf.len) fatal("failed to read {}: unexpected end of file", .{test_path}); | 2325 | if (n2 != buf2.len) fatal("failed to read {}: unexpected end of file", .{test_path}); |
| 2326 | var diags = Diags.init(gpa); | 2326 | var diags = Diags.init(gpa); |
| 2327 | defer diags.deinit(); | 2327 | defer diags.deinit(); |
| 2328 | const ld_script_result = LdScript.parse(gpa, &diags, test_path, ld_script_bytes.items); | 2328 | const ld_script_result = LdScript.parse(gpa, &diags, test_path, ld_script_bytes.items); |
src/link/Elf.zig+20-19| ... | @@ -99,7 +99,7 @@ copy_rel: CopyRelSection = .{}, | ... | @@ -99,7 +99,7 @@ copy_rel: CopyRelSection = .{}, |
| 99 | rela_plt: std.ArrayListUnmanaged(elf.Elf64_Rela) = .empty, | 99 | rela_plt: std.ArrayListUnmanaged(elf.Elf64_Rela) = .empty, |
| 100 | /// SHT_GROUP sections | 100 | /// SHT_GROUP sections |
| 101 | /// Applies only to a relocatable. | 101 | /// Applies only to a relocatable. |
| 102 | comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .empty, | 102 | group_sections: std.ArrayListUnmanaged(GroupSection) = .empty, |
| 103 | 103 | ||
| 104 | resolver: SymbolResolver = .{}, | 104 | resolver: SymbolResolver = .{}, |
| 105 | 105 | ||
| ... | @@ -510,7 +510,7 @@ pub fn deinit(self: *Elf) void { | ... | @@ -510,7 +510,7 @@ pub fn deinit(self: *Elf) void { |
| 510 | self.copy_rel.deinit(gpa); | 510 | self.copy_rel.deinit(gpa); |
| 511 | self.rela_dyn.deinit(gpa); | 511 | self.rela_dyn.deinit(gpa); |
| 512 | self.rela_plt.deinit(gpa); | 512 | self.rela_plt.deinit(gpa); |
| 513 | self.comdat_group_sections.deinit(gpa); | 513 | self.group_sections.deinit(gpa); |
| 514 | self.dump_argv_list.deinit(gpa); | 514 | self.dump_argv_list.deinit(gpa); |
| 515 | } | 515 | } |
| 516 | 516 | ||
| ... | @@ -919,7 +919,7 @@ fn flushModuleInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { | ... | @@ -919,7 +919,7 @@ fn flushModuleInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { |
| 919 | &self.sections, | 919 | &self.sections, |
| 920 | self.shstrtab.items, | 920 | self.shstrtab.items, |
| 921 | self.merge_sections.items, | 921 | self.merge_sections.items, |
| 922 | self.comdat_group_sections.items, | 922 | self.group_sections.items, |
| 923 | self.zigObjectPtr(), | 923 | self.zigObjectPtr(), |
| 924 | self.files, | 924 | self.files, |
| 925 | ); | 925 | ); |
| ... | @@ -1315,16 +1315,16 @@ pub fn resolveSymbols(self: *Elf) !void { | ... | @@ -1315,16 +1315,16 @@ pub fn resolveSymbols(self: *Elf) !void { |
| 1315 | } | 1315 | } |
| 1316 | 1316 | ||
| 1317 | { | 1317 | { |
| 1318 | // Dedup comdat groups. | 1318 | // Dedup groups. |
| 1319 | var table = std.StringHashMap(Ref).init(self.base.comp.gpa); | 1319 | var table = std.StringHashMap(Ref).init(self.base.comp.gpa); |
| 1320 | defer table.deinit(); | 1320 | defer table.deinit(); |
| 1321 | 1321 | ||
| 1322 | for (self.objects.items) |index| { | 1322 | for (self.objects.items) |index| { |
| 1323 | try self.file(index).?.object.resolveComdatGroups(self, &table); | 1323 | try self.file(index).?.object.resolveGroups(self, &table); |
| 1324 | } | 1324 | } |
| 1325 | 1325 | ||
| 1326 | for (self.objects.items) |index| { | 1326 | for (self.objects.items) |index| { |
| 1327 | self.file(index).?.object.markComdatGroupsDead(self); | 1327 | self.file(index).?.object.markGroupsDead(self); |
| 1328 | } | 1328 | } |
| 1329 | } | 1329 | } |
| 1330 | 1330 | ||
| ... | @@ -3125,7 +3125,7 @@ pub fn sortShdrs( | ... | @@ -3125,7 +3125,7 @@ pub fn sortShdrs( |
| 3125 | sections: *std.MultiArrayList(Section), | 3125 | sections: *std.MultiArrayList(Section), |
| 3126 | shstrtab: []const u8, | 3126 | shstrtab: []const u8, |
| 3127 | merge_sections: []Merge.Section, | 3127 | merge_sections: []Merge.Section, |
| 3128 | comdat_group_sections: []ComdatGroupSection, | 3128 | comdat_group_sections: []GroupSection, |
| 3129 | zig_object_ptr: ?*ZigObject, | 3129 | zig_object_ptr: ?*ZigObject, |
| 3130 | files: std.MultiArrayList(File.Entry), | 3130 | files: std.MultiArrayList(File.Entry), |
| 3131 | ) !void { | 3131 | ) !void { |
| ... | @@ -4446,8 +4446,8 @@ pub fn atom(self: *Elf, ref: Ref) ?*Atom { | ... | @@ -4446,8 +4446,8 @@ pub fn atom(self: *Elf, ref: Ref) ?*Atom { |
| 4446 | return file_ptr.atom(ref.index); | 4446 | return file_ptr.atom(ref.index); |
| 4447 | } | 4447 | } |
| 4448 | 4448 | ||
| 4449 | pub fn comdatGroup(self: *Elf, ref: Ref) *ComdatGroup { | 4449 | pub fn group(self: *Elf, ref: Ref) *Group { |
| 4450 | return self.file(ref.file).?.comdatGroup(ref.index); | 4450 | return self.file(ref.file).?.group(ref.index); |
| 4451 | } | 4451 | } |
| 4452 | 4452 | ||
| 4453 | pub fn symbol(self: *Elf, ref: Ref) ?*Symbol { | 4453 | pub fn symbol(self: *Elf, ref: Ref) ?*Symbol { |
| ... | @@ -4814,7 +4814,7 @@ fn fmtDumpState( | ... | @@ -4814,7 +4814,7 @@ fn fmtDumpState( |
| 4814 | object.fmtCies(self), | 4814 | object.fmtCies(self), |
| 4815 | object.fmtFdes(self), | 4815 | object.fmtFdes(self), |
| 4816 | object.fmtSymtab(self), | 4816 | object.fmtSymtab(self), |
| 4817 | object.fmtComdatGroups(self), | 4817 | object.fmtGroups(self), |
| 4818 | }); | 4818 | }); |
| 4819 | } | 4819 | } |
| 4820 | 4820 | ||
| ... | @@ -4852,9 +4852,9 @@ fn fmtDumpState( | ... | @@ -4852,9 +4852,9 @@ fn fmtDumpState( |
| 4852 | try writer.print("{}\n", .{self.got.fmt(self)}); | 4852 | try writer.print("{}\n", .{self.got.fmt(self)}); |
| 4853 | try writer.print("{}\n", .{self.plt.fmt(self)}); | 4853 | try writer.print("{}\n", .{self.plt.fmt(self)}); |
| 4854 | 4854 | ||
| 4855 | try writer.writeAll("Output COMDAT groups\n"); | 4855 | try writer.writeAll("Output groups\n"); |
| 4856 | for (self.comdat_group_sections.items) |cg| { | 4856 | for (self.group_sections.items) |cg| { |
| 4857 | try writer.print(" shdr({d}) : COMDAT({})\n", .{ cg.shndx, cg.cg_ref }); | 4857 | try writer.print(" shdr({d}) : GROUP({})\n", .{ cg.shndx, cg.cg_ref }); |
| 4858 | } | 4858 | } |
| 4859 | 4859 | ||
| 4860 | try writer.writeAll("\nOutput merge sections\n"); | 4860 | try writer.writeAll("\nOutput merge sections\n"); |
| ... | @@ -4934,25 +4934,26 @@ const default_entry_addr = 0x8000000; | ... | @@ -4934,25 +4934,26 @@ const default_entry_addr = 0x8000000; |
| 4934 | 4934 | ||
| 4935 | pub const base_tag: link.File.Tag = .elf; | 4935 | pub const base_tag: link.File.Tag = .elf; |
| 4936 | 4936 | ||
| 4937 | pub const ComdatGroup = struct { | 4937 | pub const Group = struct { |
| 4938 | signature_off: u32, | 4938 | signature_off: u32, |
| 4939 | file_index: File.Index, | 4939 | file_index: File.Index, |
| 4940 | shndx: u32, | 4940 | shndx: u32, |
| 4941 | members_start: u32, | 4941 | members_start: u32, |
| 4942 | members_len: u32, | 4942 | members_len: u32, |
| 4943 | is_comdat: bool, | ||
| 4943 | alive: bool = true, | 4944 | alive: bool = true, |
| 4944 | 4945 | ||
| 4945 | pub fn file(cg: ComdatGroup, elf_file: *Elf) File { | 4946 | pub fn file(cg: Group, elf_file: *Elf) File { |
| 4946 | return elf_file.file(cg.file_index).?; | 4947 | return elf_file.file(cg.file_index).?; |
| 4947 | } | 4948 | } |
| 4948 | 4949 | ||
| 4949 | pub fn signature(cg: ComdatGroup, elf_file: *Elf) [:0]const u8 { | 4950 | pub fn signature(cg: Group, elf_file: *Elf) [:0]const u8 { |
| 4950 | return cg.file(elf_file).object.getString(cg.signature_off); | 4951 | return cg.file(elf_file).object.getString(cg.signature_off); |
| 4951 | } | 4952 | } |
| 4952 | 4953 | ||
| 4953 | pub fn comdatGroupMembers(cg: ComdatGroup, elf_file: *Elf) []const u32 { | 4954 | pub fn members(cg: Group, elf_file: *Elf) []const u32 { |
| 4954 | const object = cg.file(elf_file).object; | 4955 | const object = cg.file(elf_file).object; |
| 4955 | return object.comdat_group_data.items[cg.members_start..][0..cg.members_len]; | 4956 | return object.group_data.items[cg.members_start..][0..cg.members_len]; |
| 4956 | } | 4957 | } |
| 4957 | 4958 | ||
| 4958 | pub const Index = u32; | 4959 | pub const Index = u32; |
| ... | @@ -5310,7 +5311,7 @@ const Air = @import("../Air.zig"); | ... | @@ -5310,7 +5311,7 @@ const Air = @import("../Air.zig"); |
| 5310 | const Archive = @import("Elf/Archive.zig"); | 5311 | const Archive = @import("Elf/Archive.zig"); |
| 5311 | const AtomList = @import("Elf/AtomList.zig"); | 5312 | const AtomList = @import("Elf/AtomList.zig"); |
| 5312 | const Compilation = @import("../Compilation.zig"); | 5313 | const Compilation = @import("../Compilation.zig"); |
| 5313 | const ComdatGroupSection = synthetic_sections.ComdatGroupSection; | 5314 | const GroupSection = synthetic_sections.GroupSection; |
| 5314 | const CopyRelSection = synthetic_sections.CopyRelSection; | 5315 | const CopyRelSection = synthetic_sections.CopyRelSection; |
| 5315 | const Diags = @import("../link.zig").Diags; | 5316 | const Diags = @import("../link.zig").Diags; |
| 5316 | const DynamicSection = synthetic_sections.DynamicSection; | 5317 | const DynamicSection = synthetic_sections.DynamicSection; |
src/link/Elf/Object.zig+45-45| ... | @@ -20,8 +20,8 @@ atoms: std.ArrayListUnmanaged(Atom) = .empty, | ... | @@ -20,8 +20,8 @@ atoms: std.ArrayListUnmanaged(Atom) = .empty, |
| 20 | atoms_indexes: std.ArrayListUnmanaged(Atom.Index) = .empty, | 20 | atoms_indexes: std.ArrayListUnmanaged(Atom.Index) = .empty, |
| 21 | atoms_extra: std.ArrayListUnmanaged(u32) = .empty, | 21 | atoms_extra: std.ArrayListUnmanaged(u32) = .empty, |
| 22 | 22 | ||
| 23 | comdat_groups: std.ArrayListUnmanaged(Elf.ComdatGroup) = .empty, | 23 | groups: std.ArrayListUnmanaged(Elf.Group) = .empty, |
| 24 | comdat_group_data: std.ArrayListUnmanaged(u32) = .empty, | 24 | group_data: std.ArrayListUnmanaged(u32) = .empty, |
| 25 | 25 | ||
| 26 | input_merge_sections: std.ArrayListUnmanaged(Merge.InputSection) = .empty, | 26 | input_merge_sections: std.ArrayListUnmanaged(Merge.InputSection) = .empty, |
| 27 | input_merge_sections_indexes: std.ArrayListUnmanaged(Merge.InputSection.Index) = .empty, | 27 | input_merge_sections_indexes: std.ArrayListUnmanaged(Merge.InputSection.Index) = .empty, |
| ... | @@ -49,8 +49,8 @@ pub fn deinit(self: *Object, gpa: Allocator) void { | ... | @@ -49,8 +49,8 @@ pub fn deinit(self: *Object, gpa: Allocator) void { |
| 49 | self.atoms.deinit(gpa); | 49 | self.atoms.deinit(gpa); |
| 50 | self.atoms_indexes.deinit(gpa); | 50 | self.atoms_indexes.deinit(gpa); |
| 51 | self.atoms_extra.deinit(gpa); | 51 | self.atoms_extra.deinit(gpa); |
| 52 | self.comdat_groups.deinit(gpa); | 52 | self.groups.deinit(gpa); |
| 53 | self.comdat_group_data.deinit(gpa); | 53 | self.group_data.deinit(gpa); |
| 54 | self.relocs.deinit(gpa); | 54 | self.relocs.deinit(gpa); |
| 55 | self.fdes.deinit(gpa); | 55 | self.fdes.deinit(gpa); |
| 56 | self.cies.deinit(gpa); | 56 | self.cies.deinit(gpa); |
| ... | @@ -304,22 +304,22 @@ fn initAtoms( | ... | @@ -304,22 +304,22 @@ fn initAtoms( |
| 304 | } | 304 | } |
| 305 | const group_members = @as([*]align(1) const u32, @ptrCast(group_raw_data.ptr))[0..group_nmembers]; | 305 | const group_members = @as([*]align(1) const u32, @ptrCast(group_raw_data.ptr))[0..group_nmembers]; |
| 306 | 306 | ||
| 307 | if (group_members[0] != elf.GRP_COMDAT) { | 307 | switch (group_members[0]) { |
| 308 | return diags.failParse(path, "corrupt section group: unknown SHT_GROUP format", .{}); | 308 | 0, elf.GRP_COMDAT => { |
| 309 | const group_start: u32 = @intCast(self.group_data.items.len); | ||
| 310 | try self.group_data.appendUnalignedSlice(gpa, group_members[1..]); | ||
| 311 | |||
| 312 | self.group(try self.addGroup(gpa)).* = .{ | ||
| 313 | .signature_off = group_signature, | ||
| 314 | .file_index = self.index, | ||
| 315 | .shndx = shndx, | ||
| 316 | .members_start = group_start, | ||
| 317 | .members_len = @intCast(group_nmembers - 1), | ||
| 318 | .is_comdat = group_members[0] == elf.GRP_COMDAT, | ||
| 319 | }; | ||
| 320 | }, | ||
| 321 | else => return diags.failParse(path, "corrupt section group: unknown SHT_GROUP format", .{}), | ||
| 309 | } | 322 | } |
| 310 | |||
| 311 | const group_start: u32 = @intCast(self.comdat_group_data.items.len); | ||
| 312 | try self.comdat_group_data.appendUnalignedSlice(gpa, group_members[1..]); | ||
| 313 | |||
| 314 | const comdat_group_index = try self.addComdatGroup(gpa); | ||
| 315 | const comdat_group = self.comdatGroup(comdat_group_index); | ||
| 316 | comdat_group.* = .{ | ||
| 317 | .signature_off = group_signature, | ||
| 318 | .file_index = self.index, | ||
| 319 | .shndx = shndx, | ||
| 320 | .members_start = group_start, | ||
| 321 | .members_len = @intCast(group_nmembers - 1), | ||
| 322 | }; | ||
| 323 | }, | 323 | }, |
| 324 | 324 | ||
| 325 | elf.SHT_SYMTAB_SHNDX => @panic("TODO SHT_SYMTAB_SHNDX"), | 325 | elf.SHT_SYMTAB_SHNDX => @panic("TODO SHT_SYMTAB_SHNDX"), |
| ... | @@ -986,28 +986,28 @@ pub fn convertCommonSymbols(self: *Object, elf_file: *Elf) !void { | ... | @@ -986,28 +986,28 @@ pub fn convertCommonSymbols(self: *Object, elf_file: *Elf) !void { |
| 986 | } | 986 | } |
| 987 | } | 987 | } |
| 988 | 988 | ||
| 989 | pub fn resolveComdatGroups(self: *Object, elf_file: *Elf, table: anytype) !void { | 989 | pub fn resolveGroups(self: *Object, elf_file: *Elf, table: anytype) !void { |
| 990 | for (self.comdat_groups.items, 0..) |*cg, cgi| { | 990 | for (self.groups.items, 0..) |*g, gi| { |
| 991 | const signature = cg.signature(elf_file); | 991 | const signature = g.signature(elf_file); |
| 992 | const gop = try table.getOrPut(signature); | 992 | const gop = try table.getOrPut(signature); |
| 993 | if (!gop.found_existing) { | 993 | if (!gop.found_existing) { |
| 994 | gop.value_ptr.* = .{ .index = @intCast(cgi), .file = self.index }; | 994 | gop.value_ptr.* = .{ .index = @intCast(gi), .file = self.index }; |
| 995 | continue; | 995 | continue; |
| 996 | } | 996 | } |
| 997 | const current = elf_file.comdatGroup(gop.value_ptr.*); | 997 | const current = elf_file.group(gop.value_ptr.*); |
| 998 | cg.alive = false; | 998 | g.alive = false; |
| 999 | if (self.index < current.file_index) { | 999 | if (self.index < current.file_index) { |
| 1000 | current.alive = false; | 1000 | current.alive = false; |
| 1001 | cg.alive = true; | 1001 | g.alive = true; |
| 1002 | gop.value_ptr.* = .{ .index = @intCast(cgi), .file = self.index }; | 1002 | gop.value_ptr.* = .{ .index = @intCast(gi), .file = self.index }; |
| 1003 | } | 1003 | } |
| 1004 | } | 1004 | } |
| 1005 | } | 1005 | } |
| 1006 | 1006 | ||
| 1007 | pub fn markComdatGroupsDead(self: *Object, elf_file: *Elf) void { | 1007 | pub fn markGroupsDead(self: *Object, elf_file: *Elf) void { |
| 1008 | for (self.comdat_groups.items) |cg| { | 1008 | for (self.groups.items) |g| { |
| 1009 | if (cg.alive) continue; | 1009 | if (g.alive) continue; |
| 1010 | for (cg.comdatGroupMembers(elf_file)) |shndx| { | 1010 | for (g.members(elf_file)) |shndx| { |
| 1011 | const atom_index = self.atoms_indexes.items[shndx]; | 1011 | const atom_index = self.atoms_indexes.items[shndx]; |
| 1012 | if (self.atom(atom_index)) |atom_ptr| { | 1012 | if (self.atom(atom_index)) |atom_ptr| { |
| 1013 | atom_ptr.alive = false; | 1013 | atom_ptr.alive = false; |
| ... | @@ -1421,15 +1421,15 @@ fn inputMergeSection(self: *Object, index: Merge.InputSection.Index) ?*Merge.Inp | ... | @@ -1421,15 +1421,15 @@ fn inputMergeSection(self: *Object, index: Merge.InputSection.Index) ?*Merge.Inp |
| 1421 | return &self.input_merge_sections.items[index]; | 1421 | return &self.input_merge_sections.items[index]; |
| 1422 | } | 1422 | } |
| 1423 | 1423 | ||
| 1424 | fn addComdatGroup(self: *Object, gpa: Allocator) !Elf.ComdatGroup.Index { | 1424 | fn addGroup(self: *Object, gpa: Allocator) !Elf.Group.Index { |
| 1425 | const index = @as(Elf.ComdatGroup.Index, @intCast(self.comdat_groups.items.len)); | 1425 | const index: Elf.Group.Index = @intCast(self.groups.items.len); |
| 1426 | _ = try self.comdat_groups.addOne(gpa); | 1426 | _ = try self.groups.addOne(gpa); |
| 1427 | return index; | 1427 | return index; |
| 1428 | } | 1428 | } |
| 1429 | 1429 | ||
| 1430 | pub fn comdatGroup(self: *Object, index: Elf.ComdatGroup.Index) *Elf.ComdatGroup { | 1430 | pub fn group(self: *Object, index: Elf.Group.Index) *Elf.Group { |
| 1431 | assert(index < self.comdat_groups.items.len); | 1431 | assert(index < self.groups.items.len); |
| 1432 | return &self.comdat_groups.items[index]; | 1432 | return &self.groups.items[index]; |
| 1433 | } | 1433 | } |
| 1434 | 1434 | ||
| 1435 | pub fn format( | 1435 | pub fn format( |
| ... | @@ -1550,14 +1550,14 @@ fn formatFdes( | ... | @@ -1550,14 +1550,14 @@ fn formatFdes( |
| 1550 | } | 1550 | } |
| 1551 | } | 1551 | } |
| 1552 | 1552 | ||
| 1553 | pub fn fmtComdatGroups(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatComdatGroups) { | 1553 | pub fn fmtGroups(self: *Object, elf_file: *Elf) std.fmt.Formatter(formatGroups) { |
| 1554 | return .{ .data = .{ | 1554 | return .{ .data = .{ |
| 1555 | .object = self, | 1555 | .object = self, |
| 1556 | .elf_file = elf_file, | 1556 | .elf_file = elf_file, |
| 1557 | } }; | 1557 | } }; |
| 1558 | } | 1558 | } |
| 1559 | 1559 | ||
| 1560 | fn formatComdatGroups( | 1560 | fn formatGroups( |
| 1561 | ctx: FormatContext, | 1561 | ctx: FormatContext, |
| 1562 | comptime unused_fmt_string: []const u8, | 1562 | comptime unused_fmt_string: []const u8, |
| 1563 | options: std.fmt.FormatOptions, | 1563 | options: std.fmt.FormatOptions, |
| ... | @@ -1567,13 +1567,13 @@ fn formatComdatGroups( | ... | @@ -1567,13 +1567,13 @@ fn formatComdatGroups( |
| 1567 | _ = options; | 1567 | _ = options; |
| 1568 | const object = ctx.object; | 1568 | const object = ctx.object; |
| 1569 | const elf_file = ctx.elf_file; | 1569 | const elf_file = ctx.elf_file; |
| 1570 | try writer.writeAll(" COMDAT groups\n"); | 1570 | try writer.writeAll(" groups\n"); |
| 1571 | for (object.comdat_groups.items, 0..) |cg, cg_index| { | 1571 | for (object.groups.items, 0..) |g, g_index| { |
| 1572 | try writer.print(" COMDAT({d})", .{cg_index}); | 1572 | try writer.print(" {s}({d})", .{ if (g.is_comdat) "COMDAT" else "GROUP", g_index }); |
| 1573 | if (!cg.alive) try writer.writeAll(" : [*]"); | 1573 | if (!g.alive) try writer.writeAll(" : [*]"); |
| 1574 | try writer.writeByte('\n'); | 1574 | try writer.writeByte('\n'); |
| 1575 | const cg_members = cg.comdatGroupMembers(elf_file); | 1575 | const g_members = g.members(elf_file); |
| 1576 | for (cg_members) |shndx| { | 1576 | for (g_members) |shndx| { |
| 1577 | const atom_index = object.atoms_indexes.items[shndx]; | 1577 | const atom_index = object.atoms_indexes.items[shndx]; |
| 1578 | const atom_ptr = object.atom(atom_index) orelse continue; | 1578 | const atom_ptr = object.atom(atom_index) orelse continue; |
| 1579 | try writer.print(" atom({d}) : {s}\n", .{ atom_index, atom_ptr.name(elf_file) }); | 1579 | try writer.print(" atom({d}) : {s}\n", .{ atom_index, atom_ptr.name(elf_file) }); |
src/link/Elf/file.zig+2-2| ... | @@ -198,10 +198,10 @@ pub const File = union(enum) { | ... | @@ -198,10 +198,10 @@ pub const File = union(enum) { |
| 198 | }; | 198 | }; |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | pub fn comdatGroup(file: File, ind: Elf.ComdatGroup.Index) *Elf.ComdatGroup { | 201 | pub fn group(file: File, ind: Elf.Group.Index) *Elf.Group { |
| 202 | return switch (file) { | 202 | return switch (file) { |
| 203 | .linker_defined, .shared_object, .zig_object => unreachable, | 203 | .linker_defined, .shared_object, .zig_object => unreachable, |
| 204 | .object => |x| x.comdatGroup(ind), | 204 | .object => |x| x.group(ind), |
| 205 | }; | 205 | }; |
| 206 | } | 206 | } |
| 207 | 207 |
src/link/Elf/relocatable.zig+13-13| ... | @@ -19,7 +19,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void { | ... | @@ -19,7 +19,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void { |
| 19 | &elf_file.sections, | 19 | &elf_file.sections, |
| 20 | elf_file.shstrtab.items, | 20 | elf_file.shstrtab.items, |
| 21 | elf_file.merge_sections.items, | 21 | elf_file.merge_sections.items, |
| 22 | elf_file.comdat_group_sections.items, | 22 | elf_file.group_sections.items, |
| 23 | elf_file.zigObjectPtr(), | 23 | elf_file.zigObjectPtr(), |
| 24 | elf_file.files, | 24 | elf_file.files, |
| 25 | ); | 25 | ); |
| ... | @@ -152,7 +152,7 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation) !void { | ... | @@ -152,7 +152,7 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation) !void { |
| 152 | &elf_file.sections, | 152 | &elf_file.sections, |
| 153 | elf_file.shstrtab.items, | 153 | elf_file.shstrtab.items, |
| 154 | elf_file.merge_sections.items, | 154 | elf_file.merge_sections.items, |
| 155 | elf_file.comdat_group_sections.items, | 155 | elf_file.group_sections.items, |
| 156 | elf_file.zigObjectPtr(), | 156 | elf_file.zigObjectPtr(), |
| 157 | elf_file.files, | 157 | elf_file.files, |
| 158 | ); | 158 | ); |
| ... | @@ -233,19 +233,19 @@ fn initSections(elf_file: *Elf) !void { | ... | @@ -233,19 +233,19 @@ fn initSections(elf_file: *Elf) !void { |
| 233 | ); | 233 | ); |
| 234 | } | 234 | } |
| 235 | 235 | ||
| 236 | try initComdatGroups(elf_file); | 236 | try initGroups(elf_file); |
| 237 | try elf_file.initSymtab(); | 237 | try elf_file.initSymtab(); |
| 238 | try elf_file.initShStrtab(); | 238 | try elf_file.initShStrtab(); |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | fn initComdatGroups(elf_file: *Elf) !void { | 241 | fn initGroups(elf_file: *Elf) !void { |
| 242 | const gpa = elf_file.base.comp.gpa; | 242 | const gpa = elf_file.base.comp.gpa; |
| 243 | 243 | ||
| 244 | for (elf_file.objects.items) |index| { | 244 | for (elf_file.objects.items) |index| { |
| 245 | const object = elf_file.file(index).?.object; | 245 | const object = elf_file.file(index).?.object; |
| 246 | for (object.comdat_groups.items, 0..) |cg, cg_index| { | 246 | for (object.groups.items, 0..) |cg, cg_index| { |
| 247 | if (!cg.alive) continue; | 247 | if (!cg.alive) continue; |
| 248 | const cg_sec = try elf_file.comdat_group_sections.addOne(gpa); | 248 | const cg_sec = try elf_file.group_sections.addOne(gpa); |
| 249 | cg_sec.* = .{ | 249 | cg_sec.* = .{ |
| 250 | .shndx = try elf_file.addSection(.{ | 250 | .shndx = try elf_file.addSection(.{ |
| 251 | .name = try elf_file.insertShString(".group"), | 251 | .name = try elf_file.insertShString(".group"), |
| ... | @@ -292,12 +292,12 @@ fn updateSectionSizes(elf_file: *Elf) !void { | ... | @@ -292,12 +292,12 @@ fn updateSectionSizes(elf_file: *Elf) !void { |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | try elf_file.updateSymtabSize(); | 294 | try elf_file.updateSymtabSize(); |
| 295 | updateComdatGroupsSizes(elf_file); | 295 | updateGroupsSizes(elf_file); |
| 296 | elf_file.updateShStrtabSize(); | 296 | elf_file.updateShStrtabSize(); |
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | fn updateComdatGroupsSizes(elf_file: *Elf) void { | 299 | fn updateGroupsSizes(elf_file: *Elf) void { |
| 300 | for (elf_file.comdat_group_sections.items) |cg| { | 300 | for (elf_file.group_sections.items) |cg| { |
| 301 | const shdr = &elf_file.sections.items(.shdr)[cg.shndx]; | 301 | const shdr = &elf_file.sections.items(.shdr)[cg.shndx]; |
| 302 | shdr.sh_size = cg.size(elf_file); | 302 | shdr.sh_size = cg.size(elf_file); |
| 303 | shdr.sh_link = elf_file.section_indexes.symtab.?; | 303 | shdr.sh_link = elf_file.section_indexes.symtab.?; |
| ... | @@ -436,21 +436,21 @@ fn writeSyntheticSections(elf_file: *Elf) !void { | ... | @@ -436,21 +436,21 @@ fn writeSyntheticSections(elf_file: *Elf) !void { |
| 436 | try elf_file.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), shdr.sh_offset); | 436 | try elf_file.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), shdr.sh_offset); |
| 437 | } | 437 | } |
| 438 | 438 | ||
| 439 | try writeComdatGroups(elf_file); | 439 | try writeGroups(elf_file); |
| 440 | try elf_file.writeSymtab(); | 440 | try elf_file.writeSymtab(); |
| 441 | try elf_file.writeShStrtab(); | 441 | try elf_file.writeShStrtab(); |
| 442 | } | 442 | } |
| 443 | 443 | ||
| 444 | fn writeComdatGroups(elf_file: *Elf) !void { | 444 | fn writeGroups(elf_file: *Elf) !void { |
| 445 | const gpa = elf_file.base.comp.gpa; | 445 | const gpa = elf_file.base.comp.gpa; |
| 446 | for (elf_file.comdat_group_sections.items) |cgs| { | 446 | for (elf_file.group_sections.items) |cgs| { |
| 447 | const shdr = elf_file.sections.items(.shdr)[cgs.shndx]; | 447 | const shdr = elf_file.sections.items(.shdr)[cgs.shndx]; |
| 448 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; | 448 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| 449 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); | 449 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 450 | defer buffer.deinit(); | 450 | defer buffer.deinit(); |
| 451 | try cgs.write(elf_file, buffer.writer()); | 451 | try cgs.write(elf_file, buffer.writer()); |
| 452 | assert(buffer.items.len == sh_size); | 452 | assert(buffer.items.len == sh_size); |
| 453 | log.debug("writing COMDAT group from 0x{x} to 0x{x}", .{ | 453 | log.debug("writing group from 0x{x} to 0x{x}", .{ |
| 454 | shdr.sh_offset, | 454 | shdr.sh_offset, |
| 455 | shdr.sh_offset + shdr.sh_size, | 455 | shdr.sh_offset + shdr.sh_size, |
| 456 | }); | 456 | }); |
src/link/Elf/synthetic_sections.zig+12-12| ... | @@ -1484,33 +1484,33 @@ pub const VerneedSection = struct { | ... | @@ -1484,33 +1484,33 @@ pub const VerneedSection = struct { |
| 1484 | } | 1484 | } |
| 1485 | }; | 1485 | }; |
| 1486 | 1486 | ||
| 1487 | pub const ComdatGroupSection = struct { | 1487 | pub const GroupSection = struct { |
| 1488 | shndx: u32, | 1488 | shndx: u32, |
| 1489 | cg_ref: Elf.Ref, | 1489 | cg_ref: Elf.Ref, |
| 1490 | 1490 | ||
| 1491 | fn comdatGroup(cgs: ComdatGroupSection, elf_file: *Elf) *Elf.ComdatGroup { | 1491 | fn group(cgs: GroupSection, elf_file: *Elf) *Elf.Group { |
| 1492 | const cg_file = elf_file.file(cgs.cg_ref.file).?; | 1492 | const cg_file = elf_file.file(cgs.cg_ref.file).?; |
| 1493 | return cg_file.object.comdatGroup(cgs.cg_ref.index); | 1493 | return cg_file.object.group(cgs.cg_ref.index); |
| 1494 | } | 1494 | } |
| 1495 | 1495 | ||
| 1496 | pub fn symbol(cgs: ComdatGroupSection, elf_file: *Elf) *Symbol { | 1496 | pub fn symbol(cgs: GroupSection, elf_file: *Elf) *Symbol { |
| 1497 | const cg = cgs.comdatGroup(elf_file); | 1497 | const cg = cgs.group(elf_file); |
| 1498 | const object = cg.file(elf_file).object; | 1498 | const object = cg.file(elf_file).object; |
| 1499 | const shdr = object.shdrs.items[cg.shndx]; | 1499 | const shdr = object.shdrs.items[cg.shndx]; |
| 1500 | return &object.symbols.items[shdr.sh_info]; | 1500 | return &object.symbols.items[shdr.sh_info]; |
| 1501 | } | 1501 | } |
| 1502 | 1502 | ||
| 1503 | pub fn size(cgs: ComdatGroupSection, elf_file: *Elf) usize { | 1503 | pub fn size(cgs: GroupSection, elf_file: *Elf) usize { |
| 1504 | const cg = cgs.comdatGroup(elf_file); | 1504 | const cg = cgs.group(elf_file); |
| 1505 | const members = cg.comdatGroupMembers(elf_file); | 1505 | const members = cg.members(elf_file); |
| 1506 | return (members.len + 1) * @sizeOf(u32); | 1506 | return (members.len + 1) * @sizeOf(u32); |
| 1507 | } | 1507 | } |
| 1508 | 1508 | ||
| 1509 | pub fn write(cgs: ComdatGroupSection, elf_file: *Elf, writer: anytype) !void { | 1509 | pub fn write(cgs: GroupSection, elf_file: *Elf, writer: anytype) !void { |
| 1510 | const cg = cgs.comdatGroup(elf_file); | 1510 | const cg = cgs.group(elf_file); |
| 1511 | const object = cg.file(elf_file).object; | 1511 | const object = cg.file(elf_file).object; |
| 1512 | const members = cg.comdatGroupMembers(elf_file); | 1512 | const members = cg.members(elf_file); |
| 1513 | try writer.writeInt(u32, elf.GRP_COMDAT, .little); | 1513 | try writer.writeInt(u32, if (cg.is_comdat) elf.GRP_COMDAT else 0, .little); |
| 1514 | for (members) |shndx| { | 1514 | for (members) |shndx| { |
| 1515 | const shdr = object.shdrs.items[shndx]; | 1515 | const shdr = object.shdrs.items[shndx]; |
| 1516 | switch (shdr.sh_type) { | 1516 | switch (shdr.sh_type) { |