diff --git a/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h b/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h index e2c5ea186e20..2f30f31673cc 100644 --- a/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h +++ b/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h @@ -257,11 +257,13 @@ public: bool addSectionRenaming(raw_ostream &diagnostics, StringRef from, StringRef to); - StringRef getAlternateName(StringRef def) const; - const std::map &alternateNames() { - return _alternateNames; + const std::set &getAlternateNames(StringRef name) { + return _alternateNames[name]; + } + + void addAlternateName(StringRef weak, StringRef def) { + _alternateNames[def].insert(weak); } - void setAlternateName(StringRef def, StringRef weak); void addNoDefaultLib(StringRef path) { if (path.endswith_lower(".lib")) @@ -423,7 +425,7 @@ private: std::unique_ptr _writer; // A map for weak aliases. - std::map _alternateNames; + std::map> _alternateNames; // A map for section renaming. For example, if there is an entry in the map // whose value is .rdata -> .text, the section contens of .rdata will be diff --git a/lld/lib/Driver/WinLinkDriver.cpp b/lld/lib/Driver/WinLinkDriver.cpp index 1baa4863a4bf..f27c80618de5 100644 --- a/lld/lib/Driver/WinLinkDriver.cpp +++ b/lld/lib/Driver/WinLinkDriver.cpp @@ -954,7 +954,7 @@ bool WinLinkDriver::parse(int argc, const char *argv[], StringRef weak, def; if (!parseAlternateName(arg->getValue(), weak, def, diag)) return false; - ctx.setAlternateName(weak, def); + ctx.addAlternateName(weak, def); } // Parse /base command line option. The argument for the parameter is in diff --git a/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp b/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp index 936eef1f297a..2adbd84790eb 100644 --- a/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp +++ b/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp @@ -215,17 +215,6 @@ bool PECOFFLinkingContext::addSectionRenaming(raw_ostream &diagnostics, return true; } -StringRef PECOFFLinkingContext::getAlternateName(StringRef def) const { - auto it = _alternateNames.find(def); - if (it == _alternateNames.end()) - return ""; - return it->second; -} - -void PECOFFLinkingContext::setAlternateName(StringRef weak, StringRef def) { - _alternateNames[def] = weak; -} - /// Try to find the input library file from the search paths and append it to /// the input file list. Returns true if the library file is found. StringRef PECOFFLinkingContext::searchLibraryFile(StringRef filename) const { diff --git a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp index 9756feeed3a4..422df4034802 100644 --- a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp +++ b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp @@ -112,7 +112,7 @@ public: _undefinedAtoms._atoms.push_back(new (_alloc) COFFUndefinedAtom(*this, sym)); } - AliasAtom *createAlias(StringRef name, const DefinedAtom *target); + AliasAtom *createAlias(StringRef name, const DefinedAtom *target, int cnt); void createAlternateNameAtoms(); std::error_code parseDirectiveSection( StringRef directives, std::set *undefinedSymbols); @@ -860,24 +860,24 @@ std::error_code FileCOFF::getSectionContents(StringRef sectionName, return std::error_code(); } -AliasAtom *FileCOFF::createAlias(StringRef name, - const DefinedAtom *target) { +AliasAtom * +FileCOFF::createAlias(StringRef name, const DefinedAtom *target, int cnt) { AliasAtom *alias = new (_alloc) AliasAtom(*this, name); alias->addReference(Reference::KindNamespace::all, Reference::KindArch::all, Reference::kindLayoutAfter, 0, target, 0); alias->setMerge(DefinedAtom::mergeAsWeak); if (target->contentType() == DefinedAtom::typeCode) alias->setDeadStrip(DefinedAtom::deadStripNever); - alias->setOrdinal(target->ordinal() - 1); + alias->setOrdinal(target->ordinal() - cnt); return alias; } void FileCOFF::createAlternateNameAtoms() { std::vector aliases; for (const DefinedAtom *atom : defined()) { - auto it = _ctx.alternateNames().find(atom->name()); - if (it != _ctx.alternateNames().end()) - aliases.push_back(createAlias(it->second, atom)); + int cnt = 1; + for (StringRef alias : _ctx.getAlternateNames(atom->name())) + aliases.push_back(createAlias(alias, atom, cnt++)); } for (AliasAtom *alias : aliases) _definedAtoms._atoms.push_back(alias); diff --git a/lld/unittests/DriverTests/WinLinkDriverTest.cpp b/lld/unittests/DriverTests/WinLinkDriverTest.cpp index c87eaa4fb060..c2bc455aa81f 100644 --- a/lld/unittests/DriverTests/WinLinkDriverTest.cpp +++ b/lld/unittests/DriverTests/WinLinkDriverTest.cpp @@ -149,9 +149,13 @@ TEST_F(WinLinkParserTest, InputOrder) { // TEST_F(WinLinkParserTest, AlternateName) { - EXPECT_TRUE(parse("link.exe", "/alternatename:sym1=sym2", "a.out", nullptr)); - EXPECT_EQ("sym1", _ctx.getAlternateName("sym2")); - EXPECT_EQ("", _ctx.getAlternateName("foo")); + EXPECT_TRUE(parse("link.exe", "/alternatename:sym1=sym", + "/alternatename:sym2=sym", "a.out", nullptr)); + const std::set &aliases = _ctx.getAlternateNames("sym"); + EXPECT_EQ(2U, aliases.size()); + auto it = aliases.begin(); + EXPECT_EQ("sym1", *it++); + EXPECT_EQ("sym2", *it++); } TEST_F(WinLinkParserTest, Export) {