summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/include/lld/Core/Resolver.h12
-rw-r--r--lld/lib/Core/Resolver.cpp54
-rw-r--r--lld/test/elf/Mips/rel-dynamic-01-micro.test12
-rw-r--r--lld/test/elf/Mips/rel-dynamic-01.test14
-rw-r--r--lld/test/elf/Mips/rel-dynamic-04-micro.test10
-rw-r--r--lld/test/elf/Mips/rel-dynamic-04.test10
-rw-r--r--lld/test/elf/Mips/rel-dynamic-05-micro.test12
-rw-r--r--lld/test/elf/Mips/rel-dynamic-05.test12
-rw-r--r--lld/test/elf/dynamic.test8
-rw-r--r--lld/test/mach-o/use-simple-dylib.yaml8
-rw-r--r--lld/test/pecoff/hello64.test8
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
OpenPOWER on IntegriCloud