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