forked from OSchip/llvm-project
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
This commit is contained in:
parent
17512a95ae
commit
53a93c6c39
|
@ -257,11 +257,13 @@ public:
|
|||
bool addSectionRenaming(raw_ostream &diagnostics,
|
||||
StringRef from, StringRef to);
|
||||
|
||||
StringRef getAlternateName(StringRef def) const;
|
||||
const std::map<std::string, std::string> &alternateNames() {
|
||||
return _alternateNames;
|
||||
const std::set<std::string> &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> _writer;
|
||||
|
||||
// A map for weak aliases.
|
||||
std::map<std::string, std::string> _alternateNames;
|
||||
std::map<std::string, std::set<std::string>> _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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<StringRef> *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<AliasAtom *> 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);
|
||||
|
|
|
@ -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<std::string> &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) {
|
||||
|
|
Loading…
Reference in New Issue