[lld] remove trailing whitespace
llvm-svn: 177079
This commit is contained in:
parent
0a22bc4156
commit
8962feb915
@ -20,7 +20,7 @@ class AbsoluteAtom : public Atom {
|
||||
public:
|
||||
|
||||
virtual uint64_t value() const = 0;
|
||||
|
||||
|
||||
/// scope - The visibility of this atom to other atoms. C static functions
|
||||
/// have scope scopeTranslationUnit. Regular C functions have scope
|
||||
/// scopeGlobal. Functions compiled with visibility=hidden have scope
|
||||
|
||||
@ -17,13 +17,13 @@ namespace lld {
|
||||
|
||||
///
|
||||
/// The ArchiveLibraryFile subclass of File is used to represent unix
|
||||
/// static library archives. These libraries provide no atoms to the
|
||||
/// static library archives. These libraries provide no atoms to the
|
||||
/// initial set of atoms linked. Instead, when the Resolver will query
|
||||
/// ArchiveLibraryFile instances for specific symbols names using the
|
||||
/// find() method. If the archive contains an object file which has a
|
||||
/// DefinedAtom whose scope is not translationUnit, then that entire
|
||||
/// object file File is returned.
|
||||
///
|
||||
///
|
||||
class ArchiveLibraryFile : public File {
|
||||
public:
|
||||
|
||||
@ -42,7 +42,7 @@ public:
|
||||
virtual const TargetInfo &getTargetInfo() const { return _targetInfo; }
|
||||
|
||||
protected:
|
||||
/// only subclasses of ArchiveLibraryFile can be instantiated
|
||||
/// only subclasses of ArchiveLibraryFile can be instantiated
|
||||
ArchiveLibraryFile(const TargetInfo &ti, StringRef path)
|
||||
: File(path), _targetInfo(ti) {
|
||||
}
|
||||
|
||||
@ -183,8 +183,8 @@ public:
|
||||
|
||||
uint16_t powerOf2;
|
||||
uint16_t modulus;
|
||||
|
||||
bool operator==(const Alignment &rhs) const {
|
||||
|
||||
bool operator==(const Alignment &rhs) const {
|
||||
return (powerOf2 == rhs.powerOf2) && (modulus == rhs.modulus);
|
||||
}
|
||||
};
|
||||
@ -233,8 +233,8 @@ public:
|
||||
virtual StringRef customSectionName() const = 0;
|
||||
|
||||
/// \brief constraints on whether the linker may dead strip away this atom.
|
||||
virtual SectionPosition sectionPosition() const = 0;
|
||||
|
||||
virtual SectionPosition sectionPosition() const = 0;
|
||||
|
||||
/// \brief constraints on whether the linker may dead strip away this atom.
|
||||
virtual DeadStripKind deadStrip() const = 0;
|
||||
|
||||
|
||||
@ -65,11 +65,11 @@ public:
|
||||
virtual StringRef translationUnitSource() const;
|
||||
|
||||
/// Returns the command line order of the file.
|
||||
uint64_t ordinal() const {
|
||||
uint64_t ordinal() const {
|
||||
assert(_ordinal != UINT64_MAX);
|
||||
return _ordinal;
|
||||
return _ordinal;
|
||||
}
|
||||
|
||||
|
||||
/// Sets the command line order of the file. The parameter must
|
||||
/// also be incremented to the next available ordinal number.
|
||||
virtual void setOrdinalAndIncrement(uint64_t &ordinal) const {
|
||||
@ -157,7 +157,7 @@ public:
|
||||
virtual const TargetInfo &getTargetInfo() const = 0;
|
||||
|
||||
protected:
|
||||
/// \brief only subclasses of File can be instantiated
|
||||
/// \brief only subclasses of File can be instantiated
|
||||
File(StringRef p) : _path(p), _ordinal(UINT64_MAX) {}
|
||||
|
||||
/// \brief This is a convenience class for File subclasses which manage their
|
||||
@ -193,10 +193,10 @@ protected:
|
||||
template <typename T>
|
||||
class atom_collection_empty : public atom_collection<T> {
|
||||
public:
|
||||
virtual atom_iterator<T> begin() const {
|
||||
virtual atom_iterator<T> begin() const {
|
||||
return atom_iterator<T>(*this, nullptr);
|
||||
}
|
||||
virtual atom_iterator<T> end() const{
|
||||
virtual atom_iterator<T> end() const{
|
||||
return atom_iterator<T>(*this, nullptr);
|
||||
}
|
||||
virtual const T *deref(const void *it) const {
|
||||
@ -231,7 +231,7 @@ public:
|
||||
virtual const TargetInfo &getTargetInfo() const { return _targetInfo; }
|
||||
|
||||
protected:
|
||||
/// \brief only subclasses of MutableFile can be instantiated
|
||||
/// \brief only subclasses of MutableFile can be instantiated
|
||||
MutableFile(const TargetInfo &ti, StringRef p) : File(p), _targetInfo(ti) {}
|
||||
|
||||
private:
|
||||
|
||||
@ -40,13 +40,13 @@ public:
|
||||
|
||||
/// Used by Writers to insert writer specific files.
|
||||
virtual void prependFile(const File&);
|
||||
|
||||
|
||||
/// Used by Writers to insert writer specific files.
|
||||
virtual void appendFile(const File&);
|
||||
|
||||
|
||||
/// Transfers ownership of a vector of Files to this InputFile object.
|
||||
virtual void appendFiles(std::vector<std::unique_ptr<File>> &files);
|
||||
|
||||
|
||||
/// Assigns an ordinal to each File for use by sort().
|
||||
virtual void assignFileOrdinals();
|
||||
|
||||
@ -62,7 +62,7 @@ public:
|
||||
|
||||
protected:
|
||||
void handleFile(const File *file, InputFiles::Handler &handler) const;
|
||||
|
||||
|
||||
std::vector<const File*> _files;
|
||||
};
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ namespace lld {
|
||||
|
||||
///
|
||||
/// The SharedLibraryFile subclass of File is used to represent dynamic
|
||||
/// shared libraries being linked against.
|
||||
/// shared libraries being linked against.
|
||||
///
|
||||
class SharedLibraryFile : public File {
|
||||
public:
|
||||
@ -32,8 +32,8 @@ public:
|
||||
static inline bool classof(const File *f) {
|
||||
return f->kind() == kindSharedLibrary;
|
||||
}
|
||||
static inline bool classof(const SharedLibraryFile *) {
|
||||
return true;
|
||||
static inline bool classof(const SharedLibraryFile *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ public:
|
||||
virtual const SharedLibraryAtom *exports(StringRef name,
|
||||
bool dataSymbolOnly) const = 0;
|
||||
protected:
|
||||
/// only subclasses of SharedLibraryFile can be instantiated
|
||||
/// only subclasses of SharedLibraryFile can be instantiated
|
||||
SharedLibraryFile(StringRef path) : File(path) {}
|
||||
};
|
||||
|
||||
|
||||
@ -60,7 +60,7 @@ public:
|
||||
|
||||
/// @brief returns vector of remaining UndefinedAtoms
|
||||
void undefines(std::vector<const UndefinedAtom *>&);
|
||||
|
||||
|
||||
/// returns vector of tentative definitions
|
||||
void tentativeDefinitions(std::vector<StringRef> &);
|
||||
|
||||
|
||||
@ -650,7 +650,7 @@ private:
|
||||
advance_upto(last, stop - start, end(), iterator_category());
|
||||
} else {
|
||||
// Complicated: 'start' walked from the end of the sequence,
|
||||
// but 'stop' needs to walk from the beginning.
|
||||
// but 'stop' needs to walk from the beginning.
|
||||
Iterator dummy = begin();
|
||||
// Walk up to 'stop' increments from begin(), stopping when we
|
||||
// get to 'first', and capturing the remaining number of
|
||||
|
||||
@ -25,7 +25,7 @@ namespace lld {
|
||||
class DefinedAtom;
|
||||
class MutableFile;
|
||||
|
||||
/// This linker pass does the layout of the atoms. The pass is done after the
|
||||
/// This linker pass does the layout of the atoms. The pass is done after the
|
||||
/// order their .o files were found on the command line, then by order of the
|
||||
/// atoms (address) in the .o file. But some atoms have a prefered location
|
||||
/// in their section (such as pinned to the start or end of the section), so
|
||||
@ -50,19 +50,19 @@ public:
|
||||
virtual ~LayoutPass() {}
|
||||
|
||||
private:
|
||||
// Build the followOn atoms chain as specified by the kindLayoutAfter
|
||||
// reference type
|
||||
// Build the followOn atoms chain as specified by the kindLayoutAfter
|
||||
// reference type
|
||||
void buildFollowOnTable(MutableFile::DefinedAtomRange &range);
|
||||
|
||||
// Build the followOn atoms chain as specified by the kindInGroup
|
||||
// reference type
|
||||
// reference type
|
||||
void buildInGroupTable(MutableFile::DefinedAtomRange &range);
|
||||
|
||||
// Build the PrecededBy Table as specified by the kindLayoutBefore
|
||||
// reference type
|
||||
// reference type
|
||||
void buildPrecededByTable(MutableFile::DefinedAtomRange &range);
|
||||
|
||||
// Build a map of Atoms to ordinals for sorting the atoms
|
||||
// Build a map of Atoms to ordinals for sorting the atoms
|
||||
void buildOrdinalOverrideMap(MutableFile::DefinedAtomRange &range);
|
||||
|
||||
typedef llvm::DenseMap<const DefinedAtom *, const DefinedAtom *> AtomToAtomT;
|
||||
|
||||
@ -27,22 +27,22 @@ struct LinkerOptions;
|
||||
/// executable files.
|
||||
///
|
||||
/// Each file format (e.g. ELF, mach-o, PECOFF, native, etc) have a concrete
|
||||
/// subclass of Reader.
|
||||
/// subclass of Reader.
|
||||
class Reader {
|
||||
public:
|
||||
virtual ~Reader();
|
||||
|
||||
|
||||
/// \brief Parse a file given its file system path and create a File object.
|
||||
virtual error_code readFile(StringRef path,
|
||||
std::vector<std::unique_ptr<File>> &result);
|
||||
|
||||
/// \brief Parse a supplied buffer (already filled with the contents of a
|
||||
/// file) and create a File object.
|
||||
/// file) and create a File object.
|
||||
///
|
||||
/// On success, the resulting File object takes ownership of the MemoryBuffer.
|
||||
virtual error_code parseFile(std::unique_ptr<MemoryBuffer> mb,
|
||||
std::vector<std::unique_ptr<File>> &result) = 0;
|
||||
|
||||
|
||||
protected:
|
||||
// only concrete subclasses can be instantiated
|
||||
Reader(const TargetInfo &ti)
|
||||
|
||||
@ -34,7 +34,7 @@ public:
|
||||
: Reader(ti),
|
||||
_getReader(getReader) {}
|
||||
|
||||
/// \brief Returns a vector of Files that are contained in the archive file
|
||||
/// \brief Returns a vector of Files that are contained in the archive file
|
||||
/// pointed to by the Memorybuffer
|
||||
error_code parseFile(std::unique_ptr<llvm::MemoryBuffer> mb,
|
||||
std::vector<std::unique_ptr<File>> &result);
|
||||
|
||||
@ -26,7 +26,7 @@ public:
|
||||
std::function<ErrorOr<Reader &>(const LinkerInput &)> getReader)
|
||||
: Reader(ti), _getReader(getReader) {}
|
||||
|
||||
/// \brief Returns a vector of Files that are contained in the archive file
|
||||
/// \brief Returns a vector of Files that are contained in the archive file
|
||||
/// pointed to by the Memorybuffer
|
||||
error_code parseFile(std::unique_ptr<llvm::MemoryBuffer> mb,
|
||||
std::vector<std::unique_ptr<File>> &result);
|
||||
|
||||
@ -13,16 +13,16 @@
|
||||
namespace lld {
|
||||
|
||||
/// \brief Return the bits that are described by the mask
|
||||
template < typename T >
|
||||
template < typename T >
|
||||
T gatherBits(T val, T mask)
|
||||
{
|
||||
T result = 0;
|
||||
size_t off = 0;
|
||||
|
||||
|
||||
for (size_t bit = 0; bit != sizeof (T) * 8; ++bit) {
|
||||
const bool valBit = (val >> bit) & 1;
|
||||
const bool maskBit = (mask >> bit) & 1;
|
||||
if (maskBit) {
|
||||
if (maskBit) {
|
||||
result |= static_cast <T> (valBit) << off;
|
||||
++off;
|
||||
}
|
||||
@ -31,7 +31,7 @@ T gatherBits(T val, T mask)
|
||||
}
|
||||
|
||||
/// \brief Set the bits as described by the mask
|
||||
template <typename T>
|
||||
template <typename T>
|
||||
T scatterBits(T val, T mask)
|
||||
{
|
||||
T result = 0;
|
||||
@ -48,6 +48,6 @@ T scatterBits(T val, T mask)
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace lld
|
||||
} // namespace lld
|
||||
|
||||
#endif // LLD_READER_WRITER_RELOCATION_HELPER_FUNCTIONS_H
|
||||
|
||||
@ -27,15 +27,15 @@ class TargetInfo;
|
||||
class Writer {
|
||||
public:
|
||||
virtual ~Writer();
|
||||
|
||||
/// \brief Write a file from the supplied File object
|
||||
|
||||
/// \brief Write a file from the supplied File object
|
||||
virtual error_code writeFile(const File &linkedFile, StringRef path) = 0;
|
||||
|
||||
|
||||
/// \brief This method is called by Core Linking to give the Writer a chance
|
||||
/// to add file format specific "files" to set of files to be linked. This is
|
||||
/// how file format specific atoms can be added to the link.
|
||||
virtual void addFiles(InputFiles&) {}
|
||||
|
||||
|
||||
protected:
|
||||
// only concrete subclasses can be instantiated
|
||||
Writer();
|
||||
|
||||
@ -30,7 +30,7 @@ DefinedAtom::ContentPermissions DefinedAtom::permissions(ContentType type) {
|
||||
case typeStub:
|
||||
case typeStubHelper:
|
||||
return permR_X;
|
||||
|
||||
|
||||
case typeConstant:
|
||||
case typeCString:
|
||||
case typeUTF16String:
|
||||
@ -65,7 +65,7 @@ DefinedAtom::ContentPermissions DefinedAtom::permissions(ContentType type) {
|
||||
case typeTLVInitialZeroFill:
|
||||
case typeTLVInitializerPtr:
|
||||
return permRW_L;
|
||||
|
||||
|
||||
case typeUnknown:
|
||||
case typeTempLTO:
|
||||
return permUnknown;
|
||||
|
||||
@ -30,7 +30,7 @@ void InputFiles::forEachInitialAtom(InputFiles::Handler &handler) const {
|
||||
void InputFiles::prependFile(const File &file) {
|
||||
_files.insert(_files.begin(), &file);
|
||||
}
|
||||
|
||||
|
||||
void InputFiles::appendFile(const File &file) {
|
||||
_files.push_back(&file);
|
||||
}
|
||||
@ -52,11 +52,11 @@ void InputFiles::assignFileOrdinals() {
|
||||
bool InputFiles::searchLibraries(StringRef name, bool searchSharedLibs,
|
||||
bool searchArchives, bool dataSymbolOnly,
|
||||
InputFiles::Handler &handler) const {
|
||||
|
||||
|
||||
for ( const File *file : _files ) {
|
||||
if ( searchSharedLibs ) {
|
||||
if (const SharedLibraryFile *shlib = dyn_cast<SharedLibraryFile>(file)) {
|
||||
if ( const SharedLibraryAtom* shAtom = shlib->exports(name,
|
||||
if ( const SharedLibraryAtom* shAtom = shlib->exports(name,
|
||||
dataSymbolOnly) ) {
|
||||
handler.doSharedLibraryAtom(*shAtom);
|
||||
return true;
|
||||
@ -76,7 +76,7 @@ bool InputFiles::searchLibraries(StringRef name, bool searchSharedLibs,
|
||||
}
|
||||
|
||||
|
||||
void InputFiles::handleFile(const File *file,
|
||||
void InputFiles::handleFile(const File *file,
|
||||
InputFiles::Handler &handler) const {
|
||||
handler.doFile(*file);
|
||||
for( const DefinedAtom *atom : file->defined() ) {
|
||||
|
||||
@ -114,19 +114,19 @@ void Resolver::doDefinedAtom(const DefinedAtom &atom) {
|
||||
|
||||
// Verify on zero-size atoms are pinned to start or end of section.
|
||||
switch ( atom.sectionPosition() ) {
|
||||
case DefinedAtom::sectionPositionStart:
|
||||
case DefinedAtom::sectionPositionStart:
|
||||
case DefinedAtom::sectionPositionEnd:
|
||||
assert(atom.size() == 0);
|
||||
break;
|
||||
case DefinedAtom::sectionPositionEarly:
|
||||
case DefinedAtom::sectionPositionAny:
|
||||
case DefinedAtom::sectionPositionEarly:
|
||||
case DefinedAtom::sectionPositionAny:
|
||||
break;
|
||||
}
|
||||
|
||||
// add to list of known atoms
|
||||
_atoms.push_back(&atom);
|
||||
|
||||
// tell symbol table
|
||||
// tell symbol table
|
||||
_symbolTable.add(atom);
|
||||
|
||||
if (_targetInfo.getLinkerOptions()._deadStrip) {
|
||||
|
||||
@ -46,7 +46,7 @@ void SymbolTable::add(const AbsoluteAtom &atom) {
|
||||
}
|
||||
|
||||
void SymbolTable::add(const DefinedAtom &atom) {
|
||||
if (!atom.name().empty() &&
|
||||
if (!atom.name().empty() &&
|
||||
(atom.scope() != DefinedAtom::scopeTranslationUnit)) {
|
||||
// Named atoms cannot be merged by content.
|
||||
assert(atom.merge() != DefinedAtom::mergeByContent);
|
||||
|
||||
@ -170,7 +170,7 @@ public:
|
||||
*it, _core.getOption(core::OPT_input_search_path), (*it)->getValue());
|
||||
_inputSearchPaths.push_back((*it)->getValue());
|
||||
}
|
||||
|
||||
|
||||
// Copy input args.
|
||||
for (llvm::opt::arg_iterator it = _inputArgs->filtered_begin(ld::OPT_INPUT,
|
||||
ld::OPT_l),
|
||||
|
||||
@ -84,7 +84,7 @@ bool LayoutPass::CompareAtoms::operator()(const DefinedAtom *left,
|
||||
// right is overridden and left is not, so right < left
|
||||
return false;
|
||||
} else {
|
||||
// neither are overridden,
|
||||
// neither are overridden,
|
||||
// fall into default sorting below
|
||||
}
|
||||
}
|
||||
@ -123,7 +123,7 @@ bool LayoutPass::CompareAtoms::operator()(const DefinedAtom *left,
|
||||
/// current Atom
|
||||
/// The algorithm follows a very simple approach
|
||||
/// a) If the atom is first seen, then make that as the root atom
|
||||
/// b) The targetAtom which this Atom contains, has the root thats set to the
|
||||
/// b) The targetAtom which this Atom contains, has the root thats set to the
|
||||
/// root of the current atom
|
||||
/// c) If the targetAtom is part of a different tree and the root of the
|
||||
/// targetAtom is itself, Chain all the atoms that are contained in the tree
|
||||
@ -142,7 +142,7 @@ void LayoutPass::buildFollowOnTable(MutableFile::DefinedAtomRange &range) {
|
||||
if (_followOnRoots.count(ai) == 0) {
|
||||
_followOnRoots[ai] = ai;
|
||||
}
|
||||
// If the targetAtom is not a root of any chain, lets make
|
||||
// If the targetAtom is not a root of any chain, lets make
|
||||
// the root of the targetAtom to the root of the current chain
|
||||
auto iter = _followOnRoots.find(targetAtom);
|
||||
if (iter == _followOnRoots.end()) {
|
||||
@ -169,13 +169,13 @@ void LayoutPass::buildFollowOnTable(MutableFile::DefinedAtomRange &range) {
|
||||
const DefinedAtom *a = _followOnRoots[targetAtom];
|
||||
const DefinedAtom *targetPrevAtom = nullptr;
|
||||
|
||||
// If the size of the atom is 0, and the target
|
||||
// If the size of the atom is 0, and the target
|
||||
// is already part of a chain, lets bring the current
|
||||
// atom into the chain
|
||||
size_t currentAtomSize = (*ai).size();
|
||||
|
||||
// Lets add to the chain only if the atoms that
|
||||
// appear before the targetAtom in the chain
|
||||
// Lets add to the chain only if the atoms that
|
||||
// appear before the targetAtom in the chain
|
||||
// are of size 0
|
||||
bool foundNonZeroSizeAtom = false;
|
||||
while (true) {
|
||||
@ -201,9 +201,9 @@ void LayoutPass::buildFollowOnTable(MutableFile::DefinedAtomRange &range) {
|
||||
|
||||
} // while true
|
||||
if (foundNonZeroSizeAtom) {
|
||||
// TODO: print warning that an impossible layout
|
||||
// TODO: print warning that an impossible layout
|
||||
// is being desired by the user
|
||||
// Continue to the next atom
|
||||
// Continue to the next atom
|
||||
break;
|
||||
}
|
||||
|
||||
@ -216,7 +216,7 @@ void LayoutPass::buildFollowOnTable(MutableFile::DefinedAtomRange &range) {
|
||||
_followOnNexts[ai] = targetAtom;
|
||||
} else {
|
||||
_followOnNexts[ai] = _followOnRoots[targetAtom];
|
||||
// Set the root of all atoms in the
|
||||
// Set the root of all atoms in the
|
||||
a = _followOnRoots[targetAtom];
|
||||
while (true) {
|
||||
_followOnRoots[a] = _followOnRoots[ai];
|
||||
@ -249,19 +249,19 @@ void LayoutPass::buildFollowOnTable(MutableFile::DefinedAtomRange &range) {
|
||||
/// if not add the atom to the chain, so that the current atom is part of the
|
||||
/// the chain where the rootAtom is in
|
||||
void LayoutPass::buildInGroupTable(MutableFile::DefinedAtomRange &range) {
|
||||
// This table would convert precededby references to follow on
|
||||
// references so that we have only one table
|
||||
// This table would convert precededby references to follow on
|
||||
// references so that we have only one table
|
||||
for (auto ai : range) {
|
||||
for (const Reference *r : *ai) {
|
||||
if (r->kind() == lld::Reference::kindInGroup) {
|
||||
const DefinedAtom *rootAtom = llvm::dyn_cast<DefinedAtom>(r->target());
|
||||
// If the root atom is not part of any root
|
||||
// create a new root
|
||||
// create a new root
|
||||
if (_followOnRoots.count(rootAtom) == 0) {
|
||||
_followOnRoots[rootAtom] = rootAtom;
|
||||
}
|
||||
// If the current Atom has not been seen yet and there is no root
|
||||
// that has been set, set the root of the atom to the targetAtom
|
||||
// If the current Atom has not been seen yet and there is no root
|
||||
// that has been set, set the root of the atom to the targetAtom
|
||||
// as the targetAtom points to the ingroup root
|
||||
auto iter = _followOnRoots.find(ai);
|
||||
if (iter == _followOnRoots.end()) {
|
||||
@ -300,7 +300,7 @@ void LayoutPass::buildInGroupTable(MutableFile::DefinedAtomRange &range) {
|
||||
bool isAtomInChain = false;
|
||||
const DefinedAtom *lastAtom = rootAtom;
|
||||
while (true) {
|
||||
AtomToAtomT::iterator followOnAtomsIter =
|
||||
AtomToAtomT::iterator followOnAtomsIter =
|
||||
_followOnNexts.find(lastAtom);
|
||||
if (followOnAtomsIter != _followOnNexts.end()) {
|
||||
lastAtom = followOnAtomsIter->second;
|
||||
@ -309,11 +309,11 @@ void LayoutPass::buildInGroupTable(MutableFile::DefinedAtomRange &range) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
break;
|
||||
} // findAtomInChain
|
||||
|
||||
if (!isAtomInChain)
|
||||
if (!isAtomInChain)
|
||||
_followOnNexts[lastAtom] = ai;
|
||||
}
|
||||
}
|
||||
@ -323,20 +323,20 @@ void LayoutPass::buildInGroupTable(MutableFile::DefinedAtomRange &range) {
|
||||
/// This pass builds the followon tables using Preceded By relationships
|
||||
/// The algorithm follows a very simple approach
|
||||
/// a) If the targetAtom is not part of any root and the current atom is not
|
||||
/// part of any root, create a chain with the current atom as root and
|
||||
/// part of any root, create a chain with the current atom as root and
|
||||
/// the targetAtom as following the current atom
|
||||
/// b) Chain the targetAtom to the current Atom if the targetAtom is not part
|
||||
/// b) Chain the targetAtom to the current Atom if the targetAtom is not part
|
||||
/// of any chain and the currentAtom has no followOn's
|
||||
/// c) If the targetAtom is part of a different tree and the root of the
|
||||
/// targetAtom is itself, and if the current atom is not part of any root
|
||||
/// chain all the atoms together
|
||||
/// d) If the current atom has no followon and the root of the targetAtom is
|
||||
/// not equal to the root of the current atom(the targetAtom is not in the
|
||||
/// same chain), chain all the atoms that are lead by the targetAtom into
|
||||
/// chain all the atoms together
|
||||
/// d) If the current atom has no followon and the root of the targetAtom is
|
||||
/// not equal to the root of the current atom(the targetAtom is not in the
|
||||
/// same chain), chain all the atoms that are lead by the targetAtom into
|
||||
/// the current chain
|
||||
void LayoutPass::buildPrecededByTable(MutableFile::DefinedAtomRange &range) {
|
||||
// This table would convert precededby references to follow on
|
||||
// references so that we have only one table
|
||||
// This table would convert precededby references to follow on
|
||||
// references so that we have only one table
|
||||
for (auto ai : range) {
|
||||
for (const Reference *r : *ai) {
|
||||
if (r->kind() == lld::Reference::kindLayoutBefore) {
|
||||
@ -371,7 +371,7 @@ void LayoutPass::buildPrecededByTable(MutableFile::DefinedAtomRange &range) {
|
||||
changeRoots = true;
|
||||
}
|
||||
}
|
||||
// Change the roots of the targetAtom and its chain to
|
||||
// Change the roots of the targetAtom and its chain to
|
||||
// the current atoms root
|
||||
if (changeRoots) {
|
||||
const DefinedAtom *a = _followOnRoots[targetAtom];
|
||||
@ -387,16 +387,16 @@ void LayoutPass::buildPrecededByTable(MutableFile::DefinedAtomRange &range) {
|
||||
break;
|
||||
}
|
||||
} // changeRoots
|
||||
} // Is targetAtom root
|
||||
} // Is targetAtom root
|
||||
} // kindLayoutBefore
|
||||
} // Reference
|
||||
} // atom iteration
|
||||
} // end function
|
||||
} // end function
|
||||
|
||||
|
||||
/// Build an ordinal override map by traversing the followon chain, and
|
||||
/// assigning ordinals to each atom, if the atoms have their ordinals
|
||||
/// already assigned skip the atom and move to the next. This is the
|
||||
/// assigning ordinals to each atom, if the atoms have their ordinals
|
||||
/// already assigned skip the atom and move to the next. This is the
|
||||
/// main map thats used to sort the atoms while comparing two atoms together
|
||||
void LayoutPass::buildOrdinalOverrideMap(MutableFile::DefinedAtomRange &range) {
|
||||
uint64_t index = 0;
|
||||
@ -419,7 +419,7 @@ void LayoutPass::buildOrdinalOverrideMap(MutableFile::DefinedAtomRange &range) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Perform the actual pass
|
||||
/// Perform the actual pass
|
||||
void LayoutPass::perform(MutableFile &mergedFile) {
|
||||
MutableFile::DefinedAtomRange atomRange = mergedFile.definedAtoms();
|
||||
|
||||
|
||||
@ -206,8 +206,8 @@ public:
|
||||
virtual uint64_t size() const {
|
||||
// Common symbols are not allocated in object files,
|
||||
// so use st_size to tell how many bytes are required.
|
||||
|
||||
// Treat target defined common symbols
|
||||
|
||||
// Treat target defined common symbols
|
||||
if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
|
||||
_symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
|
||||
if (!_targetAtomHandler) {
|
||||
@ -245,7 +245,7 @@ public:
|
||||
return mergeAsWeak;
|
||||
|
||||
// If the symbol is a target defined and if the target
|
||||
// defines the symbol as a common symbol treat it as
|
||||
// defines the symbol as a common symbol treat it as
|
||||
// mergeTentative
|
||||
if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
|
||||
_symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
|
||||
@ -269,7 +269,7 @@ public:
|
||||
ContentType ret = typeUnknown;
|
||||
uint64_t flags = _section->sh_flags;
|
||||
|
||||
// Treat target defined symbols
|
||||
// Treat target defined symbols
|
||||
if ((_section->sh_flags & llvm::ELF::SHF_MASKPROC) ||
|
||||
((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
|
||||
_symbol->st_shndx < llvm::ELF::SHN_HIPROC))) {
|
||||
@ -333,8 +333,8 @@ public:
|
||||
virtual Alignment alignment() const {
|
||||
// Unallocated common symbols specify their alignment constraints in
|
||||
// st_value.
|
||||
|
||||
// Treat target defined common symbols
|
||||
|
||||
// Treat target defined common symbols
|
||||
if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
|
||||
_symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
|
||||
if (!_targetAtomHandler) {
|
||||
|
||||
@ -47,7 +47,7 @@ public:
|
||||
// If its determined, that the layout needs to change
|
||||
// just changing the order of enumerations would essentially
|
||||
// change the layout in the output file
|
||||
// Change the enumerations so that Target can override and stick
|
||||
// Change the enumerations so that Target can override and stick
|
||||
// a section anywhere it wants to
|
||||
enum DefaultSectionOrder {
|
||||
ORDER_NOT_DEFINED = 0,
|
||||
@ -112,10 +112,10 @@ public:
|
||||
};
|
||||
|
||||
typedef typename std::vector<Chunk<ELFT> *>::iterator ChunkIter;
|
||||
// The additional segments are used to figure out
|
||||
// The additional segments are used to figure out
|
||||
// if there is a segment by that type already created
|
||||
// For example : PT_TLS, we have two sections .tdata/.tbss
|
||||
// that are part of PT_TLS, we need to create this additional
|
||||
// For example : PT_TLS, we have two sections .tdata/.tbss
|
||||
// that are part of PT_TLS, we need to create this additional
|
||||
// segment only once
|
||||
typedef int64_t AdditionalSegmentKey;
|
||||
// The segments are created using
|
||||
@ -181,7 +181,7 @@ public:
|
||||
/// \brief Find an output Section given a section name.
|
||||
MergedSections<ELFT> *findOutputSection(StringRef name) {
|
||||
auto iter = _mergedSectionMap.find(name);
|
||||
if (iter == _mergedSectionMap.end())
|
||||
if (iter == _mergedSectionMap.end())
|
||||
return nullptr;
|
||||
return iter->second;
|
||||
}
|
||||
@ -319,7 +319,7 @@ Layout::SectionOrder DefaultLayout<ELFT>::getSectionOrder(
|
||||
.StartsWith(".fini", ORDER_FINI)
|
||||
.StartsWith(".hash", ORDER_HASH)
|
||||
.Default(ORDER_TEXT);
|
||||
|
||||
|
||||
case DefinedAtom::typeConstant:
|
||||
return ORDER_RODATA;
|
||||
|
||||
@ -346,7 +346,7 @@ Layout::SectionOrder DefaultLayout<ELFT>::getSectionOrder(
|
||||
// If we get passed in a section push it to OTHER
|
||||
if (contentPermissions == DefinedAtom::perm___)
|
||||
return ORDER_OTHER;
|
||||
|
||||
|
||||
return ORDER_NOT_DEFINED;
|
||||
}
|
||||
}
|
||||
@ -356,8 +356,8 @@ template <class ELFT>
|
||||
StringRef DefaultLayout<ELFT>::getSectionName(
|
||||
StringRef name, const int32_t contentType,
|
||||
const int32_t contentPermissions) {
|
||||
if ((contentType == DefinedAtom::typeZeroFill) ||
|
||||
(contentType == DefinedAtom::typeZeroFillFast))
|
||||
if ((contentType == DefinedAtom::typeZeroFill) ||
|
||||
(contentType == DefinedAtom::typeZeroFillFast))
|
||||
return ".bss";
|
||||
if (name.startswith(".text"))
|
||||
return ".text";
|
||||
@ -514,7 +514,7 @@ ErrorOr<const AtomLayout &> DefaultLayout<ELFT>::addAtom(const Atom *atom) {
|
||||
|
||||
/// Merge sections with the same name into a MergedSections
|
||||
template<class ELFT>
|
||||
void
|
||||
void
|
||||
DefaultLayout<ELFT>::mergeSimiliarSections() {
|
||||
MergedSections<ELFT> *mergedSection;
|
||||
|
||||
@ -538,7 +538,7 @@ DefaultLayout<ELFT>::mergeSimiliarSections() {
|
||||
|
||||
template <class ELFT> void DefaultLayout<ELFT>::assignSectionsToSegments() {
|
||||
// TODO: Do we want to give a chance for the targetHandlers
|
||||
// to sort segments in an arbitrary order ?
|
||||
// to sort segments in an arbitrary order ?
|
||||
// sort the sections by their order as defined by the layout
|
||||
std::stable_sort(_sections.begin(), _sections.end(),
|
||||
[](Chunk<ELFT> *A, Chunk<ELFT> *B) {
|
||||
@ -569,12 +569,12 @@ template <class ELFT> void DefaultLayout<ELFT>::assignSectionsToSegments() {
|
||||
StringRef segmentName = section->segmentKindToStr();
|
||||
|
||||
int64_t lookupSectionFlag = msi->flags();
|
||||
if (!(lookupSectionFlag & llvm::ELF::SHF_WRITE))
|
||||
if (!(lookupSectionFlag & llvm::ELF::SHF_WRITE))
|
||||
lookupSectionFlag &= ~llvm::ELF::SHF_EXECINSTR;
|
||||
lookupSectionFlag &= ~(llvm::ELF::SHF_STRINGS | llvm::ELF::SHF_MERGE);
|
||||
|
||||
Segment<ELFT> *segment;
|
||||
// We need a seperate segment for sections that dont have
|
||||
// We need a seperate segment for sections that dont have
|
||||
// the segment type to be PT_LOAD
|
||||
if (segmentType != llvm::ELF::PT_LOAD) {
|
||||
const std::pair<AdditionalSegmentKey, Segment<ELFT> *>
|
||||
@ -622,7 +622,7 @@ template <class ELFT> void DefaultLayout<ELFT>::assignSectionsToSegments() {
|
||||
|
||||
template <class ELFT> void DefaultLayout<ELFT>::assignFileOffsets() {
|
||||
// TODO: Do we want to give a chance for the targetHandlers
|
||||
// to sort segments in an arbitrary order ?
|
||||
// to sort segments in an arbitrary order ?
|
||||
std::sort(_segments.begin(), _segments.end(), Segment<ELFT>::compareSegments);
|
||||
int ordinal = 0;
|
||||
// Compute the number of segments that might be needed, so that the
|
||||
@ -643,13 +643,13 @@ void
|
||||
DefaultLayout<ELFT>::assignVirtualAddress() {
|
||||
if (_segments.empty())
|
||||
return;
|
||||
|
||||
|
||||
uint64_t virtualAddress = _targetInfo.getBaseAddress();
|
||||
|
||||
// HACK: This is a super dirty hack. The elf header and program header are
|
||||
// not part of a section, but we need them to be loaded at the base address
|
||||
// so that AT_PHDR is set correctly by the loader and so they are accessible
|
||||
// at runtime. To do this we simply prepend them to the first loadable Segment
|
||||
// at runtime. To do this we simply prepend them to the first loadable Segment
|
||||
// and let the layout logic take care of it.
|
||||
Segment<ELFT> *firstLoadSegment = nullptr;
|
||||
for (auto si : _segments) {
|
||||
|
||||
@ -49,14 +49,14 @@ public:
|
||||
/// \brief Add a section to the current Layout
|
||||
void addSection(Section<ELFT> *section) {}
|
||||
|
||||
/// \brief add new symbol file
|
||||
/// \brief add new symbol file
|
||||
void addFiles(InputFiles &) {}
|
||||
|
||||
/// \brief Finalize the symbol values
|
||||
void finalizeSymbolValues() {}
|
||||
|
||||
/// \brief allocate Commons, some architectures may move small common
|
||||
/// symbols over to small data, this would also be used
|
||||
/// symbols over to small data, this would also be used
|
||||
void allocateCommons() {}
|
||||
};
|
||||
} // end namespace elf
|
||||
|
||||
@ -43,13 +43,13 @@ private:
|
||||
template <class ELFT>
|
||||
void DynamicLibraryWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
|
||||
// Add all the defined symbols to the dynamic symbol table
|
||||
// we need hooks into the Atom to find out which atoms need
|
||||
// to be exported
|
||||
// we need hooks into the Atom to find out which atoms need
|
||||
// to be exported
|
||||
for (auto sec : this->_layout->sections())
|
||||
if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
|
||||
for (const auto &atom : section->atoms()) {
|
||||
const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom);
|
||||
if (da && (da->scope() != DefinedAtom::scopeTranslationUnit))
|
||||
if (da && (da->scope() != DefinedAtom::scopeTranslationUnit))
|
||||
this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
|
||||
atom->_virtualAddr, atom);
|
||||
}
|
||||
|
||||
@ -22,8 +22,8 @@
|
||||
namespace lld {
|
||||
namespace elf {
|
||||
/// \brief All atoms are owned by a File. To add linker specific atoms
|
||||
/// the atoms need to be inserted to a file called (CRuntimeFile) which
|
||||
/// are basically additional symbols required by libc and other runtime
|
||||
/// the atoms need to be inserted to a file called (CRuntimeFile) which
|
||||
/// are basically additional symbols required by libc and other runtime
|
||||
/// libraries part of executing a program. This class provides support
|
||||
/// for adding absolute symbols and undefined symbols
|
||||
template <class ELFT> class CRuntimeFile : public ELFFile<ELFT> {
|
||||
@ -38,7 +38,7 @@ public:
|
||||
symbol->st_name = 0;
|
||||
symbol->st_value = 0;
|
||||
symbol->st_shndx = llvm::ELF::SHN_ABS;
|
||||
symbol->setBindingAndType(llvm::ELF::STB_GLOBAL,
|
||||
symbol->setBindingAndType(llvm::ELF::STB_GLOBAL,
|
||||
llvm::ELF::STT_OBJECT);
|
||||
symbol->st_other = llvm::ELF::STV_DEFAULT;
|
||||
symbol->st_size = 0;
|
||||
@ -47,7 +47,7 @@ public:
|
||||
_absoluteAtoms._atoms.push_back(newAtom);
|
||||
}
|
||||
|
||||
/// \brief add an undefined atom
|
||||
/// \brief add an undefined atom
|
||||
virtual void addUndefinedAtom(StringRef symbolName) {
|
||||
Elf_Sym *symbol = new (_allocator) Elf_Sym;
|
||||
symbol->st_name = 0;
|
||||
@ -89,6 +89,6 @@ protected:
|
||||
File::atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
|
||||
};
|
||||
} // end namespace elf
|
||||
} // end namespace lld
|
||||
} // end namespace lld
|
||||
|
||||
#endif
|
||||
|
||||
@ -25,7 +25,7 @@ class ExecutableWriter;
|
||||
template<class ELFT>
|
||||
class ExecutableWriter : public OutputELFWriter<ELFT> {
|
||||
public:
|
||||
ExecutableWriter(const ELFTargetInfo &ti)
|
||||
ExecutableWriter(const ELFTargetInfo &ti)
|
||||
: OutputELFWriter<ELFT>(ti), _runtimeFile(ti)
|
||||
{}
|
||||
|
||||
@ -60,7 +60,7 @@ void ExecutableWriter<ELFT>::addDefaultAtoms() {
|
||||
_runtimeFile.addAbsoluteAtom("__fini_array_end");
|
||||
}
|
||||
|
||||
/// \brief Hook in lld to add CRuntime file
|
||||
/// \brief Hook in lld to add CRuntime file
|
||||
template <class ELFT>
|
||||
void ExecutableWriter<ELFT>::addFiles(InputFiles &inputFiles) {
|
||||
addDefaultAtoms();
|
||||
@ -69,7 +69,7 @@ void ExecutableWriter<ELFT>::addFiles(InputFiles &inputFiles) {
|
||||
this->_targetHandler.addFiles(inputFiles);
|
||||
}
|
||||
|
||||
/// Finalize the value of all the absolute symbols that we
|
||||
/// Finalize the value of all the absolute symbols that we
|
||||
/// created
|
||||
template<class ELFT>
|
||||
void ExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
|
||||
|
||||
@ -78,7 +78,7 @@ template <class ELFT> class ELFFile : public File {
|
||||
}
|
||||
// the offset of this atom
|
||||
int32_t _offset;
|
||||
// The content
|
||||
// The content
|
||||
StringRef _string;
|
||||
// Section header
|
||||
const Elf_Shdr *_shdr;
|
||||
@ -86,7 +86,7 @@ template <class ELFT> class ELFFile : public File {
|
||||
StringRef _sectionName;
|
||||
};
|
||||
|
||||
// This is used to find the MergeAtom given a relocation
|
||||
// This is used to find the MergeAtom given a relocation
|
||||
// offset
|
||||
typedef std::vector<ELFMergeAtom<ELFT> *> MergeAtomsT;
|
||||
typedef typename MergeAtomsT::iterator MergeAtomsIter;
|
||||
@ -173,7 +173,7 @@ public:
|
||||
int64_t sectionFlags = section->sh_flags;
|
||||
sectionFlags &= ~llvm::ELF::SHF_ALLOC;
|
||||
|
||||
// If the section have mergeable strings, the linker would
|
||||
// If the section have mergeable strings, the linker would
|
||||
// need to split the section into multiple atoms and mark them
|
||||
// mergeByContent
|
||||
if ((section->sh_entsize < 2) &&
|
||||
@ -399,7 +399,7 @@ public:
|
||||
ELFReference<ELFT>(lld::Reference::kindLayoutAfter);
|
||||
previous_atom->addReference(followOn);
|
||||
}
|
||||
else
|
||||
else
|
||||
followOn = anonFollowedBy;
|
||||
}
|
||||
|
||||
@ -418,9 +418,9 @@ public:
|
||||
ArrayRef<uint8_t>((uint8_t *)sectionContents.data() +
|
||||
(*si)->st_value, contentSize));
|
||||
|
||||
// If this is the last atom, lets not create a followon
|
||||
// If this is the last atom, lets not create a followon
|
||||
// reference
|
||||
if ((si + 1) != se)
|
||||
if ((si + 1) != se)
|
||||
anonFollowedBy = new (_readerStorage)
|
||||
ELFReference<ELFT>(lld::Reference::kindLayoutAfter);
|
||||
anonPrecededBy = new (_readerStorage)
|
||||
@ -429,7 +429,7 @@ public:
|
||||
if (anonFollowedBy)
|
||||
anonAtom->addReference(anonFollowedBy);
|
||||
anonAtom->addReference(anonPrecededBy);
|
||||
if (previous_atom)
|
||||
if (previous_atom)
|
||||
anonPrecededBy->setTarget(previous_atom);
|
||||
contentSize = 0;
|
||||
}
|
||||
@ -437,7 +437,7 @@ public:
|
||||
ArrayRef<uint8_t> symbolData = ArrayRef<uint8_t>(
|
||||
(uint8_t *)sectionContents.data() + (*si)->st_value, contentSize);
|
||||
|
||||
// If the linker finds that a section has global atoms that are in a
|
||||
// If the linker finds that a section has global atoms that are in a
|
||||
// mergeable section, treat them as defined atoms as they shouldnt be
|
||||
// merged away as well as these symbols have to be part of symbol
|
||||
// resolution
|
||||
@ -459,7 +459,7 @@ public:
|
||||
auto newAtom = createDefinedAtomAndAssignRelocations(
|
||||
symbolName, sectionName, *si, i.first, symbolData);
|
||||
|
||||
// If the atom was a weak symbol, lets create a followon
|
||||
// If the atom was a weak symbol, lets create a followon
|
||||
// reference to the anonymous atom that we created
|
||||
if ((*si)->getBinding() == llvm::ELF::STB_WEAK && anonAtom) {
|
||||
ELFReference<ELFT> *wFollowedBy = new (_readerStorage)
|
||||
@ -470,14 +470,14 @@ public:
|
||||
|
||||
if (followOn) {
|
||||
ELFReference<ELFT> *precededby = nullptr;
|
||||
// Set the followon atom to the weak atom
|
||||
// Set the followon atom to the weak atom
|
||||
// that we have created, so that they would
|
||||
// alias when the file gets written
|
||||
if (anonAtom)
|
||||
if (anonAtom)
|
||||
followOn->setTarget(anonAtom);
|
||||
else
|
||||
followOn->setTarget(newAtom);
|
||||
// Add a preceded by reference only if the current atom is not a
|
||||
// Add a preceded by reference only if the current atom is not a
|
||||
// weak atom
|
||||
if ((*si)->getBinding() != llvm::ELF::STB_WEAK) {
|
||||
precededby = new (_readerStorage)
|
||||
|
||||
@ -95,13 +95,13 @@ public:
|
||||
/// we are looking for
|
||||
class FindPhdr {
|
||||
public:
|
||||
FindPhdr(uint64_t type, uint64_t flags, uint64_t flagsClear)
|
||||
FindPhdr(uint64_t type, uint64_t flags, uint64_t flagsClear)
|
||||
: _type(type)
|
||||
, _flags(flags)
|
||||
, _flagsClear(flagsClear)
|
||||
{}
|
||||
|
||||
bool operator()(const Elf_Phdr *j) const {
|
||||
bool operator()(const Elf_Phdr *j) const {
|
||||
return ((j->p_type == _type) &&
|
||||
((j->p_flags & _flags) == _flags) &&
|
||||
(!(j->p_flags & _flagsClear)));
|
||||
@ -248,13 +248,13 @@ public:
|
||||
SectionHeader(const ELFTargetInfo &, int32_t order);
|
||||
|
||||
void appendSection(MergedSections<ELFT> *section);
|
||||
|
||||
|
||||
void updateSection(Section<ELFT> *section);
|
||||
|
||||
|
||||
static inline bool classof(const Chunk<ELFT> *c) {
|
||||
return c->getChunkKind() == Chunk<ELFT>::K_SectionHeader;
|
||||
}
|
||||
|
||||
|
||||
void setStringSection(StringTable<ELFT> *s) {
|
||||
_stringSection = s;
|
||||
}
|
||||
@ -270,7 +270,7 @@ public:
|
||||
inline uint64_t entsize() {
|
||||
return sizeof(Elf_Shdr);
|
||||
}
|
||||
|
||||
|
||||
inline uint64_t numHeaders() {
|
||||
return _sectionInfo.size();
|
||||
}
|
||||
@ -295,7 +295,7 @@ SectionHeader<ELFT>::SectionHeader(const ELFTargetInfo &ti, int32_t order)
|
||||
}
|
||||
|
||||
template<class ELFT>
|
||||
void
|
||||
void
|
||||
SectionHeader<ELFT>::appendSection(MergedSections<ELFT> *section) {
|
||||
Elf_Shdr *shdr = new (_sectionAllocate.Allocate<Elf_Shdr>()) Elf_Shdr;
|
||||
shdr->sh_name = _stringSection->addString(section->name());
|
||||
@ -312,7 +312,7 @@ SectionHeader<ELFT>::appendSection(MergedSections<ELFT> *section) {
|
||||
}
|
||||
|
||||
template<class ELFT>
|
||||
void
|
||||
void
|
||||
SectionHeader<ELFT>::updateSection(Section<ELFT> *section) {
|
||||
Elf_Shdr *shdr = _sectionInfo[section->ordinal()];
|
||||
shdr->sh_type = section->getType();
|
||||
|
||||
@ -45,10 +45,10 @@ public:
|
||||
};
|
||||
|
||||
const uint8_t HexagonPLTAtom::_defaultContent[16] = {
|
||||
0x00, 0x40, 0x00, 0x00, // { immext (#0)
|
||||
0x00, 0x40, 0x00, 0x00, // { immext (#0)
|
||||
0x0e, 0xc0, 0x49, 0x6a, // r14 = add (pc, ##GOTn@PCREL) } # address of GOTn
|
||||
0x1c, 0xc0, 0x8e, 0x91, // r28 = memw (r14) # contents of GOTn
|
||||
0x00, 0xc0, 0x9c, 0x52, // jumpr r28 # call it
|
||||
0x00, 0xc0, 0x9c, 0x52, // jumpr r28 # call it
|
||||
};
|
||||
|
||||
class HexagonPLT0Atom : public PLT0Atom {
|
||||
@ -67,16 +67,16 @@ public:
|
||||
};
|
||||
|
||||
const uint8_t HexagonPLT0Atom::_plt0Content[28] = {
|
||||
0x00, 0x40, 0x00, 0x00, // { immext (#0)
|
||||
0x00, 0x40, 0x00, 0x00, // { immext (#0)
|
||||
0x1c, 0xc0, 0x49, 0x6a, // r28 = add (pc, ##GOT0@PCREL) } # address of GOT0
|
||||
0x0e, 0x42, 0x9c, 0xe2, // { r14 -= add (r28, #16) # offset of GOTn from GOTa
|
||||
0x4f, 0x40, 0x9c, 0x91, // r15 = memw (r28 + #8) # object ID at GOT2
|
||||
0x3c, 0xc0, 0x9c, 0x91, // r28 = memw (r28 + #4) }# dynamic link at GOT1
|
||||
0x0e, 0x42, 0x0e, 0x8c, // { r14 = asr (r14, #2) # index of PLTn
|
||||
0x00, 0xc0, 0x9c, 0x52, // jumpr r28 } # call dynamic linker
|
||||
0x4f, 0x40, 0x9c, 0x91, // r15 = memw (r28 + #8) # object ID at GOT2
|
||||
0x3c, 0xc0, 0x9c, 0x91, // r28 = memw (r28 + #4) }# dynamic link at GOT1
|
||||
0x0e, 0x42, 0x0e, 0x8c, // { r14 = asr (r14, #2) # index of PLTn
|
||||
0x00, 0xc0, 0x9c, 0x52, // jumpr r28 } # call dynamic linker
|
||||
};
|
||||
|
||||
} // elf
|
||||
} // elf
|
||||
} // lld
|
||||
|
||||
#endif // LLD_READER_WRITER_ELF_HEXAGON_DYNAMIC_ATOMS_H
|
||||
|
||||
@ -17,15 +17,15 @@ namespace elf {
|
||||
typedef llvm::object::ELFType<llvm::support::little, 4, false> HexagonELFType;
|
||||
class HexagonTargetInfo;
|
||||
|
||||
template <class HexagonELFType> class HexagonRuntimeFile
|
||||
template <class HexagonELFType> class HexagonRuntimeFile
|
||||
: public CRuntimeFile<HexagonELFType> {
|
||||
public:
|
||||
HexagonRuntimeFile(const HexagonTargetInfo &hti)
|
||||
:CRuntimeFile<HexagonELFType>(hti, "Hexagon runtime file")
|
||||
:CRuntimeFile<HexagonELFType>(hti, "Hexagon runtime file")
|
||||
{}
|
||||
|
||||
};
|
||||
} // elf
|
||||
} // elf
|
||||
} // lld
|
||||
|
||||
#endif // LLD_READER_WRITER_ELF_HEXAGON_EXECUTABLE_ATOM_H
|
||||
|
||||
@ -37,13 +37,13 @@ uint32_t findBitMask(uint32_t insn, Instruction *encodings, int32_t numInsns) {
|
||||
if (((insn & 0xc000) != 0) && (encodings[i].isDuplex))
|
||||
continue;
|
||||
|
||||
if (((encodings[i].insnMask) & insn) == encodings[i].insnCmpMask)
|
||||
if (((encodings[i].insnMask) & insn) == encodings[i].insnCmpMask)
|
||||
return encodings[i].insnBitMask;
|
||||
}
|
||||
llvm_unreachable("found unknown instruction");
|
||||
}
|
||||
|
||||
} // elf
|
||||
} // elf
|
||||
} // lld
|
||||
|
||||
#endif // LLD_READER_WRITER_ELF_HEXAGON_RELOCATION_FUNCTIONS_H
|
||||
|
||||
@ -37,5 +37,5 @@ private:
|
||||
const HexagonTargetLayout<HexagonELFType> &_targetLayout;
|
||||
};
|
||||
} // elf
|
||||
} // lld
|
||||
} // lld
|
||||
#endif
|
||||
|
||||
@ -100,7 +100,7 @@ public:
|
||||
protected:
|
||||
/// \brief Owner of all the Atoms created by this pass.
|
||||
ELFPassFile _file;
|
||||
|
||||
|
||||
/// \brief Map Atoms to their GOT entries.
|
||||
llvm::DenseMap<const Atom *, GOTAtom *> _gotMap;
|
||||
|
||||
|
||||
@ -141,7 +141,7 @@ private:
|
||||
SDataSection<HexagonELFType> *_sdataSection;
|
||||
};
|
||||
|
||||
/// \brief TargetHandler for Hexagon
|
||||
/// \brief TargetHandler for Hexagon
|
||||
class HexagonTargetHandler LLVM_FINAL :
|
||||
public DefaultTargetHandler<HexagonELFType> {
|
||||
public:
|
||||
@ -179,7 +179,7 @@ public:
|
||||
|
||||
void finalizeSymbolValues() {
|
||||
auto sdabaseAtomIter = _targetLayout.findAbsoluteAtom("_SDA_BASE_");
|
||||
(*sdabaseAtomIter)->_virtualAddr =
|
||||
(*sdabaseAtomIter)->_virtualAddr =
|
||||
_targetLayout.getSDataSection()->virtualAddr();
|
||||
}
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ class OutputELFWriter;
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// \brief This acts as the base class for all the ELF writers that are output
|
||||
/// for emitting an ELF output file. This class also acts as a common class for
|
||||
/// creating static and dynamic executables. All the function in this class
|
||||
/// creating static and dynamic executables. All the function in this class
|
||||
/// can be overridden and an appropriate writer be created
|
||||
template<class ELFT>
|
||||
class OutputELFWriter : public ELFWriter {
|
||||
@ -56,7 +56,7 @@ protected:
|
||||
// Write the file to the path specified
|
||||
virtual error_code writeFile(const File &File, StringRef path);
|
||||
|
||||
// Build the atom to address map, this has to be called
|
||||
// Build the atom to address map, this has to be called
|
||||
// before applying relocations
|
||||
virtual void buildAtomToAddressMap();
|
||||
|
||||
@ -69,14 +69,14 @@ protected:
|
||||
// Build the section header table
|
||||
virtual void buildSectionHeaderTable();
|
||||
|
||||
// Assign sections that have no segments such as the symbol table,
|
||||
// Assign sections that have no segments such as the symbol table,
|
||||
// section header table, string table etc
|
||||
virtual void assignSectionsWithNoSegments();
|
||||
|
||||
// Add default atoms that need to be present in the output file
|
||||
virtual void addDefaultAtoms() = 0;
|
||||
|
||||
// Add any runtime files and their atoms to the output
|
||||
// Add any runtime files and their atoms to the output
|
||||
virtual void addFiles(InputFiles&) = 0;
|
||||
|
||||
// Finalize the default atom values
|
||||
@ -253,7 +253,7 @@ template <class ELFT>
|
||||
error_code OutputELFWriter<ELFT>::buildOutput(const File &file) {
|
||||
buildChunks(file);
|
||||
|
||||
// Call the preFlight callbacks to modify the sections and the atoms
|
||||
// Call the preFlight callbacks to modify the sections and the atoms
|
||||
// contained in them, in anyway the targets may want
|
||||
_layout->doPreFlight();
|
||||
|
||||
|
||||
@ -136,7 +136,7 @@ public:
|
||||
case DefinedAtom::typeTLVInitialData:
|
||||
this->_type = SHT_PROGBITS;
|
||||
break;
|
||||
|
||||
|
||||
case DefinedAtom::typeTLVInitialZeroFill:
|
||||
case DefinedAtom::typeZeroFillFast:
|
||||
case DefinedAtom::typeZeroFill:
|
||||
@ -478,7 +478,7 @@ MergedSections<ELFT>::MergedSections(StringRef name)
|
||||
,_align2(0)
|
||||
,_kind(0)
|
||||
,_type(0) { }
|
||||
|
||||
|
||||
|
||||
template<class ELFT>
|
||||
void
|
||||
@ -585,7 +585,7 @@ class SymbolTable : public Section<ELFT> {
|
||||
|
||||
struct SymbolEntry {
|
||||
SymbolEntry(const Atom *a, const Elf_Sym &sym,
|
||||
const AtomLayout *layout) : _atom(a), _symbol(sym),
|
||||
const AtomLayout *layout) : _atom(a), _symbol(sym),
|
||||
_atomLayout(layout) {}
|
||||
SymbolEntry() : _atom(nullptr) {}
|
||||
|
||||
@ -597,7 +597,7 @@ class SymbolTable : public Section<ELFT> {
|
||||
public:
|
||||
SymbolTable(const ELFTargetInfo &ti, const char *str, int32_t order);
|
||||
|
||||
void addSymbol(const Atom *atom, int32_t sectionIndex,
|
||||
void addSymbol(const Atom *atom, int32_t sectionIndex,
|
||||
uint64_t addr = 0, const AtomLayout *layout=nullptr);
|
||||
|
||||
/// \brief Get the symbol table index for an Atom. If it's not in the symbol
|
||||
@ -626,7 +626,7 @@ protected:
|
||||
std::vector<SymbolEntry> _symbolTable;
|
||||
};
|
||||
|
||||
/// ELF Symbol Table
|
||||
/// ELF Symbol Table
|
||||
template <class ELFT>
|
||||
SymbolTable<ELFT>::SymbolTable(const ELFTargetInfo &ti, const char *str,
|
||||
int32_t order)
|
||||
@ -643,7 +643,7 @@ SymbolTable<ELFT>::SymbolTable(const ELFTargetInfo &ti, const char *str,
|
||||
|
||||
/// Add a symbol to the symbol Table, definedAtoms which get added to the symbol
|
||||
/// section dont have their virtual addresses set at the time of adding the
|
||||
/// symbol to the symbol table(Example: dynamic symbols), the addresses needs
|
||||
/// symbol to the symbol table(Example: dynamic symbols), the addresses needs
|
||||
/// to be updated in the table before writing the dynamic symbol table
|
||||
/// information
|
||||
template <class ELFT>
|
||||
@ -692,7 +692,7 @@ void SymbolTable<ELFT>::addSymbol(const Atom *atom, int32_t sectionIndex,
|
||||
default:
|
||||
type = llvm::ELF::STT_NOTYPE;
|
||||
}
|
||||
if (da->customSectionName() == da->name())
|
||||
if (da->customSectionName() == da->name())
|
||||
type = llvm::ELF::STT_SECTION;
|
||||
|
||||
if (da->scope() == DefinedAtom::scopeTranslationUnit)
|
||||
@ -883,7 +883,7 @@ public:
|
||||
|
||||
range<typename EntriesT::iterator> entries() { return _entries; }
|
||||
|
||||
/// \returns the index of the entry.
|
||||
/// \returns the index of the entry.
|
||||
std::size_t addEntry(Elf_Dyn e) {
|
||||
_entries.push_back(e);
|
||||
this->_fsize = (_entries.size() * sizeof(Elf_Dyn)) + sizeof(Elf_Dyn);
|
||||
|
||||
@ -173,8 +173,8 @@ public:
|
||||
// segments, since those values are not set in the Layout
|
||||
if (_segmentType == llvm::ELF::PT_LOAD)
|
||||
return;
|
||||
// The size is the difference of the
|
||||
// last section to the first section, especially for TLS because
|
||||
// The size is the difference of the
|
||||
// last section to the first section, especially for TLS because
|
||||
// the TLS segment contains both .tdata/.tbss
|
||||
this->setFileOffset(_sections.front()->fileOffset());
|
||||
this->setVAddr(_sections.front()->virtualAddr());
|
||||
@ -269,9 +269,9 @@ public:
|
||||
/// Finalize the segment, before we want to write the segment header
|
||||
/// information
|
||||
inline void finalize() {
|
||||
// If the segment is of type Program Header, then the values fileOffset
|
||||
// If the segment is of type Program Header, then the values fileOffset
|
||||
// and the fileSize need to be picked up from the last section, the first
|
||||
// section points to the ELF header and the second chunk points to the
|
||||
// section points to the ELF header and the second chunk points to the
|
||||
// actual program headers
|
||||
this->setFileOffset(_sections.back()->fileOffset());
|
||||
this->setVAddr(_sections.back()->virtualAddr());
|
||||
@ -473,8 +473,8 @@ template <class ELFT> void Segment<ELFT>::assignVirtualAddress(uint64_t &addr) {
|
||||
for (auto section : slice->sections()) {
|
||||
// Align the section address
|
||||
addr = llvm::RoundUpToAlignment(addr, section->align2());
|
||||
// Check if the segment is of type TLS
|
||||
// The sections that belong to the TLS segment have their
|
||||
// Check if the segment is of type TLS
|
||||
// The sections that belong to the TLS segment have their
|
||||
// virtual addresses that are relative To TP
|
||||
Section<ELFT> *currentSection = llvm::dyn_cast<Section<ELFT> >(section);
|
||||
if (currentSection)
|
||||
@ -512,7 +512,7 @@ void Segment<ELFT>::write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
|
||||
}
|
||||
|
||||
template<class ELFT>
|
||||
int64_t
|
||||
int64_t
|
||||
Segment<ELFT>::flags() const {
|
||||
int64_t fl = 0;
|
||||
if (_flags & llvm::ELF::SHF_ALLOC)
|
||||
|
||||
@ -41,7 +41,7 @@ template <class ELFT> class TargetLayout;
|
||||
|
||||
/// \brief The target registers a set of handlers for overriding target specific
|
||||
/// attributes for a DefinedAtom. The Reader uses this class to query for the
|
||||
/// type of atom and its permissions
|
||||
/// type of atom and its permissions
|
||||
template <class ELFT> class TargetAtomHandler {
|
||||
public:
|
||||
typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
|
||||
@ -76,7 +76,7 @@ public:
|
||||
virtual int64_t relocAddend(const Reference &)const { return 0; }
|
||||
};
|
||||
|
||||
/// \brief An interface to override functions that are provided by the
|
||||
/// \brief An interface to override functions that are provided by the
|
||||
/// the default ELF Layout
|
||||
template <class ELFT> class TargetHandler : public TargetHandlerBase {
|
||||
|
||||
@ -88,10 +88,10 @@ public:
|
||||
/// that target
|
||||
virtual bool doesOverrideHeader() = 0;
|
||||
|
||||
/// Set the ELF Header information
|
||||
/// Set the ELF Header information
|
||||
virtual void setHeaderInfo(Header<ELFT> *Header) = 0;
|
||||
|
||||
/// TargetLayout
|
||||
/// TargetLayout
|
||||
virtual TargetLayout<ELFT> &targetLayout() = 0;
|
||||
|
||||
/// TargetAtomHandler
|
||||
@ -105,14 +105,14 @@ public:
|
||||
/// \brief Add a section to the current Layout
|
||||
virtual void addSection(Section<ELFT> *section) = 0;
|
||||
|
||||
/// \brief add new symbol file
|
||||
/// \brief add new symbol file
|
||||
virtual void addFiles(InputFiles &) = 0;
|
||||
|
||||
/// \brief Finalize the symbol values
|
||||
virtual void finalizeSymbolValues() = 0;
|
||||
|
||||
/// \brief allocate Commons, some architectures may move small common
|
||||
/// symbols over to small data, this would also be used
|
||||
/// symbols over to small data, this would also be used
|
||||
virtual void allocateCommons() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
@ -21,7 +21,7 @@ namespace elf {
|
||||
/// be changed in the final layout
|
||||
template <class ELFT> class TargetLayout : public DefaultLayout<ELFT> {
|
||||
public:
|
||||
TargetLayout(const ELFTargetInfo &targetInfo)
|
||||
TargetLayout(const ELFTargetInfo &targetInfo)
|
||||
: DefaultLayout<ELFT>(targetInfo) {}
|
||||
};
|
||||
} // end namespace elf
|
||||
|
||||
@ -52,7 +52,7 @@ std::unique_ptr<Writer> createWriterELF(const ELFTargetInfo &TI) {
|
||||
elf::DynamicLibraryWriter<ELFType<support::big, 8, true>>(TI));
|
||||
llvm_unreachable("Invalid Options!");
|
||||
}
|
||||
else
|
||||
else
|
||||
llvm_unreachable("unsupported options");
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,7 +254,7 @@ public:
|
||||
protected:
|
||||
/// \brief Owner of all the Atoms created by this pass.
|
||||
ELFPassFile _file;
|
||||
|
||||
|
||||
/// \brief Map Atoms to their GOT entries.
|
||||
llvm::DenseMap<const Atom *, GOTAtom *> _gotMap;
|
||||
|
||||
|
||||
@ -80,7 +80,7 @@ StringRef KindHandler_x86_64::kindToString(Reference::Kind kind) {
|
||||
return StringRef("invalid");
|
||||
case none:
|
||||
return StringRef("none");
|
||||
case branch32:
|
||||
case branch32:
|
||||
return StringRef("branch32");
|
||||
case ripRel32:
|
||||
return StringRef("ripRel32");
|
||||
@ -123,23 +123,23 @@ bool KindHandler_x86_64::isCallSite(Kind kind) {
|
||||
bool KindHandler_x86_64::isPointer(Kind kind) {
|
||||
return (kind == pointer64);
|
||||
}
|
||||
|
||||
|
||||
bool KindHandler_x86_64::isLazyImmediate(Kind kind) {
|
||||
return (kind == lazyImmediate);
|
||||
}
|
||||
|
||||
|
||||
bool KindHandler_x86_64::isLazyTarget(Kind kind) {
|
||||
return (kind == lazyTarget);
|
||||
}
|
||||
|
||||
|
||||
void KindHandler_x86_64::applyFixup(Kind kind, uint64_t addend,
|
||||
uint8_t *location, uint64_t fixupAddress,
|
||||
|
||||
void KindHandler_x86_64::applyFixup(Kind kind, uint64_t addend,
|
||||
uint8_t *location, uint64_t fixupAddress,
|
||||
uint64_t targetAddress) {
|
||||
int32_t *loc32 = reinterpret_cast<int32_t*>(location);
|
||||
uint64_t* loc64 = reinterpret_cast<uint64_t*>(location);
|
||||
switch ( (Kinds)kind ) {
|
||||
case branch32:
|
||||
case branch32:
|
||||
case ripRel32:
|
||||
case gotLoadRipRel32:
|
||||
case gotUseRipRel32:
|
||||
@ -158,7 +158,7 @@ void KindHandler_x86_64::applyFixup(Kind kind, uint64_t addend,
|
||||
case ripRel32_4:
|
||||
*loc32 = (targetAddress - (fixupAddress+8)) + addend;
|
||||
break;
|
||||
case pointerRel32:
|
||||
case pointerRel32:
|
||||
*loc32 = (targetAddress - fixupAddress) + addend;
|
||||
break;
|
||||
case gotLoadRipRel32NowLea:
|
||||
@ -199,7 +199,7 @@ Reference::Kind KindHandler_x86::stringToKind(StringRef str) {
|
||||
.Case("lazyTarget", lazyTarget)
|
||||
.Case("lazyImmediate", lazyImmediate)
|
||||
.Default(invalid);
|
||||
|
||||
|
||||
llvm_unreachable("invalid x86 Reference kind");
|
||||
}
|
||||
|
||||
@ -209,7 +209,7 @@ StringRef KindHandler_x86::kindToString(Reference::Kind kind) {
|
||||
return StringRef("invalid");
|
||||
case none:
|
||||
return StringRef("none");
|
||||
case branch32:
|
||||
case branch32:
|
||||
return StringRef("branch32");
|
||||
case abs32:
|
||||
return StringRef("abs32");
|
||||
@ -237,22 +237,22 @@ bool KindHandler_x86::isPointer(Kind kind) {
|
||||
return (kind == pointer32);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool KindHandler_x86::isLazyImmediate(Kind kind) {
|
||||
return (kind == lazyImmediate);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool KindHandler_x86::isLazyTarget(Kind kind) {
|
||||
return (kind == lazyTarget);
|
||||
}
|
||||
|
||||
|
||||
void KindHandler_x86::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
|
||||
|
||||
void KindHandler_x86::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
|
||||
uint64_t fixupAddress, uint64_t targetAddress) {
|
||||
int32_t *loc32 = reinterpret_cast<int32_t*>(location);
|
||||
switch ( (Kinds)kind ) {
|
||||
case branch32:
|
||||
case branch32:
|
||||
*loc32 = (targetAddress - (fixupAddress+4)) + addend;
|
||||
break;
|
||||
case pointer32:
|
||||
@ -308,9 +308,9 @@ StringRef KindHandler_arm::kindToString(Reference::Kind kind) {
|
||||
return StringRef("invalid");
|
||||
case none:
|
||||
return StringRef("none");
|
||||
case thumbBranch22:
|
||||
case thumbBranch22:
|
||||
return StringRef("thumbBranch22");
|
||||
case armBranch24:
|
||||
case armBranch24:
|
||||
return StringRef("armBranch24");
|
||||
case thumbAbsLow16:
|
||||
return StringRef("thumbAbsLow16");
|
||||
@ -342,43 +342,43 @@ bool KindHandler_arm::isPointer(Kind kind) {
|
||||
return (kind == pointer32);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool KindHandler_arm::isLazyImmediate(Kind kind) {
|
||||
return (kind == lazyImmediate);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool KindHandler_arm::isLazyTarget(Kind kind) {
|
||||
return (kind == lazyTarget);
|
||||
}
|
||||
|
||||
|
||||
void KindHandler_arm::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
|
||||
|
||||
void KindHandler_arm::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
|
||||
uint64_t fixupAddress, uint64_t targetAddress) {
|
||||
//int32_t *loc32 = reinterpret_cast<int32_t*>(location);
|
||||
switch ( (Kinds)kind ) {
|
||||
case thumbBranch22:
|
||||
case thumbBranch22:
|
||||
// FIXME
|
||||
break;
|
||||
case armBranch24:
|
||||
case armBranch24:
|
||||
// FIXME
|
||||
break;
|
||||
case thumbAbsLow16:
|
||||
case thumbAbsLow16:
|
||||
// FIXME
|
||||
break;
|
||||
case thumbAbsHigh16:
|
||||
case thumbAbsHigh16:
|
||||
// FIXME
|
||||
break;
|
||||
case thumbPcRelLow16:
|
||||
case thumbPcRelLow16:
|
||||
// FIXME
|
||||
break;
|
||||
case thumbPcRelHigh16:
|
||||
case thumbPcRelHigh16:
|
||||
// FIXME
|
||||
break;
|
||||
case abs32:
|
||||
case abs32:
|
||||
// FIXME
|
||||
break;
|
||||
case pointer32:
|
||||
case pointer32:
|
||||
// FIXME
|
||||
break;
|
||||
case none:
|
||||
@ -392,7 +392,7 @@ void KindHandler_arm::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace mach_o
|
||||
} // namespace lld
|
||||
|
||||
@ -28,18 +28,18 @@ namespace mach_o {
|
||||
class KindHandler {
|
||||
public:
|
||||
typedef Reference::Kind Kind;
|
||||
|
||||
|
||||
static KindHandler *makeHandler(llvm::Triple::ArchType arch);
|
||||
virtual ~KindHandler();
|
||||
virtual Kind stringToKind(StringRef str) = 0;
|
||||
virtual StringRef kindToString(Kind) = 0;
|
||||
virtual bool isCallSite(Kind) = 0;
|
||||
virtual bool isPointer(Kind) = 0;
|
||||
virtual bool isLazyImmediate(Kind) = 0;
|
||||
virtual bool isLazyTarget(Kind) = 0;
|
||||
virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
|
||||
virtual bool isPointer(Kind) = 0;
|
||||
virtual bool isLazyImmediate(Kind) = 0;
|
||||
virtual bool isLazyTarget(Kind) = 0;
|
||||
virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
|
||||
uint64_t fixupAddress, uint64_t targetAddress) = 0;
|
||||
|
||||
|
||||
protected:
|
||||
KindHandler();
|
||||
};
|
||||
@ -73,10 +73,10 @@ public:
|
||||
virtual Kind stringToKind(StringRef str);
|
||||
virtual StringRef kindToString(Kind);
|
||||
virtual bool isCallSite(Kind);
|
||||
virtual bool isPointer(Kind);
|
||||
virtual bool isLazyImmediate(Kind);
|
||||
virtual bool isLazyTarget(Kind);
|
||||
virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
|
||||
virtual bool isPointer(Kind);
|
||||
virtual bool isLazyImmediate(Kind);
|
||||
virtual bool isLazyTarget(Kind);
|
||||
virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
|
||||
uint64_t fixupAddress, uint64_t targetAddress);
|
||||
|
||||
};
|
||||
@ -101,10 +101,10 @@ public:
|
||||
virtual Kind stringToKind(StringRef str);
|
||||
virtual StringRef kindToString(Kind);
|
||||
virtual bool isCallSite(Kind);
|
||||
virtual bool isPointer(Kind);
|
||||
virtual bool isLazyImmediate(Kind);
|
||||
virtual bool isLazyTarget(Kind);
|
||||
virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
|
||||
virtual bool isPointer(Kind);
|
||||
virtual bool isLazyImmediate(Kind);
|
||||
virtual bool isLazyTarget(Kind);
|
||||
virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
|
||||
uint64_t fixupAddress, uint64_t targetAddress);
|
||||
|
||||
};
|
||||
@ -131,10 +131,10 @@ public:
|
||||
virtual Kind stringToKind(StringRef str);
|
||||
virtual StringRef kindToString(Kind);
|
||||
virtual bool isCallSite(Kind);
|
||||
virtual bool isPointer(Kind);
|
||||
virtual bool isLazyImmediate(Kind);
|
||||
virtual bool isLazyTarget(Kind);
|
||||
virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
|
||||
virtual bool isPointer(Kind);
|
||||
virtual bool isLazyImmediate(Kind);
|
||||
virtual bool isLazyTarget(Kind);
|
||||
virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
|
||||
uint64_t fixupAddress, uint64_t targetAddress);
|
||||
|
||||
};
|
||||
|
||||
@ -353,7 +353,7 @@ public:
|
||||
KindHandler *kindHandler() { return _referenceKindHandler; }
|
||||
|
||||
bool use64BitMachO() const;
|
||||
|
||||
|
||||
private:
|
||||
friend class LoadCommandsChunk;
|
||||
friend class LazyBindingInfoChunk;
|
||||
@ -440,7 +440,7 @@ void Chunk::assignFileOffset(uint64_t &curOffset, uint64_t &curAddress) {
|
||||
curAddress = _address + _size;
|
||||
}
|
||||
|
||||
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
|
||||
<< " fileOffset="
|
||||
<< llvm::format("0x%08X", _fileOffset)
|
||||
<< " address="
|
||||
@ -580,7 +580,7 @@ void SectionChunk::write(uint8_t *chunkBuffer) {
|
||||
if ( ref->target() != nullptr )
|
||||
targetAddress = _writer.addressOfAtom(ref->target());
|
||||
uint64_t fixupAddress = _writer.addressOfAtom(atomInfo.atom) + offset;
|
||||
_writer.kindHandler()->applyFixup(ref->kind(), ref->addend(),
|
||||
_writer.kindHandler()->applyFixup(ref->kind(), ref->addend(),
|
||||
&atomContent[offset], fixupAddress, targetAddress);
|
||||
}
|
||||
}
|
||||
@ -601,7 +601,7 @@ MachHeaderChunk::MachHeaderChunk(const MachOTargetInfo &ti, const File &file) {
|
||||
_mh.sizeofcmds = 0;
|
||||
_mh.flags = 0;
|
||||
_mh.reserved = 0;
|
||||
|
||||
|
||||
_size = _mh.size();
|
||||
}
|
||||
|
||||
@ -673,7 +673,7 @@ LoadCommandsChunk::LoadCommandsChunk(MachHeaderChunk &mh,
|
||||
MachOWriter& writer)
|
||||
: _mh(mh), _targetInfo(ti), _writer(writer),
|
||||
_linkEditSegment(nullptr), _symbolTableLoadCommand(nullptr),
|
||||
_entryPointLoadCommand(nullptr), _threadLoadCommand(nullptr),
|
||||
_entryPointLoadCommand(nullptr), _threadLoadCommand(nullptr),
|
||||
_dyldInfoLoadCommand(nullptr) {
|
||||
}
|
||||
|
||||
@ -687,7 +687,7 @@ void LoadCommandsChunk::write(uint8_t *chunkBuffer) {
|
||||
for ( load_command* lc : _loadCmds ) {
|
||||
assert( ((uintptr_t)p & 0x3) == 0);
|
||||
lc->copyTo(p);
|
||||
p += lc->cmdsize;
|
||||
p += lc->cmdsize;
|
||||
}
|
||||
}
|
||||
|
||||
@ -808,11 +808,11 @@ void LoadCommandsChunk::computeSize(const lld::File &file) {
|
||||
_threadLoadCommand = new thread_command(_targetInfo.getCPUType(), is64);
|
||||
this->addLoadCommand(_threadLoadCommand);
|
||||
}
|
||||
|
||||
|
||||
// Compute total size.
|
||||
_size = _mh.loadCommandsSize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LoadCommandsChunk::updateLoadCommandContent(const lld::File &file) {
|
||||
// Update segment/section information in segment load commands
|
||||
@ -886,7 +886,7 @@ void LoadCommandsChunk::updateLoadCommandContent(const lld::File &file) {
|
||||
assert(startAtom != nullptr);
|
||||
_threadLoadCommand->setPC(_writer.addressOfAtom(startAtom));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1092,7 +1092,7 @@ const char* LazyBindingInfoChunk::info() {
|
||||
}
|
||||
|
||||
//
|
||||
// Called when lazy-binding-info is being laid out in __LINKEDIT. We need
|
||||
// Called when lazy-binding-info is being laid out in __LINKEDIT. We need
|
||||
// to find the helper atom which contains the instruction which loads an
|
||||
// immediate value that is the offset into the lazy-binding-info, and set
|
||||
// that immediate value to be the offset parameter.
|
||||
@ -1390,7 +1390,7 @@ void MachOWriter::addLinkEditChunk(LinkEditChunk *chunk) {
|
||||
|
||||
|
||||
void MachOWriter::buildAtomToAddressMap() {
|
||||
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
|
||||
<< "assign atom addresses:\n");
|
||||
const bool lookForEntry = _targetInfo.getLinkerOptions()._outputKind ==
|
||||
OutputKind::StaticExecutable ||
|
||||
@ -1405,7 +1405,7 @@ void MachOWriter::buildAtomToAddressMap() {
|
||||
&& info.atom->name() == _targetInfo.getEntry()) {
|
||||
_entryAtom = info.atom;
|
||||
}
|
||||
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
|
||||
<< " address="
|
||||
<< llvm::format("0x%016X", _atomToAddress[info.atom])
|
||||
<< " atom=" << info.atom
|
||||
@ -1422,7 +1422,7 @@ void MachOWriter::buildAtomToAddressMap() {
|
||||
//}
|
||||
|
||||
void MachOWriter::assignFileOffsets() {
|
||||
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
|
||||
<< "assign file offsets:\n");
|
||||
uint64_t offset = 0;
|
||||
uint64_t address = _targetInfo.getPageZeroSize();
|
||||
@ -1437,7 +1437,7 @@ void MachOWriter::assignFileOffsets() {
|
||||
}
|
||||
|
||||
void MachOWriter::assignLinkEditFileOffsets() {
|
||||
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
|
||||
<< "assign LINKEDIT file offsets:\n");
|
||||
uint64_t offset = _linkEditStartOffset;
|
||||
uint64_t address = _linkEditStartAddress;
|
||||
@ -1498,19 +1498,19 @@ bool MachOWriter::use64BitMachO() const {
|
||||
error_code MachOWriter::writeFile(const lld::File &file, StringRef path) {
|
||||
this->build(file);
|
||||
|
||||
// FIXME: re-enable when FileOutputBuffer is in LLVMSupport.a
|
||||
// FIXME: re-enable when FileOutputBuffer is in LLVMSupport.a
|
||||
uint64_t totalSize = _chunks.back()->fileOffset() + _chunks.back()->size();
|
||||
|
||||
OwningPtr<llvm::FileOutputBuffer> buffer;
|
||||
error_code ec = llvm::FileOutputBuffer::create(path,
|
||||
error_code ec = llvm::FileOutputBuffer::create(path,
|
||||
totalSize, buffer,
|
||||
llvm::FileOutputBuffer::F_executable);
|
||||
llvm::FileOutputBuffer::F_executable);
|
||||
if ( ec )
|
||||
return ec;
|
||||
|
||||
|
||||
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs() << "writeFile:\n");
|
||||
for ( Chunk *chunk : _chunks ) {
|
||||
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
|
||||
<< " fileOffset="
|
||||
<< llvm::format("0x%08X", chunk->fileOffset())
|
||||
<< " chunk="
|
||||
@ -1518,7 +1518,7 @@ error_code MachOWriter::writeFile(const lld::File &file, StringRef path) {
|
||||
<< "\n");
|
||||
chunk->write(buffer->getBufferStart()+chunk->fileOffset());
|
||||
}
|
||||
|
||||
|
||||
return buffer->commit();
|
||||
return error_code::success();
|
||||
}
|
||||
|
||||
@ -85,7 +85,7 @@ public:
|
||||
return (DefinedAtom::SectionPosition)(
|
||||
attributes().sectionChoiceAndPosition & 0xF);
|
||||
}
|
||||
|
||||
|
||||
virtual DefinedAtom::DeadStripKind deadStrip() const {
|
||||
return (DefinedAtom::DeadStripKind)(attributes().deadStrip);
|
||||
}
|
||||
@ -324,19 +324,19 @@ public:
|
||||
}
|
||||
}
|
||||
// TO DO: validate enough chunks were used
|
||||
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
<< " ReaderNative DefinedAtoms:\n");
|
||||
for (const DefinedAtom *a : file->defined() ) {
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
<< llvm::format(" 0x%09lX", a)
|
||||
<< ", name=" << a->name()
|
||||
<< ", size=" << a->size()
|
||||
<< "\n");
|
||||
for (const Reference *r : *a ) {
|
||||
(void)r;
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
<< " offset="
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
<< " offset="
|
||||
<< llvm::format("0x%03X", r->offsetInAtom())
|
||||
<< ", kind=" << r->kind()
|
||||
<< ", target=" << r->target()
|
||||
@ -411,7 +411,7 @@ private:
|
||||
this->_definedAtoms._arrayEnd = atomsEnd;
|
||||
this->_definedAtoms._elementSize = atomSize;
|
||||
this->_definedAtoms._elementCount = chunk->elementCount;
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
<< " chunk DefinedAtomsV1: "
|
||||
<< " count=" << chunk->elementCount
|
||||
<< " chunkSize=" << chunk->fileSize
|
||||
@ -426,7 +426,7 @@ private:
|
||||
const NativeChunk *chunk) {
|
||||
this->_attributes = base + chunk->fileOffset;
|
||||
this->_attributesMaxOffset = chunk->fileSize;
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
<< " chunk AttributesV1: "
|
||||
<< " count=" << chunk->elementCount
|
||||
<< " chunkSize=" << chunk->fileSize
|
||||
@ -439,7 +439,7 @@ private:
|
||||
const NativeChunk *chunk) {
|
||||
this->_absAttributes = base + chunk->fileOffset;
|
||||
this->_absAbsoluteMaxOffset = chunk->fileSize;
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
<< " chunk AbsoluteAttributesV1: "
|
||||
<< " count=" << chunk->elementCount
|
||||
<< " chunkSize=" << chunk->fileSize
|
||||
@ -474,7 +474,7 @@ private:
|
||||
this->_undefinedAtoms._arrayEnd = atomsEnd;
|
||||
this->_undefinedAtoms._elementSize = atomSize;
|
||||
this->_undefinedAtoms._elementCount = chunk->elementCount;
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
<< " chunk UndefinedAtomsV1:"
|
||||
<< " count=" << chunk->elementCount
|
||||
<< " chunkSize=" << chunk->fileSize
|
||||
@ -510,7 +510,7 @@ private:
|
||||
this->_sharedLibraryAtoms._arrayEnd = atomsEnd;
|
||||
this->_sharedLibraryAtoms._elementSize = atomSize;
|
||||
this->_sharedLibraryAtoms._elementCount = chunk->elementCount;
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
<< " chunk SharedLibraryAtomsV1:"
|
||||
<< " count=" << chunk->elementCount
|
||||
<< " chunkSize=" << chunk->fileSize
|
||||
@ -546,7 +546,7 @@ private:
|
||||
this->_absoluteAtoms._arrayEnd = atomsEnd;
|
||||
this->_absoluteAtoms._elementSize = atomSize;
|
||||
this->_absoluteAtoms._elementCount = chunk->elementCount;
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
<< " chunk AbsoluteAtomsV1: "
|
||||
<< " count=" << chunk->elementCount
|
||||
<< " chunkSize=" << chunk->fileSize
|
||||
@ -586,7 +586,7 @@ private:
|
||||
this->_references.arrayEnd = refsEnd;
|
||||
this->_references.elementSize = refSize;
|
||||
this->_references.elementCount = chunk->elementCount;
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
<< " chunk ReferencesV1: "
|
||||
<< " count=" << chunk->elementCount
|
||||
<< " chunkSize=" << chunk->fileSize
|
||||
@ -635,7 +635,7 @@ private:
|
||||
}
|
||||
return make_error_code(native_reader_error::file_malformed);
|
||||
}
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
<< " chunk Targets Table: "
|
||||
<< " count=" << chunk->elementCount
|
||||
<< " chunkSize=" << chunk->fileSize
|
||||
@ -650,7 +650,7 @@ private:
|
||||
this->_addends = reinterpret_cast<const Reference::Addend*>
|
||||
(base + chunk->fileOffset);
|
||||
this->_addendsMaxIndex = chunk->elementCount;
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
<< " chunk Addends: "
|
||||
<< " count=" << chunk->elementCount
|
||||
<< " chunkSize=" << chunk->fileSize
|
||||
@ -663,7 +663,7 @@ private:
|
||||
const NativeChunk *chunk) {
|
||||
this->_strings = reinterpret_cast<const char*>(base + chunk->fileOffset);
|
||||
this->_stringsMaxOffset = chunk->fileSize;
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
<< " chunk Strings: "
|
||||
<< " chunkSize=" << chunk->fileSize
|
||||
<< "\n");
|
||||
@ -675,7 +675,7 @@ private:
|
||||
const NativeChunk *chunk) {
|
||||
this->_contentStart = base + chunk->fileOffset;
|
||||
this->_contentEnd = base + chunk->fileOffset + chunk->fileSize;
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("ReaderNative", llvm::dbgs()
|
||||
<< " chunk content: "
|
||||
<< " chunkSize=" << chunk->fileSize
|
||||
<< "\n");
|
||||
@ -823,7 +823,7 @@ inline const NativeAtomAttributesV1& NativeDefinedAtomV1::attributes() const {
|
||||
|
||||
inline ArrayRef<uint8_t> NativeDefinedAtomV1::rawContent() const {
|
||||
if (( this->contentType() == DefinedAtom::typeZeroFill ) ||
|
||||
( this->contentType() == DefinedAtom::typeZeroFillFast))
|
||||
( this->contentType() == DefinedAtom::typeZeroFillFast))
|
||||
return ArrayRef<uint8_t>();
|
||||
const uint8_t* p = _file->content(_ivarData->contentOffset,
|
||||
_ivarData->contentSize);
|
||||
|
||||
@ -29,7 +29,7 @@ namespace native {
|
||||
class Writer : public lld::Writer {
|
||||
public:
|
||||
Writer(const TargetInfo &ti) {}
|
||||
|
||||
|
||||
virtual error_code writeFile(const lld::File &file, StringRef outPath) {
|
||||
// reserve first byte for unnamed atoms
|
||||
_stringPool.push_back('\0');
|
||||
@ -49,7 +49,7 @@ public:
|
||||
|
||||
// construct file header based on atom information accumulated
|
||||
this->makeHeader();
|
||||
|
||||
|
||||
std::string errorInfo;
|
||||
llvm::raw_fd_ostream out(outPath.data(), errorInfo,
|
||||
llvm::raw_fd_ostream::F_Binary);
|
||||
@ -57,7 +57,7 @@ public:
|
||||
return error_code::success(); // FIXME
|
||||
|
||||
this->write(out);
|
||||
|
||||
|
||||
return error_code::success();
|
||||
}
|
||||
|
||||
@ -437,7 +437,7 @@ private:
|
||||
attrs.interposable = atom.interposable();
|
||||
attrs.merge = atom.merge();
|
||||
attrs.contentType = atom.contentType();
|
||||
attrs.sectionChoiceAndPosition
|
||||
attrs.sectionChoiceAndPosition
|
||||
= atom.sectionChoice() << 4 | atom.sectionPosition();
|
||||
attrs.deadStrip = atom.deadStrip();
|
||||
attrs.permissions = atom.permissions();
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
using llvm::object::coff_symbol;
|
||||
using namespace lld;
|
||||
|
||||
namespace { // anonymous
|
||||
namespace { // anonymous
|
||||
|
||||
class COFFAbsoluteAtom : public AbsoluteAtom {
|
||||
public:
|
||||
|
||||
@ -23,8 +23,8 @@ error_code Reader::readFile(StringRef path,
|
||||
OwningPtr<llvm::MemoryBuffer> opmb;
|
||||
if (error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, opmb))
|
||||
return ec;
|
||||
|
||||
|
||||
std::unique_ptr<MemoryBuffer> mb(opmb.take());
|
||||
return this->parseFile(std::move(mb), result);
|
||||
}
|
||||
} // end namespace lld
|
||||
} // end namespace lld
|
||||
|
||||
@ -32,7 +32,7 @@ public:
|
||||
return nullptr;
|
||||
|
||||
llvm::object::Archive::child_iterator ci = member->second;
|
||||
|
||||
|
||||
if (dataSymbolOnly) {
|
||||
OwningPtr<MemoryBuffer> buff;
|
||||
if (ci->getMemoryBuffer(buff, true))
|
||||
@ -40,7 +40,7 @@ public:
|
||||
if (isDataSymbol(buff.take(), name))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::unique_ptr<File>> result;
|
||||
|
||||
OwningPtr<MemoryBuffer> buff;
|
||||
@ -53,7 +53,7 @@ public:
|
||||
assert(result.size() == 1);
|
||||
|
||||
// TO DO: set ordinal of child just loaded
|
||||
|
||||
|
||||
// give up the pointer so that this object no longer manages it
|
||||
return result[0].release();
|
||||
}
|
||||
@ -61,7 +61,7 @@ public:
|
||||
virtual void setOrdinalAndIncrement(uint64_t &ordinal) const {
|
||||
_ordinal = ordinal++;
|
||||
// Leave space in ordinal range for all children
|
||||
for (auto mf = _archive->begin_children(),
|
||||
for (auto mf = _archive->begin_children(),
|
||||
me = _archive->end_children(); mf != me; ++mf) {
|
||||
ordinal++;
|
||||
}
|
||||
@ -85,7 +85,7 @@ public:
|
||||
|
||||
protected:
|
||||
error_code isDataSymbol(MemoryBuffer *mb, StringRef symbol) const {
|
||||
std::unique_ptr<llvm::object::ObjectFile>
|
||||
std::unique_ptr<llvm::object::ObjectFile>
|
||||
obj(llvm::object::ObjectFile::createObjectFile(mb));
|
||||
error_code ec;
|
||||
llvm::object::SymbolRef::Type symtype;
|
||||
@ -96,22 +96,22 @@ protected:
|
||||
|
||||
for (llvm::object::symbol_iterator i = ibegin; i != iend; i.increment(ec)) {
|
||||
if (ec) return ec;
|
||||
|
||||
|
||||
// Get symbol name
|
||||
if ((ec = (i->getName(symbolname)))) return ec;
|
||||
|
||||
if (symbolname != symbol)
|
||||
|
||||
if (symbolname != symbol)
|
||||
continue;
|
||||
|
||||
|
||||
// Get symbol flags
|
||||
if ((ec = (i->getFlags(symflags)))) return ec;
|
||||
|
||||
|
||||
if (symflags <= llvm::object::SymbolRef::SF_Undefined)
|
||||
continue;
|
||||
|
||||
|
||||
// Get Symbol Type
|
||||
if ((ec = (i->getType(symtype)))) return ec;
|
||||
|
||||
|
||||
if (symtype == llvm::object::SymbolRef::ST_Data) {
|
||||
return error_code::success();
|
||||
}
|
||||
@ -128,7 +128,7 @@ private:
|
||||
atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
|
||||
|
||||
public:
|
||||
/// only subclasses of ArchiveLibraryFile can be instantiated
|
||||
/// only subclasses of ArchiveLibraryFile can be instantiated
|
||||
FileArchive(const TargetInfo &ti,
|
||||
std::function<ErrorOr<Reader &>(const LinkerInput &)> getReader,
|
||||
std::unique_ptr<llvm::MemoryBuffer> mb, error_code &ec)
|
||||
@ -156,18 +156,18 @@ public:
|
||||
std::unordered_map<StringRef, llvm::object::Archive::child_iterator> _symbolMemberMap;
|
||||
}; // class FileArchive
|
||||
|
||||
// Returns a vector of Files that are contained in the archive file
|
||||
// Returns a vector of Files that are contained in the archive file
|
||||
// pointed to by the MemoryBuffer
|
||||
error_code ReaderArchive::parseFile(std::unique_ptr<llvm::MemoryBuffer> mb,
|
||||
std::vector<std::unique_ptr<File>> &result){
|
||||
error_code ec;
|
||||
|
||||
|
||||
if (_options._forceLoadArchives) {
|
||||
_archive.reset(new llvm::object::Archive(mb.release(), ec));
|
||||
if (ec)
|
||||
return ec;
|
||||
|
||||
for (auto mf = _archive->begin_children(),
|
||||
|
||||
for (auto mf = _archive->begin_children(),
|
||||
me = _archive->end_children(); mf != me; ++mf) {
|
||||
OwningPtr<MemoryBuffer> buff;
|
||||
if ((ec = mf->getMemoryBuffer(buff, true)))
|
||||
|
||||
@ -49,7 +49,7 @@ using namespace lld;
|
||||
namespace {
|
||||
/// Most of the traits are context-free and always do the same transformation.
|
||||
/// But, there are some traits that need some contextual information to properly
|
||||
/// do their transform. This struct is available via io.getContext() and
|
||||
/// do their transform. This struct is available via io.getContext() and
|
||||
/// supplies contextual information.
|
||||
class ContextInfo {
|
||||
public:
|
||||
@ -72,7 +72,7 @@ public:
|
||||
/// ref-name is added.
|
||||
class RefNameBuilder {
|
||||
public:
|
||||
RefNameBuilder(const lld::File &file)
|
||||
RefNameBuilder(const lld::File &file)
|
||||
: _collisionCount(0), _unnamedCounter(0) {
|
||||
if (&file == nullptr)
|
||||
return;
|
||||
@ -92,9 +92,9 @@ public:
|
||||
buffer << llvm::format("L%03d", _unnamedCounter++);
|
||||
llvm::StringRef newName = copyString(buffer.str());
|
||||
_refNames[target] = newName;
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
<< "unnamed atom: creating ref-name: '" << newName
|
||||
<< "' (" << (void*)newName.data() << ", "
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
<< "unnamed atom: creating ref-name: '" << newName
|
||||
<< "' (" << (void*)newName.data() << ", "
|
||||
<< newName.size() << ")\n");
|
||||
}
|
||||
}
|
||||
@ -109,7 +109,7 @@ public:
|
||||
buildDuplicateNameMap(*absAtom);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void buildDuplicateNameMap(const lld::Atom &atom) {
|
||||
assert(!atom.name().empty());
|
||||
NameToAtom::iterator pos = _nameMap.find(atom.name());
|
||||
@ -120,9 +120,9 @@ public:
|
||||
buffer << atom.name() << llvm::format(".%03d", ++_collisionCount);
|
||||
llvm::StringRef newName = copyString(buffer.str());
|
||||
_refNames[&atom] = newName;
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
<< "name collsion: creating ref-name: '" << newName
|
||||
<< "' (" << (void*)newName.data() << ", "
|
||||
<< "' (" << (void*)newName.data() << ", "
|
||||
<< newName.size() << ")\n");
|
||||
const lld::Atom *prevAtom = pos->second;
|
||||
AtomToRefName::iterator pos2 = _refNames.find(prevAtom);
|
||||
@ -133,18 +133,18 @@ public:
|
||||
buffer2 << prevAtom->name() << llvm::format(".%03d", ++_collisionCount);
|
||||
llvm::StringRef newName2 = copyString(buffer2.str());
|
||||
_refNames[prevAtom] = newName2;
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
<< "name collsion: creating ref-name: '" << newName2
|
||||
<< "' (" << (void*)newName2.data() << ", "
|
||||
<< "' (" << (void*)newName2.data() << ", "
|
||||
<< newName2.size() << ")\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
// First time we've seen this name, just add it to map.
|
||||
_nameMap[atom.name()] = &atom;
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
<< "atom name seen for first time: '" << atom.name()
|
||||
<< "' (" << (void*)atom.name().data() << ", "
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
<< "atom name seen for first time: '" << atom.name()
|
||||
<< "' (" << (void*)atom.name().data() << ", "
|
||||
<< atom.name().size() << ")\n");
|
||||
}
|
||||
}
|
||||
@ -173,7 +173,7 @@ private:
|
||||
_stringCopies.push_back(std::move(s));
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
unsigned int _collisionCount;
|
||||
unsigned int _unnamedCounter;
|
||||
NameToAtom _nameMap;
|
||||
@ -187,7 +187,7 @@ private:
|
||||
class RefNameResolver {
|
||||
public:
|
||||
RefNameResolver(const lld::File *file, IO &io);
|
||||
|
||||
|
||||
const lld::Atom *lookup(llvm::StringRef name) const {
|
||||
NameToAtom::const_iterator pos = _nameMap.find(name);
|
||||
if (pos != _nameMap.end()) {
|
||||
@ -201,12 +201,12 @@ public:
|
||||
|
||||
private:
|
||||
typedef llvm::StringMap<const lld::Atom*> NameToAtom;
|
||||
|
||||
|
||||
void add(llvm::StringRef name, const lld::Atom *atom) {
|
||||
if (_nameMap.count(name)) {
|
||||
_io.setError(llvm::Twine("duplicate atom name: ") + name);
|
||||
}
|
||||
else {
|
||||
else {
|
||||
_nameMap[name] = atom;
|
||||
}
|
||||
}
|
||||
@ -245,7 +245,7 @@ public:
|
||||
};
|
||||
|
||||
/// Mapping of kind: field in yaml files.
|
||||
enum FileKinds {
|
||||
enum FileKinds {
|
||||
fileKindObjectAtoms, // atom based object file encoded in yaml
|
||||
fileKindArchive, // static archive library encoded in yaml
|
||||
fileKindObjectELF, // ELF object files encoded in yaml
|
||||
@ -279,12 +279,12 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(ArchMember)
|
||||
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(ImplicitHex8)
|
||||
// for compatibility with gcc-4.7 in C++11 mode, add extra namespace
|
||||
namespace llvm {
|
||||
namespace yaml {
|
||||
namespace yaml {
|
||||
|
||||
// This is a custom formatter for RefKind
|
||||
template<>
|
||||
struct ScalarTraits<RefKind> {
|
||||
static void output(const RefKind &value, void *ctxt,
|
||||
static void output(const RefKind &value, void *ctxt,
|
||||
llvm::raw_ostream &out) {
|
||||
assert(ctxt != nullptr);
|
||||
ContextInfo *info = reinterpret_cast<ContextInfo*>(ctxt);
|
||||
@ -327,7 +327,7 @@ struct ScalarEnumerationTraits<lld::DefinedAtom::SectionChoice> {
|
||||
static void enumeration(IO &io, lld::DefinedAtom::SectionChoice &value) {
|
||||
io.enumCase(value, "content", lld::DefinedAtom::sectionBasedOnContent);
|
||||
io.enumCase(value, "custom", lld::DefinedAtom::sectionCustomPreferred);
|
||||
io.enumCase(value, "custom-required",
|
||||
io.enumCase(value, "custom-required",
|
||||
lld::DefinedAtom::sectionCustomRequired);
|
||||
}
|
||||
};
|
||||
@ -347,7 +347,7 @@ struct ScalarEnumerationTraits<lld::DefinedAtom::Interposable> {
|
||||
static void enumeration(IO &io, lld::DefinedAtom::Interposable &value) {
|
||||
io.enumCase(value, "no", lld::DefinedAtom::interposeNo);
|
||||
io.enumCase(value, "yes", lld::DefinedAtom::interposeYes);
|
||||
io.enumCase(value, "yes-and-weak",
|
||||
io.enumCase(value, "yes-and-weak",
|
||||
lld::DefinedAtom::interposeYesAndRuntimeWeak);
|
||||
}
|
||||
};
|
||||
@ -358,7 +358,7 @@ struct ScalarEnumerationTraits<lld::DefinedAtom::Merge> {
|
||||
io.enumCase(value, "no", lld::DefinedAtom::mergeNo);
|
||||
io.enumCase(value, "as-tentative", lld::DefinedAtom::mergeAsTentative);
|
||||
io.enumCase(value, "as-weak", lld::DefinedAtom::mergeAsWeak);
|
||||
io.enumCase(value, "as-addressed-weak",
|
||||
io.enumCase(value, "as-addressed-weak",
|
||||
lld::DefinedAtom::mergeAsWeakAndAddressUsed);
|
||||
io.enumCase(value, "by-content", lld::DefinedAtom::mergeByContent);
|
||||
}
|
||||
@ -388,12 +388,12 @@ struct ScalarEnumerationTraits<lld::DefinedAtom::ContentPermissions> {
|
||||
|
||||
template <>
|
||||
struct ScalarEnumerationTraits<lld::DefinedAtom::ContentType> {
|
||||
static void enumeration(IO &io, lld::DefinedAtom::ContentType &value) {
|
||||
io.enumCase(value, "unknown",
|
||||
static void enumeration(IO &io, lld::DefinedAtom::ContentType &value) {
|
||||
io.enumCase(value, "unknown",
|
||||
lld::DefinedAtom::typeUnknown);
|
||||
io.enumCase(value, "code",
|
||||
io.enumCase(value, "code",
|
||||
lld::DefinedAtom::typeCode);
|
||||
io.enumCase(value, "stub",
|
||||
io.enumCase(value, "stub",
|
||||
lld::DefinedAtom::typeStub);
|
||||
io.enumCase(value, "constant", lld::DefinedAtom::typeConstant);
|
||||
io.enumCase(value, "data", lld::DefinedAtom::typeData);
|
||||
@ -401,61 +401,61 @@ struct ScalarEnumerationTraits<lld::DefinedAtom::ContentType> {
|
||||
io.enumCase(value, "zero-fill", lld::DefinedAtom::typeZeroFill);
|
||||
io.enumCase(value, "zero-fill-quick", lld::DefinedAtom::typeZeroFillFast);
|
||||
io.enumCase(value, "const-data", lld::DefinedAtom::typeConstData);
|
||||
io.enumCase(value, "got",
|
||||
io.enumCase(value, "got",
|
||||
lld::DefinedAtom::typeGOT);
|
||||
io.enumCase(value, "resolver",
|
||||
io.enumCase(value, "resolver",
|
||||
lld::DefinedAtom::typeResolver);
|
||||
io.enumCase(value, "branch-island",
|
||||
io.enumCase(value, "branch-island",
|
||||
lld::DefinedAtom::typeBranchIsland);
|
||||
io.enumCase(value, "branch-shim",
|
||||
io.enumCase(value, "branch-shim",
|
||||
lld::DefinedAtom::typeBranchShim);
|
||||
io.enumCase(value, "stub-helper",
|
||||
io.enumCase(value, "stub-helper",
|
||||
lld::DefinedAtom::typeStubHelper);
|
||||
io.enumCase(value, "c-string",
|
||||
io.enumCase(value, "c-string",
|
||||
lld::DefinedAtom::typeCString);
|
||||
io.enumCase(value, "utf16-string",
|
||||
io.enumCase(value, "utf16-string",
|
||||
lld::DefinedAtom::typeUTF16String);
|
||||
io.enumCase(value, "unwind-cfi",
|
||||
io.enumCase(value, "unwind-cfi",
|
||||
lld::DefinedAtom::typeCFI);
|
||||
io.enumCase(value, "unwind-lsda",
|
||||
io.enumCase(value, "unwind-lsda",
|
||||
lld::DefinedAtom::typeLSDA);
|
||||
io.enumCase(value, "const-4-byte",
|
||||
io.enumCase(value, "const-4-byte",
|
||||
lld::DefinedAtom::typeLiteral4);
|
||||
io.enumCase(value, "const-8-byte",
|
||||
io.enumCase(value, "const-8-byte",
|
||||
lld::DefinedAtom::typeLiteral8);
|
||||
io.enumCase(value, "const-16-byte",
|
||||
io.enumCase(value, "const-16-byte",
|
||||
lld::DefinedAtom::typeLiteral16);
|
||||
io.enumCase(value, "lazy-pointer",
|
||||
io.enumCase(value, "lazy-pointer",
|
||||
lld::DefinedAtom::typeLazyPointer);
|
||||
io.enumCase(value, "lazy-dylib-pointer",
|
||||
io.enumCase(value, "lazy-dylib-pointer",
|
||||
lld::DefinedAtom::typeLazyDylibPointer);
|
||||
io.enumCase(value, "cfstring",
|
||||
io.enumCase(value, "cfstring",
|
||||
lld::DefinedAtom::typeCFString);
|
||||
io.enumCase(value, "initializer-pointer",
|
||||
io.enumCase(value, "initializer-pointer",
|
||||
lld::DefinedAtom::typeInitializerPtr);
|
||||
io.enumCase(value, "terminator-pointer",
|
||||
io.enumCase(value, "terminator-pointer",
|
||||
lld::DefinedAtom::typeTerminatorPtr);
|
||||
io.enumCase(value, "c-string-pointer",
|
||||
io.enumCase(value, "c-string-pointer",
|
||||
lld::DefinedAtom::typeCStringPtr);
|
||||
io.enumCase(value, "objc-class-pointer",
|
||||
io.enumCase(value, "objc-class-pointer",
|
||||
lld::DefinedAtom::typeObjCClassPtr);
|
||||
io.enumCase(value, "objc-category-list",
|
||||
io.enumCase(value, "objc-category-list",
|
||||
lld::DefinedAtom::typeObjC2CategoryList);
|
||||
io.enumCase(value, "objc-class1",
|
||||
io.enumCase(value, "objc-class1",
|
||||
lld::DefinedAtom::typeObjC1Class);
|
||||
io.enumCase(value, "dtraceDOF",
|
||||
io.enumCase(value, "dtraceDOF",
|
||||
lld::DefinedAtom::typeDTraceDOF);
|
||||
io.enumCase(value, "lto-temp",
|
||||
io.enumCase(value, "lto-temp",
|
||||
lld::DefinedAtom::typeTempLTO);
|
||||
io.enumCase(value, "compact-unwind",
|
||||
io.enumCase(value, "compact-unwind",
|
||||
lld::DefinedAtom::typeCompactUnwindInfo);
|
||||
io.enumCase(value, "tlv-thunk",
|
||||
io.enumCase(value, "tlv-thunk",
|
||||
lld::DefinedAtom::typeThunkTLV);
|
||||
io.enumCase(value, "tlv-data",
|
||||
io.enumCase(value, "tlv-data",
|
||||
lld::DefinedAtom::typeTLVInitialData);
|
||||
io.enumCase(value, "tlv-zero-fill",
|
||||
io.enumCase(value, "tlv-zero-fill",
|
||||
lld::DefinedAtom::typeTLVInitialZeroFill);
|
||||
io.enumCase(value, "tlv-initializer-ptr",
|
||||
io.enumCase(value, "tlv-initializer-ptr",
|
||||
lld::DefinedAtom::typeTLVInitializerPtr);
|
||||
}
|
||||
};
|
||||
@ -481,12 +481,12 @@ struct ScalarEnumerationTraits<ShlibCanBeNull> {
|
||||
|
||||
|
||||
/// This is a custom formatter for lld::DefinedAtom::Alignment. Values look
|
||||
/// like:
|
||||
/// like:
|
||||
/// 2^3 # 8-byte aligned
|
||||
/// 7 mod 2^4 # 16-byte aligned plus 7 bytes
|
||||
template<>
|
||||
struct ScalarTraits<lld::DefinedAtom::Alignment> {
|
||||
static void output(const lld::DefinedAtom::Alignment &value, void *ctxt,
|
||||
static void output(const lld::DefinedAtom::Alignment &value, void *ctxt,
|
||||
llvm::raw_ostream &out) {
|
||||
if (value.modulus == 0) {
|
||||
out << llvm::format("2^%d", value.powerOf2);
|
||||
@ -496,7 +496,7 @@ struct ScalarTraits<lld::DefinedAtom::Alignment> {
|
||||
}
|
||||
}
|
||||
|
||||
static StringRef input(StringRef scalar, void *ctxt,
|
||||
static StringRef input(StringRef scalar, void *ctxt,
|
||||
lld::DefinedAtom::Alignment &value) {
|
||||
value.modulus = 0;
|
||||
size_t modStart = scalar.find("mod");
|
||||
@ -564,7 +564,7 @@ struct SequenceTraits<AtomList<T>> {
|
||||
}
|
||||
};
|
||||
|
||||
// Used to allow DefinedAtom content bytes to be a flow sequence of
|
||||
// Used to allow DefinedAtom content bytes to be a flow sequence of
|
||||
// two-digit hex numbers without the leading 0x (e.g. FF, 04, 0A)
|
||||
template<>
|
||||
struct ScalarTraits<ImplicitHex8> {
|
||||
@ -591,7 +591,7 @@ struct DocumentListTraits< std::vector<const lld::File*> > {
|
||||
static size_t size(IO &io, std::vector<const lld::File*> &seq) {
|
||||
return seq.size();
|
||||
}
|
||||
static const lld::File *&element(IO &io, std::vector<const lld::File*> &seq,
|
||||
static const lld::File *&element(IO &io, std::vector<const lld::File*> &seq,
|
||||
size_t index) {
|
||||
if (index >= seq.size())
|
||||
seq.resize(index+1);
|
||||
@ -630,7 +630,7 @@ struct MappingTraits<const lld::File*> {
|
||||
member._content->setOrdinalAndIncrement(ordinal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual const atom_collection<lld::DefinedAtom> &defined() const {
|
||||
return _noDefinedAtoms;
|
||||
}
|
||||
@ -661,7 +661,7 @@ struct MappingTraits<const lld::File*> {
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
StringRef _path;
|
||||
std::vector<ArchMember> _members;
|
||||
};
|
||||
@ -681,7 +681,7 @@ struct MappingTraits<const lld::File*> {
|
||||
for (const lld::AbsoluteAtom *a : file->absolute())
|
||||
_absoluteAtoms.push_back(a);
|
||||
}
|
||||
const lld::File *denormalize(IO &io);
|
||||
const lld::File *denormalize(IO &io);
|
||||
|
||||
virtual const atom_collection<lld::DefinedAtom> &defined() const {
|
||||
return _definedAtoms;
|
||||
@ -726,10 +726,10 @@ struct MappingTraits<const lld::File*> {
|
||||
|
||||
static void mapping(IO &io, const lld::File *&file) {
|
||||
// We only support writing atom based YAML
|
||||
FileKinds kind = fileKindObjectAtoms;
|
||||
FileKinds kind = fileKindObjectAtoms;
|
||||
// If reading, peek ahead to see what kind of file this is.
|
||||
io.mapOptional("kind", kind, fileKindObjectAtoms);
|
||||
//
|
||||
//
|
||||
switch (kind) {
|
||||
case fileKindObjectAtoms:
|
||||
mappingAtoms(io, file);
|
||||
@ -745,7 +745,7 @@ struct MappingTraits<const lld::File*> {
|
||||
llvm_unreachable("section based YAML not supported yet");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void mappingAtoms(IO &io, const lld::File *&file) {
|
||||
MappingNormalizationHeap<NormalizedFile, const lld::File*> keys(io, file);
|
||||
ContextInfo *info = reinterpret_cast<ContextInfo*>(io.getContext());
|
||||
@ -758,14 +758,14 @@ struct MappingTraits<const lld::File*> {
|
||||
io.mapOptional("shared-library-atoms", keys->_sharedLibraryAtoms);
|
||||
io.mapOptional("absolute-atoms", keys->_absoluteAtoms);
|
||||
}
|
||||
|
||||
|
||||
static void mappingArchive(IO &io, const lld::File *&file) {
|
||||
MappingNormalizationHeap<NormArchiveFile, const lld::File*> keys(io, file);
|
||||
|
||||
io.mapOptional("path", keys->_path);
|
||||
io.mapOptional("members", keys->_members);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -780,9 +780,9 @@ struct MappingTraits<const lld::Reference*> {
|
||||
: _target(nullptr), _targetName(), _offset(0), _addend(0) , _kind(0) {
|
||||
}
|
||||
NormalizedReference(IO &io, const lld::Reference *ref)
|
||||
: _target(nullptr),
|
||||
_targetName(targetName(io, ref)),
|
||||
_offset(ref->offsetInAtom()),
|
||||
: _target(nullptr),
|
||||
_targetName(targetName(io, ref)),
|
||||
_offset(ref->offsetInAtom()),
|
||||
_addend(ref->addend()),
|
||||
_kind(ref->kind()) {
|
||||
}
|
||||
@ -793,15 +793,15 @@ struct MappingTraits<const lld::Reference*> {
|
||||
NormalizedFile *f = reinterpret_cast<NormalizedFile*>(info->_currentFile);
|
||||
if (!_targetName.empty())
|
||||
_targetName = f->copyString(_targetName);
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
<< "created Reference to name: '" << _targetName
|
||||
<< "' (" << (void*)_targetName.data() << ", "
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
<< "created Reference to name: '" << _targetName
|
||||
<< "' (" << (void*)_targetName.data() << ", "
|
||||
<< _targetName.size() << ")\n");
|
||||
return this;
|
||||
}
|
||||
void bind(const RefNameResolver&);
|
||||
static StringRef targetName(IO &io, const lld::Reference *ref);
|
||||
|
||||
|
||||
virtual uint64_t offsetInAtom() const { return _offset; }
|
||||
virtual Kind kind() const { return _kind; }
|
||||
virtual const lld::Atom *target() const { return _target; }
|
||||
@ -809,7 +809,7 @@ struct MappingTraits<const lld::Reference*> {
|
||||
virtual void setKind(Kind k) { _kind = k; }
|
||||
virtual void setAddend(Addend a) { _addend = a; }
|
||||
virtual void setTarget(const lld::Atom *a) { _target = a; }
|
||||
|
||||
|
||||
const lld::Atom *_target;
|
||||
StringRef _targetName;
|
||||
uint32_t _offset;
|
||||
@ -819,7 +819,7 @@ struct MappingTraits<const lld::Reference*> {
|
||||
|
||||
|
||||
static void mapping(IO &io, const lld::Reference *&ref) {
|
||||
MappingNormalizationHeap<NormalizedReference,
|
||||
MappingNormalizationHeap<NormalizedReference,
|
||||
const lld::Reference*> keys(io, ref);
|
||||
|
||||
io.mapRequired("kind", keys->_kind);
|
||||
@ -838,7 +838,7 @@ struct MappingTraits<const lld::DefinedAtom*> {
|
||||
class NormalizedAtom : public lld::DefinedAtom {
|
||||
public:
|
||||
NormalizedAtom(IO &io)
|
||||
: _file(fileFromContext(io)), _name(), _refName(),
|
||||
: _file(fileFromContext(io)), _name(), _refName(),
|
||||
_alignment(0), _content(), _references() {
|
||||
static uint32_t ordinalCounter = 1;
|
||||
_ordinal = ordinalCounter++;
|
||||
@ -858,7 +858,7 @@ struct MappingTraits<const lld::DefinedAtom*> {
|
||||
_permissions(atom->permissions()),
|
||||
_size(atom->size()),
|
||||
_sectionName(atom->customSectionName()) {
|
||||
for ( const lld::Reference *r : *atom )
|
||||
for ( const lld::Reference *r : *atom )
|
||||
_references.push_back(r);
|
||||
ArrayRef<uint8_t> cont = atom->rawContent();
|
||||
_content.reserve(cont.size());
|
||||
@ -876,9 +876,9 @@ struct MappingTraits<const lld::DefinedAtom*> {
|
||||
_refName = f->copyString(_refName);
|
||||
if ( !_sectionName.empty() )
|
||||
_sectionName = f->copyString(_sectionName);
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
<< "created DefinedAtom named: '" << _name
|
||||
<< "' (" << (void*)_name.data() << ", "
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
<< "created DefinedAtom named: '" << _name
|
||||
<< "' (" << (void*)_name.data() << ", "
|
||||
<< _name.size() << ")\n");
|
||||
return this;
|
||||
}
|
||||
@ -912,18 +912,18 @@ struct MappingTraits<const lld::DefinedAtom*> {
|
||||
}
|
||||
|
||||
virtual uint64_t ordinal() const { return _ordinal; }
|
||||
|
||||
reference_iterator begin() const {
|
||||
|
||||
reference_iterator begin() const {
|
||||
uintptr_t index = 0;
|
||||
const void *it = reinterpret_cast<const void*>(index);
|
||||
return reference_iterator(*this, it);
|
||||
}
|
||||
reference_iterator end() const {
|
||||
reference_iterator end() const {
|
||||
uintptr_t index = _references.size();
|
||||
const void *it = reinterpret_cast<const void*>(index);
|
||||
return reference_iterator(*this, it);
|
||||
}
|
||||
const lld::Reference *derefIterator(const void *it) const {
|
||||
const lld::Reference *derefIterator(const void *it) const {
|
||||
uintptr_t index = reinterpret_cast<uintptr_t>(it);
|
||||
assert(index < _references.size());
|
||||
return _references[index];
|
||||
@ -952,9 +952,9 @@ struct MappingTraits<const lld::DefinedAtom*> {
|
||||
StringRef _sectionName;
|
||||
std::vector<const lld::Reference*> _references;
|
||||
};
|
||||
|
||||
|
||||
static void mapping(IO &io, const lld::DefinedAtom *&atom) {
|
||||
MappingNormalizationHeap<NormalizedAtom,
|
||||
MappingNormalizationHeap<NormalizedAtom,
|
||||
const lld::DefinedAtom*> keys(io, atom);
|
||||
if ( io.outputting() ) {
|
||||
// If writing YAML, check if atom needs a ref-name.
|
||||
@ -968,34 +968,34 @@ struct MappingTraits<const lld::DefinedAtom*> {
|
||||
keys->_refName = f->_rnb->refName(atom);
|
||||
}
|
||||
}
|
||||
|
||||
io.mapOptional("name", keys->_name,
|
||||
|
||||
io.mapOptional("name", keys->_name,
|
||||
StringRef());
|
||||
io.mapOptional("ref-name", keys->_refName,
|
||||
io.mapOptional("ref-name", keys->_refName,
|
||||
StringRef());
|
||||
io.mapOptional("scope", keys->_scope,
|
||||
io.mapOptional("scope", keys->_scope,
|
||||
lld::DefinedAtom::scopeTranslationUnit);
|
||||
io.mapOptional("type", keys->_contentType,
|
||||
io.mapOptional("type", keys->_contentType,
|
||||
lld::DefinedAtom::typeCode);
|
||||
io.mapOptional("content", keys->_content);
|
||||
io.mapOptional("size", keys->_size,
|
||||
io.mapOptional("size", keys->_size,
|
||||
(uint64_t)keys->_content.size());
|
||||
io.mapOptional("interposable", keys->_interpose,
|
||||
io.mapOptional("interposable", keys->_interpose,
|
||||
lld::DefinedAtom::interposeNo);
|
||||
io.mapOptional("merge", keys->_merge,
|
||||
io.mapOptional("merge", keys->_merge,
|
||||
lld::DefinedAtom::mergeNo);
|
||||
io.mapOptional("alignment", keys->_alignment,
|
||||
io.mapOptional("alignment", keys->_alignment,
|
||||
lld::DefinedAtom::Alignment(0));
|
||||
io.mapOptional("section-choice", keys->_sectionChoice,
|
||||
io.mapOptional("section-choice", keys->_sectionChoice,
|
||||
lld::DefinedAtom::sectionBasedOnContent);
|
||||
io.mapOptional("section-name", keys->_sectionName,
|
||||
io.mapOptional("section-name", keys->_sectionName,
|
||||
StringRef());
|
||||
io.mapOptional("section-position",keys->_sectionPosition,
|
||||
io.mapOptional("section-position",keys->_sectionPosition,
|
||||
lld::DefinedAtom::sectionPositionAny);
|
||||
io.mapOptional("dead-strip", keys->_deadStrip,
|
||||
io.mapOptional("dead-strip", keys->_deadStrip,
|
||||
lld::DefinedAtom::deadStripNormal);
|
||||
// default permissions based on content type
|
||||
io.mapOptional("permissions", keys->_permissions,
|
||||
io.mapOptional("permissions", keys->_permissions,
|
||||
lld::DefinedAtom::permissions(
|
||||
keys->_contentType));
|
||||
io.mapOptional("references", keys->_references);
|
||||
@ -1015,8 +1015,8 @@ struct MappingTraits<const lld::UndefinedAtom*> {
|
||||
: _file(fileFromContext(io)), _name(), _canBeNull(canBeNullNever) {
|
||||
}
|
||||
NormalizedAtom(IO &io, const lld::UndefinedAtom *atom)
|
||||
: _file(fileFromContext(io)),
|
||||
_name(atom->name()),
|
||||
: _file(fileFromContext(io)),
|
||||
_name(atom->name()),
|
||||
_canBeNull(atom->canBeNull()) {
|
||||
}
|
||||
const lld::UndefinedAtom *denormalize(IO &io) {
|
||||
@ -1027,9 +1027,9 @@ struct MappingTraits<const lld::UndefinedAtom*> {
|
||||
if ( !_name.empty() )
|
||||
_name = f->copyString(_name);
|
||||
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
<< "created UndefinedAtom named: '" << _name
|
||||
<< "' (" << (void*)_name.data() << ", "
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
<< "created UndefinedAtom named: '" << _name
|
||||
<< "' (" << (void*)_name.data() << ", "
|
||||
<< _name.size() << ")\n");
|
||||
return this;
|
||||
}
|
||||
@ -1044,7 +1044,7 @@ struct MappingTraits<const lld::UndefinedAtom*> {
|
||||
virtual const lld::File &file() const { return _file; }
|
||||
virtual StringRef name() const { return _name; }
|
||||
virtual CanBeNull canBeNull() const { return _canBeNull; }
|
||||
|
||||
|
||||
const lld::File &_file;
|
||||
StringRef _name;
|
||||
CanBeNull _canBeNull;
|
||||
@ -1052,11 +1052,11 @@ struct MappingTraits<const lld::UndefinedAtom*> {
|
||||
|
||||
|
||||
static void mapping(IO &io, const lld::UndefinedAtom* &atom) {
|
||||
MappingNormalizationHeap<NormalizedAtom,
|
||||
MappingNormalizationHeap<NormalizedAtom,
|
||||
const lld::UndefinedAtom*> keys(io, atom);
|
||||
|
||||
io.mapRequired("name", keys->_name);
|
||||
io.mapOptional("can-be-null", keys->_canBeNull,
|
||||
io.mapOptional("can-be-null", keys->_canBeNull,
|
||||
lld::UndefinedAtom::canBeNullNever);
|
||||
}
|
||||
};
|
||||
@ -1073,9 +1073,9 @@ struct MappingTraits<const lld::SharedLibraryAtom*> {
|
||||
: _file(fileFromContext(io)), _name(), _loadName(), _canBeNull(false) {
|
||||
}
|
||||
NormalizedAtom(IO &io, const lld::SharedLibraryAtom *atom)
|
||||
: _file(fileFromContext(io)),
|
||||
_name(atom->name()),
|
||||
_loadName(atom->loadName()),
|
||||
: _file(fileFromContext(io)),
|
||||
_name(atom->name()),
|
||||
_loadName(atom->loadName()),
|
||||
_canBeNull(atom->canBeNullAtRuntime()) {
|
||||
}
|
||||
const lld::SharedLibraryAtom *denormalize(IO &io) {
|
||||
@ -1088,9 +1088,9 @@ struct MappingTraits<const lld::SharedLibraryAtom*> {
|
||||
if ( !_loadName.empty() )
|
||||
_loadName = f->copyString(_loadName);
|
||||
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
<< "created SharedLibraryAtom named: '" << _name
|
||||
<< "' (" << (void*)_name.data() << ", "
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
<< "created SharedLibraryAtom named: '" << _name
|
||||
<< "' (" << (void*)_name.data() << ", "
|
||||
<< _name.size() << ")\n");
|
||||
return this;
|
||||
}
|
||||
@ -1106,7 +1106,7 @@ struct MappingTraits<const lld::SharedLibraryAtom*> {
|
||||
virtual StringRef name() const { return _name; }
|
||||
virtual StringRef loadName() const { return _loadName;}
|
||||
virtual bool canBeNullAtRuntime() const { return _canBeNull; }
|
||||
|
||||
|
||||
const lld::File &_file;
|
||||
StringRef _name;
|
||||
StringRef _loadName;
|
||||
@ -1115,13 +1115,13 @@ struct MappingTraits<const lld::SharedLibraryAtom*> {
|
||||
|
||||
|
||||
static void mapping(IO &io, const lld::SharedLibraryAtom *&atom) {
|
||||
|
||||
MappingNormalizationHeap<NormalizedAtom,
|
||||
|
||||
MappingNormalizationHeap<NormalizedAtom,
|
||||
const lld::SharedLibraryAtom*> keys(io, atom);
|
||||
|
||||
io.mapRequired("name", keys->_name);
|
||||
io.mapOptional("load-name", keys->_loadName);
|
||||
io.mapOptional("can-be-null", keys->_canBeNull,
|
||||
io.mapOptional("can-be-null", keys->_canBeNull,
|
||||
(ShlibCanBeNull)false);
|
||||
}
|
||||
};
|
||||
@ -1137,8 +1137,8 @@ struct MappingTraits<const lld::AbsoluteAtom*> {
|
||||
: _file(fileFromContext(io)), _name(), _scope(), _value(0) {
|
||||
}
|
||||
NormalizedAtom(IO &io, const lld::AbsoluteAtom *atom)
|
||||
: _file(fileFromContext(io)),
|
||||
_name(atom->name()),
|
||||
: _file(fileFromContext(io)),
|
||||
_name(atom->name()),
|
||||
_scope(atom->scope()),
|
||||
_value(atom->value()) {
|
||||
}
|
||||
@ -1149,10 +1149,10 @@ struct MappingTraits<const lld::AbsoluteAtom*> {
|
||||
NormalizedFile *f = reinterpret_cast<NormalizedFile*>(info->_currentFile);
|
||||
if ( !_name.empty() )
|
||||
_name = f->copyString(_name);
|
||||
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
<< "created AbsoluteAtom named: '" << _name
|
||||
<< "' (" << (void*)_name.data() << ", "
|
||||
|
||||
DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
|
||||
<< "created AbsoluteAtom named: '" << _name
|
||||
<< "' (" << (void*)_name.data() << ", "
|
||||
<< _name.size() << ")\n");
|
||||
return this;
|
||||
}
|
||||
@ -1168,7 +1168,7 @@ struct MappingTraits<const lld::AbsoluteAtom*> {
|
||||
virtual StringRef name() const { return _name; }
|
||||
virtual uint64_t value() const { return _value; }
|
||||
virtual Scope scope() const { return _scope; }
|
||||
|
||||
|
||||
const lld::File &_file;
|
||||
StringRef _name;
|
||||
StringRef _refName;
|
||||
@ -1178,7 +1178,7 @@ struct MappingTraits<const lld::AbsoluteAtom*> {
|
||||
|
||||
|
||||
static void mapping(IO &io, const lld::AbsoluteAtom *&atom) {
|
||||
MappingNormalizationHeap<NormalizedAtom,
|
||||
MappingNormalizationHeap<NormalizedAtom,
|
||||
const lld::AbsoluteAtom*> keys(io, atom);
|
||||
|
||||
if ( io.outputting() ) {
|
||||
@ -1201,7 +1201,7 @@ struct MappingTraits<const lld::AbsoluteAtom*> {
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
} // namespace yaml
|
||||
} // namespace yaml
|
||||
|
||||
|
||||
RefNameResolver::RefNameResolver(const lld::File *file, IO &io) : _io(io) {
|
||||
@ -1213,13 +1213,13 @@ RefNameResolver::RefNameResolver(const lld::File *file, IO &io) : _io(io) {
|
||||
else
|
||||
add(na->_refName, a);
|
||||
}
|
||||
|
||||
|
||||
for (const lld::UndefinedAtom *a : file->undefined() )
|
||||
add(a->name(), a);
|
||||
|
||||
|
||||
for (const lld::SharedLibraryAtom *a : file->sharedLibrary() )
|
||||
add(a->name(), a);
|
||||
|
||||
|
||||
typedef MappingTraits<const lld::AbsoluteAtom*>::NormalizedAtom NormAbsAtom;
|
||||
for (const lld::AbsoluteAtom *a : file->absolute() ) {
|
||||
NormAbsAtom *na = (NormAbsAtom*)a;
|
||||
@ -1232,11 +1232,11 @@ RefNameResolver::RefNameResolver(const lld::File *file, IO &io) : _io(io) {
|
||||
|
||||
|
||||
|
||||
inline
|
||||
inline
|
||||
const lld::File*
|
||||
MappingTraits<const lld::File*>::NormalizedFile::denormalize(IO &io) {
|
||||
typedef MappingTraits<const lld::DefinedAtom*>::NormalizedAtom NormalizedAtom;
|
||||
|
||||
|
||||
RefNameResolver nameResolver(this, io);
|
||||
// Now that all atoms are parsed, references can be bound.
|
||||
for (const lld::DefinedAtom *a : this->defined() ) {
|
||||
@ -1249,7 +1249,7 @@ MappingTraits<const lld::File*>::NormalizedFile::denormalize(IO &io) {
|
||||
inline
|
||||
void MappingTraits<const lld::DefinedAtom*>::
|
||||
NormalizedAtom::bind(const RefNameResolver &resolver) {
|
||||
typedef MappingTraits<const lld::Reference*>::NormalizedReference
|
||||
typedef MappingTraits<const lld::Reference*>::NormalizedReference
|
||||
NormalizedReference;
|
||||
for (const lld::Reference *ref : _references) {
|
||||
NormalizedReference *normRef = (NormalizedReference*)ref;
|
||||
@ -1274,7 +1274,7 @@ llvm::StringRef MappingTraits<const lld::Reference*>::NormalizedReference::
|
||||
typedef MappingTraits<const lld::File*>::NormalizedFile NormalizedFile;
|
||||
NormalizedFile *f = reinterpret_cast<NormalizedFile*>(info->_currentFile);
|
||||
RefNameBuilder *rnb = f->_rnb;
|
||||
if ( rnb->hasRefName(ref->target()) )
|
||||
if ( rnb->hasRefName(ref->target()) )
|
||||
return rnb->refName(ref->target());
|
||||
return ref->target()->name();
|
||||
}
|
||||
@ -1287,7 +1287,7 @@ namespace yaml {
|
||||
class Writer : public lld::Writer {
|
||||
public:
|
||||
Writer(const TargetInfo &ti) : _targetInfo(ti) {}
|
||||
|
||||
|
||||
virtual error_code writeFile(const lld::File &file, StringRef outPath) {
|
||||
// Create stream to path.
|
||||
std::string errorInfo;
|
||||
@ -1298,14 +1298,14 @@ public:
|
||||
// Create yaml Output writer, using yaml options for context.
|
||||
ContextInfo context(_targetInfo);
|
||||
llvm::yaml::Output yout(out, &context);
|
||||
|
||||
|
||||
// Write yaml output.
|
||||
const lld::File *fileRef = &file;
|
||||
yout << fileRef;
|
||||
|
||||
|
||||
return error_code::success();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
const TargetInfo &_targetInfo;
|
||||
};
|
||||
@ -1316,7 +1316,7 @@ public:
|
||||
|
||||
error_code parseFile(std::unique_ptr<MemoryBuffer> mb,
|
||||
std::vector<std::unique_ptr<File>> &result) {
|
||||
// Note: we do not take ownership of the MemoryBuffer. That is
|
||||
// Note: we do not take ownership of the MemoryBuffer. That is
|
||||
// because yaml may produce multiple File objects, so there is no
|
||||
// *one* File to take ownership. Therefore, the yaml File objects
|
||||
// produced must make copies of all strings that come from YAML I/O.
|
||||
@ -1326,17 +1326,17 @@ public:
|
||||
// Create YAML Input parser.
|
||||
ContextInfo context(_targetInfo);
|
||||
llvm::yaml::Input yin(mb->getBuffer(), &context);
|
||||
|
||||
|
||||
// Fill vector with File objects created by parsing yaml.
|
||||
std::vector<const lld::File*> createdFiles;
|
||||
yin >> createdFiles;
|
||||
|
||||
|
||||
// Quit now if there were parsing errors.
|
||||
if ( yin.error() )
|
||||
return make_error_code(lld::yaml_reader_error::illegal_value);
|
||||
|
||||
|
||||
for (const File *file : createdFiles) {
|
||||
// Note: parseFile() should return vector of *const* File
|
||||
// Note: parseFile() should return vector of *const* File
|
||||
File *f = const_cast<File*>(file);
|
||||
result.emplace_back(f);
|
||||
}
|
||||
|
||||
@ -56,9 +56,9 @@ llvm::cl::list<std::string>
|
||||
cmdLineInputFilePaths(llvm::cl::Positional,
|
||||
llvm::cl::desc("<input file>"));
|
||||
|
||||
llvm::cl::opt<std::string>
|
||||
cmdLineOutputFilePath("o",
|
||||
llvm::cl::desc("Specify output filename"),
|
||||
llvm::cl::opt<std::string>
|
||||
cmdLineOutputFilePath("o",
|
||||
llvm::cl::desc("Specify output filename"),
|
||||
llvm::cl::value_desc("filename"));
|
||||
|
||||
llvm::cl::opt<bool> cmdLineDoStubsPass(
|
||||
@ -72,7 +72,7 @@ cmdLineDoLayoutPass("layout-pass", llvm::cl::desc("Run pass to layout atoms"));
|
||||
|
||||
llvm::cl::opt<bool>
|
||||
cmdLineDoMergeStrings(
|
||||
"merge-strings",
|
||||
"merge-strings",
|
||||
llvm::cl::desc("make common strings merge possible"));
|
||||
|
||||
llvm::cl::opt<bool> cmdLineUndefinesIsError(
|
||||
@ -82,16 +82,16 @@ llvm::cl::opt<bool> cmdLineUndefinesIsError(
|
||||
llvm::cl::opt<bool> cmdLineForceLoad(
|
||||
"force-load", llvm::cl::desc("force load all members of the archive"));
|
||||
|
||||
llvm::cl::opt<bool>
|
||||
cmdLineCommonsSearchArchives("commons-search-archives",
|
||||
llvm::cl::opt<bool>
|
||||
cmdLineCommonsSearchArchives("commons-search-archives",
|
||||
llvm::cl::desc("Tentative definitions trigger archive search"));
|
||||
|
||||
llvm::cl::opt<bool>
|
||||
cmdLineDeadStrip("dead-strip",
|
||||
llvm::cl::opt<bool>
|
||||
cmdLineDeadStrip("dead-strip",
|
||||
llvm::cl::desc("Remove unreachable code and data"));
|
||||
|
||||
llvm::cl::opt<bool>
|
||||
cmdLineGlobalsNotDeadStrip("keep-globals",
|
||||
llvm::cl::opt<bool>
|
||||
cmdLineGlobalsNotDeadStrip("keep-globals",
|
||||
llvm::cl::desc("All global symbols are roots for dead-strip"));
|
||||
|
||||
llvm::cl::opt<std::string>
|
||||
@ -104,7 +104,7 @@ enum WriteChoice {
|
||||
writeYAML, writeMachO, writePECOFF, writeELF
|
||||
};
|
||||
|
||||
llvm::cl::opt<WriteChoice>
|
||||
llvm::cl::opt<WriteChoice>
|
||||
writeSelected("writer",
|
||||
llvm::cl::desc("Select writer"),
|
||||
llvm::cl::values(
|
||||
@ -118,7 +118,7 @@ writeSelected("writer",
|
||||
enum ReaderChoice {
|
||||
readerYAML, readerMachO, readerPECOFF, readerELF
|
||||
};
|
||||
llvm::cl::opt<ReaderChoice>
|
||||
llvm::cl::opt<ReaderChoice>
|
||||
readerSelected("reader",
|
||||
llvm::cl::desc("Select reader"),
|
||||
llvm::cl::values(
|
||||
@ -128,24 +128,24 @@ readerSelected("reader",
|
||||
clEnumValN(readerELF, "ELF", "read as linux would"),
|
||||
clEnumValEnd),
|
||||
llvm::cl::init(readerYAML));
|
||||
|
||||
|
||||
enum ArchChoice {
|
||||
i386 = llvm::ELF::EM_386,
|
||||
x86_64 = llvm::ELF::EM_X86_64,
|
||||
hexagon = llvm::ELF::EM_HEXAGON,
|
||||
ppc = llvm::ELF::EM_PPC
|
||||
};
|
||||
llvm::cl::opt<ArchChoice>
|
||||
llvm::cl::opt<ArchChoice>
|
||||
archSelected("arch",
|
||||
llvm::cl::desc("Select architecture, only valid with ELF output"),
|
||||
llvm::cl::values(
|
||||
clEnumValN(i386, "i386",
|
||||
clEnumValN(i386, "i386",
|
||||
"output i386, EM_386 file"),
|
||||
clEnumValN(x86_64,
|
||||
clEnumValN(x86_64,
|
||||
"x86_64", "output x86_64, EM_X86_64 file"),
|
||||
clEnumValN(hexagon,
|
||||
clEnumValN(hexagon,
|
||||
"hexagon", "output Hexagon, EM_HEXAGON file"),
|
||||
clEnumValN(ppc,
|
||||
clEnumValN(ppc,
|
||||
"ppc", "output PowerPC, EM_PPC file"),
|
||||
clEnumValEnd),
|
||||
llvm::cl::init(i386));
|
||||
@ -277,7 +277,7 @@ int main(int argc, char *argv[]) {
|
||||
ti = eti.get();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// create object to mange input files
|
||||
InputFiles inputFiles;
|
||||
|
||||
@ -343,22 +343,22 @@ int main(int argc, char *argv[]) {
|
||||
error("createTemporaryFileOnDisk() failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// write as native file
|
||||
std::unique_ptr<Writer> natWriter = createWriterNative(tti);
|
||||
if (error(natWriter->writeFile(mergedMasterFile, tmpNativePath.c_str())))
|
||||
return 1;
|
||||
|
||||
|
||||
// read as native file
|
||||
std::unique_ptr<Reader> natReader = createReaderNative(tti);
|
||||
std::vector<std::unique_ptr<File>> readNativeFiles;
|
||||
if (error(natReader->readFile(tmpNativePath.c_str(), readNativeFiles)))
|
||||
return 1;
|
||||
|
||||
|
||||
// write new atom graph
|
||||
const File *parsedNativeFile = readNativeFiles[0].get();
|
||||
if (error(writer->writeFile(*parsedNativeFile, cmdLineOutputFilePath)))
|
||||
return 1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user