aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/Object/ELFTypes.h
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-07-05 14:21:36 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-07-05 14:21:36 +0000
commit1a82d4c088707c791c792f6822f611b47a12bdfe (patch)
tree7c411f9b5d807f7f204fdd16965d8925a82b6d18 /include/llvm/Object/ELFTypes.h
parent3a0822f094b578157263e04114075ad7df81db41 (diff)
downloadsrc-1a82d4c088707c791c792f6822f611b47a12bdfe.tar.gz
src-1a82d4c088707c791c792f6822f611b47a12bdfe.zip
Notes
Diffstat (limited to 'include/llvm/Object/ELFTypes.h')
-rw-r--r--include/llvm/Object/ELFTypes.h125
1 files changed, 51 insertions, 74 deletions
diff --git a/include/llvm/Object/ELFTypes.h b/include/llvm/Object/ELFTypes.h
index 2eda0c179f10..63e13909ae5c 100644
--- a/include/llvm/Object/ELFTypes.h
+++ b/include/llvm/Object/ELFTypes.h
@@ -10,9 +10,11 @@
#ifndef LLVM_OBJECT_ELFTYPES_H
#define LLVM_OBJECT_ELFTYPES_H
+#include "llvm/Object/Error.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorOr.h"
namespace llvm {
namespace object {
@@ -24,6 +26,11 @@ template <endianness target_endianness, bool is64Bits> struct ELFType {
static const bool Is64Bits = is64Bits;
};
+typedef ELFType<support::little, false> ELF32LE;
+typedef ELFType<support::big, false> ELF32BE;
+typedef ELFType<support::little, true> ELF64LE;
+typedef ELFType<support::big, true> ELF64BE;
+
// Use an alignment of 2 for the typedefs since that is the worst case for
// ELF files in archives.
@@ -197,8 +204,21 @@ struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
return st_shndx >= ELF::SHN_LORESERVE;
}
bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; }
+ bool isExternal() const {
+ return getBinding() != ELF::STB_LOCAL;
+ }
+
+ ErrorOr<StringRef> getName(StringRef StrTab) const;
};
+template <class ELFT>
+ErrorOr<StringRef> Elf_Sym_Impl<ELFT>::getName(StringRef StrTab) const {
+ uint32_t Offset = this->st_name;
+ if (Offset >= StrTab.size())
+ return object_error::parse_failed;
+ return StringRef(StrTab.data() + Offset);
+}
+
/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
/// (.gnu.version). This structure is identical for ELF32 and ELF64.
template <class ELFT>
@@ -293,14 +313,14 @@ struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
using Elf_Dyn_Base<ELFT>::d_un;
int64_t getTag() const { return d_tag; }
uint64_t getVal() const { return d_un.d_val; }
- uint64_t getPtr() const { return d_un.ptr; }
+ uint64_t getPtr() const { return d_un.d_ptr; }
};
// Elf_Rel: Elf Relocation
-template <class ELFT, bool isRela> struct Elf_Rel_Base;
+template <class ELFT, bool isRela> struct Elf_Rel_Impl;
template <endianness TargetEndianness>
-struct Elf_Rel_Base<ELFType<TargetEndianness, false>, false> {
+struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf_Word r_info; // Symbol table index and type of relocation to apply
@@ -313,64 +333,46 @@ struct Elf_Rel_Base<ELFType<TargetEndianness, false>, false> {
assert(!IsMips64EL);
r_info = R;
}
-};
-
-template <endianness TargetEndianness>
-struct Elf_Rel_Base<ELFType<TargetEndianness, true>, false> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
- Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
- Elf_Xword r_info; // Symbol table index and type of relocation to apply
- uint64_t getRInfo(bool isMips64EL) const {
- uint64_t t = r_info;
- if (!isMips64EL)
- return t;
- // Mips64 little endian has a "special" encoding of r_info. Instead of one
- // 64 bit little endian number, it is a little endian 32 bit number followed
- // by a 32 bit big endian number.
- return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
- ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
+ // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
+ // and ELF32_R_INFO macros defined in the ELF specification:
+ uint32_t getSymbol(bool isMips64EL) const {
+ return this->getRInfo(isMips64EL) >> 8;
}
- void setRInfo(uint64_t R, bool IsMips64EL) {
- if (IsMips64EL)
- r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) |
- ((R & 0x0000ff00) << 40) | ((R & 0x000000ff) << 56);
- else
- r_info = R;
+ unsigned char getType(bool isMips64EL) const {
+ return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff);
+ }
+ void setSymbol(uint32_t s, bool IsMips64EL) {
+ setSymbolAndType(s, getType(), IsMips64EL);
+ }
+ void setType(unsigned char t, bool IsMips64EL) {
+ setSymbolAndType(getSymbol(), t, IsMips64EL);
+ }
+ void setSymbolAndType(uint32_t s, unsigned char t, bool IsMips64EL) {
+ this->setRInfo((s << 8) + t, IsMips64EL);
}
};
template <endianness TargetEndianness>
-struct Elf_Rel_Base<ELFType<TargetEndianness, false>, true> {
+struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, true>
+ : public Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
- Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
- Elf_Word r_info; // Symbol table index and type of relocation to apply
Elf_Sword r_addend; // Compute value for relocatable field by adding this
-
- uint32_t getRInfo(bool isMips64EL) const {
- assert(!isMips64EL);
- return r_info;
- }
- void setRInfo(uint32_t R, bool IsMips64EL) {
- assert(!IsMips64EL);
- r_info = R;
- }
};
template <endianness TargetEndianness>
-struct Elf_Rel_Base<ELFType<TargetEndianness, true>, true> {
+struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
- Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
- Elf_Xword r_info; // Symbol table index and type of relocation to apply
- Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
+ Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
+ Elf_Xword r_info; // Symbol table index and type of relocation to apply
uint64_t getRInfo(bool isMips64EL) const {
- // Mips64 little endian has a "special" encoding of r_info. Instead of one
- // 64 bit little endian number, it is a little endian 32 bit number followed
- // by a 32 bit big endian number.
uint64_t t = r_info;
if (!isMips64EL)
return t;
+ // Mips64 little endian has a "special" encoding of r_info. Instead of one
+ // 64 bit little endian number, it is a little endian 32 bit number followed
+ // by a 32 bit big endian number.
return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
}
@@ -381,14 +383,6 @@ struct Elf_Rel_Base<ELFType<TargetEndianness, true>, true> {
else
r_info = R;
}
-};
-
-template <class ELFT, bool isRela> struct Elf_Rel_Impl;
-
-template <endianness TargetEndianness, bool isRela>
-struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, isRela>
- : Elf_Rel_Base<ELFType<TargetEndianness, true>, isRela> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
// These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
// and ELF64_R_INFO macros defined in the ELF specification:
@@ -409,28 +403,11 @@ struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, isRela>
}
};
-template <endianness TargetEndianness, bool isRela>
-struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, isRela>
- : Elf_Rel_Base<ELFType<TargetEndianness, false>, isRela> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
-
- // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
- // and ELF32_R_INFO macros defined in the ELF specification:
- uint32_t getSymbol(bool isMips64EL) const {
- return this->getRInfo(isMips64EL) >> 8;
- }
- unsigned char getType(bool isMips64EL) const {
- return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff);
- }
- void setSymbol(uint32_t s, bool IsMips64EL) {
- setSymbolAndType(s, getType(), IsMips64EL);
- }
- void setType(unsigned char t, bool IsMips64EL) {
- setSymbolAndType(getSymbol(), t, IsMips64EL);
- }
- void setSymbolAndType(uint32_t s, unsigned char t, bool IsMips64EL) {
- this->setRInfo((s << 8) + t, IsMips64EL);
- }
+template <endianness TargetEndianness>
+struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, true>
+ : public Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
};
template <class ELFT>