| ... | @@ -37,72 +37,87 @@ num_dynrelocs: u32 = 0, | ... | @@ -37,72 +37,87 @@ num_dynrelocs: u32 = 0, |
| 37 | output_symtab_ctx: Elf.SymtabCtx = .{}, | 37 | output_symtab_ctx: Elf.SymtabCtx = .{}, |
| 38 | output_ar_state: Archive.ArState = .{}, | 38 | output_ar_state: Archive.ArState = .{}, |
| 39 | | 39 | |
| 40 | pub fn deinit(self: *Object, allocator: Allocator) void { | 40 | pub fn deinit(self: *Object, gpa: Allocator) void { |
| 41 | if (self.archive) |*ar| allocator.free(ar.path.sub_path); | 41 | if (self.archive) |*ar| gpa.free(ar.path.sub_path); |
| 42 | allocator.free(self.path.sub_path); | 42 | gpa.free(self.path.sub_path); |
| 43 | self.shdrs.deinit(allocator); | 43 | self.shdrs.deinit(gpa); |
| 44 | self.symtab.deinit(allocator); | 44 | self.symtab.deinit(gpa); |
| 45 | self.strtab.deinit(allocator); | 45 | self.strtab.deinit(gpa); |
| 46 | self.symbols.deinit(allocator); | 46 | self.symbols.deinit(gpa); |
| 47 | self.symbols_extra.deinit(allocator); | 47 | self.symbols_extra.deinit(gpa); |
| 48 | self.symbols_resolver.deinit(allocator); | 48 | self.symbols_resolver.deinit(gpa); |
| 49 | self.atoms.deinit(allocator); | 49 | self.atoms.deinit(gpa); |
| 50 | self.atoms_indexes.deinit(allocator); | 50 | self.atoms_indexes.deinit(gpa); |
| 51 | self.atoms_extra.deinit(allocator); | 51 | self.atoms_extra.deinit(gpa); |
| 52 | self.comdat_groups.deinit(allocator); | 52 | self.comdat_groups.deinit(gpa); |
| 53 | self.comdat_group_data.deinit(allocator); | 53 | self.comdat_group_data.deinit(gpa); |
| 54 | self.relocs.deinit(allocator); | 54 | self.relocs.deinit(gpa); |
| 55 | self.fdes.deinit(allocator); | 55 | self.fdes.deinit(gpa); |
| 56 | self.cies.deinit(allocator); | 56 | self.cies.deinit(gpa); |
| 57 | self.eh_frame_data.deinit(allocator); | 57 | self.eh_frame_data.deinit(gpa); |
| 58 | for (self.input_merge_sections.items) |*isec| { | 58 | for (self.input_merge_sections.items) |*isec| { |
| 59 | isec.deinit(allocator); | 59 | isec.deinit(gpa); |
| 60 | } | 60 | } |
| 61 | self.input_merge_sections.deinit(allocator); | 61 | self.input_merge_sections.deinit(gpa); |
| 62 | self.input_merge_sections_indexes.deinit(allocator); | 62 | self.input_merge_sections_indexes.deinit(gpa); |
| 63 | } | 63 | } |
| 64 | | 64 | |
| 65 | pub fn parse(self: *Object, elf_file: *Elf) !void { | 65 | pub fn parse( |
| 66 | const gpa = elf_file.base.comp.gpa; | 66 | self: *Object, |
| 67 | const cpu_arch = elf_file.getTarget().cpu.arch; | 67 | gpa: Allocator, |
| 68 | const handle = elf_file.fileHandle(self.file_handle); | 68 | diags: *Diags, |
| 69 | | 69 | /// For error reporting purposes only. |
| 70 | try self.parseCommon(gpa, handle, elf_file); | 70 | path: Path, |
| | 71 | handle: fs.File, |
| | 72 | first_eflags: *?elf.Word, |
| | 73 | target: std.Target, |
| | 74 | debug_fmt_strip: bool, |
| | 75 | default_sym_version: elf.Versym, |
| | 76 | ) !void { |
| | 77 | try self.parseCommon(gpa, diags, path, handle, first_eflags, target); |
| 71 | | 78 | |
| 72 | // Append null input merge section | 79 | // Append null input merge section |
| 73 | try self.input_merge_sections.append(gpa, .{}); | 80 | try self.input_merge_sections.append(gpa, .{}); |
| 74 | // Allocate atom index 0 to null atom | 81 | // Allocate atom index 0 to null atom |
| 75 | try self.atoms.append(gpa, .{ .extra_index = try self.addAtomExtra(gpa, .{}) }); | 82 | try self.atoms.append(gpa, .{ .extra_index = try self.addAtomExtra(gpa, .{}) }); |
| 76 | | 83 | |
| 77 | try self.initAtoms(gpa, handle, elf_file); | 84 | try self.initAtoms(gpa, diags, path, handle, debug_fmt_strip, target); |
| 78 | try self.initSymbols(gpa, elf_file); | 85 | try self.initSymbols(gpa, default_sym_version); |
| 79 | | 86 | |
| 80 | for (self.shdrs.items, 0..) |shdr, i| { | 87 | for (self.shdrs.items, 0..) |shdr, i| { |
| 81 | const atom_ptr = self.atom(self.atoms_indexes.items[i]) orelse continue; | 88 | const atom_ptr = self.atom(self.atoms_indexes.items[i]) orelse continue; |
| 82 | if (!atom_ptr.alive) continue; | 89 | if (!atom_ptr.alive) continue; |
| 83 | if ((cpu_arch == .x86_64 and shdr.sh_type == elf.SHT_X86_64_UNWIND) or | 90 | if ((target.cpu.arch == .x86_64 and shdr.sh_type == elf.SHT_X86_64_UNWIND) or |
| 84 | mem.eql(u8, atom_ptr.name(elf_file), ".eh_frame")) | 91 | mem.eql(u8, self.getString(atom_ptr.name_offset), ".eh_frame")) |
| 85 | { | 92 | { |
| 86 | try self.parseEhFrame(gpa, handle, @as(u32, @intCast(i)), elf_file); | 93 | try self.parseEhFrame(gpa, handle, @intCast(i), target); |
| 87 | } | 94 | } |
| 88 | } | 95 | } |
| 89 | } | 96 | } |
| 90 | | 97 | |
| 91 | fn parseCommon(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file: *Elf) !void { | 98 | fn parseCommon( |
| | 99 | self: *Object, |
| | 100 | gpa: Allocator, |
| | 101 | diags: *Diags, |
| | 102 | path: Path, |
| | 103 | handle: fs.File, |
| | 104 | first_eflags: *?elf.Word, |
| | 105 | target: std.Target, |
| | 106 | ) !void { |
| 92 | const offset = if (self.archive) |ar| ar.offset else 0; | 107 | const offset = if (self.archive) |ar| ar.offset else 0; |
| 93 | const file_size = (try handle.stat()).size; | 108 | const file_size = (try handle.stat()).size; |
| 94 | | 109 | |
| 95 | const header_buffer = try Elf.preadAllAlloc(allocator, handle, offset, @sizeOf(elf.Elf64_Ehdr)); | 110 | const header_buffer = try Elf.preadAllAlloc(gpa, handle, offset, @sizeOf(elf.Elf64_Ehdr)); |
| 96 | defer allocator.free(header_buffer); | 111 | defer gpa.free(header_buffer); |
| 97 | self.header = @as(*align(1) const elf.Elf64_Ehdr, @ptrCast(header_buffer)).*; | 112 | self.header = @as(*align(1) const elf.Elf64_Ehdr, @ptrCast(header_buffer)).*; |
| 98 | | 113 | |
| 99 | const em = elf_file.base.comp.root_mod.resolved_target.result.toElfMachine(); | 114 | const em = target.toElfMachine(); |
| 100 | if (em != self.header.?.e_machine) { | 115 | if (em != self.header.?.e_machine) { |
| 101 | return elf_file.failFile(self.index, "invalid ELF machine type: {s}", .{ | 116 | return diags.failParse(path, "invalid ELF machine type: {s}", .{ |
| 102 | @tagName(self.header.?.e_machine), | 117 | @tagName(self.header.?.e_machine), |
| 103 | }); | 118 | }); |
| 104 | } | 119 | } |
| 105 | try elf_file.validateEFlags(self.index, self.header.?.e_flags); | 120 | try validateEFlags(diags, path, target, self.header.?.e_flags, first_eflags); |
| 106 | | 121 | |
| 107 | if (self.header.?.e_shnum == 0) return; | 122 | if (self.header.?.e_shnum == 0) return; |
| 108 | | 123 | |
| ... | @@ -110,30 +125,30 @@ fn parseCommon(self: *Object, allocator: Allocator, handle: std.fs.File, elf_fil | ... | @@ -110,30 +125,30 @@ fn parseCommon(self: *Object, allocator: Allocator, handle: std.fs.File, elf_fil |
| 110 | const shnum = math.cast(usize, self.header.?.e_shnum) orelse return error.Overflow; | 125 | const shnum = math.cast(usize, self.header.?.e_shnum) orelse return error.Overflow; |
| 111 | const shsize = shnum * @sizeOf(elf.Elf64_Shdr); | 126 | const shsize = shnum * @sizeOf(elf.Elf64_Shdr); |
| 112 | if (file_size < offset + shoff or file_size < offset + shoff + shsize) { | 127 | if (file_size < offset + shoff or file_size < offset + shoff + shsize) { |
| 113 | return elf_file.failFile(self.index, "corrupt header: section header table extends past the end of file", .{}); | 128 | return diags.failParse(path, "corrupt header: section header table extends past the end of file", .{}); |
| 114 | } | 129 | } |
| 115 | | 130 | |
| 116 | const shdrs_buffer = try Elf.preadAllAlloc(allocator, handle, offset + shoff, shsize); | 131 | const shdrs_buffer = try Elf.preadAllAlloc(gpa, handle, offset + shoff, shsize); |
| 117 | defer allocator.free(shdrs_buffer); | 132 | defer gpa.free(shdrs_buffer); |
| 118 | const shdrs = @as([*]align(1) const elf.Elf64_Shdr, @ptrCast(shdrs_buffer.ptr))[0..shnum]; | 133 | const shdrs = @as([*]align(1) const elf.Elf64_Shdr, @ptrCast(shdrs_buffer.ptr))[0..shnum]; |
| 119 | try self.shdrs.appendUnalignedSlice(allocator, shdrs); | 134 | try self.shdrs.appendUnalignedSlice(gpa, shdrs); |
| 120 | | 135 | |
| 121 | for (self.shdrs.items) |shdr| { | 136 | for (self.shdrs.items) |shdr| { |
| 122 | if (shdr.sh_type != elf.SHT_NOBITS) { | 137 | if (shdr.sh_type != elf.SHT_NOBITS) { |
| 123 | if (file_size < offset + shdr.sh_offset or file_size < offset + shdr.sh_offset + shdr.sh_size) { | 138 | if (file_size < offset + shdr.sh_offset or file_size < offset + shdr.sh_offset + shdr.sh_size) { |
| 124 | return elf_file.failFile(self.index, "corrupt section: extends past the end of file", .{}); | 139 | return diags.failParse(path, "corrupt section: extends past the end of file", .{}); |
| 125 | } | 140 | } |
| 126 | } | 141 | } |
| 127 | } | 142 | } |
| 128 | | 143 | |
| 129 | const shstrtab = try self.preadShdrContentsAlloc(allocator, handle, self.header.?.e_shstrndx); | 144 | const shstrtab = try self.preadShdrContentsAlloc(gpa, handle, self.header.?.e_shstrndx); |
| 130 | defer allocator.free(shstrtab); | 145 | defer gpa.free(shstrtab); |
| 131 | for (self.shdrs.items) |shdr| { | 146 | for (self.shdrs.items) |shdr| { |
| 132 | if (shdr.sh_name >= shstrtab.len) { | 147 | if (shdr.sh_name >= shstrtab.len) { |
| 133 | return elf_file.failFile(self.index, "corrupt section name offset", .{}); | 148 | return diags.failParse(path, "corrupt section name offset", .{}); |
| 134 | } | 149 | } |
| 135 | } | 150 | } |
| 136 | try self.strtab.appendSlice(allocator, shstrtab); | 151 | try self.strtab.appendSlice(gpa, shstrtab); |
| 137 | | 152 | |
| 138 | const symtab_index = for (self.shdrs.items, 0..) |shdr, i| switch (shdr.sh_type) { | 153 | const symtab_index = for (self.shdrs.items, 0..) |shdr, i| switch (shdr.sh_type) { |
| 139 | elf.SHT_SYMTAB => break @as(u32, @intCast(i)), | 154 | elf.SHT_SYMTAB => break @as(u32, @intCast(i)), |
| ... | @@ -144,19 +159,19 @@ fn parseCommon(self: *Object, allocator: Allocator, handle: std.fs.File, elf_fil | ... | @@ -144,19 +159,19 @@ fn parseCommon(self: *Object, allocator: Allocator, handle: std.fs.File, elf_fil |
| 144 | const shdr = self.shdrs.items[index]; | 159 | const shdr = self.shdrs.items[index]; |
| 145 | self.first_global = shdr.sh_info; | 160 | self.first_global = shdr.sh_info; |
| 146 | | 161 | |
| 147 | const raw_symtab = try self.preadShdrContentsAlloc(allocator, handle, index); | 162 | const raw_symtab = try self.preadShdrContentsAlloc(gpa, handle, index); |
| 148 | defer allocator.free(raw_symtab); | 163 | defer gpa.free(raw_symtab); |
| 149 | const nsyms = math.divExact(usize, raw_symtab.len, @sizeOf(elf.Elf64_Sym)) catch { | 164 | const nsyms = math.divExact(usize, raw_symtab.len, @sizeOf(elf.Elf64_Sym)) catch { |
| 150 | return elf_file.failFile(self.index, "symbol table not evenly divisible", .{}); | 165 | return diags.failParse(path, "symbol table not evenly divisible", .{}); |
| 151 | }; | 166 | }; |
| 152 | const symtab = @as([*]align(1) const elf.Elf64_Sym, @ptrCast(raw_symtab.ptr))[0..nsyms]; | 167 | const symtab = @as([*]align(1) const elf.Elf64_Sym, @ptrCast(raw_symtab.ptr))[0..nsyms]; |
| 153 | | 168 | |
| 154 | const strtab_bias = @as(u32, @intCast(self.strtab.items.len)); | 169 | const strtab_bias = @as(u32, @intCast(self.strtab.items.len)); |
| 155 | const strtab = try self.preadShdrContentsAlloc(allocator, handle, shdr.sh_link); | 170 | const strtab = try self.preadShdrContentsAlloc(gpa, handle, shdr.sh_link); |
| 156 | defer allocator.free(strtab); | 171 | defer gpa.free(strtab); |
| 157 | try self.strtab.appendSlice(allocator, strtab); | 172 | try self.strtab.appendSlice(gpa, strtab); |
| 158 | | 173 | |
| 159 | try self.symtab.ensureUnusedCapacity(allocator, symtab.len); | 174 | try self.symtab.ensureUnusedCapacity(gpa, symtab.len); |
| 160 | for (symtab) |sym| { | 175 | for (symtab) |sym| { |
| 161 | const out_sym = self.symtab.addOneAssumeCapacity(); | 176 | const out_sym = self.symtab.addOneAssumeCapacity(); |
| 162 | out_sym.* = sym; | 177 | out_sym.* = sym; |
| ... | @@ -168,15 +183,56 @@ fn parseCommon(self: *Object, allocator: Allocator, handle: std.fs.File, elf_fil | ... | @@ -168,15 +183,56 @@ fn parseCommon(self: *Object, allocator: Allocator, handle: std.fs.File, elf_fil |
| 168 | } | 183 | } |
| 169 | } | 184 | } |
| 170 | | 185 | |
| 171 | fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file: *Elf) !void { | 186 | fn validateEFlags( |
| 172 | const comp = elf_file.base.comp; | 187 | diags: *Diags, |
| 173 | const debug_fmt_strip = comp.config.debug_format == .strip; | 188 | path: Path, |
| 174 | const target = comp.root_mod.resolved_target.result; | 189 | target: std.Target, |
| | 190 | e_flags: elf.Word, |
| | 191 | first_eflags: *?elf.Word, |
| | 192 | ) error{LinkFailure}!void { |
| | 193 | if (first_eflags.*) |*self_eflags| { |
| | 194 | switch (target.cpu.arch) { |
| | 195 | .riscv64 => { |
| | 196 | if (e_flags != self_eflags.*) { |
| | 197 | const riscv_eflags: riscv.RiscvEflags = @bitCast(e_flags); |
| | 198 | const self_riscv_eflags: *riscv.RiscvEflags = @ptrCast(self_eflags); |
| | 199 | |
| | 200 | self_riscv_eflags.rvc = self_riscv_eflags.rvc or riscv_eflags.rvc; |
| | 201 | self_riscv_eflags.tso = self_riscv_eflags.tso or riscv_eflags.tso; |
| | 202 | |
| | 203 | var any_errors: bool = false; |
| | 204 | if (self_riscv_eflags.fabi != riscv_eflags.fabi) { |
| | 205 | any_errors = true; |
| | 206 | diags.addParseError(path, "cannot link object files with different float-point ABIs", .{}); |
| | 207 | } |
| | 208 | if (self_riscv_eflags.rve != riscv_eflags.rve) { |
| | 209 | any_errors = true; |
| | 210 | diags.addParseError(path, "cannot link object files with different RVEs", .{}); |
| | 211 | } |
| | 212 | if (any_errors) return error.LinkFailure; |
| | 213 | } |
| | 214 | }, |
| | 215 | else => {}, |
| | 216 | } |
| | 217 | } else { |
| | 218 | first_eflags.* = e_flags; |
| | 219 | } |
| | 220 | } |
| | 221 | |
| | 222 | fn initAtoms( |
| | 223 | self: *Object, |
| | 224 | gpa: Allocator, |
| | 225 | diags: *Diags, |
| | 226 | path: Path, |
| | 227 | handle: fs.File, |
| | 228 | debug_fmt_strip: bool, |
| | 229 | target: std.Target, |
| | 230 | ) !void { |
| 175 | const shdrs = self.shdrs.items; | 231 | const shdrs = self.shdrs.items; |
| 176 | try self.atoms.ensureTotalCapacityPrecise(allocator, shdrs.len); | 232 | try self.atoms.ensureTotalCapacityPrecise(gpa, shdrs.len); |
| 177 | try self.atoms_extra.ensureTotalCapacityPrecise(allocator, shdrs.len * @sizeOf(Atom.Extra)); | 233 | try self.atoms_extra.ensureTotalCapacityPrecise(gpa, shdrs.len * @sizeOf(Atom.Extra)); |
| 178 | try self.atoms_indexes.ensureTotalCapacityPrecise(allocator, shdrs.len); | 234 | try self.atoms_indexes.ensureTotalCapacityPrecise(gpa, shdrs.len); |
| 179 | try self.atoms_indexes.resize(allocator, shdrs.len); | 235 | try self.atoms_indexes.resize(gpa, shdrs.len); |
| 180 | @memset(self.atoms_indexes.items, 0); | 236 | @memset(self.atoms_indexes.items, 0); |
| 181 | | 237 | |
| 182 | for (shdrs, 0..) |shdr, i| { | 238 | for (shdrs, 0..) |shdr, i| { |
| ... | @@ -201,24 +257,24 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file: | ... | @@ -201,24 +257,24 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file: |
| 201 | }; | 257 | }; |
| 202 | | 258 | |
| 203 | const shndx: u32 = @intCast(i); | 259 | const shndx: u32 = @intCast(i); |
| 204 | const group_raw_data = try self.preadShdrContentsAlloc(allocator, handle, shndx); | 260 | const group_raw_data = try self.preadShdrContentsAlloc(gpa, handle, shndx); |
| 205 | defer allocator.free(group_raw_data); | 261 | defer gpa.free(group_raw_data); |
| 206 | const group_nmembers = math.divExact(usize, group_raw_data.len, @sizeOf(u32)) catch { | 262 | const group_nmembers = math.divExact(usize, group_raw_data.len, @sizeOf(u32)) catch { |
| 207 | return elf_file.failFile(self.index, "corrupt section group: not evenly divisible ", .{}); | 263 | return diags.failParse(path, "corrupt section group: not evenly divisible ", .{}); |
| 208 | }; | 264 | }; |
| 209 | if (group_nmembers == 0) { | 265 | if (group_nmembers == 0) { |
| 210 | return elf_file.failFile(self.index, "corrupt section group: empty section", .{}); | 266 | return diags.failParse(path, "corrupt section group: empty section", .{}); |
| 211 | } | 267 | } |
| 212 | const group_members = @as([*]align(1) const u32, @ptrCast(group_raw_data.ptr))[0..group_nmembers]; | 268 | const group_members = @as([*]align(1) const u32, @ptrCast(group_raw_data.ptr))[0..group_nmembers]; |
| 213 | | 269 | |
| 214 | if (group_members[0] != elf.GRP_COMDAT) { | 270 | if (group_members[0] != elf.GRP_COMDAT) { |
| 215 | return elf_file.failFile(self.index, "corrupt section group: unknown SHT_GROUP format", .{}); | 271 | return diags.failParse(path, "corrupt section group: unknown SHT_GROUP format", .{}); |
| 216 | } | 272 | } |
| 217 | | 273 | |
| 218 | const group_start: u32 = @intCast(self.comdat_group_data.items.len); | 274 | const group_start: u32 = @intCast(self.comdat_group_data.items.len); |
| 219 | try self.comdat_group_data.appendUnalignedSlice(allocator, group_members[1..]); | 275 | try self.comdat_group_data.appendUnalignedSlice(gpa, group_members[1..]); |
| 220 | | 276 | |
| 221 | const comdat_group_index = try self.addComdatGroup(allocator); | 277 | const comdat_group_index = try self.addComdatGroup(gpa); |
| 222 | const comdat_group = self.comdatGroup(comdat_group_index); | 278 | const comdat_group = self.comdatGroup(comdat_group_index); |
| 223 | comdat_group.* = .{ | 279 | comdat_group.* = .{ |
| 224 | .signature_off = group_signature, | 280 | .signature_off = group_signature, |
| ... | @@ -242,8 +298,8 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file: | ... | @@ -242,8 +298,8 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file: |
| 242 | const shndx: u32 = @intCast(i); | 298 | const shndx: u32 = @intCast(i); |
| 243 | if (self.skipShdr(shndx, debug_fmt_strip)) continue; | 299 | if (self.skipShdr(shndx, debug_fmt_strip)) continue; |
| 244 | const size, const alignment = if (shdr.sh_flags & elf.SHF_COMPRESSED != 0) blk: { | 300 | const size, const alignment = if (shdr.sh_flags & elf.SHF_COMPRESSED != 0) blk: { |
| 245 | const data = try self.preadShdrContentsAlloc(allocator, handle, shndx); | 301 | const data = try self.preadShdrContentsAlloc(gpa, handle, shndx); |
| 246 | defer allocator.free(data); | 302 | defer gpa.free(data); |
| 247 | const chdr = @as(*align(1) const elf.Elf64_Chdr, @ptrCast(data.ptr)).*; | 303 | const chdr = @as(*align(1) const elf.Elf64_Chdr, @ptrCast(data.ptr)).*; |
| 248 | break :blk .{ chdr.ch_size, Alignment.fromNonzeroByteUnits(chdr.ch_addralign) }; | 304 | break :blk .{ chdr.ch_size, Alignment.fromNonzeroByteUnits(chdr.ch_addralign) }; |
| 249 | } else .{ shdr.sh_size, Alignment.fromNonzeroByteUnits(shdr.sh_addralign) }; | 305 | } else .{ shdr.sh_size, Alignment.fromNonzeroByteUnits(shdr.sh_addralign) }; |
| ... | @@ -263,13 +319,13 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file: | ... | @@ -263,13 +319,13 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file: |
| 263 | elf.SHT_REL, elf.SHT_RELA => { | 319 | elf.SHT_REL, elf.SHT_RELA => { |
| 264 | const atom_index = self.atoms_indexes.items[shdr.sh_info]; | 320 | const atom_index = self.atoms_indexes.items[shdr.sh_info]; |
| 265 | if (self.atom(atom_index)) |atom_ptr| { | 321 | if (self.atom(atom_index)) |atom_ptr| { |
| 266 | const relocs = try self.preadRelocsAlloc(allocator, handle, @intCast(i)); | 322 | const relocs = try self.preadRelocsAlloc(gpa, handle, @intCast(i)); |
| 267 | defer allocator.free(relocs); | 323 | defer gpa.free(relocs); |
| 268 | atom_ptr.relocs_section_index = @intCast(i); | 324 | atom_ptr.relocs_section_index = @intCast(i); |
| 269 | const rel_index: u32 = @intCast(self.relocs.items.len); | 325 | const rel_index: u32 = @intCast(self.relocs.items.len); |
| 270 | const rel_count: u32 = @intCast(relocs.len); | 326 | const rel_count: u32 = @intCast(relocs.len); |
| 271 | self.setAtomFields(atom_ptr, .{ .rel_index = rel_index, .rel_count = rel_count }); | 327 | self.setAtomFields(atom_ptr, .{ .rel_index = rel_index, .rel_count = rel_count }); |
| 272 | try self.relocs.appendUnalignedSlice(allocator, relocs); | 328 | try self.relocs.appendUnalignedSlice(gpa, relocs); |
| 273 | if (target.cpu.arch == .riscv64) { | 329 | if (target.cpu.arch == .riscv64) { |
| 274 | sortRelocs(self.relocs.items[rel_index..][0..rel_count]); | 330 | sortRelocs(self.relocs.items[rel_index..][0..rel_count]); |
| 275 | } | 331 | } |
| ... | @@ -293,14 +349,18 @@ fn skipShdr(self: *Object, index: u32, debug_fmt_strip: bool) bool { | ... | @@ -293,14 +349,18 @@ fn skipShdr(self: *Object, index: u32, debug_fmt_strip: bool) bool { |
| 293 | return ignore; | 349 | return ignore; |
| 294 | } | 350 | } |
| 295 | | 351 | |
| 296 | fn initSymbols(self: *Object, allocator: Allocator, elf_file: *Elf) !void { | 352 | fn initSymbols( |
| | 353 | self: *Object, |
| | 354 | gpa: Allocator, |
| | 355 | default_sym_version: elf.Versym, |
| | 356 | ) !void { |
| 297 | const first_global = self.first_global orelse self.symtab.items.len; | 357 | const first_global = self.first_global orelse self.symtab.items.len; |
| 298 | const nglobals = self.symtab.items.len - first_global; | 358 | const nglobals = self.symtab.items.len - first_global; |
| 299 | | 359 | |
| 300 | try self.symbols.ensureTotalCapacityPrecise(allocator, self.symtab.items.len); | 360 | try self.symbols.ensureTotalCapacityPrecise(gpa, self.symtab.items.len); |
| 301 | try self.symbols_extra.ensureTotalCapacityPrecise(allocator, self.symtab.items.len * @sizeOf(Symbol.Extra)); | 361 | try self.symbols_extra.ensureTotalCapacityPrecise(gpa, self.symtab.items.len * @sizeOf(Symbol.Extra)); |
| 302 | try self.symbols_resolver.ensureTotalCapacityPrecise(allocator, nglobals); | 362 | try self.symbols_resolver.ensureTotalCapacityPrecise(gpa, nglobals); |
| 303 | self.symbols_resolver.resize(allocator, nglobals) catch unreachable; | 363 | self.symbols_resolver.resize(gpa, nglobals) catch unreachable; |
| 304 | @memset(self.symbols_resolver.items, 0); | 364 | @memset(self.symbols_resolver.items, 0); |
| 305 | | 365 | |
| 306 | for (self.symtab.items, 0..) |sym, i| { | 366 | for (self.symtab.items, 0..) |sym, i| { |
| ... | @@ -310,7 +370,7 @@ fn initSymbols(self: *Object, allocator: Allocator, elf_file: *Elf) !void { | ... | @@ -310,7 +370,7 @@ fn initSymbols(self: *Object, allocator: Allocator, elf_file: *Elf) !void { |
| 310 | sym_ptr.name_offset = sym.st_name; | 370 | sym_ptr.name_offset = sym.st_name; |
| 311 | sym_ptr.esym_index = @intCast(i); | 371 | sym_ptr.esym_index = @intCast(i); |
| 312 | sym_ptr.extra_index = self.addSymbolExtraAssumeCapacity(.{}); | 372 | sym_ptr.extra_index = self.addSymbolExtraAssumeCapacity(.{}); |
| 313 | sym_ptr.version_index = if (i >= first_global) elf_file.default_sym_version else .LOCAL; | 373 | sym_ptr.version_index = if (i >= first_global) default_sym_version else .LOCAL; |
| 314 | sym_ptr.flags.weak = sym.st_bind() == elf.STB_WEAK; | 374 | sym_ptr.flags.weak = sym.st_bind() == elf.STB_WEAK; |
| 315 | if (sym.st_shndx != elf.SHN_ABS and sym.st_shndx != elf.SHN_COMMON) { | 375 | if (sym.st_shndx != elf.SHN_ABS and sym.st_shndx != elf.SHN_COMMON) { |
| 316 | sym_ptr.ref = .{ .index = self.atoms_indexes.items[sym.st_shndx], .file = self.index }; | 376 | sym_ptr.ref = .{ .index = self.atoms_indexes.items[sym.st_shndx], .file = self.index }; |
| ... | @@ -318,24 +378,30 @@ fn initSymbols(self: *Object, allocator: Allocator, elf_file: *Elf) !void { | ... | @@ -318,24 +378,30 @@ fn initSymbols(self: *Object, allocator: Allocator, elf_file: *Elf) !void { |
| 318 | } | 378 | } |
| 319 | } | 379 | } |
| 320 | | 380 | |
| 321 | fn parseEhFrame(self: *Object, allocator: Allocator, handle: std.fs.File, shndx: u32, elf_file: *Elf) !void { | 381 | fn parseEhFrame( |
| | 382 | self: *Object, |
| | 383 | gpa: Allocator, |
| | 384 | handle: fs.File, |
| | 385 | shndx: u32, |
| | 386 | target: std.Target, |
| | 387 | ) !void { |
| 322 | const relocs_shndx = for (self.shdrs.items, 0..) |shdr, i| switch (shdr.sh_type) { | 388 | const relocs_shndx = for (self.shdrs.items, 0..) |shdr, i| switch (shdr.sh_type) { |
| 323 | elf.SHT_RELA => if (shdr.sh_info == shndx) break @as(u32, @intCast(i)), | 389 | elf.SHT_RELA => if (shdr.sh_info == shndx) break @as(u32, @intCast(i)), |
| 324 | else => {}, | 390 | else => {}, |
| 325 | } else null; | 391 | } else null; |
| 326 | | 392 | |
| 327 | const raw = try self.preadShdrContentsAlloc(allocator, handle, shndx); | 393 | const raw = try self.preadShdrContentsAlloc(gpa, handle, shndx); |
| 328 | defer allocator.free(raw); | 394 | defer gpa.free(raw); |
| 329 | const data_start = @as(u32, @intCast(self.eh_frame_data.items.len)); | 395 | const data_start: u32 = @intCast(self.eh_frame_data.items.len); |
| 330 | try self.eh_frame_data.appendSlice(allocator, raw); | 396 | try self.eh_frame_data.appendSlice(gpa, raw); |
| 331 | const relocs = if (relocs_shndx) |index| | 397 | const relocs = if (relocs_shndx) |index| |
| 332 | try self.preadRelocsAlloc(allocator, handle, index) | 398 | try self.preadRelocsAlloc(gpa, handle, index) |
| 333 | else | 399 | else |
| 334 | &[0]elf.Elf64_Rela{}; | 400 | &[0]elf.Elf64_Rela{}; |
| 335 | defer allocator.free(relocs); | 401 | defer gpa.free(relocs); |
| 336 | const rel_start = @as(u32, @intCast(self.relocs.items.len)); | 402 | const rel_start: u32 = @intCast(self.relocs.items.len); |
| 337 | try self.relocs.appendUnalignedSlice(allocator, relocs); | 403 | try self.relocs.appendUnalignedSlice(gpa, relocs); |
| 338 | if (elf_file.getTarget().cpu.arch == .riscv64) { | 404 | if (target.cpu.arch == .riscv64) { |
| 339 | sortRelocs(self.relocs.items[rel_start..][0..relocs.len]); | 405 | sortRelocs(self.relocs.items[rel_start..][0..relocs.len]); |
| 340 | } | 406 | } |
| 341 | const fdes_start = self.fdes.items.len; | 407 | const fdes_start = self.fdes.items.len; |
| ... | @@ -345,11 +411,11 @@ fn parseEhFrame(self: *Object, allocator: Allocator, handle: std.fs.File, shndx: | ... | @@ -345,11 +411,11 @@ fn parseEhFrame(self: *Object, allocator: Allocator, handle: std.fs.File, shndx: |
| 345 | while (try it.next()) |rec| { | 411 | while (try it.next()) |rec| { |
| 346 | const rel_range = filterRelocs(self.relocs.items[rel_start..][0..relocs.len], rec.offset, rec.size + 4); | 412 | const rel_range = filterRelocs(self.relocs.items[rel_start..][0..relocs.len], rec.offset, rec.size + 4); |
| 347 | switch (rec.tag) { | 413 | switch (rec.tag) { |
| 348 | .cie => try self.cies.append(allocator, .{ | 414 | .cie => try self.cies.append(gpa, .{ |
| 349 | .offset = data_start + rec.offset, | 415 | .offset = data_start + rec.offset, |
| 350 | .size = rec.size, | 416 | .size = rec.size, |
| 351 | .rel_index = rel_start + @as(u32, @intCast(rel_range.start)), | 417 | .rel_index = rel_start + @as(u32, @intCast(rel_range.start)), |
| 352 | .rel_num = @as(u32, @intCast(rel_range.len)), | 418 | .rel_num = @intCast(rel_range.len), |
| 353 | .input_section_index = shndx, | 419 | .input_section_index = shndx, |
| 354 | .file_index = self.index, | 420 | .file_index = self.index, |
| 355 | }), | 421 | }), |
| ... | @@ -361,12 +427,12 @@ fn parseEhFrame(self: *Object, allocator: Allocator, handle: std.fs.File, shndx: | ... | @@ -361,12 +427,12 @@ fn parseEhFrame(self: *Object, allocator: Allocator, handle: std.fs.File, shndx: |
| 361 | // this can happen for object files built with -r flag by the linker. | 427 | // this can happen for object files built with -r flag by the linker. |
| 362 | continue; | 428 | continue; |
| 363 | } | 429 | } |
| 364 | try self.fdes.append(allocator, .{ | 430 | try self.fdes.append(gpa, .{ |
| 365 | .offset = data_start + rec.offset, | 431 | .offset = data_start + rec.offset, |
| 366 | .size = rec.size, | 432 | .size = rec.size, |
| 367 | .cie_index = undefined, | 433 | .cie_index = undefined, |
| 368 | .rel_index = rel_start + @as(u32, @intCast(rel_range.start)), | 434 | .rel_index = rel_start + @as(u32, @intCast(rel_range.start)), |
| 369 | .rel_num = @as(u32, @intCast(rel_range.len)), | 435 | .rel_num = @intCast(rel_range.len), |
| 370 | .input_section_index = shndx, | 436 | .input_section_index = shndx, |
| 371 | .file_index = self.index, | 437 | .file_index = self.index, |
| 372 | }); | 438 | }); |
| ... | @@ -376,7 +442,7 @@ fn parseEhFrame(self: *Object, allocator: Allocator, handle: std.fs.File, shndx: | ... | @@ -376,7 +442,7 @@ fn parseEhFrame(self: *Object, allocator: Allocator, handle: std.fs.File, shndx: |
| 376 | | 442 | |
| 377 | // Tie each FDE to its CIE | 443 | // Tie each FDE to its CIE |
| 378 | for (self.fdes.items[fdes_start..]) |*fde| { | 444 | for (self.fdes.items[fdes_start..]) |*fde| { |
| 379 | const cie_ptr = fde.offset + 4 - fde.ciePointer(elf_file); | 445 | const cie_ptr = fde.offset + 4 - fde.ciePointer(self); |
| 380 | const cie_index = for (self.cies.items[cies_start..], cies_start..) |cie, cie_index| { | 446 | const cie_index = for (self.cies.items[cies_start..], cies_start..) |cie, cie_index| { |
| 381 | if (cie.offset == cie_ptr) break @as(u32, @intCast(cie_index)); | 447 | if (cie.offset == cie_ptr) break @as(u32, @intCast(cie_index)); |
| 382 | } else { | 448 | } else { |
| ... | @@ -392,26 +458,26 @@ fn parseEhFrame(self: *Object, allocator: Allocator, handle: std.fs.File, shndx: | ... | @@ -392,26 +458,26 @@ fn parseEhFrame(self: *Object, allocator: Allocator, handle: std.fs.File, shndx: |
| 392 | | 458 | |
| 393 | // Tie each FDE record to its matching atom | 459 | // Tie each FDE record to its matching atom |
| 394 | const SortFdes = struct { | 460 | const SortFdes = struct { |
| 395 | pub fn lessThan(ctx: *Elf, lhs: Fde, rhs: Fde) bool { | 461 | pub fn lessThan(ctx: *Object, lhs: Fde, rhs: Fde) bool { |
| 396 | const lhs_atom = lhs.atom(ctx); | 462 | const lhs_atom = lhs.atom(ctx); |
| 397 | const rhs_atom = rhs.atom(ctx); | 463 | const rhs_atom = rhs.atom(ctx); |
| 398 | return lhs_atom.priority(ctx) < rhs_atom.priority(ctx); | 464 | return Atom.priorityLookup(ctx.index, lhs_atom.input_section_index) < Atom.priorityLookup(ctx.index, rhs_atom.input_section_index); |
| 399 | } | 465 | } |
| 400 | }; | 466 | }; |
| 401 | mem.sort(Fde, self.fdes.items[fdes_start..], elf_file, SortFdes.lessThan); | 467 | mem.sort(Fde, self.fdes.items[fdes_start..], self, SortFdes.lessThan); |
| 402 | | 468 | |
| 403 | // Create a back-link from atom to FDEs | 469 | // Create a back-link from atom to FDEs |
| 404 | var i: u32 = @as(u32, @intCast(fdes_start)); | 470 | var i: u32 = @intCast(fdes_start); |
| 405 | while (i < self.fdes.items.len) { | 471 | while (i < self.fdes.items.len) { |
| 406 | const fde = self.fdes.items[i]; | 472 | const fde = self.fdes.items[i]; |
| 407 | const atom_ptr = fde.atom(elf_file); | 473 | const atom_ptr = fde.atom(self); |
| 408 | const start = i; | 474 | const start = i; |
| 409 | i += 1; | 475 | i += 1; |
| 410 | while (i < self.fdes.items.len) : (i += 1) { | 476 | while (i < self.fdes.items.len) : (i += 1) { |
| 411 | const next_fde = self.fdes.items[i]; | 477 | const next_fde = self.fdes.items[i]; |
| 412 | if (atom_ptr.atom_index != next_fde.atom(elf_file).atom_index) break; | 478 | if (atom_ptr.atom_index != next_fde.atom(self).atom_index) break; |
| 413 | } | 479 | } |
| 414 | atom_ptr.addExtra(.{ .fde_start = start, .fde_count = i - start }, elf_file); | 480 | self.setAtomFields(atom_ptr, .{ .fde_start = start, .fde_count = i - start }); |
| 415 | } | 481 | } |
| 416 | } | 482 | } |
| 417 | | 483 | |
| ... | @@ -904,7 +970,7 @@ pub fn markComdatGroupsDead(self: *Object, elf_file: *Elf) void { | ... | @@ -904,7 +970,7 @@ pub fn markComdatGroupsDead(self: *Object, elf_file: *Elf) void { |
| 904 | const atom_index = self.atoms_indexes.items[shndx]; | 970 | const atom_index = self.atoms_indexes.items[shndx]; |
| 905 | if (self.atom(atom_index)) |atom_ptr| { | 971 | if (self.atom(atom_index)) |atom_ptr| { |
| 906 | atom_ptr.alive = false; | 972 | atom_ptr.alive = false; |
| 907 | atom_ptr.markFdesDead(elf_file); | 973 | atom_ptr.markFdesDead(self); |
| 908 | } | 974 | } |
| 909 | } | 975 | } |
| 910 | } | 976 | } |
| ... | @@ -970,10 +1036,13 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void { | ... | @@ -970,10 +1036,13 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void { |
| 970 | } | 1036 | } |
| 971 | } | 1037 | } |
| 972 | | 1038 | |
| 973 | pub fn parseAr(self: *Object, elf_file: *Elf) !void { | 1039 | pub fn parseAr(self: *Object, path: Path, elf_file: *Elf) !void { |
| 974 | const gpa = elf_file.base.comp.gpa; | 1040 | const gpa = elf_file.base.comp.gpa; |
| | 1041 | const diags = &elf_file.base.comp.link_diags; |
| 975 | const handle = elf_file.fileHandle(self.file_handle); | 1042 | const handle = elf_file.fileHandle(self.file_handle); |
| 976 | try self.parseCommon(gpa, handle, elf_file); | 1043 | const first_eflags = &elf_file.first_eflags; |
| | 1044 | const target = elf_file.base.comp.root_mod.resolved_target.result; |
| | 1045 | try self.parseCommon(gpa, diags, path, handle, first_eflags, target); |
| 977 | } | 1046 | } |
| 978 | | 1047 | |
| 979 | pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) !void { | 1048 | pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) !void { |
| ... | @@ -1000,7 +1069,7 @@ pub fn updateArSize(self: *Object, elf_file: *Elf) !void { | ... | @@ -1000,7 +1069,7 @@ pub fn updateArSize(self: *Object, elf_file: *Elf) !void { |
| 1000 | pub fn writeAr(self: Object, elf_file: *Elf, writer: anytype) !void { | 1069 | pub fn writeAr(self: Object, elf_file: *Elf, writer: anytype) !void { |
| 1001 | const size = std.math.cast(usize, self.output_ar_state.size) orelse return error.Overflow; | 1070 | const size = std.math.cast(usize, self.output_ar_state.size) orelse return error.Overflow; |
| 1002 | const offset: u64 = if (self.archive) |ar| ar.offset else 0; | 1071 | const offset: u64 = if (self.archive) |ar| ar.offset else 0; |
| 1003 | const name = std.fs.path.basename(self.path.sub_path); | 1072 | const name = fs.path.basename(self.path.sub_path); |
| 1004 | const hdr = Archive.setArHdr(.{ | 1073 | const hdr = Archive.setArHdr(.{ |
| 1005 | .name = if (name.len <= Archive.max_member_name_len) | 1074 | .name = if (name.len <= Archive.max_member_name_len) |
| 1006 | .{ .name = name } | 1075 | .{ .name = name } |
| ... | @@ -1136,8 +1205,8 @@ pub fn resolveSymbol(self: Object, index: Symbol.Index, elf_file: *Elf) Elf.Ref | ... | @@ -1136,8 +1205,8 @@ pub fn resolveSymbol(self: Object, index: Symbol.Index, elf_file: *Elf) Elf.Ref |
| 1136 | return elf_file.resolver.get(resolv).?; | 1205 | return elf_file.resolver.get(resolv).?; |
| 1137 | } | 1206 | } |
| 1138 | | 1207 | |
| 1139 | fn addSymbol(self: *Object, allocator: Allocator) !Symbol.Index { | 1208 | fn addSymbol(self: *Object, gpa: Allocator) !Symbol.Index { |
| 1140 | try self.symbols.ensureUnusedCapacity(allocator, 1); | 1209 | try self.symbols.ensureUnusedCapacity(gpa, 1); |
| 1141 | return self.addSymbolAssumeCapacity(); | 1210 | return self.addSymbolAssumeCapacity(); |
| 1142 | } | 1211 | } |
| 1143 | | 1212 | |
| ... | @@ -1147,9 +1216,9 @@ fn addSymbolAssumeCapacity(self: *Object) Symbol.Index { | ... | @@ -1147,9 +1216,9 @@ fn addSymbolAssumeCapacity(self: *Object) Symbol.Index { |
| 1147 | return index; | 1216 | return index; |
| 1148 | } | 1217 | } |
| 1149 | | 1218 | |
| 1150 | pub fn addSymbolExtra(self: *Object, allocator: Allocator, extra: Symbol.Extra) !u32 { | 1219 | pub fn addSymbolExtra(self: *Object, gpa: Allocator, extra: Symbol.Extra) !u32 { |
| 1151 | const fields = @typeInfo(Symbol.Extra).@"struct".fields; | 1220 | const fields = @typeInfo(Symbol.Extra).@"struct".fields; |
| 1152 | try self.symbols_extra.ensureUnusedCapacity(allocator, fields.len); | 1221 | try self.symbols_extra.ensureUnusedCapacity(gpa, fields.len); |
| 1153 | return self.addSymbolExtraAssumeCapacity(extra); | 1222 | return self.addSymbolExtraAssumeCapacity(extra); |
| 1154 | } | 1223 | } |
| 1155 | | 1224 | |
| ... | @@ -1198,27 +1267,27 @@ pub fn getString(self: Object, off: u32) [:0]const u8 { | ... | @@ -1198,27 +1267,27 @@ pub fn getString(self: Object, off: u32) [:0]const u8 { |
| 1198 | return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.items.ptr + off)), 0); | 1267 | return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.items.ptr + off)), 0); |
| 1199 | } | 1268 | } |
| 1200 | | 1269 | |
| 1201 | fn addString(self: *Object, allocator: Allocator, str: []const u8) !u32 { | 1270 | fn addString(self: *Object, gpa: Allocator, str: []const u8) !u32 { |
| 1202 | const off: u32 = @intCast(self.strtab.items.len); | 1271 | const off: u32 = @intCast(self.strtab.items.len); |
| 1203 | try self.strtab.ensureUnusedCapacity(allocator, str.len + 1); | 1272 | try self.strtab.ensureUnusedCapacity(gpa, str.len + 1); |
| 1204 | self.strtab.appendSliceAssumeCapacity(str); | 1273 | self.strtab.appendSliceAssumeCapacity(str); |
| 1205 | self.strtab.appendAssumeCapacity(0); | 1274 | self.strtab.appendAssumeCapacity(0); |
| 1206 | return off; | 1275 | return off; |
| 1207 | } | 1276 | } |
| 1208 | | 1277 | |
| 1209 | /// Caller owns the memory. | 1278 | /// Caller owns the memory. |
| 1210 | fn preadShdrContentsAlloc(self: Object, allocator: Allocator, handle: std.fs.File, index: u32) ![]u8 { | 1279 | fn preadShdrContentsAlloc(self: Object, gpa: Allocator, handle: fs.File, index: u32) ![]u8 { |
| 1211 | assert(index < self.shdrs.items.len); | 1280 | assert(index < self.shdrs.items.len); |
| 1212 | const offset = if (self.archive) |ar| ar.offset else 0; | 1281 | const offset = if (self.archive) |ar| ar.offset else 0; |
| 1213 | const shdr = self.shdrs.items[index]; | 1282 | const shdr = self.shdrs.items[index]; |
| 1214 | const sh_offset = math.cast(u64, shdr.sh_offset) orelse return error.Overflow; | 1283 | const sh_offset = math.cast(u64, shdr.sh_offset) orelse return error.Overflow; |
| 1215 | const sh_size = math.cast(u64, shdr.sh_size) orelse return error.Overflow; | 1284 | const sh_size = math.cast(u64, shdr.sh_size) orelse return error.Overflow; |
| 1216 | return Elf.preadAllAlloc(allocator, handle, offset + sh_offset, sh_size); | 1285 | return Elf.preadAllAlloc(gpa, handle, offset + sh_offset, sh_size); |
| 1217 | } | 1286 | } |
| 1218 | | 1287 | |
| 1219 | /// Caller owns the memory. | 1288 | /// Caller owns the memory. |
| 1220 | fn preadRelocsAlloc(self: Object, allocator: Allocator, handle: std.fs.File, shndx: u32) ![]align(1) const elf.Elf64_Rela { | 1289 | fn preadRelocsAlloc(self: Object, gpa: Allocator, handle: fs.File, shndx: u32) ![]align(1) const elf.Elf64_Rela { |
| 1221 | const raw = try self.preadShdrContentsAlloc(allocator, handle, shndx); | 1290 | const raw = try self.preadShdrContentsAlloc(gpa, handle, shndx); |
| 1222 | const num = @divExact(raw.len, @sizeOf(elf.Elf64_Rela)); | 1291 | const num = @divExact(raw.len, @sizeOf(elf.Elf64_Rela)); |
| 1223 | return @as([*]align(1) const elf.Elf64_Rela, @ptrCast(raw.ptr))[0..num]; | 1292 | return @as([*]align(1) const elf.Elf64_Rela, @ptrCast(raw.ptr))[0..num]; |
| 1224 | } | 1293 | } |
| ... | @@ -1230,9 +1299,9 @@ const AddAtomArgs = struct { | ... | @@ -1230,9 +1299,9 @@ const AddAtomArgs = struct { |
| 1230 | alignment: Alignment, | 1299 | alignment: Alignment, |
| 1231 | }; | 1300 | }; |
| 1232 | | 1301 | |
| 1233 | fn addAtom(self: *Object, allocator: Allocator, args: AddAtomArgs) !Atom.Index { | 1302 | fn addAtom(self: *Object, gpa: Allocator, args: AddAtomArgs) !Atom.Index { |
| 1234 | try self.atoms.ensureUnusedCapacity(allocator, 1); | 1303 | try self.atoms.ensureUnusedCapacity(gpa, 1); |
| 1235 | try self.atoms_extra.ensureUnusedCapacity(allocator, @sizeOf(Atom.Extra)); | 1304 | try self.atoms_extra.ensureUnusedCapacity(gpa, @sizeOf(Atom.Extra)); |
| 1236 | return self.addAtomAssumeCapacity(args); | 1305 | return self.addAtomAssumeCapacity(args); |
| 1237 | } | 1306 | } |
| 1238 | | 1307 | |
| ... | @@ -1257,9 +1326,9 @@ pub fn atom(self: *Object, atom_index: Atom.Index) ?*Atom { | ... | @@ -1257,9 +1326,9 @@ pub fn atom(self: *Object, atom_index: Atom.Index) ?*Atom { |
| 1257 | return &self.atoms.items[atom_index]; | 1326 | return &self.atoms.items[atom_index]; |
| 1258 | } | 1327 | } |
| 1259 | | 1328 | |
| 1260 | pub fn addAtomExtra(self: *Object, allocator: Allocator, extra: Atom.Extra) !u32 { | 1329 | pub fn addAtomExtra(self: *Object, gpa: Allocator, extra: Atom.Extra) !u32 { |
| 1261 | const fields = @typeInfo(Atom.Extra).@"struct".fields; | 1330 | const fields = @typeInfo(Atom.Extra).@"struct".fields; |
| 1262 | try self.atoms_extra.ensureUnusedCapacity(allocator, fields.len); | 1331 | try self.atoms_extra.ensureUnusedCapacity(gpa, fields.len); |
| 1263 | return self.addAtomExtraAssumeCapacity(extra); | 1332 | return self.addAtomExtraAssumeCapacity(extra); |
| 1264 | } | 1333 | } |
| 1265 | | 1334 | |
| ... | @@ -1308,9 +1377,9 @@ fn setAtomFields(o: *Object, atom_ptr: *Atom, opts: Atom.Extra.AsOptionals) void | ... | @@ -1308,9 +1377,9 @@ fn setAtomFields(o: *Object, atom_ptr: *Atom, opts: Atom.Extra.AsOptionals) void |
| 1308 | o.setAtomExtra(atom_ptr.extra_index, extras); | 1377 | o.setAtomExtra(atom_ptr.extra_index, extras); |
| 1309 | } | 1378 | } |
| 1310 | | 1379 | |
| 1311 | fn addInputMergeSection(self: *Object, allocator: Allocator) !Merge.InputSection.Index { | 1380 | fn addInputMergeSection(self: *Object, gpa: Allocator) !Merge.InputSection.Index { |
| 1312 | const index: Merge.InputSection.Index = @intCast(self.input_merge_sections.items.len); | 1381 | const index: Merge.InputSection.Index = @intCast(self.input_merge_sections.items.len); |
| 1313 | const msec = try self.input_merge_sections.addOne(allocator); | 1382 | const msec = try self.input_merge_sections.addOne(gpa); |
| 1314 | msec.* = .{}; | 1383 | msec.* = .{}; |
| 1315 | return index; | 1384 | return index; |
| 1316 | } | 1385 | } |
| ... | @@ -1320,9 +1389,9 @@ fn inputMergeSection(self: *Object, index: Merge.InputSection.Index) ?*Merge.Inp | ... | @@ -1320,9 +1389,9 @@ fn inputMergeSection(self: *Object, index: Merge.InputSection.Index) ?*Merge.Inp |
| 1320 | return &self.input_merge_sections.items[index]; | 1389 | return &self.input_merge_sections.items[index]; |
| 1321 | } | 1390 | } |
| 1322 | | 1391 | |
| 1323 | fn addComdatGroup(self: *Object, allocator: Allocator) !Elf.ComdatGroup.Index { | 1392 | fn addComdatGroup(self: *Object, gpa: Allocator) !Elf.ComdatGroup.Index { |
| 1324 | const index = @as(Elf.ComdatGroup.Index, @intCast(self.comdat_groups.items.len)); | 1393 | const index = @as(Elf.ComdatGroup.Index, @intCast(self.comdat_groups.items.len)); |
| 1325 | _ = try self.comdat_groups.addOne(allocator); | 1394 | _ = try self.comdat_groups.addOne(gpa); |
| 1326 | return index; | 1395 | return index; |
| 1327 | } | 1396 | } |
| 1328 | | 1397 | |
| ... | @@ -1516,8 +1585,9 @@ const log = std.log.scoped(.link); | ... | @@ -1516,8 +1585,9 @@ const log = std.log.scoped(.link); |
| 1516 | const math = std.math; | 1585 | const math = std.math; |
| 1517 | const mem = std.mem; | 1586 | const mem = std.mem; |
| 1518 | const Path = std.Build.Cache.Path; | 1587 | const Path = std.Build.Cache.Path; |
| 1519 | const Allocator = mem.Allocator; | 1588 | const Allocator = std.mem.Allocator; |
| 1520 | | 1589 | |
| | 1590 | const Diags = @import("../../link.zig").Diags; |
| 1521 | const Archive = @import("Archive.zig"); | 1591 | const Archive = @import("Archive.zig"); |
| 1522 | const Atom = @import("Atom.zig"); | 1592 | const Atom = @import("Atom.zig"); |
| 1523 | const AtomList = @import("AtomList.zig"); | 1593 | const AtomList = @import("AtomList.zig"); |
| ... | @@ -1528,3 +1598,4 @@ const File = @import("file.zig").File; | ... | @@ -1528,3 +1598,4 @@ const File = @import("file.zig").File; |
| 1528 | const Merge = @import("Merge.zig"); | 1598 | const Merge = @import("Merge.zig"); |
| 1529 | const Symbol = @import("Symbol.zig"); | 1599 | const Symbol = @import("Symbol.zig"); |
| 1530 | const Alignment = Atom.Alignment; | 1600 | const Alignment = Atom.Alignment; |
| | 1601 | const riscv = @import("../riscv.zig"); |