diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2023-09-30 08:43:33 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-30 08:43:33 +0200 |
| commit | 873c695c41dffd89ba7ef1b3ed6662e429bfa00d (patch) | |
| tree | b2131a824259cf307d2e626b0f38941336af97a8 /src/link/Elf/ZigModule.zig | |
| parent | 101df768a06ef85753efdd6dc558bca68d50d1a5 (diff) | |
| parent | e72fd185e01aac14d7962f2eeb718653dc0c8e68 (diff) | |
| download | zig-873c695c41dffd89ba7ef1b3ed6662e429bfa00d.tar.gz zig-873c695c41dffd89ba7ef1b3ed6662e429bfa00d.zip | |
Merge pull request #17319 from ziglang/elf-tls
elf: add basic TLS segment handling
Diffstat (limited to 'src/link/Elf/ZigModule.zig')
| -rw-r--r-- | src/link/Elf/ZigModule.zig | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/src/link/Elf/ZigModule.zig b/src/link/Elf/ZigModule.zig index 93908e5f1f..c79680dbf5 100644 --- a/src/link/Elf/ZigModule.zig +++ b/src/link/Elf/ZigModule.zig @@ -144,7 +144,14 @@ pub fn scanRelocs(self: *ZigModule, elf_file: *Elf, undefs: anytype) !void { for (self.atoms.keys()) |atom_index| { const atom = elf_file.atom(atom_index) orelse continue; if (!atom.flags.alive) continue; - try atom.scanRelocs(elf_file, undefs); + if (try atom.scanRelocsRequiresCode(elf_file)) { + // TODO ideally we don't have to fetch the code here. + // Perhaps it would make sense to save the code until flushModule where we + // would free all of generated code? + const code = try self.codeAlloc(elf_file, atom_index); + defer elf_file.base.allocator.free(code); + try atom.scanRelocs(elf_file, code, undefs); + } else try atom.scanRelocs(elf_file, null, undefs); } } @@ -253,6 +260,22 @@ pub fn asFile(self: *ZigModule) File { return .{ .zig_module = self }; } +/// Returns atom's code. +/// Caller owns the memory. +pub fn codeAlloc(self: ZigModule, elf_file: *Elf, atom_index: Atom.Index) ![]u8 { + const gpa = elf_file.base.allocator; + const atom = elf_file.atom(atom_index).?; + assert(atom.file_index == self.index); + const shdr = &elf_file.shdrs.items[atom.outputShndx().?]; + const file_offset = shdr.sh_offset + atom.value - shdr.sh_addr; + const size = std.math.cast(usize, atom.size) orelse return error.Overflow; + const code = try gpa.alloc(u8, size); + errdefer gpa.free(code); + const amt = try elf_file.base.file.?.preadAll(code, file_offset); + if (amt != code.len) return error.InputOutput; + return code; +} + pub fn fmtSymtab(self: *ZigModule, elf_file: *Elf) std.fmt.Formatter(formatSymtab) { return .{ .data = .{ .self = self, |
