From e042fa9aa5ea0fd936b532e4b17c3e185a7aabc8 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Sun, 31 May 2015 19:55:40 +0000 Subject: [PATCH] COFF: Add /include option. It does not involve notions of virtual archives or virtual files, nor store a list of undefined symbols somewhere else to consume them later. We did that before. In this patch, undefined symbols are just added to the symbol table, which now can be done in very few lines of code. llvm-svn: 238681 --- lld/COFF/Driver.cpp | 9 ++++++++- lld/COFF/SymbolTable.cpp | 6 +++++- lld/COFF/SymbolTable.h | 3 +++ lld/test/COFF/include.test | 7 +++++++ 4 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 lld/test/COFF/include.test diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index a5f6f52c3049..5d9059697fba 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -271,9 +271,16 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) { if (Optional Path = findLib(Arg->getValue())) Inputs.push_back(*Path); + // Create a symbol table. + SymbolTable Symtab; + + // Add undefined symbols given via the command line. + // (/include is equivalent to Unix linker's -u option.) + for (auto *Arg : Args->filtered(OPT_incl)) + Symtab.addUndefined(Arg->getValue()); + // Parse all input files and put all symbols to the symbol table. // The symbol table will take care of name resolution. - SymbolTable Symtab; for (StringRef Path : Inputs) { if (auto EC = Symtab.addFile(createFile(Path))) { llvm::errs() << Path << ": " << EC.message() << "\n"; diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index 880356e77466..e0dfbc381967 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -23,7 +23,7 @@ namespace coff { SymbolTable::SymbolTable() { addSymbol(new DefinedAbsolute("__ImageBase", Config->ImageBase)); if (!Config->EntryName.empty()) - addSymbol(new Undefined(Config->EntryName)); + addUndefined(Config->EntryName); } std::error_code SymbolTable::addFile(std::unique_ptr File) { @@ -183,6 +183,10 @@ ErrorOr SymbolTable::findDefaultEntry() { return make_dynamic_error_code("entry point must be defined"); } +std::error_code SymbolTable::addUndefined(StringRef Name) { + return addSymbol(new Undefined(Name)); +} + std::error_code SymbolTable::addSymbol(SymbolBody *Body) { OwningSymbols.push_back(std::unique_ptr(Body)); return resolve(Body); diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h index 0feab801c772..ed3969b95148 100644 --- a/lld/COFF/SymbolTable.h +++ b/lld/COFF/SymbolTable.h @@ -65,6 +65,9 @@ public: // The writer needs to infer the machine type from the object files. std::vector> ObjectFiles; + // Creates an Undefined symbol for a given name. + std::error_code addUndefined(StringRef Name); + private: std::error_code addObject(ObjectFile *File); std::error_code addArchive(ArchiveFile *File); diff --git a/lld/test/COFF/include.test b/lld/test/COFF/include.test new file mode 100644 index 000000000000..10c2180bcaaa --- /dev/null +++ b/lld/test/COFF/include.test @@ -0,0 +1,7 @@ +# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj + +# RUN: lld -flavor link2 /out:%t.exe %t.obj +# RUN: not lld -flavor link2 /out:%t.exe %t.obj /include:xyz >& %t.log +# RUN: FileCheck %s < %t.log + +CHECK: undefined symbol: xyz