From 53a93c6c399b7e514f9500283be59022e20034a7 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Thu, 26 Feb 2015 23:43:04 +0000 Subject: [PATCH] PECOFF: allow more than one /alternatename for the same symbol. Previously we have a string -> string map to keep the weak alias symbol mapping. Naturally we can't define more than one weak alias with that data structure. This patch is to allow multiple aliases for the same symbol by changing the map type to string -> set of string map. llvm-svn: 230702 --- .../lld/ReaderWriter/PECOFFLinkingContext.h | 12 +++++++----- lld/lib/Driver/WinLinkDriver.cpp | 2 +- .../ReaderWriter/PECOFF/PECOFFLinkingContext.cpp | 11 ----------- lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp | 14 +++++++------- lld/unittests/DriverTests/WinLinkDriverTest.cpp | 10 +++++++--- 5 files changed, 22 insertions(+), 27 deletions(-) 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) {