| author | |
| committer | |
| log | 962b46148d573f62146a2752a0ab8cfd5f8da132 |
| tree | c7c0328dd00321ebdd6f727e9fca8e250148dd97 |
| parent | 53c3757c007bc48e5db1b933b0713df099499d2c |
6 files changed, 63 insertions(+), 45 deletions(-)
src/link/Elf.zig+16-1| ... | ... | @@ -1045,6 +1045,9 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1045 | 1045 | |
| 1046 | 1046 | try self.addLinkerDefinedSymbols(); |
| 1047 | 1047 | |
| 1048 | // Resolve symbols | |
| 1049 | self.resolveSymbols(); | |
| 1050 | ||
| 1048 | 1051 | if (self.unresolved.keys().len > 0) try self.reportUndefined(); |
| 1049 | 1052 | |
| 1050 | 1053 | self.allocateLinkerDefinedSymbols(); |
| ... | ... | @@ -1321,6 +1324,18 @@ fn parseObject(self: *Elf, in_file: std.fs.File, path: []const u8, ctx: *ParseEr |
| 1321 | 1324 | if (ctx.detected_cpu_arch != self.base.options.target.cpu.arch) return error.InvalidCpuArch; |
| 1322 | 1325 | } |
| 1323 | 1326 | |
| 1327 | fn resolveSymbols(self: *Elf) void { | |
| 1328 | if (self.zig_module_index) |index| { | |
| 1329 | const zig_module = self.file(index).?.zig_module; | |
| 1330 | zig_module.resolveSymbols(self); | |
| 1331 | } | |
| 1332 | ||
| 1333 | for (self.objects.items) |index| { | |
| 1334 | const object = self.file(index).?.object; | |
| 1335 | object.resolveSymbols(self); | |
| 1336 | } | |
| 1337 | } | |
| 1338 | ||
| 1324 | 1339 | fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 1325 | 1340 | const tracy = trace(@src()); |
| 1326 | 1341 | defer tracy.end(); |
| ... | ... | @@ -2697,7 +2712,7 @@ pub fn updateDeclExports( |
| 2697 | 2712 | const name_off = try self.strtab.insert(gpa, exp_name); |
| 2698 | 2713 | const esym = &zig_module.global_esyms.items[sym_index]; |
| 2699 | 2714 | esym.st_value = decl_sym.value; |
| 2700 | esym.st_shndx = decl_sym.output_section_index; | |
| 2715 | esym.st_shndx = decl_sym.atom_index; | |
| 2701 | 2716 | esym.st_info = (stb_bits << 4) | stt_bits; |
| 2702 | 2717 | esym.st_name = name_off; |
| 2703 | 2718 |
src/link/Elf/Atom.zig+2-2| ... | ... | @@ -17,7 +17,7 @@ alignment: u8 = 0, |
| 17 | 17 | input_section_index: Index = 0, |
| 18 | 18 | |
| 19 | 19 | /// Index of the output section. |
| 20 | output_section_index: u16 = 0, | |
| 20 | output_section_index: Index = 0, | |
| 21 | 21 | |
| 22 | 22 | /// Index of the input section containing this atom's relocs. |
| 23 | 23 | relocs_section_index: Index = 0, |
| ... | ... | @@ -484,7 +484,7 @@ fn format2( |
| 484 | 484 | } |
| 485 | 485 | } |
| 486 | 486 | |
| 487 | pub const Index = u32; | |
| 487 | pub const Index = u16; | |
| 488 | 488 | |
| 489 | 489 | const std = @import("std"); |
| 490 | 490 | const assert = std.debug.assert; |
src/link/Elf/Object.zig+14-23| ... | ... | @@ -245,10 +245,6 @@ fn initSymtab(self: *Object, elf_file: *Elf) !void { |
| 245 | 245 | const off = try elf_file.strtab.insert(gpa, name); |
| 246 | 246 | const gop = try elf_file.getOrPutGlobal(off); |
| 247 | 247 | self.symbols.addOneAssumeCapacity().* = gop.index; |
| 248 | ||
| 249 | if (sym.st_shndx == elf.SHN_UNDEF) { | |
| 250 | try elf_file.unresolved.put(gpa, gop.index, {}); | |
| 251 | } | |
| 252 | 248 | } |
| 253 | 249 | } |
| 254 | 250 | |
| ... | ... | @@ -388,34 +384,29 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf) !void { |
| 388 | 384 | pub fn resolveSymbols(self: *Object, elf_file: *Elf) void { |
| 389 | 385 | const first_global = self.first_global orelse return; |
| 390 | 386 | for (self.globals(), 0..) |index, i| { |
| 391 | const sym_idx = @as(u32, @intCast(first_global + i)); | |
| 392 | const this_sym = self.symtab[sym_idx]; | |
| 387 | const esym_index = @as(Symbol.Index, @intCast(first_global + i)); | |
| 388 | const esym = self.symtab[esym_index]; | |
| 393 | 389 | |
| 394 | if (this_sym.st_shndx == elf.SHN_UNDEF) continue; | |
| 390 | if (esym.st_shndx == elf.SHN_UNDEF) continue; | |
| 395 | 391 | |
| 396 | if (this_sym.st_shndx != elf.SHN_ABS and this_sym.st_shndx != elf.SHN_COMMON) { | |
| 397 | const atom_index = self.atoms.items[this_sym.st_shndx]; | |
| 392 | if (esym.st_shndx != elf.SHN_ABS and esym.st_shndx != elf.SHN_COMMON) { | |
| 393 | const atom_index = self.atoms.items[esym.st_shndx]; | |
| 398 | 394 | const atom = elf_file.atom(atom_index) orelse continue; |
| 399 | 395 | if (!atom.alive) continue; |
| 400 | 396 | } |
| 401 | 397 | |
| 402 | _ = elf_file.unresolved.swapRemove(index); | |
| 403 | ||
| 404 | 398 | const global = elf_file.symbol(index); |
| 405 | if (self.asFile().symbolRank(this_sym, !self.alive) < global.symbolRank(elf_file)) { | |
| 406 | const atom = switch (this_sym.st_shndx) { | |
| 399 | if (self.asFile().symbolRank(esym, !self.alive) < global.symbolRank(elf_file)) { | |
| 400 | const atom_index = switch (esym.st_shndx) { | |
| 407 | 401 | elf.SHN_ABS, elf.SHN_COMMON => 0, |
| 408 | else => self.atoms.items[this_sym.st_shndx], | |
| 409 | }; | |
| 410 | global.* = .{ | |
| 411 | .value = this_sym.st_value, | |
| 412 | .name = global.name, | |
| 413 | .atom = atom, | |
| 414 | .sym_idx = sym_idx, | |
| 415 | .file = self.index, | |
| 416 | .ver_idx = elf_file.default_sym_version, | |
| 402 | else => self.atoms.items[esym.st_shndx], | |
| 417 | 403 | }; |
| 418 | if (this_sym.st_bind() == elf.STB_WEAK) global.flags.weak = true; | |
| 404 | global.value = esym.st_value; | |
| 405 | global.atom_index = atom_index; | |
| 406 | global.esym_index = esym_index; | |
| 407 | global.file_index = self.index; | |
| 408 | global.version_index = elf_file.default_sym_version; | |
| 409 | if (esym.st_bind() == elf.STB_WEAK) global.flags.weak = true; | |
| 419 | 410 | } |
| 420 | 411 | } |
| 421 | 412 | } |
src/link/Elf/Symbol.zig+4-3| ... | ... | @@ -70,9 +70,10 @@ pub fn sourceSymbol(symbol: Symbol, elf_file: *Elf) elf.Elf64_Sym { |
| 70 | 70 | const file_ptr = symbol.file(elf_file).?; |
| 71 | 71 | switch (file_ptr) { |
| 72 | 72 | .zig_module => |x| { |
| 73 | const is_global = x.globals_lookup.contains(symbol.name_offset); | |
| 74 | if (is_global) return x.global_esyms.items[symbol.esym_index]; | |
| 75 | return x.local_esyms.items[symbol.esym_index]; | |
| 73 | const is_global = symbol.esym_index & 0x10000000 != 0; | |
| 74 | const esym_index = symbol.esym_index & 0x0fffffff; | |
| 75 | if (is_global) return x.global_esyms.items[esym_index]; | |
| 76 | return x.local_esyms.items[esym_index]; | |
| 76 | 77 | }, |
| 77 | 78 | .linker_defined => |x| return x.symtab.items[symbol.esym_index], |
| 78 | 79 | .object => |x| return x.symtab[symbol.esym_index], |
src/link/Elf/ZigModule.zig+27-4| ... | ... | @@ -62,7 +62,7 @@ pub fn addAtom(self: *ZigModule, output_section_index: u16, elf_file: *Elf) !Sym |
| 62 | 62 | |
| 63 | 63 | const esym_index = try self.addLocalEsym(gpa); |
| 64 | 64 | const esym = &self.local_esyms.items[esym_index]; |
| 65 | esym.st_shndx = output_section_index; | |
| 65 | esym.st_shndx = atom_index; | |
| 66 | 66 | symbol_ptr.esym_index = esym_index; |
| 67 | 67 | |
| 68 | 68 | const relocs_index = @as(Atom.Index, @intCast(self.relocs.items.len)); |
| ... | ... | @@ -74,9 +74,32 @@ pub fn addAtom(self: *ZigModule, output_section_index: u16, elf_file: *Elf) !Sym |
| 74 | 74 | } |
| 75 | 75 | |
| 76 | 76 | pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void { |
| 77 | _ = self; | |
| 78 | _ = elf_file; | |
| 79 | @panic("TODO"); | |
| 77 | for (self.globals(), 0..) |index, i| { | |
| 78 | const esym_index = @as(Symbol.Index, @intCast(i)) | 0x10000000; | |
| 79 | const esym = self.global_esyms.items[i]; | |
| 80 | ||
| 81 | if (esym.st_shndx == elf.SHN_UNDEF) continue; | |
| 82 | ||
| 83 | if (esym.st_shndx != elf.SHN_ABS and esym.st_shndx != elf.SHN_COMMON) { | |
| 84 | const atom_index = self.atoms.keys()[esym.st_shndx]; | |
| 85 | const atom = elf_file.atom(atom_index) orelse continue; | |
| 86 | if (!atom.alive) continue; | |
| 87 | } | |
| 88 | ||
| 89 | const global = elf_file.symbol(index); | |
| 90 | if (self.asFile().symbolRank(esym, false) < global.symbolRank(elf_file)) { | |
| 91 | const atom_index = switch (esym.st_shndx) { | |
| 92 | elf.SHN_ABS, elf.SHN_COMMON => 0, | |
| 93 | else => self.atoms.keys()[esym.st_shndx], | |
| 94 | }; | |
| 95 | global.value = esym.st_value; | |
| 96 | global.atom_index = atom_index; | |
| 97 | global.esym_index = esym_index; | |
| 98 | global.file_index = self.index; | |
| 99 | global.version_index = elf_file.default_sym_version; | |
| 100 | if (esym.st_bind() == elf.STB_WEAK) global.flags.weak = true; | |
| 101 | } | |
| 102 | } | |
| 80 | 103 | } |
| 81 | 104 | |
| 82 | 105 | pub fn updateSymtabSize(self: *ZigModule, elf_file: *Elf) void { |
src/link/Elf/file.zig-12| ... | ... | @@ -30,18 +30,6 @@ pub const File = union(enum) { |
| 30 | 30 | } |
| 31 | 31 | } |
| 32 | 32 | |
| 33 | pub fn resolveSymbols(file: File, elf_file: *Elf) void { | |
| 34 | switch (file) { | |
| 35 | inline else => |x| x.resolveSymbols(elf_file), | |
| 36 | } | |
| 37 | } | |
| 38 | ||
| 39 | // pub fn resetGlobals(file: File, elf_file: *Elf) void { | |
| 40 | // switch (file) { | |
| 41 | // inline else => |x| x.resetGlobals(elf_file), | |
| 42 | // } | |
| 43 | // } | |
| 44 | ||
| 45 | 33 | pub fn isAlive(file: File) bool { |
| 46 | 34 | return switch (file) { |
| 47 | 35 | .zig_module => true, |