diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-03-08 22:44:37 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-03-08 22:46:18 +0100 |
| commit | 859f9a22c4ac28a4e6b003b6e07c2c9912fcb074 (patch) | |
| tree | 1020151bec8fb6c54eb15334d7095a8b4b16605b /src/link/Elf/Atom.zig | |
| parent | 7c5ddb6ae410a861e139ce36dec94434392bfdad (diff) | |
| download | zig-859f9a22c4ac28a4e6b003b6e07c2c9912fcb074.tar.gz zig-859f9a22c4ac28a4e6b003b6e07c2c9912fcb074.zip | |
elf+aarch64: implement basic thunk support
Diffstat (limited to 'src/link/Elf/Atom.zig')
| -rw-r--r-- | src/link/Elf/Atom.zig | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index 34c5602b0d..4841501aa6 100644 --- a/src/link/Elf/Atom.zig +++ b/src/link/Elf/Atom.zig @@ -31,6 +31,9 @@ rel_num: u32 = 0, /// Index of this atom in the linker's atoms table. atom_index: Index = 0, +/// Index of the thunk for this atom. +thunk_index: Thunk.Index = 0, + /// Flags we use for state tracking. flags: Flags = .{}, @@ -64,6 +67,10 @@ pub fn file(self: Atom, elf_file: *Elf) ?File { return elf_file.file(self.file_index); } +pub fn thunk(self: Atom, elf_file: *Elf) *Thunk { + return elf_file.thunk(self.thunk_index); +} + pub fn inputShdr(self: Atom, elf_file: *Elf) elf.Elf64_Shdr { return switch (self.file(elf_file).?) { .object => |x| x.shdrs.items[self.input_section_index], @@ -1681,6 +1688,7 @@ const aarch64 = struct { const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow; const cwriter = stream.writer(); const code = code_buffer[rel.r_offset..][0..4]; + const file_ptr = atom.file(elf_file).?; const P, const A, const S, const GOT, const G, const TP, const DTP, const ZIG_GOT = args; _ = DTP; @@ -1701,18 +1709,15 @@ const aarch64 = struct { .CALL26, .JUMP26, => { - // TODO: add thunk support - const disp: i28 = math.cast(i28, S + A - P) orelse { - var err = try elf_file.addErrorWithNotes(1); - try err.addMsg(elf_file, "TODO: branch relocation target ({s}) exceeds max jump distance", .{ - target.name(elf_file), - }); - try err.addNote(elf_file, "in {}:{s} at offset 0x{x}", .{ - atom.file(elf_file).?.fmtPath(), - atom.name(elf_file), - r_offset, - }); - return; + const disp: i28 = math.cast(i28, S + A - P) orelse blk: { + const th = atom.thunk(elf_file); + const target_index = switch (file_ptr) { + .zig_object => |x| x.symbol(rel.r_sym()), + .object => |x| x.symbols.items[rel.r_sym()], + else => unreachable, + }; + const S_: i64 = @intCast(th.targetAddress(target_index, elf_file)); + break :blk math.cast(i28, S_ + A - P) orelse return error.Overflow; }; aarch64_util.writeBranchImm(disp, code); }, @@ -2173,3 +2178,4 @@ const Fde = eh_frame.Fde; const File = @import("file.zig").File; const Object = @import("Object.zig"); const Symbol = @import("Symbol.zig"); +const Thunk = @import("thunks.zig").Thunk; |
