From: Reid Kleckner Date: Fri, 7 Jun 2019 22:05:12 +0000 (+0000) Subject: [COFF] Fix /export:foo=bar when bar is a weak alias X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b8779229b32060dac2ff930eb9a48eac7549e057;p=llvm [COFF] Fix /export:foo=bar when bar is a weak alias Summary: When handling exports from the command line or from .def files, the linker does a "fuzzy" string lookup to allow finding mangled symbols. However, when the symbol is re-exported under a new name, the linker has to transfer the decorations from the exported symbol over to the new name. This is implemented by taking the mangled symbol that was found in the object and replacing the original symbol name with the export name. Before this patch, LLD implemented the fuzzy search by adding an undefined symbol with the unmangled name, and then during symbol resolution, checking if similar mangled symbols had been added after the last round of symbol resolution. If so, LLD makes the original symbol a weak alias of the mangled symbol. Later, to get the original symbol name, LLD would look through the weak alias and forward it on to the import library writer, which copies the symbol decorations. This approach doesn't work when bar is itself a weak alias, as is the case in asan. It's especially bad when the aliasee of bar contains the string "bar", consider "bar_default". In this case, we would end up exporting the symbol "foo_default" when we should've exported just "foo". To fix this, don't look through weak aliases to find the mangled name. Save the mangled name earlier during fuzzy symbol lookup. Fixes PR42074 Reviewers: mstorsjo, ruiu Subscribers: thakis, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D62984 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362849 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Object/COFFImportFile.h b/include/llvm/Object/COFFImportFile.h index e07060cea2b..5aa83641111 100644 --- a/include/llvm/Object/COFFImportFile.h +++ b/include/llvm/Object/COFFImportFile.h @@ -69,9 +69,21 @@ private: }; struct COFFShortExport { + /// The name of the export as specified in the .def file or on the command + /// line, i.e. "foo" in "/EXPORT:foo", and "bar" in "/EXPORT:foo=bar". This + /// may lack mangling, such as underscore prefixing and stdcall suffixing. std::string Name; + + /// The external, exported name. Only non-empty when export renaming is in + /// effect, i.e. "foo" in "/EXPORT:foo=bar". std::string ExtName; + + /// The real, mangled symbol name from the object file. Given + /// "/export:foo=bar", this could be "_bar@8" if bar is stdcall. std::string SymbolName; + + /// Creates a weak alias. This is the name of the weak aliasee. In a .def + /// file, this is "baz" in "EXPORTS\nfoo = bar == baz". std::string AliasTarget; uint16_t Ordinal = 0;