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,
|
bool addSectionRenaming(raw_ostream &diagnostics,
|
||||||
StringRef from, StringRef to);
|
StringRef from, StringRef to);
|
||||||
|
|
||||||
StringRef getAlternateName(StringRef def) const;
|
const std::set<std::string> &getAlternateNames(StringRef name) {
|
||||||
const std::map<std::string, std::string> &alternateNames() {
|
return _alternateNames[name];
|
||||||
return _alternateNames;
|
}
|
||||||
|
|
||||||
|
void addAlternateName(StringRef weak, StringRef def) {
|
||||||
|
_alternateNames[def].insert(weak);
|
||||||
}
|
}
|
||||||
void setAlternateName(StringRef def, StringRef weak);
|
|
||||||
|
|
||||||
void addNoDefaultLib(StringRef path) {
|
void addNoDefaultLib(StringRef path) {
|
||||||
if (path.endswith_lower(".lib"))
|
if (path.endswith_lower(".lib"))
|
||||||
|
@ -423,7 +425,7 @@ private:
|
||||||
std::unique_ptr<Writer> _writer;
|
std::unique_ptr<Writer> _writer;
|
||||||
|
|
||||||
// A map for weak aliases.
|
// 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
|
// 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
|
// 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;
|
StringRef weak, def;
|
||||||
if (!parseAlternateName(arg->getValue(), weak, def, diag))
|
if (!parseAlternateName(arg->getValue(), weak, def, diag))
|
||||||
return false;
|
return false;
|
||||||
ctx.setAlternateName(weak, def);
|
ctx.addAlternateName(weak, def);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse /base command line option. The argument for the parameter is in
|
// Parse /base command line option. The argument for the parameter is in
|
||||||
|
|
|
@ -215,17 +215,6 @@ bool PECOFFLinkingContext::addSectionRenaming(raw_ostream &diagnostics,
|
||||||
return true;
|
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
|
/// 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.
|
/// the input file list. Returns true if the library file is found.
|
||||||
StringRef PECOFFLinkingContext::searchLibraryFile(StringRef filename) const {
|
StringRef PECOFFLinkingContext::searchLibraryFile(StringRef filename) const {
|
||||||
|
|
|
@ -112,7 +112,7 @@ public:
|
||||||
_undefinedAtoms._atoms.push_back(new (_alloc) COFFUndefinedAtom(*this, sym));
|
_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();
|
void createAlternateNameAtoms();
|
||||||
std::error_code parseDirectiveSection(
|
std::error_code parseDirectiveSection(
|
||||||
StringRef directives, std::set<StringRef> *undefinedSymbols);
|
StringRef directives, std::set<StringRef> *undefinedSymbols);
|
||||||
|
@ -860,24 +860,24 @@ std::error_code FileCOFF::getSectionContents(StringRef sectionName,
|
||||||
return std::error_code();
|
return std::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
AliasAtom *FileCOFF::createAlias(StringRef name,
|
AliasAtom *
|
||||||
const DefinedAtom *target) {
|
FileCOFF::createAlias(StringRef name, const DefinedAtom *target, int cnt) {
|
||||||
AliasAtom *alias = new (_alloc) AliasAtom(*this, name);
|
AliasAtom *alias = new (_alloc) AliasAtom(*this, name);
|
||||||
alias->addReference(Reference::KindNamespace::all, Reference::KindArch::all,
|
alias->addReference(Reference::KindNamespace::all, Reference::KindArch::all,
|
||||||
Reference::kindLayoutAfter, 0, target, 0);
|
Reference::kindLayoutAfter, 0, target, 0);
|
||||||
alias->setMerge(DefinedAtom::mergeAsWeak);
|
alias->setMerge(DefinedAtom::mergeAsWeak);
|
||||||
if (target->contentType() == DefinedAtom::typeCode)
|
if (target->contentType() == DefinedAtom::typeCode)
|
||||||
alias->setDeadStrip(DefinedAtom::deadStripNever);
|
alias->setDeadStrip(DefinedAtom::deadStripNever);
|
||||||
alias->setOrdinal(target->ordinal() - 1);
|
alias->setOrdinal(target->ordinal() - cnt);
|
||||||
return alias;
|
return alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileCOFF::createAlternateNameAtoms() {
|
void FileCOFF::createAlternateNameAtoms() {
|
||||||
std::vector<AliasAtom *> aliases;
|
std::vector<AliasAtom *> aliases;
|
||||||
for (const DefinedAtom *atom : defined()) {
|
for (const DefinedAtom *atom : defined()) {
|
||||||
auto it = _ctx.alternateNames().find(atom->name());
|
int cnt = 1;
|
||||||
if (it != _ctx.alternateNames().end())
|
for (StringRef alias : _ctx.getAlternateNames(atom->name()))
|
||||||
aliases.push_back(createAlias(it->second, atom));
|
aliases.push_back(createAlias(alias, atom, cnt++));
|
||||||
}
|
}
|
||||||
for (AliasAtom *alias : aliases)
|
for (AliasAtom *alias : aliases)
|
||||||
_definedAtoms._atoms.push_back(alias);
|
_definedAtoms._atoms.push_back(alias);
|
||||||
|
|
|
@ -149,9 +149,13 @@ TEST_F(WinLinkParserTest, InputOrder) {
|
||||||
//
|
//
|
||||||
|
|
||||||
TEST_F(WinLinkParserTest, AlternateName) {
|
TEST_F(WinLinkParserTest, AlternateName) {
|
||||||
EXPECT_TRUE(parse("link.exe", "/alternatename:sym1=sym2", "a.out", nullptr));
|
EXPECT_TRUE(parse("link.exe", "/alternatename:sym1=sym",
|
||||||
EXPECT_EQ("sym1", _ctx.getAlternateName("sym2"));
|
"/alternatename:sym2=sym", "a.out", nullptr));
|
||||||
EXPECT_EQ("", _ctx.getAlternateName("foo"));
|
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) {
|
TEST_F(WinLinkParserTest, Export) {
|
||||||
|
|
Loading…
Reference in New Issue