diff options
| -rw-r--r-- | lld/include/lld/Core/Resolver.h | 12 | ||||
| -rw-r--r-- | lld/lib/Core/Resolver.cpp | 54 | ||||
| -rw-r--r-- | lld/test/elf/Mips/rel-dynamic-01-micro.test | 12 | ||||
| -rw-r--r-- | lld/test/elf/Mips/rel-dynamic-01.test | 14 | ||||
| -rw-r--r-- | lld/test/elf/Mips/rel-dynamic-04-micro.test | 10 | ||||
| -rw-r--r-- | lld/test/elf/Mips/rel-dynamic-04.test | 10 | ||||
| -rw-r--r-- | lld/test/elf/Mips/rel-dynamic-05-micro.test | 12 | ||||
| -rw-r--r-- | lld/test/elf/Mips/rel-dynamic-05.test | 12 | ||||
| -rw-r--r-- | lld/test/elf/dynamic.test | 8 | ||||
| -rw-r--r-- | lld/test/mach-o/use-simple-dylib.yaml | 8 | ||||
| -rw-r--r-- | lld/test/pecoff/hello64.test | 8 |
11 files changed, 87 insertions, 73 deletions
diff --git a/lld/include/lld/Core/Resolver.h b/lld/include/lld/Core/Resolver.h index e07c449bf5d..c5b3ea6fecf 100644 --- a/lld/include/lld/Core/Resolver.h +++ b/lld/include/lld/Core/Resolver.h @@ -73,7 +73,7 @@ private: bool checkUndefines(); void removeCoalescedAwayAtoms(); void checkDylibSymbolCollisions(); - void forEachUndefines(bool searchForOverrides, UndefCallback callback); + void forEachUndefines(File &file, bool searchForOverrides, UndefCallback callback); void markLive(const Atom *atom); void addAtoms(const std::vector<const DefinedAtom *>&); @@ -102,6 +102,16 @@ private: // Preloading std::map<StringRef, ArchiveLibraryFile *> _archiveMap; std::unordered_set<ArchiveLibraryFile *> _archiveSeen; + + // List of undefined symbols. + std::vector<StringRef> _undefines; + + // Start position in _undefines for each archive/shared library file. + // Symbols from index 0 to the start position are already searched before. + // Searching them again would never succeed. When we look for undefined + // symbols from an archive/shared library file, start from its start + // position to save time. + std::map<File *, size_t> _undefineIndex; }; } // namespace lld diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp index 9ce948d4b25..ad5f2b71128 100644 --- a/lld/lib/Core/Resolver.cpp +++ b/lld/lib/Core/Resolver.cpp @@ -46,33 +46,35 @@ bool Resolver::handleFile(File &file) { return undefAdded; } -void Resolver::forEachUndefines(bool searchForOverrides, +void Resolver::forEachUndefines(File &file, bool searchForOverrides, UndefCallback callback) { - // Handle normal archives - unsigned undefineGenCount = 0; + size_t i = _undefineIndex[&file]; do { - undefineGenCount = _symbolTable.size(); - for (const UndefinedAtom *undefAtom : _symbolTable.undefines()) { - StringRef undefName = undefAtom->name(); - // load for previous undefine may also have loaded this undefine - if (!_symbolTable.isDefined(undefName)) - callback(undefName, false); - } - - // search libraries for overrides of common symbols - if (searchForOverrides) { - for (StringRef tentDefName : _symbolTable.tentativeDefinitions()) { - // Load for previous tentative may also have loaded - // something that overrode this tentative, so always check. - const Atom *curAtom = _symbolTable.findByName(tentDefName); - assert(curAtom != nullptr); - if (const DefinedAtom *curDefAtom = dyn_cast<DefinedAtom>(curAtom)) { - if (curDefAtom->merge() == DefinedAtom::mergeAsTentative) - callback(tentDefName, true); - } + for (; i < _undefines.size(); ++i) { + StringRef undefName = _undefines[i]; + if (undefName.empty()) + continue; + if (_symbolTable.isDefined(undefName) || + _symbolTable.isCoalescedAway(_symbolTable.findByName(undefName))) { + // The symbol was resolved by some other file. Cache the result. + _undefines[i] = ""; + continue; } + callback(undefName, false); + } + if (!searchForOverrides) + continue; + for (StringRef tentDefName : _symbolTable.tentativeDefinitions()) { + // Load for previous tentative may also have loaded + // something that overrode this tentative, so always check. + const Atom *curAtom = _symbolTable.findByName(tentDefName); + assert(curAtom != nullptr); + if (const DefinedAtom *curDefAtom = dyn_cast<DefinedAtom>(curAtom)) + if (curDefAtom->merge() == DefinedAtom::mergeAsTentative) + callback(tentDefName, true); } - } while (undefineGenCount != _symbolTable.size()); + } while (i < _undefines.size()); + _undefineIndex[&file] = i; } bool Resolver::handleArchiveFile(File &file) { @@ -80,7 +82,7 @@ bool Resolver::handleArchiveFile(File &file) { bool searchForOverrides = _ctx.searchArchivesToOverrideTentativeDefinitions(); bool undefAdded = false; - forEachUndefines(searchForOverrides, + forEachUndefines(file, searchForOverrides, [&](StringRef undefName, bool dataSymbolOnly) { if (File *member = archiveFile->find(undefName, dataSymbolOnly)) { member->setOrdinal(_ctx.getNextOrdinalAndIncrement()); @@ -98,7 +100,7 @@ void Resolver::handleSharedLibrary(File &file) { handleFile(*sharedLibrary); bool searchForOverrides = _ctx.searchSharedLibrariesToOverrideTentativeDefinitions(); - forEachUndefines(searchForOverrides, + forEachUndefines(file, searchForOverrides, [&](StringRef undefName, bool dataSymbolOnly) { if (const SharedLibraryAtom *atom = sharedLibrary->exports(undefName, dataSymbolOnly)) @@ -117,6 +119,8 @@ bool Resolver::doUndefinedAtom(const UndefinedAtom &atom) { // tell symbol table bool newUndefAdded = _symbolTable.add(atom); + if (newUndefAdded) + _undefines.push_back(atom.name()); // If the undefined symbol has an alternative name, try to resolve the // symbol with the name to give it a second chance. This feature is used diff --git a/lld/test/elf/Mips/rel-dynamic-01-micro.test b/lld/test/elf/Mips/rel-dynamic-01-micro.test index f3912f78750..6e0a41bf260 100644 --- a/lld/test/elf/Mips/rel-dynamic-01-micro.test +++ b/lld/test/elf/Mips/rel-dynamic-01-micro.test @@ -68,21 +68,21 @@ # PLT-SYM-NEXT: Section: .bss (0xD) # PLT-SYM-NEXT: } # PLT-SYM-NEXT: Symbol { -# PLT-SYM-NEXT: Name: T3@ (4) -# PLT-SYM-NEXT: Value: 0x0 +# PLT-SYM-NEXT: Name: T1@ (4) +# PLT-SYM-NEXT: Value: 0x4001D5 # PLT-SYM-NEXT: Size: 0 # PLT-SYM-NEXT: Binding: Global (0x1) # PLT-SYM-NEXT: Type: Function (0x2) -# PLT-SYM-NEXT: Other: 0 +# PLT-SYM-NEXT: Other: 8 # PLT-SYM-NEXT: Section: Undefined (0x0) # PLT-SYM-NEXT: } # PLT-SYM-NEXT: Symbol { -# PLT-SYM-NEXT: Name: T1@ (7) -# PLT-SYM-NEXT: Value: 0x4001D5 +# PLT-SYM-NEXT: Name: T3@ (7) +# PLT-SYM-NEXT: Value: 0x0 # PLT-SYM-NEXT: Size: 0 # PLT-SYM-NEXT: Binding: Global (0x1) # PLT-SYM-NEXT: Type: Function (0x2) -# PLT-SYM-NEXT: Other: 8 +# PLT-SYM-NEXT: Other: 0 # PLT-SYM-NEXT: Section: Undefined (0x0) # PLT-SYM-NEXT: } # PLT-SYM-NEXT: ] diff --git a/lld/test/elf/Mips/rel-dynamic-01.test b/lld/test/elf/Mips/rel-dynamic-01.test index 79a76390f2e..ca4619668bd 100644 --- a/lld/test/elf/Mips/rel-dynamic-01.test +++ b/lld/test/elf/Mips/rel-dynamic-01.test @@ -69,25 +69,25 @@ # PLT-SYM-NEXT: Section: .bss (0xD) # PLT-SYM-NEXT: } # PLT-SYM-NEXT: Symbol { -# PLT-SYM-NEXT: Name: T3@ (4) -# PLT-SYM-NEXT: Value: 0x0 +# PLT-SYM-NEXT: Name: T1@ (4) +# PLT-SYM-NEXT: Value: 0x400220 # PLT-SYM-NEXT: Size: 0 # PLT-SYM-NEXT: Binding: Global (0x1) # PLT-SYM-NEXT: Type: Function (0x2) -# PLT-SYM-NEXT: Other: 0 +# PLT-SYM-NEXT: Other: 8 # PLT-SYM-NEXT: Section: Undefined (0x0) # PLT-SYM-NEXT: } # PLT-SYM-NEXT: Symbol { -# PLT-SYM-NEXT: Name: T1@ (7) -# PLT-SYM-NEXT: Value: 0x400220 +# PLT-SYM-NEXT: Name: T3@ (10) +# PLT-SYM-NEXT: Value: 0x0 # PLT-SYM-NEXT: Size: 0 # PLT-SYM-NEXT: Binding: Global (0x1) # PLT-SYM-NEXT: Type: Function (0x2) -# PLT-SYM-NEXT: Other: 8 +# PLT-SYM-NEXT: Other: 0 # PLT-SYM-NEXT: Section: Undefined (0x0) # PLT-SYM-NEXT: } # PLT-SYM-NEXT: Symbol { -# PLT-SYM-NEXT: Name: T2@ (10) +# PLT-SYM-NEXT: Name: T2@ (7) # PLT-SYM-NEXT: Value: 0x0 # PLT-SYM-NEXT: Size: 0 # PLT-SYM-NEXT: Binding: Global (0x1) diff --git a/lld/test/elf/Mips/rel-dynamic-04-micro.test b/lld/test/elf/Mips/rel-dynamic-04-micro.test index b471a543fa5..1c58efdf5f7 100644 --- a/lld/test/elf/Mips/rel-dynamic-04-micro.test +++ b/lld/test/elf/Mips/rel-dynamic-04-micro.test @@ -88,8 +88,8 @@ # PLT-NEXT: Section: Undefined (0x0) # PLT-NEXT: } # PLT-NEXT: Symbol { -# PLT-NEXT: Name: T3@ (1) -# PLT-NEXT: Value: 0x4010E5 +# PLT-NEXT: Name: T2@ (4) +# PLT-NEXT: Value: 0x4010D9 # PLT-NEXT: Size: 0 # PLT-NEXT: Binding: Global (0x1) # PLT-NEXT: Type: Function (0x2) @@ -97,8 +97,8 @@ # PLT-NEXT: Section: Undefined (0x0) # PLT-NEXT: } # PLT-NEXT: Symbol { -# PLT-NEXT: Name: T2@ (7) -# PLT-NEXT: Value: 0x4010D9 +# PLT-NEXT: Name: T3@ (7) +# PLT-NEXT: Value: 0x4010E5 # PLT-NEXT: Size: 0 # PLT-NEXT: Binding: Global (0x1) # PLT-NEXT: Type: Function (0x2) @@ -106,7 +106,7 @@ # PLT-NEXT: Section: Undefined (0x0) # PLT-NEXT: } # PLT-NEXT: Symbol { -# PLT-NEXT: Name: T1@ (4) +# PLT-NEXT: Name: T1@ (1) # PLT-NEXT: Value: 0x0 # PLT-NEXT: Size: 0 # PLT-NEXT: Binding: Global (0x1) diff --git a/lld/test/elf/Mips/rel-dynamic-04.test b/lld/test/elf/Mips/rel-dynamic-04.test index a5df8cba827..5b5bcce01cd 100644 --- a/lld/test/elf/Mips/rel-dynamic-04.test +++ b/lld/test/elf/Mips/rel-dynamic-04.test @@ -86,8 +86,8 @@ # PLT-NEXT: Section: Undefined (0x0) # PLT-NEXT: } # PLT-NEXT: Symbol { -# PLT-NEXT: Name: T3@ (1) -# PLT-NEXT: Value: 0x4010F0 +# PLT-NEXT: Name: T2@ (4) +# PLT-NEXT: Value: 0x4010E0 # PLT-NEXT: Size: 0 # PLT-NEXT: Binding: Global (0x1) # PLT-NEXT: Type: Function (0x2) @@ -95,8 +95,8 @@ # PLT-NEXT: Section: Undefined (0x0) # PLT-NEXT: } # PLT-NEXT: Symbol { -# PLT-NEXT: Name: T2@ (7) -# PLT-NEXT: Value: 0x4010E0 +# PLT-NEXT: Name: T3@ (7) +# PLT-NEXT: Value: 0x4010F0 # PLT-NEXT: Size: 0 # PLT-NEXT: Binding: Global (0x1) # PLT-NEXT: Type: Function (0x2) @@ -104,7 +104,7 @@ # PLT-NEXT: Section: Undefined (0x0) # PLT-NEXT: } # PLT-NEXT: Symbol { -# PLT-NEXT: Name: T1@ (4) +# PLT-NEXT: Name: T1@ (1) # PLT-NEXT: Value: 0x0 # PLT-NEXT: Size: 0 # PLT-NEXT: Binding: Global (0x1) diff --git a/lld/test/elf/Mips/rel-dynamic-05-micro.test b/lld/test/elf/Mips/rel-dynamic-05-micro.test index 23a879a10eb..d1c87076b59 100644 --- a/lld/test/elf/Mips/rel-dynamic-05-micro.test +++ b/lld/test/elf/Mips/rel-dynamic-05-micro.test @@ -70,8 +70,8 @@ # PLT-NEXT: Section: Undefined (0x0) # PLT-NEXT: } # PLT-NEXT: Symbol { -# PLT-NEXT: Name: T3@ (1) -# PLT-NEXT: Value: 0x4001E1 +# PLT-NEXT: Name: T1@ (1) +# PLT-NEXT: Value: 0x4001C9 # PLT-NEXT: Size: 0 # PLT-NEXT: Binding: Global (0x1) # PLT-NEXT: Type: Function (0x2) @@ -79,8 +79,8 @@ # PLT-NEXT: Section: Undefined (0x0) # PLT-NEXT: } # PLT-NEXT: Symbol { -# PLT-NEXT: Name: T1@ (4) -# PLT-NEXT: Value: 0x4001C9 +# PLT-NEXT: Name: T2@ (4) +# PLT-NEXT: Value: 0x4001D5 # PLT-NEXT: Size: 0 # PLT-NEXT: Binding: Global (0x1) # PLT-NEXT: Type: Function (0x2) @@ -88,8 +88,8 @@ # PLT-NEXT: Section: Undefined (0x0) # PLT-NEXT: } # PLT-NEXT: Symbol { -# PLT-NEXT: Name: T2@ (7) -# PLT-NEXT: Value: 0x4001D5 +# PLT-NEXT: Name: T3@ (7) +# PLT-NEXT: Value: 0x4001E1 # PLT-NEXT: Size: 0 # PLT-NEXT: Binding: Global (0x1) # PLT-NEXT: Type: Function (0x2) diff --git a/lld/test/elf/Mips/rel-dynamic-05.test b/lld/test/elf/Mips/rel-dynamic-05.test index b955c133eb9..3bfbd3f6efd 100644 --- a/lld/test/elf/Mips/rel-dynamic-05.test +++ b/lld/test/elf/Mips/rel-dynamic-05.test @@ -68,8 +68,8 @@ # PLT-NEXT: Section: Undefined (0x0) # PLT-NEXT: } # PLT-NEXT: Symbol { -# PLT-NEXT: Name: T3@ (1) -# PLT-NEXT: Value: 0x4001F0 +# PLT-NEXT: Name: T1@ (1) +# PLT-NEXT: Value: 0x4001D0 # PLT-NEXT: Size: 0 # PLT-NEXT: Binding: Global (0x1) # PLT-NEXT: Type: Function (0x2) @@ -77,8 +77,8 @@ # PLT-NEXT: Section: Undefined (0x0) # PLT-NEXT: } # PLT-NEXT: Symbol { -# PLT-NEXT: Name: T1@ (4) -# PLT-NEXT: Value: 0x4001D0 +# PLT-NEXT: Name: T2@ (4) +# PLT-NEXT: Value: 0x4001E0 # PLT-NEXT: Size: 0 # PLT-NEXT: Binding: Global (0x1) # PLT-NEXT: Type: Function (0x2) @@ -86,8 +86,8 @@ # PLT-NEXT: Section: Undefined (0x0) # PLT-NEXT: } # PLT-NEXT: Symbol { -# PLT-NEXT: Name: T2@ (7) -# PLT-NEXT: Value: 0x4001E0 +# PLT-NEXT: Name: T3@ (7) +# PLT-NEXT: Value: 0x4001F0 # PLT-NEXT: Size: 0 # PLT-NEXT: Binding: Global (0x1) # PLT-NEXT: Type: Function (0x2) diff --git a/lld/test/elf/dynamic.test b/lld/test/elf/dynamic.test index 3c2897e9137..59269612cf8 100644 --- a/lld/test/elf/dynamic.test +++ b/lld/test/elf/dynamic.test @@ -46,18 +46,18 @@ CHECK-NEXT: } CHECK: DynamicSymbols [ CHECK: Symbol { -CHECK: Name: i +CHECK: Name: foo CHECK-NEXT: Value: 0 CHECK-NEXT: Size: CHECK-NEXT: Binding: Global -CHECK-NEXT: Type: Object +CHECK-NEXT: Type: Function CHECK: } CHECK: Symbol { -CHECK: Name: foo +CHECK: Name: i CHECK-NEXT: Value: 0 CHECK-NEXT: Size: CHECK-NEXT: Binding: Global -CHECK-NEXT: Type: Function +CHECK-NEXT: Type: Object CHECK: } CHECK: DynamicSection [ (15 entries) diff --git a/lld/test/mach-o/use-simple-dylib.yaml b/lld/test/mach-o/use-simple-dylib.yaml index bfa393dc405..dcc6b4614b3 100644 --- a/lld/test/mach-o/use-simple-dylib.yaml +++ b/lld/test/mach-o/use-simple-dylib.yaml @@ -119,13 +119,13 @@ install-name: libspecial.dylib # CHECK: - name: _myStatic # CHECK: - name: _myVariablePreviouslyKnownAsPrivateExtern # CHECK: shared-library-atoms: -# CHECK: - name: _myHidden -# CHECK: load-name: libspecial.dylib # CHECK: - name: _myGlobal # CHECK: load-name: libspecial.dylib -# CHECK: - name: _myHiddenWeak -# CHECK: load-name: libspecial.dylib # CHECK: - name: _myGlobalWeak # CHECK: load-name: libspecial.dylib +# CHECK: - name: _myHidden +# CHECK: load-name: libspecial.dylib +# CHECK: - name: _myHiddenWeak +# CHECK: load-name: libspecial.dylib # CHECK: - name: _myResolver # CHECK: load-name: libspecial.dylib diff --git a/lld/test/pecoff/hello64.test b/lld/test/pecoff/hello64.test index a631b553165..7536e5a8fd2 100644 --- a/lld/test/pecoff/hello64.test +++ b/lld/test/pecoff/hello64.test @@ -11,12 +11,12 @@ CHECK: 6004: 48 c7 c1 00 00 00 00 movq $0, %rcx CHECK: 600b: 48 8d 15 f4 af ff ff leaq -20492(%rip), %rdx CHECK: 6012: 4c 8d 05 e7 af ff ff leaq -20505(%rip), %r8 CHECK: 6019: 41 b9 00 00 00 00 movl $0, %r9d -CHECK: 601f: e8 0a 00 00 00 callq 10 +CHECK: 601f: e8 12 00 00 00 callq 18 CHECK: 6024: b9 00 00 00 00 movl $0, %ecx -CHECK: 6029: e8 08 00 00 00 callq 8 -CHECK: 602e: ff 25 d4 cf ff ff jmpq *-12332(%rip) +CHECK: 6029: e8 00 00 00 00 callq 0 +CHECK: 602e: ff 25 cc cf ff ff jmpq *-12340(%rip) CHECK: 6034: cc int3 CHECK: 6035: cc int3 -CHECK: 6036: ff 25 c4 cf ff ff jmpq *-12348(%rip) +CHECK: 6036: ff 25 cc cf ff ff jmpq *-12340(%rip) CHECK: 603c: cc int3 CHECK: 603d: cc int3 |

