[lld] r240620 - COFF: Handle undefined symbols starting with __imp_ in a special way.

Peter Collingbourne peter at pcc.me.uk
Wed Jun 24 19:39:17 PDT 2015


On Thu, Jun 25, 2015 at 02:21:44AM -0000, Rui Ueyama wrote:
> Author: ruiu
> Date: Wed Jun 24 21:21:44 2015
> New Revision: 240620
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=240620&view=rev
> Log:
> COFF: Handle undefined symbols starting with __imp_ in a special way.
> 
> MSVC linker is able to link an object file created from the following code.
> Note that __imp_hello is not defined anywhere.
> 
>   void hello() { printf("Hello\n"); }
>   extern void (*__imp_hello)();
>   int main() { __imp_hello(); }
> 
> Function symbols exported from DLLs are automatically mangled by appending
> __imp_ prefix, so they have two names (original one and with the prefix).
> This "feature" seems to simulate that behavior even for non-DLL symbols.
> 
> This is in my opnion very odd feature. Even MSVC linker warns if you use this.
> I'm adding that anyway for the sake of compatibiltiy.
> 
> Added:
>     lld/trunk/test/COFF/locally-imported.test
> Modified:
>     lld/trunk/COFF/SymbolTable.cpp
> 
> Modified: lld/trunk/COFF/SymbolTable.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=240620&r1=240619&r2=240620&view=diff
> ==============================================================================
> --- lld/trunk/COFF/SymbolTable.cpp (original)
> +++ lld/trunk/COFF/SymbolTable.cpp Wed Jun 24 21:21:44 2015
> @@ -70,17 +70,26 @@ bool SymbolTable::reportRemainingUndefin
>      auto *Undef = dyn_cast<Undefined>(Sym->Body);
>      if (!Undef)
>        continue;
> +    StringRef Name = Undef->getName();
>      if (SymbolBody *Alias = Undef->getWeakAlias()) {
>        Sym->Body = Alias->getReplacement();
>        if (!isa<Defined>(Sym->Body)) {
>          // Aliases are yet another symbols pointed by other symbols
>          // that could also remain undefined.
> -        llvm::errs() << "undefined symbol: " << Undef->getName() << "\n";
> +        llvm::errs() << "undefined symbol: " << Name << "\n";
>          Ret = true;
>        }
>        continue;
>      }
> -    llvm::errs() << "undefined symbol: " << Undef->getName() << "\n";
> +    // If we can resolve a symbol by removing __imp_ prefix, do that.
> +    // This odd rule is for compatibility with MSVC linker.
> +    if (Name.startswith("__imp_")) {
> +      if (Defined *Imp = find(Name.substr(strlen("__imp_")))) {
> +        Sym->Body = Imp;

Is it correct to simply strip the prefix? Don't we need to introduce a level
of indirection as if we were creating an import table entry?

Thanks,
-- 
Peter



More information about the llvm-commits mailing list