authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-19 12:30:56+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-10-19 12:30:56+02:00
logf3d23d92329f4926c08c86c5ea97628b783e7d84
tree25e4b0e4aebef50f11b8701571531621ce3cbca3
parentae2cd5fe263e9d8ddd5719b4795f9cd39b5c0324
parent1448d6b77c1367d6d42c5dfe51878e7ef19c1743
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #17594 from ziglang/elf-atom-limit

elf: increase permissible Atom <-> input section resolution to u32 for Zig's module

3 files changed, 58 insertions(+), 41 deletions(-)

src/link/Elf.zig+16-11
...@@ -331,7 +331,7 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option...@@ -331,7 +331,7 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
331 symbol_ptr.name_offset = name_off;331 symbol_ptr.name_offset = name_off;
332332
333 const esym_index = try zig_module.addLocalEsym(allocator);333 const esym_index = try zig_module.addLocalEsym(allocator);
334 const esym = &zig_module.local_esyms.items[esym_index];334 const esym = &zig_module.local_esyms.items(.elf_sym)[esym_index];
335 esym.st_name = name_off;335 esym.st_name = name_off;
336 esym.st_info |= elf.STT_FILE;336 esym.st_info |= elf.STT_FILE;
337 esym.st_shndx = elf.SHN_ABS;337 esym.st_shndx = elf.SHN_ABS;
...@@ -3172,7 +3172,7 @@ fn updateDeclCode(...@@ -3172,7 +3172,7 @@ fn updateDeclCode(
3172 const required_alignment = decl.getAlignment(mod);3172 const required_alignment = decl.getAlignment(mod);
31733173
3174 const sym = self.symbol(sym_index);3174 const sym = self.symbol(sym_index);
3175 const esym = &zig_module.local_esyms.items[sym.esym_index];3175 const esym = &zig_module.local_esyms.items(.elf_sym)[sym.esym_index];
3176 const atom_ptr = sym.atom(self).?;3176 const atom_ptr = sym.atom(self).?;
31773177
3178 const shdr_index = self.getDeclShdrIndex(decl_index, code);3178 const shdr_index = self.getDeclShdrIndex(decl_index, code);
...@@ -3438,7 +3438,7 @@ fn updateLazySymbol(self: *Elf, sym: link.File.LazySymbol, symbol_index: Symbol....@@ -3438,7 +3438,7 @@ fn updateLazySymbol(self: *Elf, sym: link.File.LazySymbol, symbol_index: Symbol.
3438 const phdr_index = self.phdr_to_shdr_table.get(output_section_index).?;3438 const phdr_index = self.phdr_to_shdr_table.get(output_section_index).?;
3439 local_sym.name_offset = name_str_index;3439 local_sym.name_offset = name_str_index;
3440 local_sym.output_section_index = output_section_index;3440 local_sym.output_section_index = output_section_index;
3441 const local_esym = &zig_module.local_esyms.items[local_sym.esym_index];3441 const local_esym = &zig_module.local_esyms.items(.elf_sym)[local_sym.esym_index];
3442 local_esym.st_name = name_str_index;3442 local_esym.st_name = name_str_index;
3443 local_esym.st_info |= elf.STT_OBJECT;3443 local_esym.st_info |= elf.STT_OBJECT;
3444 local_esym.st_size = code.len;3444 local_esym.st_size = code.len;
...@@ -3527,7 +3527,7 @@ fn lowerConst(...@@ -3527,7 +3527,7 @@ fn lowerConst(
3527 const name_str_index = try self.strtab.insert(gpa, name);3527 const name_str_index = try self.strtab.insert(gpa, name);
3528 local_sym.name_offset = name_str_index;3528 local_sym.name_offset = name_str_index;
3529 local_sym.output_section_index = output_section_index;3529 local_sym.output_section_index = output_section_index;
3530 const local_esym = &zig_module.local_esyms.items[local_sym.esym_index];3530 const local_esym = &zig_module.local_esyms.items(.elf_sym)[local_sym.esym_index];
3531 local_esym.st_name = name_str_index;3531 local_esym.st_name = name_str_index;
3532 local_esym.st_info |= elf.STT_OBJECT;3532 local_esym.st_info |= elf.STT_OBJECT;
3533 local_esym.st_size = code.len;3533 local_esym.st_size = code.len;
...@@ -3573,7 +3573,9 @@ pub fn updateDeclExports(...@@ -3573,7 +3573,9 @@ pub fn updateDeclExports(
3573 const zig_module = self.file(self.zig_module_index.?).?.zig_module;3573 const zig_module = self.file(self.zig_module_index.?).?.zig_module;
3574 const decl = mod.declPtr(decl_index);3574 const decl = mod.declPtr(decl_index);
3575 const decl_sym_index = try self.getOrCreateMetadataForDecl(decl_index);3575 const decl_sym_index = try self.getOrCreateMetadataForDecl(decl_index);
3576 const decl_esym = zig_module.local_esyms.items[self.symbol(decl_sym_index).esym_index];3576 const decl_esym_index = self.symbol(decl_sym_index).esym_index;
3577 const decl_esym = zig_module.local_esyms.items(.elf_sym)[decl_esym_index];
3578 const decl_esym_shndx = zig_module.local_esyms.items(.shndx)[decl_esym_index];
3577 const decl_metadata = self.decls.getPtr(decl_index).?;3579 const decl_metadata = self.decls.getPtr(decl_index).?;
35783580
3579 for (exports) |exp| {3581 for (exports) |exp| {
...@@ -3615,11 +3617,13 @@ pub fn updateDeclExports(...@@ -3615,11 +3617,13 @@ pub fn updateDeclExports(
3615 try zig_module.global_symbols.append(gpa, gop.index);3617 try zig_module.global_symbols.append(gpa, gop.index);
3616 break :blk sym_index;3618 break :blk sym_index;
3617 };3619 };
3618 const esym = &zig_module.global_esyms.items[sym_index & 0x0fffffff];3620 const global_esym_index = sym_index & ZigModule.symbol_mask;
3619 esym.st_value = self.symbol(decl_sym_index).value;3621 const global_esym = &zig_module.global_esyms.items(.elf_sym)[global_esym_index];
3620 esym.st_shndx = decl_esym.st_shndx;3622 global_esym.st_value = self.symbol(decl_sym_index).value;
3621 esym.st_info = (stb_bits << 4) | stt_bits;3623 global_esym.st_shndx = decl_esym.st_shndx;
3622 esym.st_name = name_off;3624 global_esym.st_info = (stb_bits << 4) | stt_bits;
3625 global_esym.st_name = name_off;
3626 zig_module.global_esyms.items(.shndx)[global_esym_index] = decl_esym_shndx;
3623 }3627 }
3624}3628}
36253629
...@@ -3651,7 +3655,7 @@ pub fn deleteDeclExport(...@@ -3651,7 +3655,7 @@ pub fn deleteDeclExport(
3651 const exp_name = mod.intern_pool.stringToSlice(name);3655 const exp_name = mod.intern_pool.stringToSlice(name);
3652 const esym_index = metadata.@"export"(self, exp_name) orelse return;3656 const esym_index = metadata.@"export"(self, exp_name) orelse return;
3653 log.debug("deleting export '{s}'", .{exp_name});3657 log.debug("deleting export '{s}'", .{exp_name});
3654 const esym = &zig_module.global_esyms.items[esym_index.*];3658 const esym = &zig_module.global_esyms.items(.elf_sym)[esym_index.*];
3655 _ = zig_module.globals_lookup.remove(esym.st_name);3659 _ = zig_module.globals_lookup.remove(esym.st_name);
3656 const sym_index = self.resolver.get(esym.st_name).?;3660 const sym_index = self.resolver.get(esym.st_name).?;
3657 const sym = self.symbol(sym_index);3661 const sym = self.symbol(sym_index);
...@@ -3660,6 +3664,7 @@ pub fn deleteDeclExport(...@@ -3660,6 +3664,7 @@ pub fn deleteDeclExport(
3660 sym.* = .{};3664 sym.* = .{};
3661 }3665 }
3662 esym.* = null_sym;3666 esym.* = null_sym;
3667 zig_module.global_esyms.items(.shndx)[esym_index.*] = elf.SHN_UNDEF;
3663}3668}
36643669
3665fn addLinkerDefinedSymbols(self: *Elf) !void {3670fn addLinkerDefinedSymbols(self: *Elf) !void {
src/link/Elf/Atom.zig+2-2
...@@ -14,13 +14,13 @@ size: u64 = 0,...@@ -14,13 +14,13 @@ size: u64 = 0,
14alignment: Alignment = .@"1",14alignment: Alignment = .@"1",
1515
16/// Index of the input section.16/// Index of the input section.
17input_section_index: u16 = 0,17input_section_index: u32 = 0,
1818
19/// Index of the output section.19/// Index of the output section.
20output_section_index: u16 = 0,20output_section_index: u16 = 0,
2121
22/// Index of the input section containing this atom's relocs.22/// Index of the input section containing this atom's relocs.
23relocs_section_index: u16 = 0,23relocs_section_index: u32 = 0,
2424
25/// Index of this atom in the linker's atoms table.25/// Index of this atom in the linker's atoms table.
26atom_index: Index = 0,26atom_index: Index = 0,
src/link/Elf/ZigModule.zig+40-28
...@@ -7,8 +7,8 @@...@@ -7,8 +7,8 @@
7path: []const u8,7path: []const u8,
8index: File.Index,8index: File.Index,
99
10local_esyms: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{},10local_esyms: std.MultiArrayList(ElfSym) = .{},
11global_esyms: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{},11global_esyms: std.MultiArrayList(ElfSym) = .{},
12local_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},12local_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
13global_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},13global_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
14globals_lookup: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{},14globals_lookup: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{},
...@@ -20,6 +20,10 @@ num_dynrelocs: u32 = 0,...@@ -20,6 +20,10 @@ num_dynrelocs: u32 = 0,
2020
21output_symtab_size: Elf.SymtabSize = .{},21output_symtab_size: Elf.SymtabSize = .{},
2222
23pub const global_symbol_bit: u32 = 0x80000000;
24pub const symbol_mask: u32 = 0x7fffffff;
25pub const SHN_ATOM: u16 = 0x100;
26
23pub fn deinit(self: *ZigModule, allocator: Allocator) void {27pub fn deinit(self: *ZigModule, allocator: Allocator) void {
24 self.local_esyms.deinit(allocator);28 self.local_esyms.deinit(allocator);
25 self.global_esyms.deinit(allocator);29 self.global_esyms.deinit(allocator);
...@@ -35,20 +39,20 @@ pub fn deinit(self: *ZigModule, allocator: Allocator) void {...@@ -35,20 +39,20 @@ pub fn deinit(self: *ZigModule, allocator: Allocator) void {
3539
36pub fn addLocalEsym(self: *ZigModule, allocator: Allocator) !Symbol.Index {40pub fn addLocalEsym(self: *ZigModule, allocator: Allocator) !Symbol.Index {
37 try self.local_esyms.ensureUnusedCapacity(allocator, 1);41 try self.local_esyms.ensureUnusedCapacity(allocator, 1);
38 const index = @as(Symbol.Index, @intCast(self.local_esyms.items.len));42 const index = @as(Symbol.Index, @intCast(self.local_esyms.addOneAssumeCapacity()));
39 const esym = self.local_esyms.addOneAssumeCapacity();43 var esym = ElfSym{ .elf_sym = Elf.null_sym };
40 esym.* = Elf.null_sym;44 esym.elf_sym.st_info = elf.STB_LOCAL << 4;
41 esym.st_info = elf.STB_LOCAL << 4;45 self.local_esyms.set(index, esym);
42 return index;46 return index;
43}47}
4448
45pub fn addGlobalEsym(self: *ZigModule, allocator: Allocator) !Symbol.Index {49pub fn addGlobalEsym(self: *ZigModule, allocator: Allocator) !Symbol.Index {
46 try self.global_esyms.ensureUnusedCapacity(allocator, 1);50 try self.global_esyms.ensureUnusedCapacity(allocator, 1);
47 const index = @as(Symbol.Index, @intCast(self.global_esyms.items.len));51 const index = @as(Symbol.Index, @intCast(self.global_esyms.addOneAssumeCapacity()));
48 const esym = self.global_esyms.addOneAssumeCapacity();52 var esym = ElfSym{ .elf_sym = Elf.null_sym };
49 esym.* = Elf.null_sym;53 esym.elf_sym.st_info = elf.STB_GLOBAL << 4;
50 esym.st_info = elf.STB_GLOBAL << 4;54 self.global_esyms.set(index, esym);
51 return index | 0x10000000;55 return index | global_symbol_bit;
52}56}
5357
54pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index {58pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index {
...@@ -58,7 +62,7 @@ pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index {...@@ -58,7 +62,7 @@ pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index {
58 const symbol_index = try elf_file.addSymbol();62 const symbol_index = try elf_file.addSymbol();
59 const esym_index = try self.addLocalEsym(gpa);63 const esym_index = try self.addLocalEsym(gpa);
6064
61 const shndx = @as(u16, @intCast(self.atoms.items.len));65 const shndx = @as(u32, @intCast(self.atoms.items.len));
62 try self.atoms.append(gpa, atom_index);66 try self.atoms.append(gpa, atom_index);
63 try self.local_symbols.append(gpa, symbol_index);67 try self.local_symbols.append(gpa, symbol_index);
6468
...@@ -69,11 +73,11 @@ pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index {...@@ -69,11 +73,11 @@ pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index {
69 symbol_ptr.file_index = self.index;73 symbol_ptr.file_index = self.index;
70 symbol_ptr.atom_index = atom_index;74 symbol_ptr.atom_index = atom_index;
7175
72 const esym = &self.local_esyms.items[esym_index];76 self.local_esyms.items(.shndx)[esym_index] = shndx;
73 esym.st_shndx = shndx;77 self.local_esyms.items(.elf_sym)[esym_index].st_shndx = SHN_ATOM;
74 symbol_ptr.esym_index = esym_index;78 symbol_ptr.esym_index = esym_index;
7579
76 const relocs_index = @as(u16, @intCast(self.relocs.items.len));80 const relocs_index = @as(u32, @intCast(self.relocs.items.len));
77 const relocs = try self.relocs.addOne(gpa);81 const relocs = try self.relocs.addOne(gpa);
78 relocs.* = .{};82 relocs.* = .{};
79 atom_ptr.relocs_section_index = relocs_index;83 atom_ptr.relocs_section_index = relocs_index;
...@@ -99,13 +103,15 @@ pub fn inputShdr(self: ZigModule, atom_index: Atom.Index, elf_file: *Elf) Object...@@ -99,13 +103,15 @@ pub fn inputShdr(self: ZigModule, atom_index: Atom.Index, elf_file: *Elf) Object
99103
100pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void {104pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void {
101 for (self.globals(), 0..) |index, i| {105 for (self.globals(), 0..) |index, i| {
102 const esym_index = @as(Symbol.Index, @intCast(i)) | 0x10000000;106 const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit;
103 const esym = self.global_esyms.items[i];107 const esym = self.global_esyms.items(.elf_sym)[i];
108 const shndx = self.global_esyms.items(.shndx)[i];
104109
105 if (esym.st_shndx == elf.SHN_UNDEF) continue;110 if (esym.st_shndx == elf.SHN_UNDEF) continue;
106111
107 if (esym.st_shndx != elf.SHN_ABS and esym.st_shndx != elf.SHN_COMMON) {112 if (esym.st_shndx != elf.SHN_ABS and esym.st_shndx != elf.SHN_COMMON) {
108 const atom_index = self.atoms.items[esym.st_shndx];113 assert(esym.st_shndx == SHN_ATOM);
114 const atom_index = self.atoms.items[shndx];
109 const atom = elf_file.atom(atom_index) orelse continue;115 const atom = elf_file.atom(atom_index) orelse continue;
110 if (!atom.flags.alive) continue;116 if (!atom.flags.alive) continue;
111 }117 }
...@@ -114,7 +120,8 @@ pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void {...@@ -114,7 +120,8 @@ pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void {
114 if (self.asFile().symbolRank(esym, false) < global.symbolRank(elf_file)) {120 if (self.asFile().symbolRank(esym, false) < global.symbolRank(elf_file)) {
115 const atom_index = switch (esym.st_shndx) {121 const atom_index = switch (esym.st_shndx) {
116 elf.SHN_ABS, elf.SHN_COMMON => 0,122 elf.SHN_ABS, elf.SHN_COMMON => 0,
117 else => self.atoms.items[esym.st_shndx],123 SHN_ATOM => self.atoms.items[shndx],
124 else => unreachable,
118 };125 };
119 const output_section_index = if (elf_file.atom(atom_index)) |atom|126 const output_section_index = if (elf_file.atom(atom_index)) |atom|
120 atom.outputShndx().?127 atom.outputShndx().?
...@@ -133,8 +140,8 @@ pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void {...@@ -133,8 +140,8 @@ pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void {
133140
134pub fn claimUnresolved(self: *ZigModule, elf_file: *Elf) void {141pub fn claimUnresolved(self: *ZigModule, elf_file: *Elf) void {
135 for (self.globals(), 0..) |index, i| {142 for (self.globals(), 0..) |index, i| {
136 const esym_index = @as(Symbol.Index, @intCast(i)) | 0x10000000;143 const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit;
137 const esym = self.global_esyms.items[i];144 const esym = self.global_esyms.items(.elf_sym)[i];
138145
139 if (esym.st_shndx != elf.SHN_UNDEF) continue;146 if (esym.st_shndx != elf.SHN_UNDEF) continue;
140147
...@@ -187,7 +194,7 @@ pub fn resetGlobals(self: *ZigModule, elf_file: *Elf) void {...@@ -187,7 +194,7 @@ pub fn resetGlobals(self: *ZigModule, elf_file: *Elf) void {
187194
188pub fn markLive(self: *ZigModule, elf_file: *Elf) void {195pub fn markLive(self: *ZigModule, elf_file: *Elf) void {
189 for (self.globals(), 0..) |index, i| {196 for (self.globals(), 0..) |index, i| {
190 const esym = self.global_esyms.items[i];197 const esym = self.global_esyms.items(.elf_sym)[i];
191 if (esym.st_bind() == elf.STB_WEAK) continue;198 if (esym.st_bind() == elf.STB_WEAK) continue;
192199
193 const global = elf_file.symbol(index);200 const global = elf_file.symbol(index);
...@@ -256,17 +263,17 @@ pub fn writeSymtab(self: *ZigModule, elf_file: *Elf, ctx: anytype) void {...@@ -256,17 +263,17 @@ pub fn writeSymtab(self: *ZigModule, elf_file: *Elf, ctx: anytype) void {
256}263}
257264
258pub fn symbol(self: *ZigModule, index: Symbol.Index) Symbol.Index {265pub fn symbol(self: *ZigModule, index: Symbol.Index) Symbol.Index {
259 const is_global = index & 0x10000000 != 0;266 const is_global = index & global_symbol_bit != 0;
260 const actual_index = index & 0x0fffffff;267 const actual_index = index & symbol_mask;
261 if (is_global) return self.global_symbols.items[actual_index];268 if (is_global) return self.global_symbols.items[actual_index];
262 return self.local_symbols.items[actual_index];269 return self.local_symbols.items[actual_index];
263}270}
264271
265pub fn elfSym(self: *ZigModule, index: Symbol.Index) *elf.Elf64_Sym {272pub fn elfSym(self: *ZigModule, index: Symbol.Index) *elf.Elf64_Sym {
266 const is_global = index & 0x10000000 != 0;273 const is_global = index & global_symbol_bit != 0;
267 const actual_index = index & 0x0fffffff;274 const actual_index = index & symbol_mask;
268 if (is_global) return &self.global_esyms.items[actual_index];275 if (is_global) return &self.global_esyms.items(.elf_sym)[actual_index];
269 return &self.local_esyms.items[actual_index];276 return &self.local_esyms.items(.elf_sym)[actual_index];
270}277}
271278
272pub fn locals(self: *ZigModule) []const Symbol.Index {279pub fn locals(self: *ZigModule) []const Symbol.Index {
...@@ -354,6 +361,11 @@ fn formatAtoms(...@@ -354,6 +361,11 @@ fn formatAtoms(
354 }361 }
355}362}
356363
364const ElfSym = struct {
365 elf_sym: elf.Elf64_Sym,
366 shndx: u32 = elf.SHN_UNDEF,
367};
368
357const assert = std.debug.assert;369const assert = std.debug.assert;
358const std = @import("std");370const std = @import("std");
359const elf = std.elf;371const elf = std.elf;