| ... | ... | @@ -15,7 +15,8 @@ comdat_groups: std.ArrayListUnmanaged(Elf.ComdatGroup.Index) = .{}, |
| 15 | 15 | comdat_group_data: std.ArrayListUnmanaged(u32) = .{}, |
| 16 | 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 | 21 | fdes: std.ArrayListUnmanaged(Fde) = .{}, |
| 21 | 22 | cies: std.ArrayListUnmanaged(Cie) = .{}, |
| ... | ... | @@ -53,7 +54,11 @@ pub fn deinit(self: *Object, allocator: Allocator) void { |
| 53 | 54 | self.fdes.deinit(allocator); |
| 54 | 55 | self.cies.deinit(allocator); |
| 55 | 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 | 64 | pub fn parse(self: *Object, elf_file: *Elf) !void { |
| ... | ... | @@ -62,6 +67,10 @@ pub fn parse(self: *Object, elf_file: *Elf) !void { |
| 62 | 67 | const handle = elf_file.fileHandle(self.file_handle); |
| 63 | 68 | |
| 64 | 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 | 74 | try self.initAtoms(gpa, handle, elf_file); |
| 66 | 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 | 673 | pub fn initMergeSections(self: *Object, elf_file: *Elf) !void { |
| 665 | 674 | const gpa = elf_file.base.comp.gpa; |
| 666 | 675 | |
| 667 | | try self.merge_sections.resize(gpa, self.shdrs.items.len); |
| 668 | | @memset(self.merge_sections.items, 0); |
| 676 | try self.input_merge_sections.ensureUnusedCapacity(gpa, self.shdrs.items.len); |
| 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 | 680 | for (self.shdrs.items, 0..) |shdr, shndx| { |
| 671 | 681 | if (shdr.sh_flags & elf.SHF_MERGE == 0) continue; |
| ... | ... | @@ -675,9 +685,9 @@ pub fn initMergeSections(self: *Object, elf_file: *Elf) !void { |
| 675 | 685 | if (!atom_ptr.flags.alive) continue; |
| 676 | 686 | if (atom_ptr.relocs(elf_file).len > 0) continue; |
| 677 | 687 | |
| 678 | | const imsec_idx = try elf_file.addInputMergeSection(); |
| 679 | | const imsec = elf_file.inputMergeSection(imsec_idx).?; |
| 680 | | self.merge_sections.items[shndx] = imsec_idx; |
| 688 | const imsec_idx = try self.addInputMergeSection(gpa); |
| 689 | const imsec = self.inputMergeSection(imsec_idx).?; |
| 690 | self.input_merge_sections_indexes.items[shndx] = imsec_idx; |
| 681 | 691 | |
| 682 | 692 | imsec.merge_section_index = try elf_file.getOrCreateMergeSection(atom_ptr.name(elf_file), shdr.sh_flags, shdr.sh_type); |
| 683 | 693 | imsec.atom_index = atom_index; |
| ... | ... | @@ -741,8 +751,8 @@ pub fn initMergeSections(self: *Object, elf_file: *Elf) !void { |
| 741 | 751 | pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { |
| 742 | 752 | const gpa = elf_file.base.comp.gpa; |
| 743 | 753 | |
| 744 | | for (self.merge_sections.items) |index| { |
| 745 | | const imsec = elf_file.inputMergeSection(index) orelse continue; |
| 754 | for (self.input_merge_sections_indexes.items) |index| { |
| 755 | const imsec = self.inputMergeSection(index) orelse continue; |
| 746 | 756 | if (imsec.offsets.items.len == 0) continue; |
| 747 | 757 | const msec = elf_file.mergeSection(imsec.merge_section_index); |
| 748 | 758 | const atom_ptr = elf_file.atom(imsec.atom_index).?; |
| ... | ... | @@ -776,8 +786,8 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { |
| 776 | 786 | |
| 777 | 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]; |
| 780 | | const imsec = elf_file.inputMergeSection(imsec_index) orelse continue; |
| 789 | const imsec_index = self.input_merge_sections_indexes.items[esym.st_shndx]; |
| 790 | const imsec = self.inputMergeSection(imsec_index) orelse continue; |
| 781 | 791 | if (imsec.offsets.items.len == 0) continue; |
| 782 | 792 | const msub_index, const offset = imsec.findSubsection(@intCast(esym.st_value)) orelse { |
| 783 | 793 | var err = try elf_file.base.addErrorWithNotes(2); |
| ... | ... | @@ -801,8 +811,8 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { |
| 801 | 811 | const esym = self.symtab.items[rel.r_sym()]; |
| 802 | 812 | if (esym.st_type() != elf.STT_SECTION) continue; |
| 803 | 813 | |
| 804 | | const imsec_index = self.merge_sections.items[esym.st_shndx]; |
| 805 | | const imsec = elf_file.inputMergeSection(imsec_index) orelse continue; |
| 814 | const imsec_index = self.input_merge_sections_indexes.items[esym.st_shndx]; |
| 815 | const imsec = self.inputMergeSection(imsec_index) orelse continue; |
| 806 | 816 | if (imsec.offsets.items.len == 0) continue; |
| 807 | 817 | const msub_index, const offset = imsec.findSubsection(@intCast(@as(i64, @intCast(esym.st_value)) + rel.r_addend)) orelse { |
| 808 | 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 | 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 | 1209 | pub fn format( |
| 1188 | 1210 | self: *Object, |
| 1189 | 1211 | comptime unused_fmt_string: []const u8, |