| author | |
| committer | |
| log | 9ccd94d56037e05e87755887e334aa6a1a096ec5 |
| tree | 9abe67a02442a5b6bad0a653104a98088e95ccd4 |
| parent | 53340544c6666d9d35463f509fbe0416f607c91c |
5 files changed, 167 insertions(+), 72 deletions(-)
src/link/Elf.zig+49-5| ... | @@ -1235,7 +1235,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1235,7 +1235,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1235 | // input Object files. | 1235 | // input Object files. |
| 1236 | // Any qualifing unresolved symbol will be upgraded to an absolute, weak | 1236 | // Any qualifing unresolved symbol will be upgraded to an absolute, weak |
| 1237 | // symbol for potential resolution at load-time. | 1237 | // symbol for potential resolution at load-time. |
| 1238 | try self.resolveSymbols(); | 1238 | self.resolveSymbols(); |
| 1239 | self.markEhFrameAtomsDead(); | ||
| 1239 | self.markImportsExports(); | 1240 | self.markImportsExports(); |
| 1240 | self.claimUnresolved(); | 1241 | self.claimUnresolved(); |
| 1241 | 1242 | ||
| ... | @@ -1610,7 +1611,7 @@ fn parseArchive( | ... | @@ -1610,7 +1611,7 @@ fn parseArchive( |
| 1610 | /// 4. Reset state of all resolved globals since we will redo this bit on the pruned set. | 1611 | /// 4. Reset state of all resolved globals since we will redo this bit on the pruned set. |
| 1611 | /// 5. Remove references to dead objects/shared objects | 1612 | /// 5. Remove references to dead objects/shared objects |
| 1612 | /// 6. Re-run symbol resolution on pruned objects and shared objects sets. | 1613 | /// 6. Re-run symbol resolution on pruned objects and shared objects sets. |
| 1613 | fn resolveSymbols(self: *Elf) error{Overflow}!void { | 1614 | fn resolveSymbols(self: *Elf) void { |
| 1614 | // Resolve symbols in the ZigModule. For now, we assume that it's always live. | 1615 | // Resolve symbols in the ZigModule. For now, we assume that it's always live. |
| 1615 | if (self.zig_module_index) |index| self.file(index).?.resolveSymbols(self); | 1616 | if (self.zig_module_index) |index| self.file(index).?.resolveSymbols(self); |
| 1616 | // Resolve symbols on the set of all objects and shared objects (even if some are unneeded). | 1617 | // Resolve symbols on the set of all objects and shared objects (even if some are unneeded). |
| ... | @@ -1652,11 +1653,11 @@ fn resolveSymbols(self: *Elf) error{Overflow}!void { | ... | @@ -1652,11 +1653,11 @@ fn resolveSymbols(self: *Elf) error{Overflow}!void { |
| 1652 | const cg = self.comdatGroup(cg_index); | 1653 | const cg = self.comdatGroup(cg_index); |
| 1653 | const cg_owner = self.comdatGroupOwner(cg.owner); | 1654 | const cg_owner = self.comdatGroupOwner(cg.owner); |
| 1654 | if (cg_owner.file != index) { | 1655 | if (cg_owner.file != index) { |
| 1655 | for (try object.comdatGroupMembers(cg.shndx)) |shndx| { | 1656 | for (object.comdatGroupMembers(cg.shndx)) |shndx| { |
| 1656 | const atom_index = object.atoms.items[shndx]; | 1657 | const atom_index = object.atoms.items[shndx]; |
| 1657 | if (self.atom(atom_index)) |atom_ptr| { | 1658 | if (self.atom(atom_index)) |atom_ptr| { |
| 1658 | atom_ptr.flags.alive = false; | 1659 | atom_ptr.flags.alive = false; |
| 1659 | // atom_ptr.markFdesDead(self); | 1660 | atom_ptr.markFdesDead(self); |
| 1660 | } | 1661 | } |
| 1661 | } | 1662 | } |
| 1662 | } | 1663 | } |
| ... | @@ -1680,6 +1681,14 @@ fn markLive(self: *Elf) void { | ... | @@ -1680,6 +1681,14 @@ fn markLive(self: *Elf) void { |
| 1680 | } | 1681 | } |
| 1681 | } | 1682 | } |
| 1682 | 1683 | ||
| 1684 | fn markEhFrameAtomsDead(self: *Elf) void { | ||
| 1685 | for (self.objects.items) |index| { | ||
| 1686 | const file_ptr = self.file(index).?; | ||
| 1687 | if (!file_ptr.isAlive()) continue; | ||
| 1688 | file_ptr.object.markEhFrameAtomsDead(self); | ||
| 1689 | } | ||
| 1690 | } | ||
| 1691 | |||
| 1683 | fn markImportsExports(self: *Elf) void { | 1692 | fn markImportsExports(self: *Elf) void { |
| 1684 | const mark = struct { | 1693 | const mark = struct { |
| 1685 | fn mark(elf_file: *Elf, file_index: File.Index) void { | 1694 | fn mark(elf_file: *Elf, file_index: File.Index) void { |
| ... | @@ -3389,17 +3398,39 @@ fn initSections(self: *Elf) !void { | ... | @@ -3389,17 +3398,39 @@ fn initSections(self: *Elf) !void { |
| 3389 | .p32 => true, | 3398 | .p32 => true, |
| 3390 | .p64 => false, | 3399 | .p64 => false, |
| 3391 | }; | 3400 | }; |
| 3401 | const ptr_size = self.ptrWidthBytes(); | ||
| 3392 | 3402 | ||
| 3393 | for (self.objects.items) |index| { | 3403 | for (self.objects.items) |index| { |
| 3394 | try self.file(index).?.object.initOutputSections(self); | 3404 | try self.file(index).?.object.initOutputSections(self); |
| 3395 | } | 3405 | } |
| 3396 | 3406 | ||
| 3407 | const needs_eh_frame = for (self.objects.items) |index| { | ||
| 3408 | if (self.file(index).?.object.cies.items.len > 0) break true; | ||
| 3409 | } else false; | ||
| 3410 | if (needs_eh_frame) { | ||
| 3411 | self.eh_frame_section_index = try self.addSection(.{ | ||
| 3412 | .name = ".eh_frame", | ||
| 3413 | .type = elf.SHT_PROGBITS, | ||
| 3414 | .flags = elf.SHF_ALLOC, | ||
| 3415 | .addralign = ptr_size, | ||
| 3416 | }); | ||
| 3417 | |||
| 3418 | if (self.base.options.eh_frame_hdr) { | ||
| 3419 | self.eh_frame_hdr_section_index = try self.addSection(.{ | ||
| 3420 | .name = ".eh_frame_hdr", | ||
| 3421 | .type = elf.SHT_PROGBITS, | ||
| 3422 | .flags = elf.SHF_ALLOC, | ||
| 3423 | .addralign = ptr_size, | ||
| 3424 | }); | ||
| 3425 | } | ||
| 3426 | } | ||
| 3427 | |||
| 3397 | if (self.got.entries.items.len > 0 and self.got_section_index == null) { | 3428 | if (self.got.entries.items.len > 0 and self.got_section_index == null) { |
| 3398 | self.got_section_index = try self.addSection(.{ | 3429 | self.got_section_index = try self.addSection(.{ |
| 3399 | .name = ".got", | 3430 | .name = ".got", |
| 3400 | .type = elf.SHT_PROGBITS, | 3431 | .type = elf.SHT_PROGBITS, |
| 3401 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, | 3432 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, |
| 3402 | .addralign = self.ptrWidthBytes(), | 3433 | .addralign = ptr_size, |
| 3403 | }); | 3434 | }); |
| 3404 | } | 3435 | } |
| 3405 | 3436 | ||
| ... | @@ -3533,6 +3564,18 @@ fn updateSectionSizes(self: *Elf) !void { | ... | @@ -3533,6 +3564,18 @@ fn updateSectionSizes(self: *Elf) !void { |
| 3533 | self.file(index).?.object.updateSectionSizes(self); | 3564 | self.file(index).?.object.updateSectionSizes(self); |
| 3534 | } | 3565 | } |
| 3535 | 3566 | ||
| 3567 | if (self.eh_frame_section_index) |index| { | ||
| 3568 | const shdr = &self.shdrs.items[index]; | ||
| 3569 | shdr.sh_size = try eh_frame.calcEhFrameSize(self); | ||
| 3570 | shdr.sh_addralign = @alignOf(u64); | ||
| 3571 | } | ||
| 3572 | |||
| 3573 | if (self.eh_frame_hdr_section_index) |index| { | ||
| 3574 | const shdr = &self.shdrs.items[index]; | ||
| 3575 | shdr.sh_size = eh_frame.calcEhFrameHdrSize(self); | ||
| 3576 | shdr.sh_addralign = @alignOf(u32); | ||
| 3577 | } | ||
| 3578 | |||
| 3536 | if (self.got_section_index) |index| { | 3579 | if (self.got_section_index) |index| { |
| 3537 | self.shdrs.items[index].sh_size = self.got.size(self); | 3580 | self.shdrs.items[index].sh_size = self.got.size(self); |
| 3538 | } | 3581 | } |
| ... | @@ -4937,6 +4980,7 @@ const math = std.math; | ... | @@ -4937,6 +4980,7 @@ const math = std.math; |
| 4937 | const mem = std.mem; | 4980 | const mem = std.mem; |
| 4938 | 4981 | ||
| 4939 | const codegen = @import("../codegen.zig"); | 4982 | const codegen = @import("../codegen.zig"); |
| 4983 | const eh_frame = @import("Elf/eh_frame.zig"); | ||
| 4940 | const glibc = @import("../glibc.zig"); | 4984 | const glibc = @import("../glibc.zig"); |
| 4941 | const link = @import("../link.zig"); | 4985 | const link = @import("../link.zig"); |
| 4942 | const lldMain = @import("../main.zig").lldMain; | 4986 | const lldMain = @import("../main.zig").lldMain; |
src/link/Elf/Atom.zig+21-6| ... | @@ -49,7 +49,7 @@ pub fn file(self: Atom, elf_file: *Elf) ?File { | ... | @@ -49,7 +49,7 @@ pub fn file(self: Atom, elf_file: *Elf) ?File { |
| 49 | return elf_file.file(self.file_index); | 49 | return elf_file.file(self.file_index); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | pub fn inputShdr(self: Atom, elf_file: *Elf) elf.Elf64_Shdr { | 52 | pub fn inputShdr(self: Atom, elf_file: *Elf) Object.ElfShdr { |
| 53 | const object = self.file(elf_file).?.object; | 53 | const object = self.file(elf_file).?.object; |
| 54 | return object.shdrs.items[self.input_section_index]; | 54 | return object.shdrs.items[self.input_section_index]; |
| 55 | } | 55 | } |
| ... | @@ -272,7 +272,7 @@ pub fn free(self: *Atom, elf_file: *Elf) void { | ... | @@ -272,7 +272,7 @@ pub fn free(self: *Atom, elf_file: *Elf) void { |
| 272 | self.* = .{}; | 272 | self.* = .{}; |
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | pub fn relocs(self: Atom, elf_file: *Elf) error{Overflow}![]align(1) const elf.Elf64_Rela { | 275 | pub fn relocs(self: Atom, elf_file: *Elf) []align(1) const elf.Elf64_Rela { |
| 276 | return switch (self.file(elf_file).?) { | 276 | return switch (self.file(elf_file).?) { |
| 277 | .zig_module => |x| x.relocs.items[self.relocs_section_index].items, | 277 | .zig_module => |x| x.relocs.items[self.relocs_section_index].items, |
| 278 | .object => |x| x.getRelocs(self.relocs_section_index), | 278 | .object => |x| x.getRelocs(self.relocs_section_index), |
| ... | @@ -280,6 +280,18 @@ pub fn relocs(self: Atom, elf_file: *Elf) error{Overflow}![]align(1) const elf.E | ... | @@ -280,6 +280,18 @@ pub fn relocs(self: Atom, elf_file: *Elf) error{Overflow}![]align(1) const elf.E |
| 280 | }; | 280 | }; |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | pub fn fdes(self: Atom, elf_file: *Elf) []Fde { | ||
| 284 | if (self.fde_start == self.fde_end) return &[0]Fde{}; | ||
| 285 | const object = self.file(elf_file).?.object; | ||
| 286 | return object.fdes.items[self.fde_start..self.fde_end]; | ||
| 287 | } | ||
| 288 | |||
| 289 | pub fn markFdesDead(self: Atom, elf_file: *Elf) void { | ||
| 290 | for (self.fdes(elf_file)) |*fde| { | ||
| 291 | fde.alive = false; | ||
| 292 | } | ||
| 293 | } | ||
| 294 | |||
| 283 | pub fn addReloc(self: Atom, elf_file: *Elf, reloc: elf.Elf64_Rela) !void { | 295 | pub fn addReloc(self: Atom, elf_file: *Elf, reloc: elf.Elf64_Rela) !void { |
| 284 | const gpa = elf_file.base.allocator; | 296 | const gpa = elf_file.base.allocator; |
| 285 | const file_ptr = self.file(elf_file).?; | 297 | const file_ptr = self.file(elf_file).?; |
| ... | @@ -296,8 +308,8 @@ pub fn freeRelocs(self: Atom, elf_file: *Elf) void { | ... | @@ -296,8 +308,8 @@ pub fn freeRelocs(self: Atom, elf_file: *Elf) void { |
| 296 | zig_module.relocs.items[self.relocs_section_index].clearRetainingCapacity(); | 308 | zig_module.relocs.items[self.relocs_section_index].clearRetainingCapacity(); |
| 297 | } | 309 | } |
| 298 | 310 | ||
| 299 | pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) error{Overflow}!bool { | 311 | pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) bool { |
| 300 | for (try self.relocs(elf_file)) |rel| { | 312 | for (self.relocs(elf_file)) |rel| { |
| 301 | if (rel.r_type() == elf.R_X86_64_GOTTPOFF) return true; | 313 | if (rel.r_type() == elf.R_X86_64_GOTTPOFF) return true; |
| 302 | } | 314 | } |
| 303 | return false; | 315 | return false; |
| ... | @@ -306,7 +318,7 @@ pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) error{Overflow}!bool { | ... | @@ -306,7 +318,7 @@ pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) error{Overflow}!bool { |
| 306 | pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype) !void { | 318 | pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype) !void { |
| 307 | const is_dyn_lib = elf_file.isDynLib(); | 319 | const is_dyn_lib = elf_file.isDynLib(); |
| 308 | const file_ptr = self.file(elf_file).?; | 320 | const file_ptr = self.file(elf_file).?; |
| 309 | const rels = try self.relocs(elf_file); | 321 | const rels = self.relocs(elf_file); |
| 310 | var i: usize = 0; | 322 | var i: usize = 0; |
| 311 | while (i < rels.len) : (i += 1) { | 323 | while (i < rels.len) : (i += 1) { |
| 312 | const rel = rels[i]; | 324 | const rel = rels[i]; |
| ... | @@ -456,7 +468,7 @@ pub fn resolveRelocs(self: Atom, elf_file: *Elf, code: []u8) !void { | ... | @@ -456,7 +468,7 @@ pub fn resolveRelocs(self: Atom, elf_file: *Elf, code: []u8) !void { |
| 456 | var stream = std.io.fixedBufferStream(code); | 468 | var stream = std.io.fixedBufferStream(code); |
| 457 | const cwriter = stream.writer(); | 469 | const cwriter = stream.writer(); |
| 458 | 470 | ||
| 459 | const rels = try self.relocs(elf_file); | 471 | const rels = self.relocs(elf_file); |
| 460 | var i: usize = 0; | 472 | var i: usize = 0; |
| 461 | while (i < rels.len) : (i += 1) { | 473 | while (i < rels.len) : (i += 1) { |
| 462 | const rel = rels[i]; | 474 | const rel = rels[i]; |
| ... | @@ -841,11 +853,14 @@ const x86_64 = struct { | ... | @@ -841,11 +853,14 @@ const x86_64 = struct { |
| 841 | const std = @import("std"); | 853 | const std = @import("std"); |
| 842 | const assert = std.debug.assert; | 854 | const assert = std.debug.assert; |
| 843 | const elf = std.elf; | 855 | const elf = std.elf; |
| 856 | const eh_frame = @import("eh_frame.zig"); | ||
| 844 | const log = std.log.scoped(.link); | 857 | const log = std.log.scoped(.link); |
| 845 | const relocs_log = std.log.scoped(.link_relocs); | 858 | const relocs_log = std.log.scoped(.link_relocs); |
| 846 | 859 | ||
| 847 | const Allocator = std.mem.Allocator; | 860 | const Allocator = std.mem.Allocator; |
| 848 | const Atom = @This(); | 861 | const Atom = @This(); |
| 849 | const Elf = @import("../Elf.zig"); | 862 | const Elf = @import("../Elf.zig"); |
| 863 | const Fde = eh_frame.Fde; | ||
| 850 | const File = @import("file.zig").File; | 864 | const File = @import("file.zig").File; |
| 865 | const Object = @import("Object.zig"); | ||
| 851 | const Symbol = @import("Symbol.zig"); | 866 | const Symbol = @import("Symbol.zig"); |
src/link/Elf/Object.zig+72-34| ... | @@ -4,7 +4,7 @@ data: []const u8, | ... | @@ -4,7 +4,7 @@ data: []const u8, |
| 4 | index: File.Index, | 4 | index: File.Index, |
| 5 | 5 | ||
| 6 | header: ?elf.Elf64_Ehdr = null, | 6 | header: ?elf.Elf64_Ehdr = null, |
| 7 | shdrs: std.ArrayListUnmanaged(elf.Elf64_Shdr) = .{}, | 7 | shdrs: std.ArrayListUnmanaged(ElfShdr) = .{}, |
| 8 | strings: StringTable(.object_strings) = .{}, | 8 | strings: StringTable(.object_strings) = .{}, |
| 9 | symtab: []align(1) const elf.Elf64_Sym = &[0]elf.Elf64_Sym{}, | 9 | symtab: []align(1) const elf.Elf64_Sym = &[0]elf.Elf64_Sym{}, |
| 10 | strtab: []const u8 = &[0]u8{}, | 10 | strtab: []const u8 = &[0]u8{}, |
| ... | @@ -64,8 +64,13 @@ pub fn parse(self: *Object, elf_file: *Elf) !void { | ... | @@ -64,8 +64,13 @@ pub fn parse(self: *Object, elf_file: *Elf) !void { |
| 64 | [*]align(1) const elf.Elf64_Shdr, | 64 | [*]align(1) const elf.Elf64_Shdr, |
| 65 | @ptrCast(self.data.ptr + shoff), | 65 | @ptrCast(self.data.ptr + shoff), |
| 66 | )[0..self.header.?.e_shnum]; | 66 | )[0..self.header.?.e_shnum]; |
| 67 | try self.shdrs.appendUnalignedSlice(gpa, shdrs); | 67 | try self.shdrs.ensureTotalCapacityPrecise(gpa, shdrs.len); |
| 68 | try self.strings.buffer.appendSlice(gpa, try self.shdrContents(self.header.?.e_shstrndx)); | 68 | |
| 69 | for (shdrs) |shdr| { | ||
| 70 | self.shdrs.appendAssumeCapacity(try ElfShdr.fromElf64Shdr(shdr)); | ||
| 71 | } | ||
| 72 | |||
| 73 | try self.strings.buffer.appendSlice(gpa, self.shdrContents(self.header.?.e_shstrndx)); | ||
| 69 | 74 | ||
| 70 | const symtab_index = for (self.shdrs.items, 0..) |shdr, i| switch (shdr.sh_type) { | 75 | const symtab_index = for (self.shdrs.items, 0..) |shdr, i| switch (shdr.sh_type) { |
| 71 | elf.SHT_SYMTAB => break @as(u16, @intCast(i)), | 76 | elf.SHT_SYMTAB => break @as(u16, @intCast(i)), |
| ... | @@ -76,21 +81,21 @@ pub fn parse(self: *Object, elf_file: *Elf) !void { | ... | @@ -76,21 +81,21 @@ pub fn parse(self: *Object, elf_file: *Elf) !void { |
| 76 | const shdr = shdrs[index]; | 81 | const shdr = shdrs[index]; |
| 77 | self.first_global = shdr.sh_info; | 82 | self.first_global = shdr.sh_info; |
| 78 | 83 | ||
| 79 | const symtab = try self.shdrContents(index); | 84 | const symtab = self.shdrContents(index); |
| 80 | const nsyms = @divExact(symtab.len, @sizeOf(elf.Elf64_Sym)); | 85 | const nsyms = @divExact(symtab.len, @sizeOf(elf.Elf64_Sym)); |
| 81 | self.symtab = @as([*]align(1) const elf.Elf64_Sym, @ptrCast(symtab.ptr))[0..nsyms]; | 86 | self.symtab = @as([*]align(1) const elf.Elf64_Sym, @ptrCast(symtab.ptr))[0..nsyms]; |
| 82 | self.strtab = try self.shdrContents(@as(u16, @intCast(shdr.sh_link))); | 87 | self.strtab = self.shdrContents(@as(u16, @intCast(shdr.sh_link))); |
| 83 | } | 88 | } |
| 84 | 89 | ||
| 85 | try self.initAtoms(elf_file); | 90 | try self.initAtoms(elf_file); |
| 86 | try self.initSymtab(elf_file); | 91 | try self.initSymtab(elf_file); |
| 87 | 92 | ||
| 88 | // for (self.shdrs.items, 0..) |shdr, i| { | 93 | for (self.shdrs.items, 0..) |shdr, i| { |
| 89 | // const atom = elf_file.atom(self.atoms.items[i]) orelse continue; | 94 | const atom = elf_file.atom(self.atoms.items[i]) orelse continue; |
| 90 | // if (!atom.alive) continue; | 95 | if (!atom.flags.alive) continue; |
| 91 | // if (shdr.sh_type == elf.SHT_X86_64_UNWIND or mem.eql(u8, atom.name(elf_file), ".eh_frame")) | 96 | if (shdr.sh_type == elf.SHT_X86_64_UNWIND or mem.eql(u8, atom.name(elf_file), ".eh_frame")) |
| 92 | // try self.parseEhFrame(@as(u16, @intCast(i)), elf_file); | 97 | try self.parseEhFrame(@as(u16, @intCast(i)), elf_file); |
| 93 | // } | 98 | } |
| 94 | } | 99 | } |
| 95 | 100 | ||
| 96 | fn initAtoms(self: *Object, elf_file: *Elf) !void { | 101 | fn initAtoms(self: *Object, elf_file: *Elf) !void { |
| ... | @@ -120,7 +125,7 @@ fn initAtoms(self: *Object, elf_file: *Elf) !void { | ... | @@ -120,7 +125,7 @@ fn initAtoms(self: *Object, elf_file: *Elf) !void { |
| 120 | }; | 125 | }; |
| 121 | 126 | ||
| 122 | const shndx = @as(u16, @intCast(i)); | 127 | const shndx = @as(u16, @intCast(i)); |
| 123 | const group_raw_data = try self.shdrContents(shndx); | 128 | const group_raw_data = self.shdrContents(shndx); |
| 124 | const group_nmembers = @divExact(group_raw_data.len, @sizeOf(u32)); | 129 | const group_nmembers = @divExact(group_raw_data.len, @sizeOf(u32)); |
| 125 | const group_members = @as([*]align(1) const u32, @ptrCast(group_raw_data.ptr))[0..group_nmembers]; | 130 | const group_members = @as([*]align(1) const u32, @ptrCast(group_raw_data.ptr))[0..group_nmembers]; |
| 126 | 131 | ||
| ... | @@ -173,11 +178,11 @@ fn initAtoms(self: *Object, elf_file: *Elf) !void { | ... | @@ -173,11 +178,11 @@ fn initAtoms(self: *Object, elf_file: *Elf) !void { |
| 173 | 178 | ||
| 174 | fn addAtom( | 179 | fn addAtom( |
| 175 | self: *Object, | 180 | self: *Object, |
| 176 | shdr: elf.Elf64_Shdr, | 181 | shdr: ElfShdr, |
| 177 | shndx: u16, | 182 | shndx: u16, |
| 178 | name: [:0]const u8, | 183 | name: [:0]const u8, |
| 179 | elf_file: *Elf, | 184 | elf_file: *Elf, |
| 180 | ) error{ OutOfMemory, Overflow }!void { | 185 | ) error{OutOfMemory}!void { |
| 181 | const atom_index = try elf_file.addAtom(); | 186 | const atom_index = try elf_file.addAtom(); |
| 182 | const atom = elf_file.atom(atom_index).?; | 187 | const atom = elf_file.atom(atom_index).?; |
| 183 | atom.atom_index = atom_index; | 188 | atom.atom_index = atom_index; |
| ... | @@ -188,7 +193,7 @@ fn addAtom( | ... | @@ -188,7 +193,7 @@ fn addAtom( |
| 188 | self.atoms.items[shndx] = atom_index; | 193 | self.atoms.items[shndx] = atom_index; |
| 189 | 194 | ||
| 190 | if (shdr.sh_flags & elf.SHF_COMPRESSED != 0) { | 195 | if (shdr.sh_flags & elf.SHF_COMPRESSED != 0) { |
| 191 | const data = try self.shdrContents(shndx); | 196 | const data = self.shdrContents(shndx); |
| 192 | const chdr = @as(*align(1) const elf.Elf64_Chdr, @ptrCast(data.ptr)).*; | 197 | const chdr = @as(*align(1) const elf.Elf64_Chdr, @ptrCast(data.ptr)).*; |
| 193 | atom.size = chdr.ch_size; | 198 | atom.size = chdr.ch_size; |
| 194 | atom.alignment = Alignment.fromNonzeroByteUnits(chdr.ch_addralign); | 199 | atom.alignment = Alignment.fromNonzeroByteUnits(chdr.ch_addralign); |
| ... | @@ -198,7 +203,7 @@ fn addAtom( | ... | @@ -198,7 +203,7 @@ fn addAtom( |
| 198 | } | 203 | } |
| 199 | } | 204 | } |
| 200 | 205 | ||
| 201 | fn initOutputSection(self: Object, elf_file: *Elf, shdr: elf.Elf64_Shdr) error{OutOfMemory}!u16 { | 206 | fn initOutputSection(self: Object, elf_file: *Elf, shdr: ElfShdr) error{OutOfMemory}!u16 { |
| 202 | const name = blk: { | 207 | const name = blk: { |
| 203 | const name = self.strings.getAssumeExists(shdr.sh_name); | 208 | const name = self.strings.getAssumeExists(shdr.sh_name); |
| 204 | if (shdr.sh_flags & elf.SHF_MERGE != 0) break :blk name; | 209 | if (shdr.sh_flags & elf.SHF_MERGE != 0) break :blk name; |
| ... | @@ -244,7 +249,6 @@ fn initOutputSection(self: Object, elf_file: *Elf, shdr: elf.Elf64_Shdr) error{O | ... | @@ -244,7 +249,6 @@ fn initOutputSection(self: Object, elf_file: *Elf, shdr: elf.Elf64_Shdr) error{O |
| 244 | } | 249 | } |
| 245 | 250 | ||
| 246 | fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool { | 251 | fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool { |
| 247 | _ = elf_file; | ||
| 248 | const shdr = self.shdrs.items[index]; | 252 | const shdr = self.shdrs.items[index]; |
| 249 | const name = self.strings.getAssumeExists(shdr.sh_name); | 253 | const name = self.strings.getAssumeExists(shdr.sh_name); |
| 250 | const ignore = blk: { | 254 | const ignore = blk: { |
| ... | @@ -252,9 +256,8 @@ fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool { | ... | @@ -252,9 +256,8 @@ fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool { |
| 252 | if (mem.startsWith(u8, name, ".comment")) break :blk true; | 256 | if (mem.startsWith(u8, name, ".comment")) break :blk true; |
| 253 | if (mem.startsWith(u8, name, ".llvm_addrsig")) break :blk true; | 257 | if (mem.startsWith(u8, name, ".llvm_addrsig")) break :blk true; |
| 254 | if (mem.startsWith(u8, name, ".eh_frame")) break :blk true; | 258 | if (mem.startsWith(u8, name, ".eh_frame")) break :blk true; |
| 255 | // if (elf_file.base.options.strip and shdr.sh_flags & elf.SHF_ALLOC == 0 and | 259 | if (elf_file.base.options.strip and shdr.sh_flags & elf.SHF_ALLOC == 0 and |
| 256 | // mem.startsWith(u8, name, ".debug")) break :blk true; | 260 | mem.startsWith(u8, name, ".debug")) break :blk true; |
| 257 | if (shdr.sh_flags & elf.SHF_ALLOC == 0 and mem.startsWith(u8, name, ".debug")) break :blk true; | ||
| 258 | break :blk false; | 261 | break :blk false; |
| 259 | }; | 262 | }; |
| 260 | return ignore; | 263 | return ignore; |
| ... | @@ -303,8 +306,8 @@ fn parseEhFrame(self: *Object, shndx: u16, elf_file: *Elf) !void { | ... | @@ -303,8 +306,8 @@ fn parseEhFrame(self: *Object, shndx: u16, elf_file: *Elf) !void { |
| 303 | }; | 306 | }; |
| 304 | 307 | ||
| 305 | const gpa = elf_file.base.allocator; | 308 | const gpa = elf_file.base.allocator; |
| 306 | const raw = try self.shdrContents(shndx); | 309 | const raw = self.shdrContents(shndx); |
| 307 | const relocs = try self.getRelocs(relocs_shndx); | 310 | const relocs = self.getRelocs(relocs_shndx); |
| 308 | const fdes_start = self.fdes.items.len; | 311 | const fdes_start = self.fdes.items.len; |
| 309 | const cies_start = self.cies.items.len; | 312 | const cies_start = self.cies.items.len; |
| 310 | 313 | ||
| ... | @@ -408,7 +411,7 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void { | ... | @@ -408,7 +411,7 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void { |
| 408 | const shdr = atom.inputShdr(elf_file); | 411 | const shdr = atom.inputShdr(elf_file); |
| 409 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; | 412 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; |
| 410 | if (shdr.sh_type == elf.SHT_NOBITS) continue; | 413 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 411 | if (try atom.scanRelocsRequiresCode(elf_file)) { | 414 | if (atom.scanRelocsRequiresCode(elf_file)) { |
| 412 | // TODO ideally, we don't have to decompress at this stage (should already be done) | 415 | // TODO ideally, we don't have to decompress at this stage (should already be done) |
| 413 | // and we just fetch the code slice. | 416 | // and we just fetch the code slice. |
| 414 | const code = try self.codeDecompressAlloc(elf_file, atom_index); | 417 | const code = try self.codeDecompressAlloc(elf_file, atom_index); |
| ... | @@ -418,7 +421,7 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void { | ... | @@ -418,7 +421,7 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void { |
| 418 | } | 421 | } |
| 419 | 422 | ||
| 420 | for (self.cies.items) |cie| { | 423 | for (self.cies.items) |cie| { |
| 421 | for (try cie.relocs(elf_file)) |rel| { | 424 | for (cie.relocs(elf_file)) |rel| { |
| 422 | const sym = elf_file.symbol(self.symbols.items[rel.r_sym()]); | 425 | const sym = elf_file.symbol(self.symbols.items[rel.r_sym()]); |
| 423 | if (sym.flags.import) { | 426 | if (sym.flags.import) { |
| 424 | if (sym.type(elf_file) != elf.STT_FUNC) | 427 | if (sym.type(elf_file) != elf.STT_FUNC) |
| ... | @@ -518,6 +521,15 @@ pub fn markLive(self: *Object, elf_file: *Elf) void { | ... | @@ -518,6 +521,15 @@ pub fn markLive(self: *Object, elf_file: *Elf) void { |
| 518 | } | 521 | } |
| 519 | } | 522 | } |
| 520 | 523 | ||
| 524 | pub fn markEhFrameAtomsDead(self: Object, elf_file: *Elf) void { | ||
| 525 | for (self.atoms.items) |atom_index| { | ||
| 526 | const atom = elf_file.atom(atom_index) orelse continue; | ||
| 527 | const is_eh_frame = atom.inputShdr(elf_file).sh_type == elf.SHT_X86_64_UNWIND or | ||
| 528 | mem.eql(u8, atom.name(elf_file), ".eh_frame"); | ||
| 529 | if (atom.flags.alive and is_eh_frame) atom.flags.alive = false; | ||
| 530 | } | ||
| 531 | } | ||
| 532 | |||
| 521 | pub fn checkDuplicates(self: *Object, elf_file: *Elf) void { | 533 | pub fn checkDuplicates(self: *Object, elf_file: *Elf) void { |
| 522 | const first_global = self.first_global orelse return; | 534 | const first_global = self.first_global orelse return; |
| 523 | for (self.globals(), 0..) |index, i| { | 535 | for (self.globals(), 0..) |index, i| { |
| ... | @@ -747,12 +759,10 @@ pub fn globals(self: Object) []const Symbol.Index { | ... | @@ -747,12 +759,10 @@ pub fn globals(self: Object) []const Symbol.Index { |
| 747 | return self.symbols.items[start..]; | 759 | return self.symbols.items[start..]; |
| 748 | } | 760 | } |
| 749 | 761 | ||
| 750 | fn shdrContents(self: Object, index: u32) error{Overflow}![]const u8 { | 762 | pub fn shdrContents(self: Object, index: u32) []const u8 { |
| 751 | assert(index < self.shdrs.items.len); | 763 | assert(index < self.shdrs.items.len); |
| 752 | const shdr = self.shdrs.items[index]; | 764 | const shdr = self.shdrs.items[index]; |
| 753 | const offset = math.cast(usize, shdr.sh_offset) orelse return error.Overflow; | 765 | return self.data[shdr.sh_offset..][0..shdr.sh_size]; |
| 754 | const size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; | ||
| 755 | return self.data[offset..][0..size]; | ||
| 756 | } | 766 | } |
| 757 | 767 | ||
| 758 | /// Returns atom's code and optionally uncompresses data if required (for compressed sections). | 768 | /// Returns atom's code and optionally uncompresses data if required (for compressed sections). |
| ... | @@ -761,7 +771,7 @@ pub fn codeDecompressAlloc(self: Object, elf_file: *Elf, atom_index: Atom.Index) | ... | @@ -761,7 +771,7 @@ pub fn codeDecompressAlloc(self: Object, elf_file: *Elf, atom_index: Atom.Index) |
| 761 | const gpa = elf_file.base.allocator; | 771 | const gpa = elf_file.base.allocator; |
| 762 | const atom_ptr = elf_file.atom(atom_index).?; | 772 | const atom_ptr = elf_file.atom(atom_index).?; |
| 763 | assert(atom_ptr.file_index == self.index); | 773 | assert(atom_ptr.file_index == self.index); |
| 764 | const data = try self.shdrContents(atom_ptr.input_section_index); | 774 | const data = self.shdrContents(atom_ptr.input_section_index); |
| 765 | const shdr = atom_ptr.inputShdr(elf_file); | 775 | const shdr = atom_ptr.inputShdr(elf_file); |
| 766 | if (shdr.sh_flags & elf.SHF_COMPRESSED != 0) { | 776 | if (shdr.sh_flags & elf.SHF_COMPRESSED != 0) { |
| 767 | const chdr = @as(*align(1) const elf.Elf64_Chdr, @ptrCast(data.ptr)).*; | 777 | const chdr = @as(*align(1) const elf.Elf64_Chdr, @ptrCast(data.ptr)).*; |
| ... | @@ -789,8 +799,8 @@ fn getString(self: *Object, off: u32) [:0]const u8 { | ... | @@ -789,8 +799,8 @@ fn getString(self: *Object, off: u32) [:0]const u8 { |
| 789 | return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.ptr + off)), 0); | 799 | return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.ptr + off)), 0); |
| 790 | } | 800 | } |
| 791 | 801 | ||
| 792 | pub fn comdatGroupMembers(self: *Object, index: u16) error{Overflow}![]align(1) const u32 { | 802 | pub fn comdatGroupMembers(self: *Object, index: u16) []align(1) const u32 { |
| 793 | const raw = try self.shdrContents(index); | 803 | const raw = self.shdrContents(index); |
| 794 | const nmembers = @divExact(raw.len, @sizeOf(u32)); | 804 | const nmembers = @divExact(raw.len, @sizeOf(u32)); |
| 795 | const members = @as([*]align(1) const u32, @ptrCast(raw.ptr))[1..nmembers]; | 805 | const members = @as([*]align(1) const u32, @ptrCast(raw.ptr))[1..nmembers]; |
| 796 | return members; | 806 | return members; |
| ... | @@ -800,8 +810,8 @@ pub fn asFile(self: *Object) File { | ... | @@ -800,8 +810,8 @@ pub fn asFile(self: *Object) File { |
| 800 | return .{ .object = self }; | 810 | return .{ .object = self }; |
| 801 | } | 811 | } |
| 802 | 812 | ||
| 803 | pub fn getRelocs(self: *Object, shndx: u32) error{Overflow}![]align(1) const elf.Elf64_Rela { | 813 | pub fn getRelocs(self: *Object, shndx: u32) []align(1) const elf.Elf64_Rela { |
| 804 | const raw = try self.shdrContents(shndx); | 814 | const raw = self.shdrContents(shndx); |
| 805 | const num = @divExact(raw.len, @sizeOf(elf.Elf64_Rela)); | 815 | const num = @divExact(raw.len, @sizeOf(elf.Elf64_Rela)); |
| 806 | return @as([*]align(1) const elf.Elf64_Rela, @ptrCast(raw.ptr))[0..num]; | 816 | return @as([*]align(1) const elf.Elf64_Rela, @ptrCast(raw.ptr))[0..num]; |
| 807 | } | 817 | } |
| ... | @@ -941,7 +951,7 @@ fn formatComdatGroups( | ... | @@ -941,7 +951,7 @@ fn formatComdatGroups( |
| 941 | const cg = elf_file.comdatGroup(cg_index); | 951 | const cg = elf_file.comdatGroup(cg_index); |
| 942 | const cg_owner = elf_file.comdatGroupOwner(cg.owner); | 952 | const cg_owner = elf_file.comdatGroupOwner(cg.owner); |
| 943 | if (cg_owner.file != object.index) continue; | 953 | if (cg_owner.file != object.index) continue; |
| 944 | const cg_members = object.comdatGroupMembers(cg.shndx) catch continue; | 954 | const cg_members = object.comdatGroupMembers(cg.shndx); |
| 945 | for (cg_members) |shndx| { | 955 | for (cg_members) |shndx| { |
| 946 | const atom_index = object.atoms.items[shndx]; | 956 | const atom_index = object.atoms.items[shndx]; |
| 947 | const atom = elf_file.atom(atom_index) orelse continue; | 957 | const atom = elf_file.atom(atom_index) orelse continue; |
| ... | @@ -970,6 +980,34 @@ fn formatPath( | ... | @@ -970,6 +980,34 @@ fn formatPath( |
| 970 | } else try writer.writeAll(object.path); | 980 | } else try writer.writeAll(object.path); |
| 971 | } | 981 | } |
| 972 | 982 | ||
| 983 | pub const ElfShdr = struct { | ||
| 984 | sh_name: u32, | ||
| 985 | sh_type: u32, | ||
| 986 | sh_flags: u64, | ||
| 987 | sh_addr: u64, | ||
| 988 | sh_offset: usize, | ||
| 989 | sh_size: usize, | ||
| 990 | sh_link: u32, | ||
| 991 | sh_info: u32, | ||
| 992 | sh_addralign: u64, | ||
| 993 | sh_entsize: u64, | ||
| 994 | |||
| 995 | fn fromElf64Shdr(shdr: elf.Elf64_Shdr) error{Overflow}!ElfShdr { | ||
| 996 | return .{ | ||
| 997 | .sh_name = shdr.sh_name, | ||
| 998 | .sh_type = shdr.sh_type, | ||
| 999 | .sh_flags = shdr.sh_flags, | ||
| 1000 | .sh_addr = shdr.sh_addr, | ||
| 1001 | .sh_offset = math.cast(usize, shdr.sh_offset) orelse return error.Overflow, | ||
| 1002 | .sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow, | ||
| 1003 | .sh_link = shdr.sh_link, | ||
| 1004 | .sh_info = shdr.sh_info, | ||
| 1005 | .sh_addralign = shdr.sh_addralign, | ||
| 1006 | .sh_entsize = shdr.sh_entsize, | ||
| 1007 | }; | ||
| 1008 | } | ||
| 1009 | }; | ||
| 1010 | |||
| 973 | const Object = @This(); | 1011 | const Object = @This(); |
| 974 | 1012 | ||
| 975 | const std = @import("std"); | 1013 | const std = @import("std"); |
src/link/Elf/ZigModule.zig+1-1| ... | @@ -145,7 +145,7 @@ pub fn scanRelocs(self: *ZigModule, elf_file: *Elf, undefs: anytype) !void { | ... | @@ -145,7 +145,7 @@ pub fn scanRelocs(self: *ZigModule, elf_file: *Elf, undefs: anytype) !void { |
| 145 | for (self.atoms.items) |atom_index| { | 145 | for (self.atoms.items) |atom_index| { |
| 146 | const atom = elf_file.atom(atom_index) orelse continue; | 146 | const atom = elf_file.atom(atom_index) orelse continue; |
| 147 | if (!atom.flags.alive) continue; | 147 | if (!atom.flags.alive) continue; |
| 148 | if (try atom.scanRelocsRequiresCode(elf_file)) { | 148 | if (atom.scanRelocsRequiresCode(elf_file)) { |
| 149 | // TODO ideally we don't have to fetch the code here. | 149 | // TODO ideally we don't have to fetch the code here. |
| 150 | // Perhaps it would make sense to save the code until flushModule where we | 150 | // Perhaps it would make sense to save the code until flushModule where we |
| 151 | // would free all of generated code? | 151 | // would free all of generated code? |
src/link/Elf/eh_frame.zig+24-26| ... | @@ -20,9 +20,9 @@ pub const Fde = struct { | ... | @@ -20,9 +20,9 @@ pub const Fde = struct { |
| 20 | return base + fde.out_offset; | 20 | return base + fde.out_offset; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | pub fn data(fde: Fde, elf_file: *Elf) error{Overflow}![]const u8 { | 23 | pub fn data(fde: Fde, elf_file: *Elf) []const u8 { |
| 24 | const object = elf_file.file(fde.file_index).?.object; | 24 | const object = elf_file.file(fde.file_index).?.object; |
| 25 | const contents = try object.shdrContents(fde.input_section_index); | 25 | const contents = object.shdrContents(fde.input_section_index); |
| 26 | return contents[fde.offset..][0..fde.calcSize()]; | 26 | return contents[fde.offset..][0..fde.calcSize()]; |
| 27 | } | 27 | } |
| 28 | 28 | ||
| ... | @@ -32,24 +32,25 @@ pub const Fde = struct { | ... | @@ -32,24 +32,25 @@ pub const Fde = struct { |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | pub fn ciePointer(fde: Fde, elf_file: *Elf) u32 { | 34 | pub fn ciePointer(fde: Fde, elf_file: *Elf) u32 { |
| 35 | return std.mem.readIntLittle(u32, fde.data(elf_file)[4..8]); | 35 | const fde_data = fde.data(elf_file); |
| 36 | return std.mem.readIntLittle(u32, fde_data[4..8]); | ||
| 36 | } | 37 | } |
| 37 | 38 | ||
| 38 | pub fn calcSize(fde: Fde) u64 { | 39 | pub fn calcSize(fde: Fde) u64 { |
| 39 | return fde.size + 4; | 40 | return fde.size + 4; |
| 40 | } | 41 | } |
| 41 | 42 | ||
| 42 | pub fn atom(fde: Fde, elf_file: *Elf) error{Overflow}!*Atom { | 43 | pub fn atom(fde: Fde, elf_file: *Elf) *Atom { |
| 43 | const object = elf_file.file(fde.file_index).?.object; | 44 | const object = elf_file.file(fde.file_index).?.object; |
| 44 | const rel = (try fde.relocs(elf_file))[0]; | 45 | const rel = fde.relocs(elf_file)[0]; |
| 45 | const sym = object.symtab[rel.r_sym()]; | 46 | const sym = object.symtab[rel.r_sym()]; |
| 46 | const atom_index = object.atoms.items[sym.st_shndx]; | 47 | const atom_index = object.atoms.items[sym.st_shndx]; |
| 47 | return elf_file.atom(atom_index).?; | 48 | return elf_file.atom(atom_index).?; |
| 48 | } | 49 | } |
| 49 | 50 | ||
| 50 | pub fn relocs(fde: Fde, elf_file: *Elf) error{Overflow}![]align(1) const elf.Elf64_Rela { | 51 | pub fn relocs(fde: Fde, elf_file: *Elf) []align(1) const elf.Elf64_Rela { |
| 51 | const object = elf_file.file(fde.file_index).?.object; | 52 | const object = elf_file.file(fde.file_index).?.object; |
| 52 | return (try object.getRelocs(fde.rel_section_index))[fde.rel_index..][0..fde.rel_num]; | 53 | return object.getRelocs(fde.rel_section_index)[fde.rel_index..][0..fde.rel_num]; |
| 53 | } | 54 | } |
| 54 | 55 | ||
| 55 | pub fn format( | 56 | pub fn format( |
| ... | @@ -88,10 +89,7 @@ pub const Fde = struct { | ... | @@ -88,10 +89,7 @@ pub const Fde = struct { |
| 88 | const fde = ctx.fde; | 89 | const fde = ctx.fde; |
| 89 | const elf_file = ctx.elf_file; | 90 | const elf_file = ctx.elf_file; |
| 90 | const base_addr = fde.address(elf_file); | 91 | const base_addr = fde.address(elf_file); |
| 91 | const atom_name = if (fde.atom(elf_file)) |atom_ptr| | 92 | const atom_name = fde.atom(elf_file).name(elf_file); |
| 92 | atom_ptr.name(elf_file) | ||
| 93 | else |_| | ||
| 94 | ""; | ||
| 95 | try writer.print("@{x} : size({x}) : cie({d}) : {s}", .{ | 93 | try writer.print("@{x} : size({x}) : cie({d}) : {s}", .{ |
| 96 | base_addr + fde.out_offset, | 94 | base_addr + fde.out_offset, |
| 97 | fde.calcSize(), | 95 | fde.calcSize(), |
| ... | @@ -123,9 +121,9 @@ pub const Cie = struct { | ... | @@ -123,9 +121,9 @@ pub const Cie = struct { |
| 123 | return base + cie.out_offset; | 121 | return base + cie.out_offset; |
| 124 | } | 122 | } |
| 125 | 123 | ||
| 126 | pub fn data(cie: Cie, elf_file: *Elf) error{Overflow}![]const u8 { | 124 | pub fn data(cie: Cie, elf_file: *Elf) []const u8 { |
| 127 | const object = elf_file.file(cie.file_index).?.object; | 125 | const object = elf_file.file(cie.file_index).?.object; |
| 128 | const contents = try object.shdrContents(cie.input_section_index); | 126 | const contents = object.shdrContents(cie.input_section_index); |
| 129 | return contents[cie.offset..][0..cie.calcSize()]; | 127 | return contents[cie.offset..][0..cie.calcSize()]; |
| 130 | } | 128 | } |
| 131 | 129 | ||
| ... | @@ -133,16 +131,16 @@ pub const Cie = struct { | ... | @@ -133,16 +131,16 @@ pub const Cie = struct { |
| 133 | return cie.size + 4; | 131 | return cie.size + 4; |
| 134 | } | 132 | } |
| 135 | 133 | ||
| 136 | pub fn relocs(cie: Cie, elf_file: *Elf) error{Overflow}![]align(1) const elf.Elf64_Rela { | 134 | pub fn relocs(cie: Cie, elf_file: *Elf) []align(1) const elf.Elf64_Rela { |
| 137 | const object = elf_file.file(cie.file_index).?.object; | 135 | const object = elf_file.file(cie.file_index).?.object; |
| 138 | return (try object.getRelocs(cie.rel_section_index))[cie.rel_index..][0..cie.rel_num]; | 136 | return object.getRelocs(cie.rel_section_index)[cie.rel_index..][0..cie.rel_num]; |
| 139 | } | 137 | } |
| 140 | 138 | ||
| 141 | pub fn eql(cie: Cie, other: Cie, elf_file: *Elf) error{Overflow}!bool { | 139 | pub fn eql(cie: Cie, other: Cie, elf_file: *Elf) bool { |
| 142 | if (!std.mem.eql(u8, try cie.data(elf_file), try other.data(elf_file))) return false; | 140 | if (!std.mem.eql(u8, cie.data(elf_file), other.data(elf_file))) return false; |
| 143 | 141 | ||
| 144 | const cie_relocs = try cie.relocs(elf_file); | 142 | const cie_relocs = cie.relocs(elf_file); |
| 145 | const other_relocs = try other.relocs(elf_file); | 143 | const other_relocs = other.relocs(elf_file); |
| 146 | if (cie_relocs.len != other_relocs.len) return false; | 144 | if (cie_relocs.len != other_relocs.len) return false; |
| 147 | 145 | ||
| 148 | for (cie_relocs, other_relocs) |cie_rel, other_rel| { | 146 | for (cie_relocs, other_relocs) |cie_rel, other_rel| { |
| ... | @@ -152,8 +150,8 @@ pub const Cie = struct { | ... | @@ -152,8 +150,8 @@ pub const Cie = struct { |
| 152 | 150 | ||
| 153 | const cie_object = elf_file.file(cie.file_index).?.object; | 151 | const cie_object = elf_file.file(cie.file_index).?.object; |
| 154 | const other_object = elf_file.file(other.file_index).?.object; | 152 | const other_object = elf_file.file(other.file_index).?.object; |
| 155 | const cie_sym = cie_object.symbol(cie_rel.r_sym(), elf_file); | 153 | const cie_sym = cie_object.symbols.items[cie_rel.r_sym()]; |
| 156 | const other_sym = other_object.symbol(other_rel.r_sym(), elf_file); | 154 | const other_sym = other_object.symbols.items[other_rel.r_sym()]; |
| 157 | if (!std.mem.eql(u8, std.mem.asBytes(&cie_sym), std.mem.asBytes(&other_sym))) return false; | 155 | if (!std.mem.eql(u8, std.mem.asBytes(&cie_sym), std.mem.asBytes(&other_sym))) return false; |
| 158 | } | 156 | } |
| 159 | return true; | 157 | return true; |
| ... | @@ -319,10 +317,10 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void { | ... | @@ -319,10 +317,10 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void { |
| 319 | for (object.cies.items) |cie| { | 317 | for (object.cies.items) |cie| { |
| 320 | if (!cie.alive) continue; | 318 | if (!cie.alive) continue; |
| 321 | 319 | ||
| 322 | const contents = try gpa.dupe(u8, try cie.data(elf_file)); | 320 | const contents = try gpa.dupe(u8, cie.data(elf_file)); |
| 323 | defer gpa.free(contents); | 321 | defer gpa.free(contents); |
| 324 | 322 | ||
| 325 | for (try cie.relocs(elf_file)) |rel| { | 323 | for (cie.relocs(elf_file)) |rel| { |
| 326 | const sym = object.symbol(rel.r_sym(), elf_file); | 324 | const sym = object.symbol(rel.r_sym(), elf_file); |
| 327 | try resolveReloc(cie, sym, rel, elf_file, contents); | 325 | try resolveReloc(cie, sym, rel, elf_file, contents); |
| 328 | } | 326 | } |
| ... | @@ -337,7 +335,7 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void { | ... | @@ -337,7 +335,7 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void { |
| 337 | for (object.fdes.items) |fde| { | 335 | for (object.fdes.items) |fde| { |
| 338 | if (!fde.alive) continue; | 336 | if (!fde.alive) continue; |
| 339 | 337 | ||
| 340 | const contents = try gpa.dupe(u8, try fde.data(elf_file)); | 338 | const contents = try gpa.dupe(u8, fde.data(elf_file)); |
| 341 | defer gpa.free(contents); | 339 | defer gpa.free(contents); |
| 342 | 340 | ||
| 343 | std.mem.writeIntLittle( | 341 | std.mem.writeIntLittle( |
| ... | @@ -346,7 +344,7 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void { | ... | @@ -346,7 +344,7 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void { |
| 346 | @as(i32, @truncate(@as(i64, @intCast(fde.out_offset + 4)) - @as(i64, @intCast(fde.cie(elf_file).out_offset)))), | 344 | @as(i32, @truncate(@as(i64, @intCast(fde.out_offset + 4)) - @as(i64, @intCast(fde.cie(elf_file).out_offset)))), |
| 347 | ); | 345 | ); |
| 348 | 346 | ||
| 349 | for (try fde.relocs(elf_file)) |rel| { | 347 | for (fde.relocs(elf_file)) |rel| { |
| 350 | const sym = object.symbol(rel.r_sym(), elf_file); | 348 | const sym = object.symbol(rel.r_sym(), elf_file); |
| 351 | try resolveReloc(fde, sym, rel, elf_file, contents); | 349 | try resolveReloc(fde, sym, rel, elf_file, contents); |
| 352 | } | 350 | } |
| ... | @@ -395,7 +393,7 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void { | ... | @@ -395,7 +393,7 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void { |
| 395 | for (object.fdes.items) |fde| { | 393 | for (object.fdes.items) |fde| { |
| 396 | if (!fde.alive) continue; | 394 | if (!fde.alive) continue; |
| 397 | 395 | ||
| 398 | const relocs = try fde.relocs(elf_file); | 396 | const relocs = fde.relocs(elf_file); |
| 399 | assert(relocs.len > 0); // Should this be an error? Things are completely broken anyhow if this trips... | 397 | assert(relocs.len > 0); // Should this be an error? Things are completely broken anyhow if this trips... |
| 400 | const rel = relocs[0]; | 398 | const rel = relocs[0]; |
| 401 | const sym = object.symbol(rel.r_sym(), elf_file); | 399 | const sym = object.symbol(rel.r_sym(), elf_file); |