| ... | @@ -15,7 +15,8 @@ comdat_groups: std.ArrayListUnmanaged(Elf.ComdatGroup.Index) = .{}, | ... | @@ -15,7 +15,8 @@ comdat_groups: std.ArrayListUnmanaged(Elf.ComdatGroup.Index) = .{}, |
| 15 | comdat_group_data: std.ArrayListUnmanaged(u32) = .{}, | 15 | comdat_group_data: std.ArrayListUnmanaged(u32) = .{}, |
| 16 | relocs: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{}, | 16 | relocs: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{}, |
| 17 | | 17 | |
| 18 | merge_sections: std.ArrayListUnmanaged(InputMergeSection.Index) = .{}, | 18 | input_merge_sections: std.ArrayListUnmanaged(InputMergeSection) = .{}, |
| | 19 | input_merge_sections_indexes: std.ArrayListUnmanaged(InputMergeSection.Index) = .{}, |
| 19 | | 20 | |
| 20 | fdes: std.ArrayListUnmanaged(Fde) = .{}, | 21 | fdes: std.ArrayListUnmanaged(Fde) = .{}, |
| 21 | cies: std.ArrayListUnmanaged(Cie) = .{}, | 22 | cies: std.ArrayListUnmanaged(Cie) = .{}, |
| ... | @@ -53,7 +54,11 @@ pub fn deinit(self: *Object, allocator: Allocator) void { | ... | @@ -53,7 +54,11 @@ pub fn deinit(self: *Object, allocator: Allocator) void { |
| 53 | self.fdes.deinit(allocator); | 54 | self.fdes.deinit(allocator); |
| 54 | self.cies.deinit(allocator); | 55 | self.cies.deinit(allocator); |
| 55 | self.eh_frame_data.deinit(allocator); | 56 | self.eh_frame_data.deinit(allocator); |
| 56 | self.merge_sections.deinit(allocator); | 57 | for (self.input_merge_sections.items) |*isec| { |
| | 58 | isec.deinit(allocator); |
| | 59 | } |
| | 60 | self.input_merge_sections.deinit(allocator); |
| | 61 | self.input_merge_sections_indexes.deinit(allocator); |
| 57 | } | 62 | } |
| 58 | | 63 | |
| 59 | pub fn parse(self: *Object, elf_file: *Elf) !void { | 64 | pub fn parse(self: *Object, elf_file: *Elf) !void { |
| ... | @@ -62,6 +67,10 @@ pub fn parse(self: *Object, elf_file: *Elf) !void { | ... | @@ -62,6 +67,10 @@ pub fn parse(self: *Object, elf_file: *Elf) !void { |
| 62 | const handle = elf_file.fileHandle(self.file_handle); | 67 | const handle = elf_file.fileHandle(self.file_handle); |
| 63 | | 68 | |
| 64 | try self.parseCommon(gpa, handle, elf_file); | 69 | try self.parseCommon(gpa, handle, elf_file); |
| | 70 | |
| | 71 | // Append null input merge section |
| | 72 | try self.input_merge_sections.append(gpa, .{}); |
| | 73 | |
| 65 | try self.initAtoms(gpa, handle, elf_file); | 74 | try self.initAtoms(gpa, handle, elf_file); |
| 66 | try self.initSymtab(gpa, elf_file); | 75 | try self.initSymtab(gpa, elf_file); |
| 67 | | 76 | |
| ... | @@ -664,8 +673,9 @@ pub fn checkDuplicates(self: *Object, dupes: anytype, elf_file: *Elf) error{OutO | ... | @@ -664,8 +673,9 @@ pub fn checkDuplicates(self: *Object, dupes: anytype, elf_file: *Elf) error{OutO |
| 664 | pub fn initMergeSections(self: *Object, elf_file: *Elf) !void { | 673 | pub fn initMergeSections(self: *Object, elf_file: *Elf) !void { |
| 665 | const gpa = elf_file.base.comp.gpa; | 674 | const gpa = elf_file.base.comp.gpa; |
| 666 | | 675 | |
| 667 | try self.merge_sections.resize(gpa, self.shdrs.items.len); | 676 | try self.input_merge_sections.ensureUnusedCapacity(gpa, self.shdrs.items.len); |
| 668 | @memset(self.merge_sections.items, 0); | 677 | try self.input_merge_sections_indexes.resize(gpa, self.shdrs.items.len); |
| | 678 | @memset(self.input_merge_sections_indexes.items, 0); |
| 669 | | 679 | |
| 670 | for (self.shdrs.items, 0..) |shdr, shndx| { | 680 | for (self.shdrs.items, 0..) |shdr, shndx| { |
| 671 | if (shdr.sh_flags & elf.SHF_MERGE == 0) continue; | 681 | if (shdr.sh_flags & elf.SHF_MERGE == 0) continue; |
| ... | @@ -675,9 +685,9 @@ pub fn initMergeSections(self: *Object, elf_file: *Elf) !void { | ... | @@ -675,9 +685,9 @@ pub fn initMergeSections(self: *Object, elf_file: *Elf) !void { |
| 675 | if (!atom_ptr.flags.alive) continue; | 685 | if (!atom_ptr.flags.alive) continue; |
| 676 | if (atom_ptr.relocs(elf_file).len > 0) continue; | 686 | if (atom_ptr.relocs(elf_file).len > 0) continue; |
| 677 | | 687 | |
| 678 | const imsec_idx = try elf_file.addInputMergeSection(); | 688 | const imsec_idx = try self.addInputMergeSection(gpa); |
| 679 | const imsec = elf_file.inputMergeSection(imsec_idx).?; | 689 | const imsec = self.inputMergeSection(imsec_idx).?; |
| 680 | self.merge_sections.items[shndx] = imsec_idx; | 690 | self.input_merge_sections_indexes.items[shndx] = imsec_idx; |
| 681 | | 691 | |
| 682 | imsec.merge_section_index = try elf_file.getOrCreateMergeSection(atom_ptr.name(elf_file), shdr.sh_flags, shdr.sh_type); | 692 | imsec.merge_section_index = try elf_file.getOrCreateMergeSection(atom_ptr.name(elf_file), shdr.sh_flags, shdr.sh_type); |
| 683 | imsec.atom_index = atom_index; | 693 | imsec.atom_index = atom_index; |
| ... | @@ -741,8 +751,8 @@ pub fn initMergeSections(self: *Object, elf_file: *Elf) !void { | ... | @@ -741,8 +751,8 @@ pub fn initMergeSections(self: *Object, elf_file: *Elf) !void { |
| 741 | pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { | 751 | pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { |
| 742 | const gpa = elf_file.base.comp.gpa; | 752 | const gpa = elf_file.base.comp.gpa; |
| 743 | | 753 | |
| 744 | for (self.merge_sections.items) |index| { | 754 | for (self.input_merge_sections_indexes.items) |index| { |
| 745 | const imsec = elf_file.inputMergeSection(index) orelse continue; | 755 | const imsec = self.inputMergeSection(index) orelse continue; |
| 746 | if (imsec.offsets.items.len == 0) continue; | 756 | if (imsec.offsets.items.len == 0) continue; |
| 747 | const msec = elf_file.mergeSection(imsec.merge_section_index); | 757 | const msec = elf_file.mergeSection(imsec.merge_section_index); |
| 748 | const atom_ptr = elf_file.atom(imsec.atom_index).?; | 758 | const atom_ptr = elf_file.atom(imsec.atom_index).?; |
| ... | @@ -776,8 +786,8 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { | ... | @@ -776,8 +786,8 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { |
| 776 | | 786 | |
| 777 | if (esym.st_shndx == elf.SHN_COMMON or esym.st_shndx == elf.SHN_UNDEF or esym.st_shndx == elf.SHN_ABS) continue; | 787 | if (esym.st_shndx == elf.SHN_COMMON or esym.st_shndx == elf.SHN_UNDEF or esym.st_shndx == elf.SHN_ABS) continue; |
| 778 | | 788 | |
| 779 | const imsec_index = self.merge_sections.items[esym.st_shndx]; | 789 | const imsec_index = self.input_merge_sections_indexes.items[esym.st_shndx]; |
| 780 | const imsec = elf_file.inputMergeSection(imsec_index) orelse continue; | 790 | const imsec = self.inputMergeSection(imsec_index) orelse continue; |
| 781 | if (imsec.offsets.items.len == 0) continue; | 791 | if (imsec.offsets.items.len == 0) continue; |
| 782 | const msub_index, const offset = imsec.findSubsection(@intCast(esym.st_value)) orelse { | 792 | const msub_index, const offset = imsec.findSubsection(@intCast(esym.st_value)) orelse { |
| 783 | var err = try elf_file.base.addErrorWithNotes(2); | 793 | var err = try elf_file.base.addErrorWithNotes(2); |
| ... | @@ -801,8 +811,8 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { | ... | @@ -801,8 +811,8 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { |
| 801 | const esym = self.symtab.items[rel.r_sym()]; | 811 | const esym = self.symtab.items[rel.r_sym()]; |
| 802 | if (esym.st_type() != elf.STT_SECTION) continue; | 812 | if (esym.st_type() != elf.STT_SECTION) continue; |
| 803 | | 813 | |
| 804 | const imsec_index = self.merge_sections.items[esym.st_shndx]; | 814 | const imsec_index = self.input_merge_sections_indexes.items[esym.st_shndx]; |
| 805 | const imsec = elf_file.inputMergeSection(imsec_index) orelse continue; | 815 | const imsec = self.inputMergeSection(imsec_index) orelse continue; |
| 806 | if (imsec.offsets.items.len == 0) continue; | 816 | if (imsec.offsets.items.len == 0) continue; |
| 807 | const msub_index, const offset = imsec.findSubsection(@intCast(@as(i64, @intCast(esym.st_value)) + rel.r_addend)) orelse { | 817 | const msub_index, const offset = imsec.findSubsection(@intCast(@as(i64, @intCast(esym.st_value)) + rel.r_addend)) orelse { |
| 808 | var err = try elf_file.base.addErrorWithNotes(1); | 818 | var err = try elf_file.base.addErrorWithNotes(1); |
| ... | @@ -1184,6 +1194,18 @@ fn preadRelocsAlloc(self: Object, allocator: Allocator, handle: std.fs.File, shn | ... | @@ -1184,6 +1194,18 @@ fn preadRelocsAlloc(self: Object, allocator: Allocator, handle: std.fs.File, shn |
| 1184 | return @as([*]align(1) const elf.Elf64_Rela, @ptrCast(raw.ptr))[0..num]; | 1194 | return @as([*]align(1) const elf.Elf64_Rela, @ptrCast(raw.ptr))[0..num]; |
| 1185 | } | 1195 | } |
| 1186 | | 1196 | |
| | 1197 | fn addInputMergeSection(self: *Object, allocator: Allocator) !InputMergeSection.Index { |
| | 1198 | const index: InputMergeSection.Index = @intCast(self.input_merge_sections.items.len); |
| | 1199 | const msec = try self.input_merge_sections.addOne(allocator); |
| | 1200 | msec.* = .{}; |
| | 1201 | return index; |
| | 1202 | } |
| | 1203 | |
| | 1204 | fn inputMergeSection(self: *Object, index: InputMergeSection.Index) ?*InputMergeSection { |
| | 1205 | if (index == 0) return null; |
| | 1206 | return &self.input_merge_sections.items[index]; |
| | 1207 | } |
| | 1208 | |
| 1187 | pub fn format( | 1209 | pub fn format( |
| 1188 | self: *Object, | 1210 | self: *Object, |
| 1189 | comptime unused_fmt_string: []const u8, | 1211 | comptime unused_fmt_string: []const u8, |