forked from OSchip/llvm-project
[PECOFF] Fix /export option in the .drectve section.
/EXPORT option has slightly different semantics if it appears in the .drectve section. This patch implements it. llvm-svn: 197970
This commit is contained in:
parent
ce7a12be8f
commit
090a7cd76d
|
@ -98,6 +98,7 @@ public:
|
|||
StringRef searchLibraryFile(StringRef path) const;
|
||||
|
||||
StringRef decorateSymbol(StringRef name) const;
|
||||
StringRef undecorateSymbol(StringRef name) const;
|
||||
|
||||
void setEntrySymbolName(StringRef name) {
|
||||
if (!name.empty())
|
||||
|
|
|
@ -892,6 +892,15 @@ WinLinkDriver::parse(int argc, const char *argv[], PECOFFLinkingContext &ctx,
|
|||
<< inputArg->getValue() << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Mangle the symbol name only if it is reading user-supplied command line
|
||||
// arguments. Because the symbol name in the .drectve section is already
|
||||
// mangled by the compiler, we shouldn't add a leading undescore here.
|
||||
// It's odd that the command line option has different semantics in the
|
||||
// .drectve section, but this behavior is needed for compatibility with
|
||||
// MSVC's link.exe.
|
||||
if (!isReadingDirectiveSection)
|
||||
desc.name = ctx.decorateSymbol(desc.name);
|
||||
ctx.addDllExport(desc);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ static bool getExportedAtoms(const PECOFFLinkingContext &ctx, MutableFile *file,
|
|||
definedAtoms[atom->name()] = atom;
|
||||
|
||||
for (const PECOFFLinkingContext::ExportDesc &desc : ctx.getDllExports()) {
|
||||
auto it = definedAtoms.find(ctx.decorateSymbol(desc.name));
|
||||
auto it = definedAtoms.find(desc.name);
|
||||
if (it == definedAtoms.end()) {
|
||||
llvm::errs() << "Symbol <" << desc.name
|
||||
<< "> is exported but not defined.\n";
|
||||
|
@ -86,8 +86,8 @@ EdataPass::createNamePointerTable(const PECOFFLinkingContext &ctx,
|
|||
|
||||
size_t offset = 0;
|
||||
for (const TableEntry &e : entries) {
|
||||
auto *stringAtom = new (_alloc)
|
||||
COFFStringAtom(_file, _stringOrdinal++, ".edata", e.exportName);
|
||||
auto *stringAtom = new (_alloc) COFFStringAtom(
|
||||
_file, _stringOrdinal++, ".edata", ctx.undecorateSymbol(e.exportName));
|
||||
file->addAtom(*stringAtom);
|
||||
addDir32NBReloc(table, stringAtom, offset);
|
||||
offset += sizeof(uint32_t);
|
||||
|
|
|
@ -219,6 +219,13 @@ StringRef PECOFFLinkingContext::decorateSymbol(StringRef name) const {
|
|||
return allocate(str);
|
||||
}
|
||||
|
||||
StringRef PECOFFLinkingContext::undecorateSymbol(StringRef name) const {
|
||||
if (_machineType != llvm::COFF::IMAGE_FILE_MACHINE_I386)
|
||||
return name;
|
||||
assert(name.startswith("_"));
|
||||
return name.substr(1);
|
||||
}
|
||||
|
||||
Writer &PECOFFLinkingContext::writer() const { return *_writer; }
|
||||
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ createModuleDefinitionFile(const PECOFFLinkingContext &ctx,
|
|||
<< "EXPORTS\n";
|
||||
|
||||
for (const PECOFFLinkingContext::ExportDesc &desc : ctx.getDllExports()) {
|
||||
os << " " << desc.name << " @" << desc.ordinal;
|
||||
os << " " << ctx.undecorateSymbol(desc.name) << " @" << desc.ordinal;
|
||||
if (desc.noname)
|
||||
os << " NONAME";
|
||||
if (desc.isData)
|
||||
|
|
|
@ -161,7 +161,7 @@ TEST_F(WinLinkParserTest, Export) {
|
|||
const std::vector<PECOFFLinkingContext::ExportDesc> &exports =
|
||||
_context.getDllExports();
|
||||
EXPECT_TRUE(exports.size() == 1);
|
||||
EXPECT_EQ("foo", exports[0].name);
|
||||
EXPECT_EQ("_foo", exports[0].name);
|
||||
EXPECT_EQ(1, exports[0].ordinal);
|
||||
EXPECT_FALSE(exports[0].noname);
|
||||
EXPECT_FALSE(exports[0].isData);
|
||||
|
@ -173,11 +173,11 @@ TEST_F(WinLinkParserTest, ExportWithOptions) {
|
|||
const std::vector<PECOFFLinkingContext::ExportDesc> &exports =
|
||||
_context.getDllExports();
|
||||
EXPECT_TRUE(exports.size() == 2);
|
||||
EXPECT_EQ("foo", exports[0].name);
|
||||
EXPECT_EQ("_foo", exports[0].name);
|
||||
EXPECT_EQ(8, exports[0].ordinal);
|
||||
EXPECT_TRUE(exports[0].noname);
|
||||
EXPECT_TRUE(exports[0].isData);
|
||||
EXPECT_EQ("bar", exports[1].name);
|
||||
EXPECT_EQ("_bar", exports[1].name);
|
||||
EXPECT_EQ(10, exports[1].ordinal);
|
||||
EXPECT_FALSE(exports[1].noname);
|
||||
EXPECT_TRUE(exports[1].isData);
|
||||
|
|
Loading…
Reference in New Issue