[PECOFF] Use the first definition of an export if specified multiple times.

If the same symbol is specified multiple times as arguments of /export, the
first definition should be used.

llvm-svn: 197998
This commit is contained in:
Rui Ueyama 2013-12-25 06:46:45 +00:00
parent 2e299d1cae
commit cf4616110c
3 changed files with 23 additions and 2 deletions

View File

@ -217,7 +217,7 @@ public:
void setDosStub(ArrayRef<uint8_t> data) { _dosStub = data; }
ArrayRef<uint8_t> getDosStub() const { return _dosStub; }
void addDllExport(ExportDesc &desc) { _dllExports.push_back(desc); }
void addDllExport(ExportDesc &desc);
std::vector<ExportDesc> &getDllExports() { return _dllExports; }
const std::vector<ExportDesc> &getDllExports() const { return _dllExports; }
@ -300,6 +300,7 @@ private:
// DLLExport'ed symbols.
std::vector<ExportDesc> _dllExports;
std::set<StringRef> _dllExportSet;
// List of files that will be removed on destruction.
std::vector<std::unique_ptr<llvm::FileRemover> > _tempFiles;

View File

@ -257,6 +257,16 @@ uint32_t PECOFFLinkingContext::getSectionAttributes(StringRef sectionName,
return (flags | setMask) & ~clearMask;
}
void PECOFFLinkingContext::addDllExport(ExportDesc &desc) {
if (_dllExportSet.count(desc.name)) {
llvm::errs() << "Export symbol '" << desc.name
<< "' specified more than once.";
return;
}
_dllExports.push_back(desc);
_dllExportSet.insert(desc.name);
}
void PECOFFLinkingContext::addPasses(PassManager &pm) {
pm.add(std::unique_ptr<Pass>(new pecoff::SetSubsystemPass(*this)));
pm.add(std::unique_ptr<Pass>(new pecoff::EdataPass(*this)));

View File

@ -183,7 +183,17 @@ TEST_F(WinLinkParserTest, ExportWithOptions) {
EXPECT_TRUE(exports[1].isData);
}
TEST_F(WinLinkParserTest, ExportDuplicates) {
TEST_F(WinLinkParserTest, ExportDuplicateExports) {
EXPECT_TRUE(
parse("link.exe", "/export:foo,@1", "/export:foo,@2", "a.out", nullptr));
const std::vector<PECOFFLinkingContext::ExportDesc> &exports =
_context.getDllExports();
EXPECT_EQ(1U, exports.size());
EXPECT_EQ("_foo", exports[0].name);
EXPECT_EQ(1, exports[0].ordinal);
}
TEST_F(WinLinkParserTest, ExportDuplicateOrdinals) {
EXPECT_FALSE(
parse("link.exe", "/export:foo,@1", "/export:bar,@1", "a.out", nullptr));
}