[lld] r209486 - [PECOFF] Make a separate pass for /alternatename symbols.
Rui Ueyama
ruiu at google.com
Thu May 22 17:02:42 PDT 2014
Author: ruiu
Date: Thu May 22 19:02:42 2014
New Revision: 209486
URL: http://llvm.org/viewvc/llvm-project?rev=209486&view=rev
Log:
[PECOFF] Make a separate pass for /alternatename symbols.
/alternatename is a command line option to define a weak alias. You
can use it as /alternatename:foo=bar to define "foo" as a weak alias
for "bar".
Because it's a command line option, the weak alias mapping is in the
LinkingContext object, and not in a object file being read.
Previously, we looked up the mapping each time we read a new symbol
from a file, to check if there is a weak alias defined for the symbol.
That's not wrong, but had made function signature's a bit complicated --
we had to pass the mapping object to many functions. Now their
parameter lists are much cleaner.
This also has another (unrealized) benefit. parseFile() now read a
file and then add alias symbols to the file. In the first pass a
LinkingContext object is not used at all. That should make it easy
to read files from archive files speculatively, as the first pass
is free from side effect.
Modified:
lld/trunk/include/lld/ReaderWriter/Alias.h
lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
lld/trunk/test/pecoff/alternatename.test
Modified: lld/trunk/include/lld/ReaderWriter/Alias.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/Alias.h?rev=209486&r1=209485&r2=209486&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/Alias.h (original)
+++ lld/trunk/include/lld/ReaderWriter/Alias.h Thu May 22 19:02:42 2014
@@ -17,6 +17,7 @@
#include "lld/Core/LLVM.h"
#include "lld/ReaderWriter/Simple.h"
+#include "llvm/ADT/Optional.h"
#include <string>
@@ -33,7 +34,9 @@ namespace lld {
class AliasAtom : public SimpleDefinedAtom {
public:
AliasAtom(const File &file, StringRef name)
- : SimpleDefinedAtom(file), _target(nullptr), _name(name) {}
+ : SimpleDefinedAtom(file), _target(nullptr), _name(name),
+ _merge(DefinedAtom::mergeNo), _deadStrip(DefinedAtom::deadStripNormal) {
+ }
StringRef name() const override { return _name; }
uint64_t size() const override { return 0; }
@@ -45,10 +48,14 @@ public:
}
Merge merge() const override {
+ if (_merge.hasValue())
+ return _merge.getValue();
getTarget();
return _target ? _target->merge() : mergeNo;
}
+ void setMerge(Merge val) { _merge = val; }
+
ContentType contentType() const override {
getTarget();
return _target ? _target->contentType() : typeUnknown;
@@ -69,6 +76,9 @@ public:
return _target ? _target->customSectionName() : StringRef("");
}
+ DeadStripKind deadStrip() const override { return _deadStrip; }
+ void setDeadStrip(DeadStripKind val) { _deadStrip = val; }
+
private:
void getTarget() const {
if (_target)
@@ -84,6 +94,8 @@ private:
mutable const DefinedAtom *_target;
std::string _name;
+ llvm::Optional<Merge> _merge;
+ DeadStripKind _deadStrip;
};
} // end namespace lld
Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp?rev=209486&r1=209485&r2=209486&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp Thu May 22 19:02:42 2014
@@ -13,6 +13,7 @@
#include "lld/Core/File.h"
#include "lld/Driver/Driver.h"
#include "lld/ReaderWriter/PECOFFLinkingContext.h"
+#include "lld/ReaderWriter/Alias.h"
#include "lld/ReaderWriter/Reader.h"
#include "llvm/ADT/ArrayRef.h"
@@ -70,7 +71,7 @@ public:
FileCOFF(std::unique_ptr<MemoryBuffer> mb, error_code &ec);
- error_code parse(StringMap &altNames);
+ error_code parse();
StringRef getLinkerDirectives() const { return _directives; }
bool isCompatibleWithSEH() const { return _compatibleWithSEH; }
@@ -90,6 +91,12 @@ public:
return _absoluteAtoms;
}
+ void addDefinedAtom(const DefinedAtom *atom) {
+ _definedAtoms._atoms.push_back(atom);
+ }
+
+ mutable llvm::BumpPtrAllocator _alloc;
+
private:
error_code readSymbolTable(vector<const coff_symbol *> &result);
@@ -100,7 +107,6 @@ private:
vector<const UndefinedAtom *> &result);
error_code createDefinedSymbols(const SymbolVectorT &symbols,
- StringMap &altNames,
vector<const DefinedAtom *> &result);
error_code cacheSectionAttributes();
@@ -108,12 +114,10 @@ private:
error_code
AtomizeDefinedSymbolsInSection(const coff_section *section,
- StringMap &altNames,
vector<const coff_symbol *> &symbols,
vector<COFFDefinedFileAtom *> &atoms);
error_code AtomizeDefinedSymbols(SectionToSymbolsT &definedSymbols,
- StringMap &altNames,
vector<const DefinedAtom *> &definedAtoms);
error_code findAtomAt(const coff_section *section, uint32_t targetAddress,
@@ -172,7 +176,6 @@ private:
std::map<uint32_t, std::vector<COFFDefinedAtom *>>>
_definedAtomLocations;
- mutable llvm::BumpPtrAllocator _alloc;
uint64_t _ordinal;
};
@@ -295,7 +298,7 @@ FileCOFF::FileCOFF(std::unique_ptr<Memor
_directives = ArrayRefToString(directives);
}
-error_code FileCOFF::parse(StringMap &altNames) {
+error_code FileCOFF::parse() {
if (error_code ec = getReferenceArch(_referenceArch))
return ec;
@@ -309,7 +312,7 @@ error_code FileCOFF::parse(StringMap &al
createAbsoluteAtoms(symbols, _absoluteAtoms._atoms);
if (error_code ec = createUndefinedAtoms(symbols, _undefinedAtoms._atoms))
return ec;
- if (error_code ec = createDefinedSymbols(symbols, altNames, _definedAtoms._atoms))
+ if (error_code ec = createDefinedSymbols(symbols, _definedAtoms._atoms))
return ec;
if (error_code ec = addRelocationReferenceToAtoms())
return ec;
@@ -440,7 +443,6 @@ FileCOFF::createUndefinedAtoms(const Sym
/// the other two, because in order to create the atom for the defined symbol
/// we need to know the adjacent symbols.
error_code FileCOFF::createDefinedSymbols(const SymbolVectorT &symbols,
- StringMap &altNames,
vector<const DefinedAtom *> &result) {
// A defined atom can be merged if its section attribute allows its contents
// to be merged. In COFF, it's not very easy to get the section attribute
@@ -521,7 +523,7 @@ error_code FileCOFF::createDefinedSymbol
}
// Atomize the defined symbols.
- if (error_code ec = AtomizeDefinedSymbols(definedSymbols, altNames, result))
+ if (error_code ec = AtomizeDefinedSymbols(definedSymbols, result))
return ec;
return error_code::success();
@@ -572,7 +574,6 @@ error_code FileCOFF::cacheSectionAttribu
/// assumed to have been defined in the \p section.
error_code
FileCOFF::AtomizeDefinedSymbolsInSection(const coff_section *section,
- StringMap &altNames,
vector<const coff_symbol *> &symbols,
vector<COFFDefinedFileAtom *> &atoms) {
// Sort symbols by position.
@@ -656,16 +657,6 @@ FileCOFF::AtomizeDefinedSymbolsInSection
// if this is the last symbol, take up the remaining data.
const uint8_t *end = (si + 1 == se) ? secData.data() + secData.size()
: secData.data() + (*(si + 1))->Value;
- auto pos = altNames.find(_symbolName[*si]);
- if (pos != altNames.end()) {
- auto *atom = new (_alloc) COFFDefinedAtom(
- *this, pos->second, sectionName, getScope(*si), type, isComdat, perms,
- DefinedAtom::mergeAsWeak, ArrayRef<uint8_t>(), _ordinal++);
- atoms.push_back(atom);
- _symbolAtom[*si] = atom;
- _definedAtomLocations[section][(*si)->Value].push_back(atom);
- }
-
ArrayRef<uint8_t> data(start, end);
auto *atom = new (_alloc) COFFDefinedAtom(
*this, _symbolName[*si], sectionName, getScope(*si), type, isComdat,
@@ -683,7 +674,6 @@ FileCOFF::AtomizeDefinedSymbolsInSection
error_code
FileCOFF::AtomizeDefinedSymbols(SectionToSymbolsT &definedSymbols,
- StringMap &altNames,
vector<const DefinedAtom *> &definedAtoms) {
// For each section, make atoms for all the symbols defined in the
// section, and append the atoms to the result objects.
@@ -691,8 +681,7 @@ FileCOFF::AtomizeDefinedSymbols(SectionT
const coff_section *section = i.first;
vector<const coff_symbol *> &symbols = i.second;
vector<COFFDefinedFileAtom *> atoms;
- if (error_code ec =
- AtomizeDefinedSymbolsInSection(section, altNames, symbols, atoms))
+ if (error_code ec = AtomizeDefinedSymbolsInSection(section, symbols, atoms))
return ec;
// Connect atoms with layout-before/layout-after edges.
@@ -939,8 +928,7 @@ public:
std::unique_ptr<FileCOFF> file(new FileCOFF(std::move(newmb), ec));
if (ec)
return ec;
- FileCOFF::StringMap emptyMap;
- if (error_code ec = file->parse(emptyMap))
+ if (error_code ec = file->parse())
return ec;
result.push_back(std::move(file));
return error_code::success();
@@ -1020,7 +1008,7 @@ public:
bool canParse(file_magic magic, StringRef ext,
const MemoryBuffer &) const override {
- return (magic == llvm::sys::fs::file_magic::coff_object);
+ return magic == llvm::sys::fs::file_magic::coff_object;
}
error_code
@@ -1039,7 +1027,7 @@ public:
if (error_code ec = handleDirectiveSection(registry, directives))
return ec;
- if (error_code ec = file->parse(_context.alternateNames()))
+ if (error_code ec = file->parse())
return ec;
// Check for /SAFESEH.
@@ -1054,6 +1042,11 @@ public:
if (!file->isCompatibleWithSEH())
_context.setSafeSEH(false);
+ // One can define alias symbols using /alternatename:<sym>=<sym> option.
+ // The mapping for /alternatename is in the context object. This helper
+ // function iterate over defined atoms and create alias atoms if needed.
+ createAlternateNameAtoms(*file);
+
result.push_back(std::move(file));
return error_code::success();
}
@@ -1096,6 +1089,30 @@ private:
return error_code::success();
}
+ AliasAtom *createAlias(FileCOFF &file, StringRef name,
+ const DefinedAtom *target) const {
+ AliasAtom *alias = new (file._alloc) AliasAtom(file, 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);
+ return alias;
+ }
+
+ // Iterates over defined atoms and create alias atoms if needed.
+ void createAlternateNameAtoms(FileCOFF &file) const {
+ std::vector<const DefinedAtom *> aliases;
+ for (const DefinedAtom *atom : file.defined()) {
+ auto it = _context.alternateNames().find(atom->name());
+ if (it != _context.alternateNames().end())
+ aliases.push_back(createAlias(file, it->second, atom));
+ }
+ for (const DefinedAtom *alias : aliases) {
+ file.addDefinedAtom(alias);
+ }
+ }
+
PECOFFLinkingContext &_context;
mutable BumpPtrStringSaver _stringSaver;
};
Modified: lld/trunk/test/pecoff/alternatename.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/alternatename.test?rev=209486&r1=209485&r2=209486&view=diff
==============================================================================
--- lld/trunk/test/pecoff/alternatename.test (original)
+++ lld/trunk/test/pecoff/alternatename.test Thu May 22 19:02:42 2014
@@ -17,11 +17,11 @@ CHECK1-NEXT: nop
CHECK1-NEXT: nop
CHECK1-NOT: int3
-CHECK2-NOT: nop
CHECK2: int3
CHECK2-NEXT: int3
CHECK2-NEXT: int3
CHECK2-NEXT: int3
+CHECK2-NOT: nop
CHECK3: nop
CHECK3-NEXT: nop
More information about the llvm-commits
mailing list