Merge pull request #17594 from ziglang/elf-atom-limit
elf: increase permissible Atom <-> input section resolution to u32 for Zig's module
This commit is contained in:
@@ -331,7 +331,7 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
|
||||
symbol_ptr.name_offset = name_off;
|
||||
|
||||
const esym_index = try zig_module.addLocalEsym(allocator);
|
||||
const esym = &zig_module.local_esyms.items[esym_index];
|
||||
const esym = &zig_module.local_esyms.items(.elf_sym)[esym_index];
|
||||
esym.st_name = name_off;
|
||||
esym.st_info |= elf.STT_FILE;
|
||||
esym.st_shndx = elf.SHN_ABS;
|
||||
@@ -3172,7 +3172,7 @@ fn updateDeclCode(
|
||||
const required_alignment = decl.getAlignment(mod);
|
||||
|
||||
const sym = self.symbol(sym_index);
|
||||
const esym = &zig_module.local_esyms.items[sym.esym_index];
|
||||
const esym = &zig_module.local_esyms.items(.elf_sym)[sym.esym_index];
|
||||
const atom_ptr = sym.atom(self).?;
|
||||
|
||||
const shdr_index = self.getDeclShdrIndex(decl_index, code);
|
||||
@@ -3438,7 +3438,7 @@ fn updateLazySymbol(self: *Elf, sym: link.File.LazySymbol, symbol_index: Symbol.
|
||||
const phdr_index = self.phdr_to_shdr_table.get(output_section_index).?;
|
||||
local_sym.name_offset = name_str_index;
|
||||
local_sym.output_section_index = output_section_index;
|
||||
const local_esym = &zig_module.local_esyms.items[local_sym.esym_index];
|
||||
const local_esym = &zig_module.local_esyms.items(.elf_sym)[local_sym.esym_index];
|
||||
local_esym.st_name = name_str_index;
|
||||
local_esym.st_info |= elf.STT_OBJECT;
|
||||
local_esym.st_size = code.len;
|
||||
@@ -3527,7 +3527,7 @@ fn lowerConst(
|
||||
const name_str_index = try self.strtab.insert(gpa, name);
|
||||
local_sym.name_offset = name_str_index;
|
||||
local_sym.output_section_index = output_section_index;
|
||||
const local_esym = &zig_module.local_esyms.items[local_sym.esym_index];
|
||||
const local_esym = &zig_module.local_esyms.items(.elf_sym)[local_sym.esym_index];
|
||||
local_esym.st_name = name_str_index;
|
||||
local_esym.st_info |= elf.STT_OBJECT;
|
||||
local_esym.st_size = code.len;
|
||||
@@ -3573,7 +3573,9 @@ pub fn updateDeclExports(
|
||||
const zig_module = self.file(self.zig_module_index.?).?.zig_module;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const decl_sym_index = try self.getOrCreateMetadataForDecl(decl_index);
|
||||
const decl_esym = zig_module.local_esyms.items[self.symbol(decl_sym_index).esym_index];
|
||||
const decl_esym_index = self.symbol(decl_sym_index).esym_index;
|
||||
const decl_esym = zig_module.local_esyms.items(.elf_sym)[decl_esym_index];
|
||||
const decl_esym_shndx = zig_module.local_esyms.items(.shndx)[decl_esym_index];
|
||||
const decl_metadata = self.decls.getPtr(decl_index).?;
|
||||
|
||||
for (exports) |exp| {
|
||||
@@ -3615,11 +3617,13 @@ pub fn updateDeclExports(
|
||||
try zig_module.global_symbols.append(gpa, gop.index);
|
||||
break :blk sym_index;
|
||||
};
|
||||
const esym = &zig_module.global_esyms.items[sym_index & 0x0fffffff];
|
||||
esym.st_value = self.symbol(decl_sym_index).value;
|
||||
esym.st_shndx = decl_esym.st_shndx;
|
||||
esym.st_info = (stb_bits << 4) | stt_bits;
|
||||
esym.st_name = name_off;
|
||||
const global_esym_index = sym_index & ZigModule.symbol_mask;
|
||||
const global_esym = &zig_module.global_esyms.items(.elf_sym)[global_esym_index];
|
||||
global_esym.st_value = self.symbol(decl_sym_index).value;
|
||||
global_esym.st_shndx = decl_esym.st_shndx;
|
||||
global_esym.st_info = (stb_bits << 4) | stt_bits;
|
||||
global_esym.st_name = name_off;
|
||||
zig_module.global_esyms.items(.shndx)[global_esym_index] = decl_esym_shndx;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3651,7 +3655,7 @@ pub fn deleteDeclExport(
|
||||
const exp_name = mod.intern_pool.stringToSlice(name);
|
||||
const esym_index = metadata.@"export"(self, exp_name) orelse return;
|
||||
log.debug("deleting export '{s}'", .{exp_name});
|
||||
const esym = &zig_module.global_esyms.items[esym_index.*];
|
||||
const esym = &zig_module.global_esyms.items(.elf_sym)[esym_index.*];
|
||||
_ = zig_module.globals_lookup.remove(esym.st_name);
|
||||
const sym_index = self.resolver.get(esym.st_name).?;
|
||||
const sym = self.symbol(sym_index);
|
||||
@@ -3660,6 +3664,7 @@ pub fn deleteDeclExport(
|
||||
sym.* = .{};
|
||||
}
|
||||
esym.* = null_sym;
|
||||
zig_module.global_esyms.items(.shndx)[esym_index.*] = elf.SHN_UNDEF;
|
||||
}
|
||||
|
||||
fn addLinkerDefinedSymbols(self: *Elf) !void {
|
||||
|
||||
@@ -14,13 +14,13 @@ size: u64 = 0,
|
||||
alignment: Alignment = .@"1",
|
||||
|
||||
/// Index of the input section.
|
||||
input_section_index: u16 = 0,
|
||||
input_section_index: u32 = 0,
|
||||
|
||||
/// Index of the output section.
|
||||
output_section_index: u16 = 0,
|
||||
|
||||
/// Index of the input section containing this atom's relocs.
|
||||
relocs_section_index: u16 = 0,
|
||||
relocs_section_index: u32 = 0,
|
||||
|
||||
/// Index of this atom in the linker's atoms table.
|
||||
atom_index: Index = 0,
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
path: []const u8,
|
||||
index: File.Index,
|
||||
|
||||
local_esyms: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{},
|
||||
global_esyms: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{},
|
||||
local_esyms: std.MultiArrayList(ElfSym) = .{},
|
||||
global_esyms: std.MultiArrayList(ElfSym) = .{},
|
||||
local_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
|
||||
global_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
|
||||
globals_lookup: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{},
|
||||
@@ -20,6 +20,10 @@ num_dynrelocs: u32 = 0,
|
||||
|
||||
output_symtab_size: Elf.SymtabSize = .{},
|
||||
|
||||
pub const global_symbol_bit: u32 = 0x80000000;
|
||||
pub const symbol_mask: u32 = 0x7fffffff;
|
||||
pub const SHN_ATOM: u16 = 0x100;
|
||||
|
||||
pub fn deinit(self: *ZigModule, allocator: Allocator) void {
|
||||
self.local_esyms.deinit(allocator);
|
||||
self.global_esyms.deinit(allocator);
|
||||
@@ -35,20 +39,20 @@ pub fn deinit(self: *ZigModule, allocator: Allocator) void {
|
||||
|
||||
pub fn addLocalEsym(self: *ZigModule, allocator: Allocator) !Symbol.Index {
|
||||
try self.local_esyms.ensureUnusedCapacity(allocator, 1);
|
||||
const index = @as(Symbol.Index, @intCast(self.local_esyms.items.len));
|
||||
const esym = self.local_esyms.addOneAssumeCapacity();
|
||||
esym.* = Elf.null_sym;
|
||||
esym.st_info = elf.STB_LOCAL << 4;
|
||||
const index = @as(Symbol.Index, @intCast(self.local_esyms.addOneAssumeCapacity()));
|
||||
var esym = ElfSym{ .elf_sym = Elf.null_sym };
|
||||
esym.elf_sym.st_info = elf.STB_LOCAL << 4;
|
||||
self.local_esyms.set(index, esym);
|
||||
return index;
|
||||
}
|
||||
|
||||
pub fn addGlobalEsym(self: *ZigModule, allocator: Allocator) !Symbol.Index {
|
||||
try self.global_esyms.ensureUnusedCapacity(allocator, 1);
|
||||
const index = @as(Symbol.Index, @intCast(self.global_esyms.items.len));
|
||||
const esym = self.global_esyms.addOneAssumeCapacity();
|
||||
esym.* = Elf.null_sym;
|
||||
esym.st_info = elf.STB_GLOBAL << 4;
|
||||
return index | 0x10000000;
|
||||
const index = @as(Symbol.Index, @intCast(self.global_esyms.addOneAssumeCapacity()));
|
||||
var esym = ElfSym{ .elf_sym = Elf.null_sym };
|
||||
esym.elf_sym.st_info = elf.STB_GLOBAL << 4;
|
||||
self.global_esyms.set(index, esym);
|
||||
return index | global_symbol_bit;
|
||||
}
|
||||
|
||||
pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index {
|
||||
@@ -58,7 +62,7 @@ pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index {
|
||||
const symbol_index = try elf_file.addSymbol();
|
||||
const esym_index = try self.addLocalEsym(gpa);
|
||||
|
||||
const shndx = @as(u16, @intCast(self.atoms.items.len));
|
||||
const shndx = @as(u32, @intCast(self.atoms.items.len));
|
||||
try self.atoms.append(gpa, atom_index);
|
||||
try self.local_symbols.append(gpa, symbol_index);
|
||||
|
||||
@@ -69,11 +73,11 @@ pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index {
|
||||
symbol_ptr.file_index = self.index;
|
||||
symbol_ptr.atom_index = atom_index;
|
||||
|
||||
const esym = &self.local_esyms.items[esym_index];
|
||||
esym.st_shndx = shndx;
|
||||
self.local_esyms.items(.shndx)[esym_index] = shndx;
|
||||
self.local_esyms.items(.elf_sym)[esym_index].st_shndx = SHN_ATOM;
|
||||
symbol_ptr.esym_index = esym_index;
|
||||
|
||||
const relocs_index = @as(u16, @intCast(self.relocs.items.len));
|
||||
const relocs_index = @as(u32, @intCast(self.relocs.items.len));
|
||||
const relocs = try self.relocs.addOne(gpa);
|
||||
relocs.* = .{};
|
||||
atom_ptr.relocs_section_index = relocs_index;
|
||||
@@ -99,13 +103,15 @@ pub fn inputShdr(self: ZigModule, atom_index: Atom.Index, elf_file: *Elf) Object
|
||||
|
||||
pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void {
|
||||
for (self.globals(), 0..) |index, i| {
|
||||
const esym_index = @as(Symbol.Index, @intCast(i)) | 0x10000000;
|
||||
const esym = self.global_esyms.items[i];
|
||||
const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit;
|
||||
const esym = self.global_esyms.items(.elf_sym)[i];
|
||||
const shndx = self.global_esyms.items(.shndx)[i];
|
||||
|
||||
if (esym.st_shndx == elf.SHN_UNDEF) continue;
|
||||
|
||||
if (esym.st_shndx != elf.SHN_ABS and esym.st_shndx != elf.SHN_COMMON) {
|
||||
const atom_index = self.atoms.items[esym.st_shndx];
|
||||
assert(esym.st_shndx == SHN_ATOM);
|
||||
const atom_index = self.atoms.items[shndx];
|
||||
const atom = elf_file.atom(atom_index) orelse continue;
|
||||
if (!atom.flags.alive) continue;
|
||||
}
|
||||
@@ -114,7 +120,8 @@ pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void {
|
||||
if (self.asFile().symbolRank(esym, false) < global.symbolRank(elf_file)) {
|
||||
const atom_index = switch (esym.st_shndx) {
|
||||
elf.SHN_ABS, elf.SHN_COMMON => 0,
|
||||
else => self.atoms.items[esym.st_shndx],
|
||||
SHN_ATOM => self.atoms.items[shndx],
|
||||
else => unreachable,
|
||||
};
|
||||
const output_section_index = if (elf_file.atom(atom_index)) |atom|
|
||||
atom.outputShndx().?
|
||||
@@ -133,8 +140,8 @@ pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void {
|
||||
|
||||
pub fn claimUnresolved(self: *ZigModule, elf_file: *Elf) void {
|
||||
for (self.globals(), 0..) |index, i| {
|
||||
const esym_index = @as(Symbol.Index, @intCast(i)) | 0x10000000;
|
||||
const esym = self.global_esyms.items[i];
|
||||
const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit;
|
||||
const esym = self.global_esyms.items(.elf_sym)[i];
|
||||
|
||||
if (esym.st_shndx != elf.SHN_UNDEF) continue;
|
||||
|
||||
@@ -187,7 +194,7 @@ pub fn resetGlobals(self: *ZigModule, elf_file: *Elf) void {
|
||||
|
||||
pub fn markLive(self: *ZigModule, elf_file: *Elf) void {
|
||||
for (self.globals(), 0..) |index, i| {
|
||||
const esym = self.global_esyms.items[i];
|
||||
const esym = self.global_esyms.items(.elf_sym)[i];
|
||||
if (esym.st_bind() == elf.STB_WEAK) continue;
|
||||
|
||||
const global = elf_file.symbol(index);
|
||||
@@ -256,17 +263,17 @@ pub fn writeSymtab(self: *ZigModule, elf_file: *Elf, ctx: anytype) void {
|
||||
}
|
||||
|
||||
pub fn symbol(self: *ZigModule, index: Symbol.Index) Symbol.Index {
|
||||
const is_global = index & 0x10000000 != 0;
|
||||
const actual_index = index & 0x0fffffff;
|
||||
const is_global = index & global_symbol_bit != 0;
|
||||
const actual_index = index & symbol_mask;
|
||||
if (is_global) return self.global_symbols.items[actual_index];
|
||||
return self.local_symbols.items[actual_index];
|
||||
}
|
||||
|
||||
pub fn elfSym(self: *ZigModule, index: Symbol.Index) *elf.Elf64_Sym {
|
||||
const is_global = index & 0x10000000 != 0;
|
||||
const actual_index = index & 0x0fffffff;
|
||||
if (is_global) return &self.global_esyms.items[actual_index];
|
||||
return &self.local_esyms.items[actual_index];
|
||||
const is_global = index & global_symbol_bit != 0;
|
||||
const actual_index = index & symbol_mask;
|
||||
if (is_global) return &self.global_esyms.items(.elf_sym)[actual_index];
|
||||
return &self.local_esyms.items(.elf_sym)[actual_index];
|
||||
}
|
||||
|
||||
pub fn locals(self: *ZigModule) []const Symbol.Index {
|
||||
@@ -354,6 +361,11 @@ fn formatAtoms(
|
||||
}
|
||||
}
|
||||
|
||||
const ElfSym = struct {
|
||||
elf_sym: elf.Elf64_Sym,
|
||||
shndx: u32 = elf.SHN_UNDEF,
|
||||
};
|
||||
|
||||
const assert = std.debug.assert;
|
||||
const std = @import("std");
|
||||
const elf = std.elf;
|
||||
|
||||
Reference in New Issue
Block a user