[lld] r240177 - COFF: Continue reading object files until converge.
Rui Ueyama
ruiu at google.com
Fri Jun 19 14:12:49 PDT 2015
Author: ruiu
Date: Fri Jun 19 16:12:48 2015
New Revision: 240177
URL: http://llvm.org/viewvc/llvm-project?rev=240177&view=rev
Log:
COFF: Continue reading object files until converge.
In this linker model, adding an undefined symbol may trigger chain
reactions. It may trigger a Lazy symbol to read a new file.
A new file may contain a directive section, which may contain various
command line options.
Previously, we didn't handle chain reactions well. We visited /include'd
symbols only once, so newly-added /include symbols were ignored.
This patch fixes that bug.
Now, the symbol table is versioned; every time the symbol table is
updated, the version number is incremented. We repeat adding undefined
symbols until the version number does not change. It is guaranteed to
converge -- the number of undefined symbol in the system is finite,
and adding the same undefined symbol more than once is basically no-op.
Added:
lld/trunk/test/COFF/Inputs/include1a.yaml
lld/trunk/test/COFF/Inputs/include1b.yaml
lld/trunk/test/COFF/Inputs/include1c.yaml
lld/trunk/test/COFF/include2.test
Modified:
lld/trunk/COFF/Driver.cpp
lld/trunk/COFF/SymbolTable.cpp
lld/trunk/COFF/SymbolTable.h
Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=240177&r1=240176&r2=240177&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Fri Jun 19 16:12:48 2015
@@ -454,11 +454,6 @@ bool LinkerDriver::link(int Argc, const
// Create a symbol table.
SymbolTable Symtab;
- // Add undefined symbols given via the command line.
- // (/include is equivalent to Unix linker's -u option.)
- for (StringRef Sym : Config->Includes)
- Symtab.addUndefined(Sym);
-
// Windows specific -- Create a resource file containing a manifest file.
if (Config->Manifest == Configuration::Embed) {
auto MBOrErr = createManifestRes();
@@ -499,36 +494,46 @@ bool LinkerDriver::link(int Argc, const
}
}
- // Windows specific -- Make sure we resolve all dllexported symbols.
- // (We don't cache the size here because Symtab.resolve() may add
- // new entries to Config->Exports.)
- for (size_t I = 0; I < Config->Exports.size(); ++I) {
- StringRef Sym = Config->Exports[I].Name;
- Symtab.addUndefined(Sym);
- }
-
- // Windows specific -- If entry point name is not given, we need to
- // infer that from user-defined entry name. The symbol table takes
- // care of details.
- if (Config->EntryName.empty()) {
- auto EntryOrErr = Symtab.findDefaultEntry();
- if (auto EC = EntryOrErr.getError()) {
- llvm::errs() << EC.message() << "\n";
- return false;
+ // Resolve auxiliary symbols until converge.
+ // (Trying to resolve a symbol may trigger a Lazy symbol to load a new file.
+ // A new file may contain a directive section to add new command line options.
+ // That's why we have to repeat until converge.)
+ for (;;) {
+ size_t Ver = Symtab.getVersion();
+
+ // Add undefined symbols specified by /include.
+ for (StringRef Sym : Config->Includes)
+ Symtab.addUndefined(Sym);
+
+ // Windows specific -- Make sure we resolve all dllexported symbols.
+ for (Export &E : Config->Exports)
+ Symtab.addUndefined(E.Name);
+
+ // Add weak aliases. Weak aliases is a mechanism to give remaining
+ // undefined symbols final chance to be resolved successfully.
+ // This is symbol renaming.
+ for (auto &P : Config->AlternateNames) {
+ StringRef From = P.first;
+ StringRef To = P.second;
+ if (auto EC = Symtab.rename(From, To)) {
+ llvm::errs() << EC.message() << "\n";
+ return false;
+ }
}
- Config->EntryName = EntryOrErr.get();
- }
- // Add weak aliases. Weak aliases is a mechanism to give remaining
- // undefined symbols final chance to be resolved successfully.
- // This is symbol renaming.
- for (auto &P : Config->AlternateNames) {
- StringRef From = P.first;
- StringRef To = P.second;
- if (auto EC = Symtab.rename(From, To)) {
- llvm::errs() << EC.message() << "\n";
- return false;
+ // Windows specific -- If entry point name is not given, we need to
+ // infer that from user-defined entry name. The symbol table takes
+ // care of details.
+ if (Config->EntryName.empty()) {
+ auto EntryOrErr = Symtab.findDefaultEntry();
+ if (auto EC = EntryOrErr.getError()) {
+ llvm::errs() << EC.message() << "\n";
+ return false;
+ }
+ Config->EntryName = EntryOrErr.get();
}
+ if (Ver == Symtab.getVersion())
+ break;
}
// Make sure we have resolved all symbols.
Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=240177&r1=240176&r2=240177&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Fri Jun 19 16:12:48 2015
@@ -128,6 +128,7 @@ std::error_code SymbolTable::resolve(Sym
if (!Sym) {
Sym = new (Alloc) Symbol(New);
New->setBackref(Sym);
+ ++Version;
return std::error_code();
}
New->setBackref(Sym);
@@ -136,8 +137,10 @@ std::error_code SymbolTable::resolve(Sym
// equivalent (conflicting), or more preferable, respectively.
SymbolBody *Existing = Sym->Body;
int comp = Existing->compare(New);
- if (comp < 0)
+ if (comp < 0) {
Sym->Body = New;
+ ++Version;
+ }
if (comp == 0) {
llvm::errs() << "duplicate symbol: " << Name << "\n";
return make_error_code(LLDError::DuplicateSymbols);
@@ -245,6 +248,7 @@ std::error_code SymbolTable::rename(Stri
return EC;
Sym->Body = Body->getReplacement();
Body->setBackref(Sym);
+ ++Version;
return std::error_code();
}
Modified: lld/trunk/COFF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.h?rev=240177&r1=240176&r2=240177&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.h (original)
+++ lld/trunk/COFF/SymbolTable.h Fri Jun 19 16:12:48 2015
@@ -34,8 +34,8 @@ namespace coff {
class SymbolTable {
public:
SymbolTable();
-
std::error_code addFile(std::unique_ptr<InputFile> File);
+ size_t getVersion() { return Version; }
// Print an error message on undefined symbols.
bool reportRemainingUndefines();
@@ -97,6 +97,9 @@ private:
std::vector<std::unique_ptr<BitcodeFile>> BitcodeFiles;
std::unique_ptr<MemoryBuffer> LTOMB;
llvm::BumpPtrAllocator Alloc;
+
+ // This variable is incremented every time Symtab is updated.
+ size_t Version = 0;
};
} // namespace coff
Added: lld/trunk/test/COFF/Inputs/include1a.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/include1a.yaml?rev=240177&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/include1a.yaml (added)
+++ lld/trunk/test/COFF/Inputs/include1a.yaml Fri Jun 19 16:12:48 2015
@@ -0,0 +1,33 @@
+---
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: []
+sections:
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: B800000000506800000000680000000050E80000000050E800000000
+ - Name: .drectve
+ Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
+ Alignment: 2147483648
+ SectionData: 2f696e636c7564653a666f6f00 # /include:foo
+symbols:
+ - Name: .text
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 28
+ NumberOfRelocations: 4
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: mainCRTStartup
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
Added: lld/trunk/test/COFF/Inputs/include1b.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/include1b.yaml?rev=240177&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/include1b.yaml (added)
+++ lld/trunk/test/COFF/Inputs/include1b.yaml Fri Jun 19 16:12:48 2015
@@ -0,0 +1,33 @@
+---
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: []
+sections:
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: B800000000506800000000680000000050E80000000050E800000000
+ - Name: .drectve
+ Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
+ Alignment: 2147483648
+ SectionData: 2f696e636c7564653a62617200 # /include:bar
+symbols:
+ - Name: .text
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 28
+ NumberOfRelocations: 4
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: foo
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
Added: lld/trunk/test/COFF/Inputs/include1c.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/include1c.yaml?rev=240177&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/include1c.yaml (added)
+++ lld/trunk/test/COFF/Inputs/include1c.yaml Fri Jun 19 16:12:48 2015
@@ -0,0 +1,29 @@
+---
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: []
+sections:
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: B800000000506800000000680000000050E80000000050E800000000
+symbols:
+ - Name: .text
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 28
+ NumberOfRelocations: 4
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: bar
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
Added: lld/trunk/test/COFF/include2.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/include2.test?rev=240177&view=auto
==============================================================================
--- lld/trunk/test/COFF/include2.test (added)
+++ lld/trunk/test/COFF/include2.test Fri Jun 19 16:12:48 2015
@@ -0,0 +1,14 @@
+# RUN: yaml2obj < %p/Inputs/include1a.yaml > %t1.obj
+# RUN: yaml2obj < %p/Inputs/include1b.yaml > %t2.obj
+# RUN: yaml2obj < %p/Inputs/include1c.yaml > %t3.obj
+# RUN: rm -f %t2.lib %t3.lib
+# RUN: llvm-ar cru %t2.lib %t2.obj
+# RUN: llvm-ar cru %t3.lib %t3.obj
+# RUN: lld -flavor link2 /out:%t.exe %t1.obj %t2.lib %t3.lib /verbose >& %t.log
+# RUN: FileCheck %s < %t.log
+
+CHECK: include2.test.tmp1.obj
+CHECK: include2.test.tmp2.lib
+CHECK: include2.test.tmp3.lib
+CHECK: include2.test.tmp2.lib(include2.test.tmp2.obj) for foo
+CHECK: include2.test.tmp3.lib(include2.test.tmp3.obj) for bar
More information about the llvm-commits
mailing list