summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2014-10-21 21:41:28 +0000
committerRui Ueyama <ruiu@google.com>2014-10-21 21:41:28 +0000
commit8bae8189b2020d461e5dc3b4cc7e24fbcc8bffeb (patch)
tree7921962addfeb3fde36a87c68272754a56d34036
parent0c6fed5716c75285181db8a20e5f84ddec11f76a (diff)
downloadbcm5719-llvm-8bae8189b2020d461e5dc3b4cc7e24fbcc8bffeb.tar.gz
bcm5719-llvm-8bae8189b2020d461e5dc3b4cc7e24fbcc8bffeb.zip
[PECOFF] Fix exported symbol in the import library
There are two ways to specify a symbol to be exported in the module definition file. 1) EXPORT <external name> = <symbol> 2) EXPORT <symbol> In (1), you give both external name and internal name. In that case, the linker tries to find a symbol using the internal name, and write that address to the export table with the external name. Thus, from the outer world, the symbol seems to be exported as the external name. In (2), internal name is basically the same as the external name with an exception: if you give an undecorated symbol to the EXPORT directive, and if the linker finds a decorated symbol, the external name for the symbol will become the decorated symbol. LLD didn't implement that exception correctly. This patch fixes that. llvm-svn: 220333
-rw-r--r--lld/include/lld/ReaderWriter/PECOFFLinkingContext.h9
-rw-r--r--lld/lib/Driver/WinLinkDriver.cpp1
-rw-r--r--lld/lib/Driver/WinLinkModuleDef.cpp2
-rw-r--r--lld/lib/ReaderWriter/PECOFF/EdataPass.cpp3
-rw-r--r--lld/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp2
-rw-r--r--lld/test/pecoff/export.test6
6 files changed, 15 insertions, 8 deletions
diff --git a/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h b/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h
index 8553bbf57d1..70c68876b37 100644
--- a/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h
+++ b/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h
@@ -61,8 +61,15 @@ public:
struct ExportDesc {
ExportDesc()
: ordinal(-1), noname(false), isData(false), isPrivate(false) {}
+
bool operator<(const ExportDesc &other) const {
- return name.compare(other.name) < 0;
+ return getExternalName().compare(other.getExternalName()) < 0;
+ }
+
+ StringRef getExternalName() const {
+ if (!externalName.empty())
+ return externalName;
+ return name;
}
std::string name;
diff --git a/lld/lib/Driver/WinLinkDriver.cpp b/lld/lib/Driver/WinLinkDriver.cpp
index 5da15eb7272..6375f599a68 100644
--- a/lld/lib/Driver/WinLinkDriver.cpp
+++ b/lld/lib/Driver/WinLinkDriver.cpp
@@ -392,7 +392,6 @@ static bool parseExport(StringRef option,
return false;
if (name.find('=') == StringRef::npos) {
ret.name = name;
- ret.externalName = name;
} else {
std::tie(ret.externalName, ret.name) = name.split("=");
if (ret.name.empty())
diff --git a/lld/lib/Driver/WinLinkModuleDef.cpp b/lld/lib/Driver/WinLinkModuleDef.cpp
index bb07c76b677..e55a0bc5fe6 100644
--- a/lld/lib/Driver/WinLinkModuleDef.cpp
+++ b/lld/lib/Driver/WinLinkModuleDef.cpp
@@ -197,13 +197,13 @@ bool Parser::parseExport(PECOFFLinkingContext::ExportDesc &result) {
return false;
}
result.name = _tok._range;
- result.externalName = result.name;
consumeToken();
if (_tok._kind == Kind::equal) {
consumeToken();
if (_tok._kind != Kind::identifier)
return false;
+ result.externalName = result.name;
result.name = _tok._range;
} else {
ungetToken();
diff --git a/lld/lib/ReaderWriter/PECOFF/EdataPass.cpp b/lld/lib/ReaderWriter/PECOFF/EdataPass.cpp
index 01339d1db57..368bb75cf9e 100644
--- a/lld/lib/ReaderWriter/PECOFF/EdataPass.cpp
+++ b/lld/lib/ReaderWriter/PECOFF/EdataPass.cpp
@@ -62,7 +62,8 @@ static bool getExportedAtoms(PECOFFLinkingContext &ctx, MutableFile *file,
// One can export a symbol with a different name than the symbol
// name used in DLL. If such name is specified, use it in the
// .edata section.
- ret.push_back(TableEntry(desc.externalName, desc.ordinal, atom, desc.noname));
+ ret.push_back(TableEntry(desc.getExternalName(), desc.ordinal, atom,
+ desc.noname));
}
std::sort(ret.begin(), ret.end(),
[](const TableEntry &a, const TableEntry &b) {
diff --git a/lld/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp b/lld/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp
index 16d64d4182e..789dff75740 100644
--- a/lld/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp
+++ b/lld/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp
@@ -30,7 +30,7 @@ createModuleDefinitionFile(const PECOFFLinkingContext &ctx) {
<< "EXPORTS\n";
for (const PECOFFLinkingContext::ExportDesc &desc : ctx.getDllExports()) {
- os << " " << desc.externalName;
+ os << " " << desc.getExternalName();
if (!desc.isPrivate)
os << " @" << desc.ordinal;
if (desc.noname)
diff --git a/lld/test/pecoff/export.test b/lld/test/pecoff/export.test
index 007698198ec..53ae0073360 100644
--- a/lld/test/pecoff/export.test
+++ b/lld/test/pecoff/export.test
@@ -58,7 +58,7 @@ CHECK5-NEXT: 1 0x2010 exportfn7
CHECK6: Export Table:
CHECK6: DLL name: export.test.tmp6.dll
CHECK6: Ordinal RVA Name
-CHECK6-NEXT: 1 0x2010 exportfn8
+CHECK6-NEXT: 1 0x2010 ?exportfn8@@YAXXZ
# RUN: lld -flavor link /out:%t6.dll /dll /entry:init \
# RUN: /export:exportfn8 /export:exportfn8 -- %t.obj
@@ -67,8 +67,8 @@ CHECK6-NEXT: 1 0x2010 exportfn8
DUP: Export Table:
DUP: DLL name: export.test.tmp6.dll
DUP: Ordinal RVA Name
-DUP: 1 0x2010 exportfn8
-DUP-NOT: 1 0x2010 exportfn8
+DUP: 1 0x2010 ?exportfn8@@YAXXZ
+DUP-NOT: 1 0x2010 ?exportfn8@@YAXXZ
# RUN: yaml2obj %p/Inputs/export.obj.yaml > %t.obj
#
OpenPOWER on IntegriCloud