| author | |
| committer | |
| log | c654f3b0ee8d02d809bb458e1e006b4aa7c3cbc6 |
| tree | 841df34409500529095b45be843bd0332c99aab0 |
| parent | b478a0dd1ab6acab92e2b1a4198fdf6428caad8d |
4 files changed, 101 insertions(+), 37 deletions(-)
src/link/Elf.zig+37-35| ... | @@ -1048,6 +1048,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1048,6 +1048,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1048 | // Resolve symbols | 1048 | // Resolve symbols |
| 1049 | self.resolveSymbols(); | 1049 | self.resolveSymbols(); |
| 1050 | self.markImportsExports(); | 1050 | self.markImportsExports(); |
| 1051 | self.claimUnresolved(); | ||
| 1051 | 1052 | ||
| 1052 | if (self.unresolved.keys().len > 0) try self.reportUndefined(); | 1053 | if (self.unresolved.keys().len > 0) try self.reportUndefined(); |
| 1053 | 1054 | ||
| ... | @@ -1338,48 +1339,45 @@ fn resolveSymbols(self: *Elf) void { | ... | @@ -1338,48 +1339,45 @@ fn resolveSymbols(self: *Elf) void { |
| 1338 | } | 1339 | } |
| 1339 | 1340 | ||
| 1340 | fn markImportsExports(self: *Elf) void { | 1341 | fn markImportsExports(self: *Elf) void { |
| 1341 | const is_dyn_lib = self.base.options.output_mode == .Lib and self.base.options.link_mode == .Dynamic; | 1342 | const mark = struct { |
| 1342 | 1343 | fn mark(elf_file: *Elf, file_index: File.Index) void { | |
| 1343 | if (self.zig_module_index) |index| { | 1344 | for (elf_file.file(file_index).?.globals()) |global_index| { |
| 1344 | const zig_module = self.file(index).?.zig_module; | 1345 | const global = elf_file.symbol(global_index); |
| 1345 | for (zig_module.globals()) |global_index| { | 1346 | if (global.version_index == elf.VER_NDX_LOCAL) continue; |
| 1346 | const global = self.symbol(global_index); | 1347 | const file_ptr = global.file(elf_file) orelse continue; |
| 1347 | if (global.version_index == elf.VER_NDX_LOCAL) continue; | 1348 | const vis = @as(elf.STV, @enumFromInt(global.elfSym(elf_file).st_other)); |
| 1348 | const file_ptr = global.file(self) orelse continue; | 1349 | if (vis == .HIDDEN) continue; |
| 1349 | const vis = @as(elf.STV, @enumFromInt(global.elfSym(self).st_other)); | 1350 | // if (file == .shared and !global.isAbs(self)) { |
| 1350 | if (vis == .HIDDEN) continue; | 1351 | // global.flags.import = true; |
| 1351 | // if (file == .shared and !global.isAbs(self)) { | 1352 | // continue; |
| 1352 | // global.flags.import = true; | 1353 | // } |
| 1353 | // continue; | 1354 | if (file_ptr.index() == file_index) { |
| 1354 | // } | 1355 | global.flags.@"export" = true; |
| 1355 | if (file_ptr.index() == index) { | 1356 | if (elf_file.isDynLib() and vis != .PROTECTED) { |
| 1356 | global.flags.@"export" = true; | 1357 | global.flags.import = true; |
| 1357 | if (is_dyn_lib and vis != .PROTECTED) { | 1358 | } |
| 1358 | global.flags.import = true; | ||
| 1359 | } | 1359 | } |
| 1360 | } | 1360 | } |
| 1361 | } | 1361 | } |
| 1362 | }.mark; | ||
| 1363 | |||
| 1364 | if (self.zig_module_index) |index| { | ||
| 1365 | mark(self, index); | ||
| 1366 | } | ||
| 1367 | |||
| 1368 | for (self.objects.items) |index| { | ||
| 1369 | mark(self, index); | ||
| 1362 | } | 1370 | } |
| 1371 | } | ||
| 1363 | 1372 | ||
| 1373 | fn claimUnresolved(self: *Elf) void { | ||
| 1374 | if (self.zig_module_index) |index| { | ||
| 1375 | const zig_module = self.file(index).?.zig_module; | ||
| 1376 | zig_module.claimUnresolved(self); | ||
| 1377 | } | ||
| 1364 | for (self.objects.items) |index| { | 1378 | for (self.objects.items) |index| { |
| 1365 | const object = self.file(index).?.object; | 1379 | const object = self.file(index).?.object; |
| 1366 | for (object.globals()) |global_index| { | 1380 | object.claimUnresolved(self); |
| 1367 | const global = self.symbol(global_index); | ||
| 1368 | if (global.version_index == elf.VER_NDX_LOCAL) continue; | ||
| 1369 | const file_ptr = global.file(self) orelse continue; | ||
| 1370 | const vis = @as(elf.STV, @enumFromInt(global.elfSym(self).st_other)); | ||
| 1371 | if (vis == .HIDDEN) continue; | ||
| 1372 | // if (file == .shared and !global.isAbs(self)) { | ||
| 1373 | // global.flags.import = true; | ||
| 1374 | // continue; | ||
| 1375 | // } | ||
| 1376 | if (file_ptr.index() == index) { | ||
| 1377 | global.flags.@"export" = true; | ||
| 1378 | if (is_dyn_lib and vis != .PROTECTED) { | ||
| 1379 | global.flags.import = true; | ||
| 1380 | } | ||
| 1381 | } | ||
| 1382 | } | ||
| 1383 | } | 1381 | } |
| 1384 | } | 1382 | } |
| 1385 | 1383 | ||
| ... | @@ -3423,6 +3421,10 @@ pub fn defaultEntryAddress(self: Elf) u64 { | ... | @@ -3423,6 +3421,10 @@ pub fn defaultEntryAddress(self: Elf) u64 { |
| 3423 | }; | 3421 | }; |
| 3424 | } | 3422 | } |
| 3425 | 3423 | ||
| 3424 | pub fn isDynLib(self: Elf) bool { | ||
| 3425 | return self.base.options.output_mode == .Lib and self.base.options.link_mode == .Dynamic; | ||
| 3426 | } | ||
| 3427 | |||
| 3426 | pub fn sectionByName(self: *Elf, name: [:0]const u8) ?u16 { | 3428 | pub fn sectionByName(self: *Elf, name: [:0]const u8) ?u16 { |
| 3427 | for (self.shdrs.items, 0..) |*shdr, i| { | 3429 | for (self.shdrs.items, 0..) |*shdr, i| { |
| 3428 | const this_name = self.shstrtab.getAssumeExists(shdr.sh_name); | 3430 | const this_name = self.shstrtab.getAssumeExists(shdr.sh_name); |
src/link/Elf/Object.zig+30-2| ... | @@ -411,6 +411,34 @@ pub fn resolveSymbols(self: *Object, elf_file: *Elf) void { | ... | @@ -411,6 +411,34 @@ pub fn resolveSymbols(self: *Object, elf_file: *Elf) void { |
| 411 | } | 411 | } |
| 412 | } | 412 | } |
| 413 | 413 | ||
| 414 | pub fn claimUnresolved(self: *Object, elf_file: *Elf) void { | ||
| 415 | const first_global = self.first_global orelse return; | ||
| 416 | for (self.globals(), 0..) |index, i| { | ||
| 417 | const esym_index = @as(u32, @intCast(first_global + i)); | ||
| 418 | const esym = self.symtab[esym_index]; | ||
| 419 | if (esym.st_shndx != elf.SHN_UNDEF) continue; | ||
| 420 | |||
| 421 | const global = elf_file.symbol(index); | ||
| 422 | if (global.file(elf_file)) |_| { | ||
| 423 | if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF) continue; | ||
| 424 | } | ||
| 425 | |||
| 426 | const is_import = blk: { | ||
| 427 | if (!elf_file.isDynLib()) break :blk false; | ||
| 428 | const vis = @as(elf.STV, @enumFromInt(esym.st_other)); | ||
| 429 | if (vis == .HIDDEN) break :blk false; | ||
| 430 | break :blk true; | ||
| 431 | }; | ||
| 432 | |||
| 433 | global.value = 0; | ||
| 434 | global.atom_index = 0; | ||
| 435 | global.esym_index = esym_index; | ||
| 436 | global.file_index = self.index; | ||
| 437 | global.version_index = if (is_import) elf.VER_NDX_LOCAL else elf_file.default_sym_version; | ||
| 438 | global.flags.import = is_import; | ||
| 439 | } | ||
| 440 | } | ||
| 441 | |||
| 414 | pub fn resetGlobals(self: *Object, elf_file: *Elf) void { | 442 | pub fn resetGlobals(self: *Object, elf_file: *Elf) void { |
| 415 | for (self.globals()) |index| { | 443 | for (self.globals()) |index| { |
| 416 | const global = elf_file.symbol(index); | 444 | const global = elf_file.symbol(index); |
| ... | @@ -576,12 +604,12 @@ pub fn writeSymtab(self: *Object, elf_file: *Elf, ctx: anytype) void { | ... | @@ -576,12 +604,12 @@ pub fn writeSymtab(self: *Object, elf_file: *Elf, ctx: anytype) void { |
| 576 | } | 604 | } |
| 577 | } | 605 | } |
| 578 | 606 | ||
| 579 | pub fn locals(self: *Object) []const u32 { | 607 | pub fn locals(self: *Object) []const Symbol.Index { |
| 580 | const end = self.first_global orelse self.symbols.items.len; | 608 | const end = self.first_global orelse self.symbols.items.len; |
| 581 | return self.symbols.items[0..end]; | 609 | return self.symbols.items[0..end]; |
| 582 | } | 610 | } |
| 583 | 611 | ||
| 584 | pub fn globals(self: *Object) []const u32 { | 612 | pub fn globals(self: *Object) []const Symbol.Index { |
| 585 | const start = self.first_global orelse self.symbols.items.len; | 613 | const start = self.first_global orelse self.symbols.items.len; |
| 586 | return self.symbols.items[start..]; | 614 | return self.symbols.items[start..]; |
| 587 | } | 615 | } |
src/link/Elf/ZigModule.zig+28| ... | @@ -102,6 +102,34 @@ pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void { | ... | @@ -102,6 +102,34 @@ pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void { |
| 102 | } | 102 | } |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | pub fn claimUnresolved(self: *ZigModule, elf_file: *Elf) void { | ||
| 106 | for (self.globals(), 0..) |index, i| { | ||
| 107 | const esym_index = @as(Symbol.Index, @intCast(i)) | 0x10000000; | ||
| 108 | const esym = self.global_esyms.items[i]; | ||
| 109 | |||
| 110 | if (esym.st_shndx != elf.SHN_UNDEF) continue; | ||
| 111 | |||
| 112 | const global = elf_file.symbol(index); | ||
| 113 | if (global.file(elf_file)) |_| { | ||
| 114 | if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF) continue; | ||
| 115 | } | ||
| 116 | |||
| 117 | const is_import = blk: { | ||
| 118 | if (!elf_file.isDynLib()) break :blk false; | ||
| 119 | const vis = @as(elf.STV, @enumFromInt(esym.st_other)); | ||
| 120 | if (vis == .HIDDEN) break :blk false; | ||
| 121 | break :blk true; | ||
| 122 | }; | ||
| 123 | |||
| 124 | global.value = 0; | ||
| 125 | global.atom_index = 0; | ||
| 126 | global.esym_index = esym_index; | ||
| 127 | global.file_index = self.index; | ||
| 128 | global.version_index = if (is_import) elf.VER_NDX_LOCAL else elf_file.default_sym_version; | ||
| 129 | global.flags.import = is_import; | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 105 | pub fn updateSymtabSize(self: *ZigModule, elf_file: *Elf) void { | 133 | pub fn updateSymtabSize(self: *ZigModule, elf_file: *Elf) void { |
| 106 | for (self.locals()) |local_index| { | 134 | for (self.locals()) |local_index| { |
| 107 | const local = elf_file.symbol(local_index); | 135 | const local = elf_file.symbol(local_index); |
src/link/Elf/file.zig+6| ... | @@ -76,6 +76,12 @@ pub const File = union(enum) { | ... | @@ -76,6 +76,12 @@ pub const File = union(enum) { |
| 76 | } | 76 | } |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | pub fn globals(file: File) []const Symbol.Index { | ||
| 80 | return switch (file) { | ||
| 81 | inline else => |x| x.globals(), | ||
| 82 | }; | ||
| 83 | } | ||
| 84 | |||
| 79 | pub const Index = u32; | 85 | pub const Index = u32; |
| 80 | 86 | ||
| 81 | pub const Entry = union(enum) { | 87 | pub const Entry = union(enum) { |