mirror of
https://github.com/ziglang/zig.git
synced 2025-12-29 09:33:18 +00:00
elf: indirect via offset table in the linker away from backend
This commit is contained in:
parent
97a65ea0d5
commit
7556b32840
@ -759,13 +759,14 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi
|
||||
// Address of the dynamic thread pointer.
|
||||
const DTP = elf_file.dtpAddress();
|
||||
|
||||
relocs_log.debug(" {s}: {x}: [{x} => {x}] G({x}) ZG({x}) ({s})", .{
|
||||
relocs_log.debug(" {s}: {x}: [{x} => {x}] G({x}) ZG({x}) ZG2({x}) ({s})", .{
|
||||
relocation.fmtRelocType(rel.r_type(), cpu_arch),
|
||||
r_offset,
|
||||
P,
|
||||
S + A,
|
||||
G + GOT + A,
|
||||
ZIG_GOT + A,
|
||||
target.zigOffsetTableAddress(elf_file) + A,
|
||||
target.name(elf_file),
|
||||
});
|
||||
|
||||
@ -1224,9 +1225,12 @@ const x86_64 = struct {
|
||||
);
|
||||
},
|
||||
|
||||
.PLT32,
|
||||
.PC32,
|
||||
=> try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little),
|
||||
.PLT32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little),
|
||||
|
||||
.PC32 => {
|
||||
const S_ = if (target.flags.zig_offset_table) target.zigOffsetTableAddress(elf_file) else S;
|
||||
try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little);
|
||||
},
|
||||
|
||||
.GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little),
|
||||
.GOTPC32 => try cwriter.writeInt(i32, @as(i32, @intCast(GOT + A - P)), .little),
|
||||
|
||||
@ -236,6 +236,14 @@ pub fn zigGotAddress(symbol: Symbol, elf_file: *Elf) i64 {
|
||||
return elf_file.zig_got.entryAddress(extras.zig_got, elf_file);
|
||||
}
|
||||
|
||||
pub fn zigOffsetTableAddress(symbol: Symbol, elf_file: *Elf) i64 {
|
||||
if (!symbol.flags.zig_offset_table) return 0;
|
||||
const zo = elf_file.zigObjectPtr().?;
|
||||
const offset_table = zo.offsetTablePtr().?;
|
||||
const ot_index = symbol.extra(elf_file).zig_offset_table;
|
||||
return offset_table.entryAddress(ot_index, zo, elf_file);
|
||||
}
|
||||
|
||||
pub fn dsoAlignment(symbol: Symbol, elf_file: *Elf) !u64 {
|
||||
const file_ptr = symbol.file(elf_file) orelse return 0;
|
||||
assert(file_ptr == .shared_object);
|
||||
|
||||
@ -760,7 +760,9 @@ pub fn getOrCreateMetadataForLazySymbol(
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
const symbol_index = try self.newSymbolWithAtom(gpa, 0);
|
||||
const sym = self.symbol(symbol_index);
|
||||
sym.flags.needs_zig_got = true;
|
||||
if (lazy_sym.kind != .code) {
|
||||
sym.flags.needs_zig_got = true;
|
||||
}
|
||||
symbol_index_ptr.* = symbol_index;
|
||||
},
|
||||
.pending_flush => return symbol_index_ptr.*,
|
||||
@ -816,7 +818,7 @@ pub fn getOrCreateMetadataForNav(
|
||||
sym.flags.is_tls = true;
|
||||
}
|
||||
}
|
||||
if (!sym.flags.is_tls) {
|
||||
if (!sym.flags.is_tls and nav_val.typeOf(zcu).zigTypeTag(zcu) != .Fn) {
|
||||
sym.flags.needs_zig_got = true;
|
||||
}
|
||||
gop.value_ptr.* = .{ .symbol_index = symbol_index };
|
||||
@ -919,16 +921,19 @@ fn updateNavCode(
|
||||
sym.value = 0;
|
||||
esym.st_value = 0;
|
||||
|
||||
if (!elf_file.base.isRelocatable()) {
|
||||
log.debug(" (writing new offset table entry)", .{});
|
||||
assert(sym.flags.has_zig_got);
|
||||
const extra = sym.extra(elf_file);
|
||||
try elf_file.zig_got.writeOne(elf_file, extra.zig_got);
|
||||
if (stt_bits == elf.STT_FUNC) {
|
||||
const offset_table = self.offsetTablePtr().?;
|
||||
offset_table.entries.items(.dirty)[extra.zig_offset_table] = true;
|
||||
if (stt_bits != elf.STT_FUNC) {
|
||||
if (!elf_file.base.isRelocatable()) {
|
||||
log.debug(" (writing new offset table entry)", .{});
|
||||
assert(sym.flags.has_zig_got);
|
||||
const extra = sym.extra(elf_file);
|
||||
try elf_file.zig_got.writeOne(elf_file, extra.zig_got);
|
||||
}
|
||||
}
|
||||
if (stt_bits == elf.STT_FUNC) {
|
||||
const extra = sym.extra(elf_file);
|
||||
const offset_table = self.offsetTablePtr().?;
|
||||
offset_table.entries.items(.dirty)[extra.zig_offset_table] = true;
|
||||
}
|
||||
}
|
||||
} else if (code.len < old_size) {
|
||||
atom_ptr.shrink(elf_file);
|
||||
@ -938,12 +943,13 @@ fn updateNavCode(
|
||||
errdefer self.freeNavMetadata(elf_file, sym_index);
|
||||
|
||||
sym.value = 0;
|
||||
sym.flags.needs_zig_got = true;
|
||||
esym.st_value = 0;
|
||||
|
||||
if (!elf_file.base.isRelocatable()) {
|
||||
const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
|
||||
try elf_file.zig_got.writeOne(elf_file, gop.index);
|
||||
if (stt_bits != elf.STT_FUNC) {
|
||||
sym.flags.needs_zig_got = true;
|
||||
if (!elf_file.base.isRelocatable()) {
|
||||
const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
|
||||
try elf_file.zig_got.writeOne(elf_file, gop.index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1061,7 +1067,12 @@ pub fn updateFunc(
|
||||
sym.flags.zig_offset_table = true;
|
||||
sym.addExtra(.{ .zig_offset_table = index }, elf_file);
|
||||
try offset_table.updateSize(self, elf_file);
|
||||
const old_vaddr = offset_table.address(self, elf_file);
|
||||
try self.symbol(offset_table.sym_index).atom(elf_file).?.allocate(elf_file);
|
||||
const new_vaddr = offset_table.address(self, elf_file);
|
||||
if (old_vaddr != new_vaddr) {
|
||||
offset_table.dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1106,7 +1117,13 @@ pub fn updateFunc(
|
||||
|
||||
// Exports will be updated by `Zcu.processExports` after the update.
|
||||
|
||||
{
|
||||
if (offset_table.dirty) {
|
||||
// TODO write in bulk
|
||||
for (offset_table.entries.items(.dirty), 0..) |*dirty, i| {
|
||||
try offset_table.writeEntry(@intCast(i), self, elf_file);
|
||||
dirty.* = false;
|
||||
}
|
||||
} else {
|
||||
const sym = self.symbol(sym_index);
|
||||
const ot_index = sym.extra(elf_file).zig_offset_table;
|
||||
var ot_entry = offset_table.entries.get(ot_index);
|
||||
@ -1261,7 +1278,9 @@ fn updateLazySymbol(
|
||||
errdefer self.freeNavMetadata(elf_file, symbol_index);
|
||||
|
||||
local_sym.value = 0;
|
||||
local_sym.flags.needs_zig_got = true;
|
||||
if (sym.kind != .code) {
|
||||
local_sym.flags.needs_zig_got = true;
|
||||
}
|
||||
local_esym.st_value = 0;
|
||||
|
||||
if (!elf_file.base.isRelocatable()) {
|
||||
@ -1476,7 +1495,7 @@ pub fn getGlobalSymbol(self: *ZigObject, elf_file: *Elf, name: []const u8, lib_n
|
||||
return lookup_gop.value_ptr.*;
|
||||
}
|
||||
|
||||
fn offsetTablePtr(self: *ZigObject) ?*OffsetTable {
|
||||
pub fn offsetTablePtr(self: *ZigObject) ?*OffsetTable {
|
||||
return if (self.offset_table) |*ot| ot else null;
|
||||
}
|
||||
|
||||
@ -1747,6 +1766,7 @@ const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable);
|
||||
pub const OffsetTable = struct {
|
||||
sym_index: Symbol.Index,
|
||||
entries: std.MultiArrayList(Entry) = .{},
|
||||
dirty: bool = false,
|
||||
|
||||
pub fn deinit(ot: *OffsetTable, allocator: Allocator) void {
|
||||
ot.entries.deinit(allocator);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user