forked from OSchip/llvm-project
[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
This commit is contained in:
parent
0c6fed5716
commit
8bae8189b2
|
@ -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;
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
Loading…
Reference in New Issue