| ... | ... | @@ -7,8 +7,8 @@ |
| 7 | 7 | path: []const u8, |
| 8 | 8 | index: File.Index, |
| 9 | 9 | |
| 10 | | local_esyms: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{}, |
| 11 | | global_esyms: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{}, |
| 10 | local_esyms: std.MultiArrayList(ElfSym) = .{}, |
| 11 | global_esyms: std.MultiArrayList(ElfSym) = .{}, |
| 12 | 12 | local_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 13 | 13 | global_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 14 | 14 | globals_lookup: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{}, |
| ... | ... | @@ -20,6 +20,10 @@ num_dynrelocs: u32 = 0, |
| 20 | 20 | |
| 21 | 21 | output_symtab_size: Elf.SymtabSize = .{}, |
| 22 | 22 | |
| 23 | pub const global_symbol_bit: u32 = 0x80000000; |
| 24 | pub const symbol_mask: u32 = 0x7fffffff; |
| 25 | pub const SHN_ATOM: u16 = 0x100; |
| 26 | |
| 23 | 27 | pub fn deinit(self: *ZigModule, allocator: Allocator) void { |
| 24 | 28 | self.local_esyms.deinit(allocator); |
| 25 | 29 | self.global_esyms.deinit(allocator); |
| ... | ... | @@ -35,20 +39,20 @@ pub fn deinit(self: *ZigModule, allocator: Allocator) void { |
| 35 | 39 | |
| 36 | 40 | pub fn addLocalEsym(self: *ZigModule, allocator: Allocator) !Symbol.Index { |
| 37 | 41 | try self.local_esyms.ensureUnusedCapacity(allocator, 1); |
| 38 | | const index = @as(Symbol.Index, @intCast(self.local_esyms.items.len)); |
| 39 | | const esym = self.local_esyms.addOneAssumeCapacity(); |
| 40 | | esym.* = Elf.null_sym; |
| 41 | | esym.st_info = elf.STB_LOCAL << 4; |
| 42 | const index = @as(Symbol.Index, @intCast(self.local_esyms.addOneAssumeCapacity())); |
| 43 | var esym = ElfSym{ .elf_sym = Elf.null_sym }; |
| 44 | esym.elf_sym.st_info = elf.STB_LOCAL << 4; |
| 45 | self.local_esyms.set(index, esym); |
| 42 | 46 | return index; |
| 43 | 47 | } |
| 44 | 48 | |
| 45 | 49 | pub fn addGlobalEsym(self: *ZigModule, allocator: Allocator) !Symbol.Index { |
| 46 | 50 | try self.global_esyms.ensureUnusedCapacity(allocator, 1); |
| 47 | | const index = @as(Symbol.Index, @intCast(self.global_esyms.items.len)); |
| 48 | | const esym = self.global_esyms.addOneAssumeCapacity(); |
| 49 | | esym.* = Elf.null_sym; |
| 50 | | esym.st_info = elf.STB_GLOBAL << 4; |
| 51 | | return index | 0x10000000; |
| 51 | const index = @as(Symbol.Index, @intCast(self.global_esyms.addOneAssumeCapacity())); |
| 52 | var esym = ElfSym{ .elf_sym = Elf.null_sym }; |
| 53 | esym.elf_sym.st_info = elf.STB_GLOBAL << 4; |
| 54 | self.global_esyms.set(index, esym); |
| 55 | return index | global_symbol_bit; |
| 52 | 56 | } |
| 53 | 57 | |
| 54 | 58 | 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 | 62 | const symbol_index = try elf_file.addSymbol(); |
| 59 | 63 | const esym_index = try self.addLocalEsym(gpa); |
| 60 | 64 | |
| 61 | | const shndx = @as(u16, @intCast(self.atoms.items.len)); |
| 65 | const shndx = @as(u32, @intCast(self.atoms.items.len)); |
| 62 | 66 | try self.atoms.append(gpa, atom_index); |
| 63 | 67 | try self.local_symbols.append(gpa, symbol_index); |
| 64 | 68 | |
| ... | ... | @@ -69,8 +73,8 @@ pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index { |
| 69 | 73 | symbol_ptr.file_index = self.index; |
| 70 | 74 | symbol_ptr.atom_index = atom_index; |
| 71 | 75 | |
| 72 | | const esym = &self.local_esyms.items[esym_index]; |
| 73 | | esym.st_shndx = shndx; |
| 76 | self.local_esyms.items(.shndx)[esym_index] = shndx; |
| 77 | self.local_esyms.items(.elf_sym)[esym_index].st_shndx = SHN_ATOM; |
| 74 | 78 | symbol_ptr.esym_index = esym_index; |
| 75 | 79 | |
| 76 | 80 | const relocs_index = @as(u32, @intCast(self.relocs.items.len)); |
| ... | ... | @@ -99,13 +103,15 @@ pub fn inputShdr(self: ZigModule, atom_index: Atom.Index, elf_file: *Elf) Object |
| 99 | 103 | |
| 100 | 104 | pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void { |
| 101 | 105 | for (self.globals(), 0..) |index, i| { |
| 102 | | const esym_index = @as(Symbol.Index, @intCast(i)) | 0x10000000; |
| 103 | | const esym = self.global_esyms.items[i]; |
| 106 | const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit; |
| 107 | const esym = self.global_esyms.items(.elf_sym)[i]; |
| 108 | const shndx = self.global_esyms.items(.shndx)[i]; |
| 104 | 109 | |
| 105 | 110 | if (esym.st_shndx == elf.SHN_UNDEF) continue; |
| 106 | 111 | |
| 107 | 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 | 115 | const atom = elf_file.atom(atom_index) orelse continue; |
| 110 | 116 | if (!atom.flags.alive) continue; |
| 111 | 117 | } |
| ... | ... | @@ -114,7 +120,8 @@ pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void { |
| 114 | 120 | if (self.asFile().symbolRank(esym, false) < global.symbolRank(elf_file)) { |
| 115 | 121 | const atom_index = switch (esym.st_shndx) { |
| 116 | 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 | 126 | const output_section_index = if (elf_file.atom(atom_index)) |atom| |
| 120 | 127 | atom.outputShndx().? |
| ... | ... | @@ -133,8 +140,8 @@ pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void { |
| 133 | 140 | |
| 134 | 141 | pub fn claimUnresolved(self: *ZigModule, elf_file: *Elf) void { |
| 135 | 142 | for (self.globals(), 0..) |index, i| { |
| 136 | | const esym_index = @as(Symbol.Index, @intCast(i)) | 0x10000000; |
| 137 | | const esym = self.global_esyms.items[i]; |
| 143 | const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit; |
| 144 | const esym = self.global_esyms.items(.elf_sym)[i]; |
| 138 | 145 | |
| 139 | 146 | if (esym.st_shndx != elf.SHN_UNDEF) continue; |
| 140 | 147 | |
| ... | ... | @@ -187,7 +194,7 @@ pub fn resetGlobals(self: *ZigModule, elf_file: *Elf) void { |
| 187 | 194 | |
| 188 | 195 | pub fn markLive(self: *ZigModule, elf_file: *Elf) void { |
| 189 | 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 | 198 | if (esym.st_bind() == elf.STB_WEAK) continue; |
| 192 | 199 | |
| 193 | 200 | const global = elf_file.symbol(index); |
| ... | ... | @@ -256,17 +263,17 @@ pub fn writeSymtab(self: *ZigModule, elf_file: *Elf, ctx: anytype) void { |
| 256 | 263 | } |
| 257 | 264 | |
| 258 | 265 | pub fn symbol(self: *ZigModule, index: Symbol.Index) Symbol.Index { |
| 259 | | const is_global = index & 0x10000000 != 0; |
| 260 | | const actual_index = index & 0x0fffffff; |
| 266 | const is_global = index & global_symbol_bit != 0; |
| 267 | const actual_index = index & symbol_mask; |
| 261 | 268 | if (is_global) return self.global_symbols.items[actual_index]; |
| 262 | 269 | return self.local_symbols.items[actual_index]; |
| 263 | 270 | } |
| 264 | 271 | |
| 265 | 272 | pub fn elfSym(self: *ZigModule, index: Symbol.Index) *elf.Elf64_Sym { |
| 266 | | const is_global = index & 0x10000000 != 0; |
| 267 | | const actual_index = index & 0x0fffffff; |
| 268 | | if (is_global) return &self.global_esyms.items[actual_index]; |
| 269 | | return &self.local_esyms.items[actual_index]; |
| 273 | const is_global = index & global_symbol_bit != 0; |
| 274 | const actual_index = index & symbol_mask; |
| 275 | if (is_global) return &self.global_esyms.items(.elf_sym)[actual_index]; |
| 276 | return &self.local_esyms.items(.elf_sym)[actual_index]; |
| 270 | 277 | } |
| 271 | 278 | |
| 272 | 279 | pub fn locals(self: *ZigModule) []const Symbol.Index { |
| ... | ... | @@ -354,6 +361,11 @@ fn formatAtoms( |
| 354 | 361 | } |
| 355 | 362 | } |
| 356 | 363 | |
| 364 | const ElfSym = struct { |
| 365 | elf_sym: elf.Elf64_Sym, |
| 366 | shndx: u32 = elf.SHN_UNDEF, |
| 367 | }; |
| 368 | |
| 357 | 369 | const assert = std.debug.assert; |
| 358 | 370 | const std = @import("std"); |
| 359 | 371 | const elf = std.elf; |