forked from OSchip/llvm-project
[ELF] Update for LLVM Object/ELF changes.
llvm-svn: 172516
This commit is contained in:
parent
1a79161fe3
commit
b03f6c489a
|
@ -8,14 +8,10 @@
|
||||||
namespace lld {
|
namespace lld {
|
||||||
/// \brief Relocation References: Defined Atoms may contain references that will
|
/// \brief Relocation References: Defined Atoms may contain references that will
|
||||||
/// need to be patched before the executable is written.
|
/// need to be patched before the executable is written.
|
||||||
template<llvm::support::endianness target_endianness,
|
template<class ELFT>
|
||||||
std::size_t max_align,
|
|
||||||
bool is64Bits>
|
|
||||||
class ELFReference final : public Reference {
|
class ELFReference final : public Reference {
|
||||||
typedef llvm::object::Elf_Rel_Impl
|
typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
|
||||||
<target_endianness, max_align, is64Bits, false> Elf_Rel;
|
typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
|
||||||
typedef llvm::object::Elf_Rel_Impl
|
|
||||||
<target_endianness, max_align, is64Bits, true> Elf_Rela;
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ELFReference(const Elf_Rela *rela, uint64_t offset, const Atom *target)
|
ELFReference(const Elf_Rela *rela, uint64_t offset, const Atom *target)
|
||||||
|
@ -75,12 +71,9 @@ private:
|
||||||
/// \brief These atoms store symbols that are fixed to a particular address.
|
/// \brief These atoms store symbols that are fixed to a particular address.
|
||||||
/// This atom has no content its address will be used by the writer to fixup
|
/// This atom has no content its address will be used by the writer to fixup
|
||||||
/// references that point to it.
|
/// references that point to it.
|
||||||
template<llvm::support::endianness target_endianness,
|
template<class ELFT>
|
||||||
std::size_t max_align,
|
|
||||||
bool is64Bits>
|
|
||||||
class ELFAbsoluteAtom final : public AbsoluteAtom {
|
class ELFAbsoluteAtom final : public AbsoluteAtom {
|
||||||
typedef llvm::object::Elf_Sym_Impl<target_endianness, max_align, is64Bits>
|
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
|
||||||
Elf_Sym;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ELFAbsoluteAtom(const File &file,
|
ELFAbsoluteAtom(const File &file,
|
||||||
|
@ -123,12 +116,9 @@ private:
|
||||||
|
|
||||||
/// \brief ELFUndefinedAtom: These atoms store undefined symbols and are place
|
/// \brief ELFUndefinedAtom: These atoms store undefined symbols and are place
|
||||||
/// holders that will be replaced by defined atoms later in the linking process.
|
/// holders that will be replaced by defined atoms later in the linking process.
|
||||||
template<llvm::support::endianness target_endianness,
|
template<class ELFT>
|
||||||
std::size_t max_align,
|
|
||||||
bool is64Bits>
|
|
||||||
class ELFUndefinedAtom final: public UndefinedAtom {
|
class ELFUndefinedAtom final: public UndefinedAtom {
|
||||||
typedef llvm::object::Elf_Sym_Impl<target_endianness, max_align, is64Bits>
|
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
|
||||||
Elf_Sym;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ELFUndefinedAtom(const File &file,
|
ELFUndefinedAtom(const File &file,
|
||||||
|
@ -165,14 +155,10 @@ private:
|
||||||
|
|
||||||
/// \brief This atom stores defined symbols and will contain either data or
|
/// \brief This atom stores defined symbols and will contain either data or
|
||||||
/// code.
|
/// code.
|
||||||
template<llvm::support::endianness target_endianness,
|
template<class ELFT>
|
||||||
std::size_t max_align,
|
|
||||||
bool is64Bits>
|
|
||||||
class ELFDefinedAtom final: public DefinedAtom {
|
class ELFDefinedAtom final: public DefinedAtom {
|
||||||
typedef llvm::object::Elf_Sym_Impl<target_endianness, max_align, is64Bits>
|
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
|
||||||
Elf_Sym;
|
typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
|
||||||
typedef llvm::object::Elf_Shdr_Impl<target_endianness, max_align, is64Bits>
|
|
||||||
Elf_Shdr;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ELFDefinedAtom(const File &file,
|
ELFDefinedAtom(const File &file,
|
||||||
|
@ -183,8 +169,7 @@ public:
|
||||||
llvm::ArrayRef<uint8_t> contentData,
|
llvm::ArrayRef<uint8_t> contentData,
|
||||||
unsigned int referenceStart,
|
unsigned int referenceStart,
|
||||||
unsigned int referenceEnd,
|
unsigned int referenceEnd,
|
||||||
std::vector<ELFReference<target_endianness,
|
std::vector<ELFReference<ELFT>*> &referenceList)
|
||||||
max_align, is64Bits>*> &referenceList)
|
|
||||||
|
|
||||||
: _owningFile(file)
|
: _owningFile(file)
|
||||||
, _symbolName(symbolName)
|
, _symbolName(symbolName)
|
||||||
|
@ -420,7 +405,7 @@ private:
|
||||||
uint64_t _ordinal;
|
uint64_t _ordinal;
|
||||||
unsigned int _referenceStartIndex;
|
unsigned int _referenceStartIndex;
|
||||||
unsigned int _referenceEndIndex;
|
unsigned int _referenceEndIndex;
|
||||||
std::vector<ELFReference<target_endianness, max_align, is64Bits>*> &
|
std::vector<ELFReference<ELFT>*> &
|
||||||
_referenceList;
|
_referenceList;
|
||||||
};
|
};
|
||||||
} // namespace lld
|
} // namespace lld
|
||||||
|
|
|
@ -26,12 +26,10 @@ namespace elf {
|
||||||
/// are basically additional symbols required by libc and other runtime
|
/// are basically additional symbols required by libc and other runtime
|
||||||
/// libraries part of executing a program. This class provides support
|
/// libraries part of executing a program. This class provides support
|
||||||
/// for adding absolute symbols and undefined symbols
|
/// for adding absolute symbols and undefined symbols
|
||||||
template<llvm::support::endianness target_endianness,
|
template<class ELFT>
|
||||||
std::size_t max_align,
|
|
||||||
bool is64Bits>
|
|
||||||
class CRuntimeFile : public File {
|
class CRuntimeFile : public File {
|
||||||
public:
|
public:
|
||||||
typedef llvm::object::Elf_Sym_Impl<target_endianness, max_align, is64Bits> Elf_Sym;
|
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
|
||||||
CRuntimeFile(const WriterOptionsELF &options)
|
CRuntimeFile(const WriterOptionsELF &options)
|
||||||
: File("C runtime")
|
: File("C runtime")
|
||||||
{ }
|
{ }
|
||||||
|
@ -47,8 +45,8 @@ public:
|
||||||
symbol->st_other = llvm::ELF::STV_DEFAULT;
|
symbol->st_other = llvm::ELF::STV_DEFAULT;
|
||||||
symbol->st_size = 0;
|
symbol->st_size = 0;
|
||||||
auto *newAtom = new (_allocator.Allocate<
|
auto *newAtom = new (_allocator.Allocate<
|
||||||
ELFAbsoluteAtom<target_endianness, max_align, is64Bits> > ())
|
ELFAbsoluteAtom<ELFT> > ())
|
||||||
ELFAbsoluteAtom<target_endianness, max_align, is64Bits>(
|
ELFAbsoluteAtom<ELFT>(
|
||||||
*this, symbolName, symbol, -1);
|
*this, symbolName, symbol, -1);
|
||||||
_absoluteAtoms._atoms.push_back(newAtom);
|
_absoluteAtoms._atoms.push_back(newAtom);
|
||||||
}
|
}
|
||||||
|
@ -62,8 +60,8 @@ public:
|
||||||
symbol->st_other = llvm::ELF::STV_DEFAULT;
|
symbol->st_other = llvm::ELF::STV_DEFAULT;
|
||||||
symbol->st_size = 0;
|
symbol->st_size = 0;
|
||||||
auto *newAtom = new (_allocator.Allocate<
|
auto *newAtom = new (_allocator.Allocate<
|
||||||
ELFUndefinedAtom<target_endianness, max_align, is64Bits> > ())
|
ELFUndefinedAtom<ELFT> > ())
|
||||||
ELFUndefinedAtom<target_endianness, max_align, is64Bits>(
|
ELFUndefinedAtom<ELFT>(
|
||||||
*this, symbolName, symbol);
|
*this, symbolName, symbol);
|
||||||
_undefinedAtoms._atoms.push_back(newAtom);
|
_undefinedAtoms._atoms.push_back(newAtom);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,12 +47,12 @@ using namespace llvm::object;
|
||||||
namespace {
|
namespace {
|
||||||
// \brief Read a binary, find out based on the symbol table contents what kind
|
// \brief Read a binary, find out based on the symbol table contents what kind
|
||||||
// of symbol it is and create corresponding atoms for it
|
// of symbol it is and create corresponding atoms for it
|
||||||
template<endianness target_endianness, std::size_t max_align, bool is64Bits>
|
template<class ELFT>
|
||||||
class FileELF: public File {
|
class FileELF: public File {
|
||||||
typedef Elf_Sym_Impl<target_endianness, max_align, is64Bits> Elf_Sym;
|
typedef Elf_Sym_Impl<ELFT> Elf_Sym;
|
||||||
typedef Elf_Shdr_Impl<target_endianness, max_align, is64Bits> Elf_Shdr;
|
typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
|
||||||
typedef Elf_Rel_Impl<target_endianness, max_align, is64Bits, false> Elf_Rel;
|
typedef Elf_Rel_Impl<ELFT, false> Elf_Rel;
|
||||||
typedef Elf_Rel_Impl<target_endianness, max_align, is64Bits, true> Elf_Rela;
|
typedef Elf_Rel_Impl<ELFT, true> Elf_Rela;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FileELF(std::unique_ptr<llvm::MemoryBuffer> MB, llvm::error_code &EC)
|
FileELF(std::unique_ptr<llvm::MemoryBuffer> MB, llvm::error_code &EC)
|
||||||
|
@ -63,8 +63,7 @@ public:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Point Obj to correct class and bitwidth ELF object
|
// Point Obj to correct class and bitwidth ELF object
|
||||||
_objFile.reset(llvm::dyn_cast<ELFObjectFile<target_endianness, max_align,
|
_objFile.reset(llvm::dyn_cast<ELFObjectFile<ELFT>>(binaryFile.get()));
|
||||||
is64Bits> >(binaryFile.get()));
|
|
||||||
|
|
||||||
if (!_objFile) {
|
if (!_objFile) {
|
||||||
EC = make_error_code(object_error::invalid_file_type);
|
EC = make_error_code(object_error::invalid_file_type);
|
||||||
|
@ -143,8 +142,8 @@ public:
|
||||||
if (symbol->st_shndx == llvm::ELF::SHN_ABS) {
|
if (symbol->st_shndx == llvm::ELF::SHN_ABS) {
|
||||||
// Create an absolute atom.
|
// Create an absolute atom.
|
||||||
auto *newAtom = new (_readerStorage.Allocate<
|
auto *newAtom = new (_readerStorage.Allocate<
|
||||||
ELFAbsoluteAtom<target_endianness, max_align, is64Bits> > ())
|
ELFAbsoluteAtom<ELFT> > ())
|
||||||
ELFAbsoluteAtom<target_endianness, max_align, is64Bits>(
|
ELFAbsoluteAtom<ELFT>(
|
||||||
*this, symbolName, symbol, symbol->st_value);
|
*this, symbolName, symbol, symbol->st_value);
|
||||||
|
|
||||||
_absoluteAtoms._atoms.push_back(newAtom);
|
_absoluteAtoms._atoms.push_back(newAtom);
|
||||||
|
@ -152,8 +151,8 @@ public:
|
||||||
} else if (symbol->st_shndx == llvm::ELF::SHN_UNDEF) {
|
} else if (symbol->st_shndx == llvm::ELF::SHN_UNDEF) {
|
||||||
// Create an undefined atom.
|
// Create an undefined atom.
|
||||||
auto *newAtom = new (_readerStorage.Allocate<
|
auto *newAtom = new (_readerStorage.Allocate<
|
||||||
ELFUndefinedAtom<target_endianness, max_align, is64Bits> > ())
|
ELFUndefinedAtom<ELFT> > ())
|
||||||
ELFUndefinedAtom<target_endianness, max_align, is64Bits>(
|
ELFUndefinedAtom<ELFT>(
|
||||||
*this, symbolName, symbol);
|
*this, symbolName, symbol);
|
||||||
|
|
||||||
_undefinedAtoms._atoms.push_back(newAtom);
|
_undefinedAtoms._atoms.push_back(newAtom);
|
||||||
|
@ -234,8 +233,8 @@ public:
|
||||||
if ((rai->r_offset >= (*si)->st_value) &&
|
if ((rai->r_offset >= (*si)->st_value) &&
|
||||||
(rai->r_offset < (*si)->st_value+contentSize)) {
|
(rai->r_offset < (*si)->st_value+contentSize)) {
|
||||||
auto *ERef = new (_readerStorage.Allocate<
|
auto *ERef = new (_readerStorage.Allocate<
|
||||||
ELFReference<target_endianness, max_align, is64Bits> > ())
|
ELFReference<ELFT> > ())
|
||||||
ELFReference<target_endianness, max_align, is64Bits> (
|
ELFReference<ELFT> (
|
||||||
rai, rai->r_offset-(*si)->st_value, nullptr);
|
rai, rai->r_offset-(*si)->st_value, nullptr);
|
||||||
|
|
||||||
_references.push_back(ERef);
|
_references.push_back(ERef);
|
||||||
|
@ -247,8 +246,8 @@ public:
|
||||||
if (((ri)->r_offset >= (*si)->st_value) &&
|
if (((ri)->r_offset >= (*si)->st_value) &&
|
||||||
((ri)->r_offset < (*si)->st_value+contentSize)) {
|
((ri)->r_offset < (*si)->st_value+contentSize)) {
|
||||||
auto *ERef = new (_readerStorage.Allocate<
|
auto *ERef = new (_readerStorage.Allocate<
|
||||||
ELFReference<target_endianness, max_align, is64Bits> > ())
|
ELFReference<ELFT> > ())
|
||||||
ELFReference<target_endianness, max_align, is64Bits> (
|
ELFReference<ELFT> (
|
||||||
(ri), (ri)->r_offset-(*si)->st_value, nullptr);
|
(ri), (ri)->r_offset-(*si)->st_value, nullptr);
|
||||||
|
|
||||||
_references.push_back(ERef);
|
_references.push_back(ERef);
|
||||||
|
@ -257,8 +256,8 @@ public:
|
||||||
|
|
||||||
// Create the DefinedAtom and add it to the list of DefinedAtoms.
|
// Create the DefinedAtom and add it to the list of DefinedAtoms.
|
||||||
auto *newAtom = new (_readerStorage.Allocate<
|
auto *newAtom = new (_readerStorage.Allocate<
|
||||||
ELFDefinedAtom<target_endianness, max_align, is64Bits> > ())
|
ELFDefinedAtom<ELFT> > ())
|
||||||
ELFDefinedAtom<target_endianness, max_align, is64Bits>(
|
ELFDefinedAtom<ELFT>(
|
||||||
*this, symbolName, sectionName, *si, i.first, symbolData,
|
*this, symbolName, sectionName, *si, i.first, symbolData,
|
||||||
referenceStart, _references.size(), _references);
|
referenceStart, _references.size(), _references);
|
||||||
|
|
||||||
|
@ -296,7 +295,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<ELFObjectFile<target_endianness, max_align, is64Bits> >
|
std::unique_ptr<ELFObjectFile<ELFT> >
|
||||||
_objFile;
|
_objFile;
|
||||||
atom_collection_vector<DefinedAtom> _definedAtoms;
|
atom_collection_vector<DefinedAtom> _definedAtoms;
|
||||||
atom_collection_vector<UndefinedAtom> _undefinedAtoms;
|
atom_collection_vector<UndefinedAtom> _undefinedAtoms;
|
||||||
|
@ -313,7 +312,7 @@ private:
|
||||||
std::map<llvm::StringRef, std::vector<const Elf_Rel *> >
|
std::map<llvm::StringRef, std::vector<const Elf_Rel *> >
|
||||||
_relocationReferences;
|
_relocationReferences;
|
||||||
|
|
||||||
std::vector<ELFReference<target_endianness, max_align, is64Bits> *>
|
std::vector<ELFReference<ELFT> *>
|
||||||
_references;
|
_references;
|
||||||
llvm::DenseMap<const Elf_Sym *, Atom *> _symbolToAtomMapping;
|
llvm::DenseMap<const Elf_Sym *, Atom *> _symbolToAtomMapping;
|
||||||
|
|
||||||
|
@ -333,6 +332,7 @@ public:
|
||||||
|
|
||||||
error_code parseFile(std::unique_ptr<MemoryBuffer> mb, std::vector<
|
error_code parseFile(std::unique_ptr<MemoryBuffer> mb, std::vector<
|
||||||
std::unique_ptr<File> > &result) {
|
std::unique_ptr<File> > &result) {
|
||||||
|
using llvm::object::ELFType;
|
||||||
llvm::error_code ec;
|
llvm::error_code ec;
|
||||||
std::unique_ptr<File> f;
|
std::unique_ptr<File> f;
|
||||||
std::pair<unsigned char, unsigned char> Ident;
|
std::pair<unsigned char, unsigned char> Ident;
|
||||||
|
@ -353,41 +353,41 @@ public:
|
||||||
if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
|
if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
|
||||||
== llvm::ELF::ELFDATA2LSB) {
|
== llvm::ELF::ELFDATA2LSB) {
|
||||||
if (MaxAlignment >= 4)
|
if (MaxAlignment >= 4)
|
||||||
f.reset(
|
f.reset(new FileELF<ELFType<llvm::support::little, 4, false>>(
|
||||||
new FileELF<llvm::support::little, 4, false>(std::move(mb), ec));
|
std::move(mb), ec));
|
||||||
else if (MaxAlignment >= 2)
|
else if (MaxAlignment >= 2)
|
||||||
f.reset(
|
f.reset(new FileELF<ELFType<llvm::support::little, 2, false>>(
|
||||||
new FileELF<llvm::support::little, 2, false>(std::move(mb), ec));
|
std::move(mb), ec));
|
||||||
else
|
else
|
||||||
llvm_unreachable("Invalid alignment for ELF file!");
|
llvm_unreachable("Invalid alignment for ELF file!");
|
||||||
} else if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
|
} else if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
|
||||||
== llvm::ELF::ELFDATA2MSB) {
|
== llvm::ELF::ELFDATA2MSB) {
|
||||||
if (MaxAlignment >= 4)
|
if (MaxAlignment >= 4)
|
||||||
f.reset(
|
f.reset(new FileELF<ELFType<llvm::support::big, 4, false>>(
|
||||||
new FileELF<llvm::support::big, 4, false>(std::move(mb), ec));
|
std::move(mb), ec));
|
||||||
else if (MaxAlignment >= 2)
|
else if (MaxAlignment >= 2)
|
||||||
f.reset(
|
f.reset(new FileELF<ELFType<llvm::support::big, 2, false>>(
|
||||||
new FileELF<llvm::support::big, 2, false>(std::move(mb), ec));
|
std::move(mb), ec));
|
||||||
else
|
else
|
||||||
llvm_unreachable("Invalid alignment for ELF file!");
|
llvm_unreachable("Invalid alignment for ELF file!");
|
||||||
} else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
|
} else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
|
||||||
== llvm::ELF::ELFDATA2MSB) {
|
== llvm::ELF::ELFDATA2MSB) {
|
||||||
if (MaxAlignment >= 8)
|
if (MaxAlignment >= 8)
|
||||||
f.reset(
|
f.reset(new FileELF<ELFType<llvm::support::big, 8, true>>(
|
||||||
new FileELF<llvm::support::big, 8, true>(std::move(mb), ec));
|
std::move(mb), ec));
|
||||||
else if (MaxAlignment >= 2)
|
else if (MaxAlignment >= 2)
|
||||||
f.reset(
|
f.reset(new FileELF<ELFType<llvm::support::big, 2, true>>(
|
||||||
new FileELF<llvm::support::big, 2, true>(std::move(mb), ec));
|
std::move(mb), ec));
|
||||||
else
|
else
|
||||||
llvm_unreachable("Invalid alignment for ELF file!");
|
llvm_unreachable("Invalid alignment for ELF file!");
|
||||||
} else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
|
} else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
|
||||||
== llvm::ELF::ELFDATA2LSB) {
|
== llvm::ELF::ELFDATA2LSB) {
|
||||||
if (MaxAlignment >= 8)
|
if (MaxAlignment >= 8)
|
||||||
f.reset(
|
f.reset(new FileELF<ELFType<llvm::support::little, 8, true>>(
|
||||||
new FileELF<llvm::support::little, 8, true>(std::move(mb), ec));
|
std::move(mb), ec));
|
||||||
else if (MaxAlignment >= 2)
|
else if (MaxAlignment >= 2)
|
||||||
f.reset(
|
f.reset(new FileELF<ELFType<llvm::support::little, 2, true>>(
|
||||||
new FileELF<llvm::support::little, 2, true>(std::move(mb), ec));
|
std::move(mb), ec));
|
||||||
else
|
else
|
||||||
llvm_unreachable("Invalid alignment for ELF file!");
|
llvm_unreachable("Invalid alignment for ELF file!");
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue