initial
This commit is contained in:
246
thirdparty/clang/include/llvm/Object/Archive.h
vendored
Normal file
246
thirdparty/clang/include/llvm/Object/Archive.h
vendored
Normal file
@@ -0,0 +1,246 @@
|
||||
//===- Archive.h - ar archive file format -----------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the ar archive file format class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_OBJECT_ARCHIVE_H
|
||||
#define LLVM_OBJECT_ARCHIVE_H
|
||||
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Object/Binary.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace object {
|
||||
struct ArchiveMemberHeader {
|
||||
char Name[16];
|
||||
char LastModified[12];
|
||||
char UID[6];
|
||||
char GID[6];
|
||||
char AccessMode[8];
|
||||
char Size[10]; ///< Size of data, not including header or padding.
|
||||
char Terminator[2];
|
||||
|
||||
///! Get the name without looking up long names.
|
||||
llvm::StringRef getName() const {
|
||||
char EndCond;
|
||||
if (Name[0] == '/' || Name[0] == '#')
|
||||
EndCond = ' ';
|
||||
else
|
||||
EndCond = '/';
|
||||
llvm::StringRef::size_type end =
|
||||
llvm::StringRef(Name, sizeof(Name)).find(EndCond);
|
||||
if (end == llvm::StringRef::npos)
|
||||
end = sizeof(Name);
|
||||
assert(end <= sizeof(Name) && end > 0);
|
||||
// Don't include the EndCond if there is one.
|
||||
return llvm::StringRef(Name, end);
|
||||
}
|
||||
|
||||
uint64_t getSize() const {
|
||||
uint64_t ret;
|
||||
if (llvm::StringRef(Size, sizeof(Size)).rtrim(" ").getAsInteger(10, ret))
|
||||
llvm_unreachable("Size is not an integer.");
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
static const ArchiveMemberHeader *ToHeader(const char *base) {
|
||||
return reinterpret_cast<const ArchiveMemberHeader *>(base);
|
||||
}
|
||||
|
||||
class Archive : public Binary {
|
||||
virtual void anchor();
|
||||
public:
|
||||
class Child {
|
||||
const Archive *Parent;
|
||||
/// \brief Includes header but not padding byte.
|
||||
StringRef Data;
|
||||
/// \brief Offset from Data to the start of the file.
|
||||
uint16_t StartOfFile;
|
||||
|
||||
public:
|
||||
Child(const Archive *p, StringRef d) : Parent(p), Data(d) {
|
||||
if (!p || d.empty())
|
||||
return;
|
||||
// Setup StartOfFile and PaddingBytes.
|
||||
StartOfFile = sizeof(ArchiveMemberHeader);
|
||||
// Don't include attached name.
|
||||
StringRef Name = ToHeader(Data.data())->getName();
|
||||
if (Name.startswith("#1/")) {
|
||||
uint64_t NameSize;
|
||||
if (Name.substr(3).rtrim(" ").getAsInteger(10, NameSize))
|
||||
llvm_unreachable("Long name length is not an integer");
|
||||
StartOfFile += NameSize;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator ==(const Child &other) const {
|
||||
return (Parent == other.Parent) && (Data.begin() == other.Data.begin());
|
||||
}
|
||||
|
||||
bool operator <(const Child &other) const {
|
||||
return Data.begin() < other.Data.begin();
|
||||
}
|
||||
|
||||
Child getNext() const {
|
||||
size_t SpaceToSkip = Data.size();
|
||||
// If it's odd, add 1 to make it even.
|
||||
if (SpaceToSkip & 1)
|
||||
++SpaceToSkip;
|
||||
|
||||
const char *NextLoc = Data.data() + SpaceToSkip;
|
||||
|
||||
// Check to see if this is past the end of the archive.
|
||||
if (NextLoc >= Parent->Data->getBufferEnd())
|
||||
return Child(Parent, StringRef(0, 0));
|
||||
|
||||
size_t NextSize =
|
||||
sizeof(ArchiveMemberHeader) + ToHeader(NextLoc)->getSize();
|
||||
|
||||
return Child(Parent, StringRef(NextLoc, NextSize));
|
||||
}
|
||||
|
||||
error_code getName(StringRef &Result) const;
|
||||
int getLastModified() const;
|
||||
int getUID() const;
|
||||
int getGID() const;
|
||||
int getAccessMode() const;
|
||||
/// \return the size of the archive member without the header or padding.
|
||||
uint64_t getSize() const { return Data.size() - StartOfFile; }
|
||||
|
||||
StringRef getBuffer() const {
|
||||
return StringRef(Data.data() + StartOfFile, getSize());
|
||||
}
|
||||
|
||||
error_code getMemoryBuffer(OwningPtr<MemoryBuffer> &Result,
|
||||
bool FullPath = false) const {
|
||||
StringRef Name;
|
||||
if (error_code ec = getName(Name))
|
||||
return ec;
|
||||
SmallString<128> Path;
|
||||
Result.reset(MemoryBuffer::getMemBuffer(
|
||||
getBuffer(), FullPath ? (Twine(Parent->getFileName()) + "(" + Name +
|
||||
")").toStringRef(Path) : Name, false));
|
||||
return error_code::success();
|
||||
}
|
||||
|
||||
error_code getAsBinary(OwningPtr<Binary> &Result) const;
|
||||
};
|
||||
|
||||
class child_iterator {
|
||||
Child child;
|
||||
public:
|
||||
child_iterator() : child(Child(0, StringRef())) {}
|
||||
child_iterator(const Child &c) : child(c) {}
|
||||
const Child* operator->() const {
|
||||
return &child;
|
||||
}
|
||||
|
||||
bool operator==(const child_iterator &other) const {
|
||||
return child == other.child;
|
||||
}
|
||||
|
||||
bool operator!=(const child_iterator &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool operator <(const child_iterator &other) const {
|
||||
return child < other.child;
|
||||
}
|
||||
|
||||
child_iterator& operator++() { // Preincrement
|
||||
child = child.getNext();
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class Symbol {
|
||||
const Archive *Parent;
|
||||
uint32_t SymbolIndex;
|
||||
uint32_t StringIndex; // Extra index to the string.
|
||||
|
||||
public:
|
||||
bool operator ==(const Symbol &other) const {
|
||||
return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex);
|
||||
}
|
||||
|
||||
Symbol(const Archive *p, uint32_t symi, uint32_t stri)
|
||||
: Parent(p)
|
||||
, SymbolIndex(symi)
|
||||
, StringIndex(stri) {}
|
||||
error_code getName(StringRef &Result) const;
|
||||
error_code getMember(child_iterator &Result) const;
|
||||
Symbol getNext() const;
|
||||
};
|
||||
|
||||
class symbol_iterator {
|
||||
Symbol symbol;
|
||||
public:
|
||||
symbol_iterator(const Symbol &s) : symbol(s) {}
|
||||
const Symbol *operator->() const {
|
||||
return &symbol;
|
||||
}
|
||||
|
||||
bool operator==(const symbol_iterator &other) const {
|
||||
return symbol == other.symbol;
|
||||
}
|
||||
|
||||
bool operator!=(const symbol_iterator &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
symbol_iterator& operator++() { // Preincrement
|
||||
symbol = symbol.getNext();
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
Archive(MemoryBuffer *source, error_code &ec);
|
||||
|
||||
enum Kind {
|
||||
K_GNU,
|
||||
K_BSD,
|
||||
K_COFF
|
||||
};
|
||||
|
||||
Kind kind() const {
|
||||
return Format;
|
||||
}
|
||||
|
||||
child_iterator begin_children(bool skip_internal = true) const;
|
||||
child_iterator end_children() const;
|
||||
|
||||
symbol_iterator begin_symbols() const;
|
||||
symbol_iterator end_symbols() const;
|
||||
|
||||
// Cast methods.
|
||||
static inline bool classof(Binary const *v) {
|
||||
return v->isArchive();
|
||||
}
|
||||
|
||||
// check if a symbol is in the archive
|
||||
child_iterator findSym(StringRef name) const;
|
||||
|
||||
private:
|
||||
child_iterator SymbolTable;
|
||||
child_iterator StringTable;
|
||||
Kind Format;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
121
thirdparty/clang/include/llvm/Object/Binary.h
vendored
Normal file
121
thirdparty/clang/include/llvm/Object/Binary.h
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
//===- Binary.h - A generic binary file -------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the Binary class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_OBJECT_BINARY_H
|
||||
#define LLVM_OBJECT_BINARY_H
|
||||
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/Object/Error.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MemoryBuffer;
|
||||
class StringRef;
|
||||
|
||||
namespace object {
|
||||
|
||||
class Binary {
|
||||
private:
|
||||
Binary() LLVM_DELETED_FUNCTION;
|
||||
Binary(const Binary &other) LLVM_DELETED_FUNCTION;
|
||||
|
||||
unsigned int TypeID;
|
||||
|
||||
protected:
|
||||
MemoryBuffer *Data;
|
||||
|
||||
Binary(unsigned int Type, MemoryBuffer *Source);
|
||||
|
||||
enum {
|
||||
ID_Archive,
|
||||
// Object and children.
|
||||
ID_StartObjects,
|
||||
ID_COFF,
|
||||
|
||||
ID_ELF32L, // ELF 32-bit, little endian
|
||||
ID_ELF32B, // ELF 32-bit, big endian
|
||||
ID_ELF64L, // ELF 64-bit, little endian
|
||||
ID_ELF64B, // ELF 64-bit, big endian
|
||||
|
||||
ID_MachO32L, // MachO 32-bit, little endian
|
||||
ID_MachO32B, // MachO 32-bit, big endian
|
||||
ID_MachO64L, // MachO 64-bit, little endian
|
||||
ID_MachO64B, // MachO 64-bit, big endian
|
||||
|
||||
ID_EndObjects
|
||||
};
|
||||
|
||||
static inline unsigned int getELFType(bool isLE, bool is64Bits) {
|
||||
if (isLE)
|
||||
return is64Bits ? ID_ELF64L : ID_ELF32L;
|
||||
else
|
||||
return is64Bits ? ID_ELF64B : ID_ELF32B;
|
||||
}
|
||||
|
||||
static unsigned int getMachOType(bool isLE, bool is64Bits) {
|
||||
if (isLE)
|
||||
return is64Bits ? ID_MachO64L : ID_MachO32L;
|
||||
else
|
||||
return is64Bits ? ID_MachO64B : ID_MachO32B;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~Binary();
|
||||
|
||||
StringRef getData() const;
|
||||
StringRef getFileName() const;
|
||||
|
||||
// Cast methods.
|
||||
unsigned int getType() const { return TypeID; }
|
||||
|
||||
// Convenience methods
|
||||
bool isObject() const {
|
||||
return TypeID > ID_StartObjects && TypeID < ID_EndObjects;
|
||||
}
|
||||
|
||||
bool isArchive() const {
|
||||
return TypeID == ID_Archive;
|
||||
}
|
||||
|
||||
bool isELF() const {
|
||||
return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B;
|
||||
}
|
||||
|
||||
bool isMachO() const {
|
||||
return TypeID >= ID_MachO32L && TypeID <= ID_MachO64B;
|
||||
}
|
||||
|
||||
bool isCOFF() const {
|
||||
return TypeID == ID_COFF;
|
||||
}
|
||||
|
||||
bool isLittleEndian() const {
|
||||
return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
|
||||
TypeID == ID_MachO32B || TypeID == ID_MachO64B);
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief Create a Binary from Source, autodetecting the file type.
|
||||
///
|
||||
/// @param Source The data to create the Binary from. Ownership is transferred
|
||||
/// to Result if successful. If an error is returned, Source is destroyed
|
||||
/// by createBinary before returning.
|
||||
/// @param Result A pointer to the resulting Binary if no error occured.
|
||||
error_code createBinary(MemoryBuffer *Source, OwningPtr<Binary> &Result);
|
||||
|
||||
error_code createBinary(StringRef Path, OwningPtr<Binary> &Result);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
207
thirdparty/clang/include/llvm/Object/COFF.h
vendored
Normal file
207
thirdparty/clang/include/llvm/Object/COFF.h
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
//===- COFF.h - COFF object file implementation -----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the COFFObjectFile class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_OBJECT_COFF_H
|
||||
#define LLVM_OBJECT_COFF_H
|
||||
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/COFF.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
|
||||
namespace llvm {
|
||||
template <typename T>
|
||||
class ArrayRef;
|
||||
|
||||
namespace object {
|
||||
|
||||
struct coff_file_header {
|
||||
support::ulittle16_t Machine;
|
||||
support::ulittle16_t NumberOfSections;
|
||||
support::ulittle32_t TimeDateStamp;
|
||||
support::ulittle32_t PointerToSymbolTable;
|
||||
support::ulittle32_t NumberOfSymbols;
|
||||
support::ulittle16_t SizeOfOptionalHeader;
|
||||
support::ulittle16_t Characteristics;
|
||||
};
|
||||
|
||||
struct coff_symbol {
|
||||
struct StringTableOffset {
|
||||
support::ulittle32_t Zeroes;
|
||||
support::ulittle32_t Offset;
|
||||
};
|
||||
|
||||
union {
|
||||
char ShortName[8];
|
||||
StringTableOffset Offset;
|
||||
} Name;
|
||||
|
||||
support::ulittle32_t Value;
|
||||
support::little16_t SectionNumber;
|
||||
|
||||
support::ulittle16_t Type;
|
||||
|
||||
support::ulittle8_t StorageClass;
|
||||
support::ulittle8_t NumberOfAuxSymbols;
|
||||
|
||||
uint8_t getBaseType() const {
|
||||
return Type & 0x0F;
|
||||
}
|
||||
|
||||
uint8_t getComplexType() const {
|
||||
return (Type & 0xF0) >> 4;
|
||||
}
|
||||
};
|
||||
|
||||
struct coff_section {
|
||||
char Name[8];
|
||||
support::ulittle32_t VirtualSize;
|
||||
support::ulittle32_t VirtualAddress;
|
||||
support::ulittle32_t SizeOfRawData;
|
||||
support::ulittle32_t PointerToRawData;
|
||||
support::ulittle32_t PointerToRelocations;
|
||||
support::ulittle32_t PointerToLinenumbers;
|
||||
support::ulittle16_t NumberOfRelocations;
|
||||
support::ulittle16_t NumberOfLinenumbers;
|
||||
support::ulittle32_t Characteristics;
|
||||
};
|
||||
|
||||
struct coff_relocation {
|
||||
support::ulittle32_t VirtualAddress;
|
||||
support::ulittle32_t SymbolTableIndex;
|
||||
support::ulittle16_t Type;
|
||||
};
|
||||
|
||||
struct coff_aux_section_definition {
|
||||
support::ulittle32_t Length;
|
||||
support::ulittle16_t NumberOfRelocations;
|
||||
support::ulittle16_t NumberOfLinenumbers;
|
||||
support::ulittle32_t CheckSum;
|
||||
support::ulittle16_t Number;
|
||||
support::ulittle8_t Selection;
|
||||
char Unused[3];
|
||||
};
|
||||
|
||||
class COFFObjectFile : public ObjectFile {
|
||||
private:
|
||||
const coff_file_header *Header;
|
||||
const coff_section *SectionTable;
|
||||
const coff_symbol *SymbolTable;
|
||||
const char *StringTable;
|
||||
uint32_t StringTableSize;
|
||||
|
||||
error_code getString(uint32_t offset, StringRef &Res) const;
|
||||
|
||||
const coff_symbol *toSymb(DataRefImpl Symb) const;
|
||||
const coff_section *toSec(DataRefImpl Sec) const;
|
||||
const coff_relocation *toRel(DataRefImpl Rel) const;
|
||||
|
||||
protected:
|
||||
virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
|
||||
virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
|
||||
virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
|
||||
virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
|
||||
virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
|
||||
virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
|
||||
virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
|
||||
virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
|
||||
virtual error_code getSymbolSection(DataRefImpl Symb,
|
||||
section_iterator &Res) const;
|
||||
virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
|
||||
|
||||
virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
|
||||
virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
|
||||
virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
|
||||
virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
|
||||
virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
|
||||
virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const;
|
||||
virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
|
||||
virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
|
||||
virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
|
||||
virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;
|
||||
virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const;
|
||||
virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
|
||||
virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
|
||||
bool &Res) const;
|
||||
virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
|
||||
bool &Result) const;
|
||||
virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
|
||||
virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const;
|
||||
|
||||
virtual error_code getRelocationNext(DataRefImpl Rel,
|
||||
RelocationRef &Res) const;
|
||||
virtual error_code getRelocationAddress(DataRefImpl Rel,
|
||||
uint64_t &Res) const;
|
||||
virtual error_code getRelocationOffset(DataRefImpl Rel,
|
||||
uint64_t &Res) const;
|
||||
virtual error_code getRelocationSymbol(DataRefImpl Rel,
|
||||
SymbolRef &Res) const;
|
||||
virtual error_code getRelocationType(DataRefImpl Rel,
|
||||
uint64_t &Res) const;
|
||||
virtual error_code getRelocationTypeName(DataRefImpl Rel,
|
||||
SmallVectorImpl<char> &Result) const;
|
||||
virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
|
||||
int64_t &Res) const;
|
||||
virtual error_code getRelocationValueString(DataRefImpl Rel,
|
||||
SmallVectorImpl<char> &Result) const;
|
||||
|
||||
virtual error_code getLibraryNext(DataRefImpl LibData,
|
||||
LibraryRef &Result) const;
|
||||
virtual error_code getLibraryPath(DataRefImpl LibData,
|
||||
StringRef &Result) const;
|
||||
|
||||
public:
|
||||
COFFObjectFile(MemoryBuffer *Object, error_code &ec);
|
||||
virtual symbol_iterator begin_symbols() const;
|
||||
virtual symbol_iterator end_symbols() const;
|
||||
virtual symbol_iterator begin_dynamic_symbols() const;
|
||||
virtual symbol_iterator end_dynamic_symbols() const;
|
||||
virtual library_iterator begin_libraries_needed() const;
|
||||
virtual library_iterator end_libraries_needed() const;
|
||||
virtual section_iterator begin_sections() const;
|
||||
virtual section_iterator end_sections() const;
|
||||
|
||||
const coff_section *getCOFFSection(section_iterator &It) const;
|
||||
const coff_symbol *getCOFFSymbol(symbol_iterator &It) const;
|
||||
const coff_relocation *getCOFFRelocation(relocation_iterator &It) const;
|
||||
|
||||
virtual uint8_t getBytesInAddress() const;
|
||||
virtual StringRef getFileFormatName() const;
|
||||
virtual unsigned getArch() const;
|
||||
virtual StringRef getLoadName() const;
|
||||
|
||||
error_code getHeader(const coff_file_header *&Res) const;
|
||||
error_code getSection(int32_t index, const coff_section *&Res) const;
|
||||
error_code getSymbol(uint32_t index, const coff_symbol *&Res) const;
|
||||
template <typename T>
|
||||
error_code getAuxSymbol(uint32_t index, const T *&Res) const {
|
||||
const coff_symbol *s;
|
||||
error_code ec = getSymbol(index, s);
|
||||
Res = reinterpret_cast<const T*>(s);
|
||||
return ec;
|
||||
}
|
||||
error_code getSymbolName(const coff_symbol *symbol, StringRef &Res) const;
|
||||
ArrayRef<uint8_t> getSymbolAuxData(const coff_symbol *symbol) const;
|
||||
|
||||
error_code getSectionName(const coff_section *Sec, StringRef &Res) const;
|
||||
error_code getSectionContents(const coff_section *Sec,
|
||||
ArrayRef<uint8_t> &Res) const;
|
||||
|
||||
static inline bool classof(const Binary *v) {
|
||||
return v->isCOFF();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
2915
thirdparty/clang/include/llvm/Object/ELF.h
vendored
Normal file
2915
thirdparty/clang/include/llvm/Object/ELF.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
50
thirdparty/clang/include/llvm/Object/Error.h
vendored
Normal file
50
thirdparty/clang/include/llvm/Object/Error.h
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
//===- Error.h - system_error extensions for Object -------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This declares a new error_category for the Object library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_OBJECT_ERROR_H
|
||||
#define LLVM_OBJECT_ERROR_H
|
||||
|
||||
#include "llvm/Support/system_error.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace object {
|
||||
|
||||
const error_category &object_category();
|
||||
|
||||
struct object_error {
|
||||
enum _ {
|
||||
success = 0,
|
||||
invalid_file_type,
|
||||
parse_failed,
|
||||
unexpected_eof
|
||||
};
|
||||
_ v_;
|
||||
|
||||
object_error(_ v) : v_(v) {}
|
||||
explicit object_error(int v) : v_(_(v)) {}
|
||||
operator int() const {return v_;}
|
||||
};
|
||||
|
||||
inline error_code make_error_code(object_error e) {
|
||||
return error_code(static_cast<int>(e), object_category());
|
||||
}
|
||||
|
||||
} // end namespace object.
|
||||
|
||||
template <> struct is_error_code_enum<object::object_error> : true_type { };
|
||||
|
||||
template <> struct is_error_code_enum<object::object_error::_> : true_type { };
|
||||
|
||||
} // end namespace llvm.
|
||||
|
||||
#endif
|
||||
162
thirdparty/clang/include/llvm/Object/MachO.h
vendored
Normal file
162
thirdparty/clang/include/llvm/Object/MachO.h
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
//===- MachO.h - MachO object file implementation ---------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the MachOObjectFile class, which implement the ObjectFile
|
||||
// interface for MachO files.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_OBJECT_MACHO_H
|
||||
#define LLVM_OBJECT_MACHO_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Object/MachOFormat.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/MachO.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace object {
|
||||
|
||||
class MachOObjectFile : public ObjectFile {
|
||||
public:
|
||||
struct LoadCommandInfo {
|
||||
const char *Ptr; // Where in memory the load command is.
|
||||
macho::LoadCommand C; // The command itself.
|
||||
};
|
||||
|
||||
MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits,
|
||||
error_code &ec);
|
||||
|
||||
virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
|
||||
virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
|
||||
virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
|
||||
virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
|
||||
virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
|
||||
virtual error_code getSymbolType(DataRefImpl Symb,
|
||||
SymbolRef::Type &Res) const;
|
||||
virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
|
||||
virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
|
||||
virtual error_code getSymbolSection(DataRefImpl Symb,
|
||||
section_iterator &Res) const;
|
||||
virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
|
||||
|
||||
virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
|
||||
virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
|
||||
virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
|
||||
virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
|
||||
virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
|
||||
virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const;
|
||||
virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
|
||||
virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
|
||||
virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
|
||||
virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
|
||||
bool &Res) const;
|
||||
virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;
|
||||
virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const;
|
||||
virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
|
||||
virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
|
||||
bool &Result) const;
|
||||
virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
|
||||
virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const;
|
||||
|
||||
virtual error_code getRelocationNext(DataRefImpl Rel,
|
||||
RelocationRef &Res) const;
|
||||
virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const;
|
||||
virtual error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const;
|
||||
virtual error_code getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const;
|
||||
virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const;
|
||||
virtual error_code getRelocationTypeName(DataRefImpl Rel,
|
||||
SmallVectorImpl<char> &Result) const;
|
||||
virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
|
||||
int64_t &Res) const;
|
||||
virtual error_code getRelocationValueString(DataRefImpl Rel,
|
||||
SmallVectorImpl<char> &Result) const;
|
||||
virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const;
|
||||
|
||||
virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const;
|
||||
virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const;
|
||||
|
||||
// TODO: Would be useful to have an iterator based version
|
||||
// of the load command interface too.
|
||||
|
||||
virtual symbol_iterator begin_symbols() const;
|
||||
virtual symbol_iterator end_symbols() const;
|
||||
|
||||
virtual symbol_iterator begin_dynamic_symbols() const;
|
||||
virtual symbol_iterator end_dynamic_symbols() const;
|
||||
|
||||
virtual section_iterator begin_sections() const;
|
||||
virtual section_iterator end_sections() const;
|
||||
|
||||
virtual library_iterator begin_libraries_needed() const;
|
||||
virtual library_iterator end_libraries_needed() const;
|
||||
|
||||
virtual uint8_t getBytesInAddress() const;
|
||||
|
||||
virtual StringRef getFileFormatName() const;
|
||||
virtual unsigned getArch() const;
|
||||
|
||||
virtual StringRef getLoadName() const;
|
||||
|
||||
// In a MachO file, sections have a segment name. This is used in the .o
|
||||
// files. They have a single segment, but this field specifies which segment
|
||||
// a section should be put in in the final object.
|
||||
StringRef getSectionFinalSegmentName(DataRefImpl Sec) const;
|
||||
|
||||
// Names are stored as 16 bytes. These returns the raw 16 bytes without
|
||||
// interpreting them as a C string.
|
||||
ArrayRef<char> getSectionRawName(DataRefImpl Sec) const;
|
||||
ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const;
|
||||
|
||||
// MachO specific Info about relocations.
|
||||
bool isRelocationScattered(const macho::RelocationEntry &RE) const;
|
||||
unsigned getPlainRelocationSymbolNum(const macho::RelocationEntry &RE) const;
|
||||
bool getPlainRelocationExternal(const macho::RelocationEntry &RE) const;
|
||||
bool getScatteredRelocationScattered(const macho::RelocationEntry &RE) const;
|
||||
uint32_t getScatteredRelocationValue(const macho::RelocationEntry &RE) const;
|
||||
unsigned getAnyRelocationAddress(const macho::RelocationEntry &RE) const;
|
||||
unsigned getAnyRelocationPCRel(const macho::RelocationEntry &RE) const;
|
||||
unsigned getAnyRelocationLength(const macho::RelocationEntry &RE) const;
|
||||
unsigned getAnyRelocationType(const macho::RelocationEntry &RE) const;
|
||||
|
||||
// Walk load commands.
|
||||
LoadCommandInfo getFirstLoadCommandInfo() const;
|
||||
LoadCommandInfo getNextLoadCommandInfo(const LoadCommandInfo &L) const;
|
||||
|
||||
// MachO specific structures.
|
||||
macho::Section getSection(DataRefImpl DRI) const;
|
||||
macho::Section64 getSection64(DataRefImpl DRI) const;
|
||||
macho::SymbolTableEntry getSymbolTableEntry(DataRefImpl DRI) const;
|
||||
macho::Symbol64TableEntry getSymbol64TableEntry(DataRefImpl DRI) const;
|
||||
macho::LinkeditDataLoadCommand
|
||||
getLinkeditDataLoadCommand(const LoadCommandInfo &L) const;
|
||||
macho::RelocationEntry getRelocation(DataRefImpl Rel) const;
|
||||
macho::Header getHeader() const;
|
||||
macho::SymtabLoadCommand getSymtabLoadCommand() const;
|
||||
|
||||
bool is64Bit() const;
|
||||
void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
|
||||
|
||||
static bool classof(const Binary *v) {
|
||||
return v->isMachO();
|
||||
}
|
||||
|
||||
private:
|
||||
typedef SmallVector<const char*, 1> SectionList;
|
||||
SectionList Sections;
|
||||
const char *SymtabLoadCmd;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
415
thirdparty/clang/include/llvm/Object/MachOFormat.h
vendored
Normal file
415
thirdparty/clang/include/llvm/Object/MachOFormat.h
vendored
Normal file
@@ -0,0 +1,415 @@
|
||||
//===- MachOFormat.h - Mach-O Format Structures And Constants ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares various structures and constants which are platform
|
||||
// independent and can be shared by any client which wishes to interact with
|
||||
// Mach object files.
|
||||
//
|
||||
// The definitions here are purposely chosen to match the LLVM style as opposed
|
||||
// to following the platform specific definition of the format.
|
||||
//
|
||||
// On a Mach system, see the <mach-o/...> includes for more information, in
|
||||
// particular <mach-o/loader.h>.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_OBJECT_MACHOFORMAT_H
|
||||
#define LLVM_OBJECT_MACHOFORMAT_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace object {
|
||||
|
||||
/// General Mach platform information.
|
||||
namespace mach {
|
||||
/// @name CPU Type and Subtype Information
|
||||
/// {
|
||||
|
||||
/// \brief Capability bits used in CPU type encoding.
|
||||
enum CPUTypeFlagsMask {
|
||||
CTFM_ArchMask = 0xFF000000,
|
||||
CTFM_ArchABI64 = 0x01000000
|
||||
};
|
||||
|
||||
/// \brief Machine type IDs used in CPU type encoding.
|
||||
enum CPUTypeMachine {
|
||||
CTM_i386 = 7,
|
||||
CTM_x86_64 = CTM_i386 | CTFM_ArchABI64,
|
||||
CTM_ARM = 12,
|
||||
CTM_SPARC = 14,
|
||||
CTM_PowerPC = 18,
|
||||
CTM_PowerPC64 = CTM_PowerPC | CTFM_ArchABI64
|
||||
};
|
||||
|
||||
/// \brief Capability bits used in CPU subtype encoding.
|
||||
enum CPUSubtypeFlagsMask {
|
||||
CSFM_SubtypeMask = 0xFF000000,
|
||||
CSFM_SubtypeLib64 = 0x80000000
|
||||
};
|
||||
|
||||
/// \brief ARM Machine Subtypes.
|
||||
enum CPUSubtypeARM {
|
||||
CSARM_ALL = 0,
|
||||
CSARM_V4T = 5,
|
||||
CSARM_V6 = 6,
|
||||
CSARM_V5TEJ = 7,
|
||||
CSARM_XSCALE = 8,
|
||||
CSARM_V7 = 9,
|
||||
CSARM_V7F = 10,
|
||||
CSARM_V7S = 11,
|
||||
CSARM_V7K = 12,
|
||||
CSARM_V6M = 14,
|
||||
CSARM_V7M = 15,
|
||||
CSARM_V7EM = 16
|
||||
};
|
||||
|
||||
/// \brief PowerPC Machine Subtypes.
|
||||
enum CPUSubtypePowerPC {
|
||||
CSPPC_ALL = 0
|
||||
};
|
||||
|
||||
/// \brief SPARC Machine Subtypes.
|
||||
enum CPUSubtypeSPARC {
|
||||
CSSPARC_ALL = 0
|
||||
};
|
||||
|
||||
/// \brief x86 Machine Subtypes.
|
||||
enum CPUSubtypeX86 {
|
||||
CSX86_ALL = 3
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
} // end namespace mach
|
||||
|
||||
/// Format information for Mach object files.
|
||||
namespace macho {
|
||||
/// \brief Constants for structure sizes.
|
||||
enum StructureSizes {
|
||||
Header32Size = 28,
|
||||
Header64Size = 32,
|
||||
SegmentLoadCommand32Size = 56,
|
||||
SegmentLoadCommand64Size = 72,
|
||||
Section32Size = 68,
|
||||
Section64Size = 80,
|
||||
SymtabLoadCommandSize = 24,
|
||||
DysymtabLoadCommandSize = 80,
|
||||
Nlist32Size = 12,
|
||||
Nlist64Size = 16,
|
||||
RelocationInfoSize = 8,
|
||||
LinkeditLoadCommandSize = 16
|
||||
};
|
||||
|
||||
/// \brief Constants for header magic field.
|
||||
enum HeaderMagic {
|
||||
HM_Object32 = 0xFEEDFACE, ///< 32-bit mach object file
|
||||
HM_Object64 = 0xFEEDFACF, ///< 64-bit mach object file
|
||||
HM_Universal = 0xCAFEBABE ///< Universal object file
|
||||
};
|
||||
|
||||
/// \brief Header common to all Mach object files.
|
||||
struct Header {
|
||||
uint32_t Magic;
|
||||
uint32_t CPUType;
|
||||
uint32_t CPUSubtype;
|
||||
uint32_t FileType;
|
||||
uint32_t NumLoadCommands;
|
||||
uint32_t SizeOfLoadCommands;
|
||||
uint32_t Flags;
|
||||
};
|
||||
|
||||
/// \brief Extended header for 64-bit object files.
|
||||
struct Header64Ext {
|
||||
uint32_t Reserved;
|
||||
};
|
||||
|
||||
// See <mach-o/loader.h>.
|
||||
enum HeaderFileType {
|
||||
HFT_Object = 0x1
|
||||
};
|
||||
|
||||
enum HeaderFlags {
|
||||
HF_SubsectionsViaSymbols = 0x2000
|
||||
};
|
||||
|
||||
enum LoadCommandType {
|
||||
LCT_Segment = 0x1,
|
||||
LCT_Symtab = 0x2,
|
||||
LCT_Dysymtab = 0xb,
|
||||
LCT_Segment64 = 0x19,
|
||||
LCT_UUID = 0x1b,
|
||||
LCT_CodeSignature = 0x1d,
|
||||
LCT_SegmentSplitInfo = 0x1e,
|
||||
LCT_FunctionStarts = 0x26,
|
||||
LCT_DataInCode = 0x29,
|
||||
LCT_LinkerOptions = 0x2D
|
||||
};
|
||||
|
||||
/// \brief Load command structure.
|
||||
struct LoadCommand {
|
||||
uint32_t Type;
|
||||
uint32_t Size;
|
||||
};
|
||||
|
||||
/// @name Load Command Structures
|
||||
/// @{
|
||||
|
||||
struct SegmentLoadCommand {
|
||||
uint32_t Type;
|
||||
uint32_t Size;
|
||||
char Name[16];
|
||||
uint32_t VMAddress;
|
||||
uint32_t VMSize;
|
||||
uint32_t FileOffset;
|
||||
uint32_t FileSize;
|
||||
uint32_t MaxVMProtection;
|
||||
uint32_t InitialVMProtection;
|
||||
uint32_t NumSections;
|
||||
uint32_t Flags;
|
||||
};
|
||||
|
||||
struct Segment64LoadCommand {
|
||||
uint32_t Type;
|
||||
uint32_t Size;
|
||||
char Name[16];
|
||||
uint64_t VMAddress;
|
||||
uint64_t VMSize;
|
||||
uint64_t FileOffset;
|
||||
uint64_t FileSize;
|
||||
uint32_t MaxVMProtection;
|
||||
uint32_t InitialVMProtection;
|
||||
uint32_t NumSections;
|
||||
uint32_t Flags;
|
||||
};
|
||||
|
||||
struct SymtabLoadCommand {
|
||||
uint32_t Type;
|
||||
uint32_t Size;
|
||||
uint32_t SymbolTableOffset;
|
||||
uint32_t NumSymbolTableEntries;
|
||||
uint32_t StringTableOffset;
|
||||
uint32_t StringTableSize;
|
||||
};
|
||||
|
||||
struct DysymtabLoadCommand {
|
||||
uint32_t Type;
|
||||
uint32_t Size;
|
||||
|
||||
uint32_t LocalSymbolsIndex;
|
||||
uint32_t NumLocalSymbols;
|
||||
|
||||
uint32_t ExternalSymbolsIndex;
|
||||
uint32_t NumExternalSymbols;
|
||||
|
||||
uint32_t UndefinedSymbolsIndex;
|
||||
uint32_t NumUndefinedSymbols;
|
||||
|
||||
uint32_t TOCOffset;
|
||||
uint32_t NumTOCEntries;
|
||||
|
||||
uint32_t ModuleTableOffset;
|
||||
uint32_t NumModuleTableEntries;
|
||||
|
||||
uint32_t ReferenceSymbolTableOffset;
|
||||
uint32_t NumReferencedSymbolTableEntries;
|
||||
|
||||
uint32_t IndirectSymbolTableOffset;
|
||||
uint32_t NumIndirectSymbolTableEntries;
|
||||
|
||||
uint32_t ExternalRelocationTableOffset;
|
||||
uint32_t NumExternalRelocationTableEntries;
|
||||
|
||||
uint32_t LocalRelocationTableOffset;
|
||||
uint32_t NumLocalRelocationTableEntries;
|
||||
};
|
||||
|
||||
struct LinkeditDataLoadCommand {
|
||||
uint32_t Type;
|
||||
uint32_t Size;
|
||||
uint32_t DataOffset;
|
||||
uint32_t DataSize;
|
||||
};
|
||||
|
||||
struct LinkerOptionsLoadCommand {
|
||||
uint32_t Type;
|
||||
uint32_t Size;
|
||||
uint32_t Count;
|
||||
// Load command is followed by Count number of zero-terminated UTF8 strings,
|
||||
// and then zero-filled to be 4-byte aligned.
|
||||
};
|
||||
|
||||
/// @}
|
||||
/// @name Section Data
|
||||
/// @{
|
||||
|
||||
enum SectionFlags {
|
||||
SF_PureInstructions = 0x80000000
|
||||
};
|
||||
|
||||
struct Section {
|
||||
char Name[16];
|
||||
char SegmentName[16];
|
||||
uint32_t Address;
|
||||
uint32_t Size;
|
||||
uint32_t Offset;
|
||||
uint32_t Align;
|
||||
uint32_t RelocationTableOffset;
|
||||
uint32_t NumRelocationTableEntries;
|
||||
uint32_t Flags;
|
||||
uint32_t Reserved1;
|
||||
uint32_t Reserved2;
|
||||
};
|
||||
struct Section64 {
|
||||
char Name[16];
|
||||
char SegmentName[16];
|
||||
uint64_t Address;
|
||||
uint64_t Size;
|
||||
uint32_t Offset;
|
||||
uint32_t Align;
|
||||
uint32_t RelocationTableOffset;
|
||||
uint32_t NumRelocationTableEntries;
|
||||
uint32_t Flags;
|
||||
uint32_t Reserved1;
|
||||
uint32_t Reserved2;
|
||||
uint32_t Reserved3;
|
||||
};
|
||||
|
||||
/// @}
|
||||
/// @name Symbol Table Entries
|
||||
/// @{
|
||||
|
||||
struct SymbolTableEntry {
|
||||
uint32_t StringIndex;
|
||||
uint8_t Type;
|
||||
uint8_t SectionIndex;
|
||||
uint16_t Flags;
|
||||
uint32_t Value;
|
||||
};
|
||||
// Despite containing a uint64_t, this structure is only 4-byte aligned within
|
||||
// a MachO file.
|
||||
#pragma pack(push)
|
||||
#pragma pack(4)
|
||||
struct Symbol64TableEntry {
|
||||
uint32_t StringIndex;
|
||||
uint8_t Type;
|
||||
uint8_t SectionIndex;
|
||||
uint16_t Flags;
|
||||
uint64_t Value;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
/// @}
|
||||
/// @name Data-in-code Table Entry
|
||||
/// @{
|
||||
|
||||
// See <mach-o/loader.h>.
|
||||
enum DataRegionType { Data = 1, JumpTable8, JumpTable16, JumpTable32 };
|
||||
struct DataInCodeTableEntry {
|
||||
uint32_t Offset; /* from mach_header to start of data region */
|
||||
uint16_t Length; /* number of bytes in data region */
|
||||
uint16_t Kind; /* a DataRegionType value */
|
||||
};
|
||||
|
||||
/// @}
|
||||
/// @name Indirect Symbol Table
|
||||
/// @{
|
||||
|
||||
struct IndirectSymbolTableEntry {
|
||||
uint32_t Index;
|
||||
};
|
||||
|
||||
/// @}
|
||||
/// @name Relocation Data
|
||||
/// @{
|
||||
|
||||
struct RelocationEntry {
|
||||
uint32_t Word0;
|
||||
uint32_t Word1;
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
// See <mach-o/nlist.h>.
|
||||
enum SymbolTypeType {
|
||||
STT_Undefined = 0x00,
|
||||
STT_Absolute = 0x02,
|
||||
STT_Section = 0x0e
|
||||
};
|
||||
|
||||
enum SymbolTypeFlags {
|
||||
// If any of these bits are set, then the entry is a stab entry number (see
|
||||
// <mach-o/stab.h>. Otherwise the other masks apply.
|
||||
STF_StabsEntryMask = 0xe0,
|
||||
|
||||
STF_TypeMask = 0x0e,
|
||||
STF_External = 0x01,
|
||||
STF_PrivateExtern = 0x10
|
||||
};
|
||||
|
||||
/// IndirectSymbolFlags - Flags for encoding special values in the indirect
|
||||
/// symbol entry.
|
||||
enum IndirectSymbolFlags {
|
||||
ISF_Local = 0x80000000,
|
||||
ISF_Absolute = 0x40000000
|
||||
};
|
||||
|
||||
/// RelocationFlags - Special flags for addresses.
|
||||
enum RelocationFlags {
|
||||
RF_Scattered = 0x80000000
|
||||
};
|
||||
|
||||
/// Common relocation info types.
|
||||
enum RelocationInfoType {
|
||||
RIT_Vanilla = 0,
|
||||
RIT_Pair = 1,
|
||||
RIT_Difference = 2
|
||||
};
|
||||
|
||||
/// Generic relocation info types, which are shared by some (but not all)
|
||||
/// platforms.
|
||||
enum RelocationInfoType_Generic {
|
||||
RIT_Generic_PreboundLazyPointer = 3,
|
||||
RIT_Generic_LocalDifference = 4,
|
||||
RIT_Generic_TLV = 5
|
||||
};
|
||||
|
||||
/// X86_64 uses its own relocation types.
|
||||
enum RelocationInfoTypeX86_64 {
|
||||
// Note that x86_64 doesn't even share the common relocation types.
|
||||
RIT_X86_64_Unsigned = 0,
|
||||
RIT_X86_64_Signed = 1,
|
||||
RIT_X86_64_Branch = 2,
|
||||
RIT_X86_64_GOTLoad = 3,
|
||||
RIT_X86_64_GOT = 4,
|
||||
RIT_X86_64_Subtractor = 5,
|
||||
RIT_X86_64_Signed1 = 6,
|
||||
RIT_X86_64_Signed2 = 7,
|
||||
RIT_X86_64_Signed4 = 8,
|
||||
RIT_X86_64_TLV = 9
|
||||
};
|
||||
|
||||
/// ARM uses its own relocation types.
|
||||
enum RelocationInfoTypeARM {
|
||||
RIT_ARM_LocalDifference = 3,
|
||||
RIT_ARM_PreboundLazyPointer = 4,
|
||||
RIT_ARM_Branch24Bit = 5,
|
||||
RIT_ARM_ThumbBranch22Bit = 6,
|
||||
RIT_ARM_ThumbBranch32Bit = 7,
|
||||
RIT_ARM_Half = 8,
|
||||
RIT_ARM_HalfDifference = 9
|
||||
|
||||
};
|
||||
|
||||
} // end namespace macho
|
||||
|
||||
} // end namespace object
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
212
thirdparty/clang/include/llvm/Object/MachOObject.h
vendored
Normal file
212
thirdparty/clang/include/llvm/Object/MachOObject.h
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
//===- MachOObject.h - Mach-O Object File Wrapper ---------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_OBJECT_MACHOOBJECT_H
|
||||
#define LLVM_OBJECT_MACHOOBJECT_H
|
||||
|
||||
#include "llvm/ADT/InMemoryStruct.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Object/MachOFormat.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MemoryBuffer;
|
||||
class raw_ostream;
|
||||
|
||||
namespace object {
|
||||
|
||||
/// \brief Wrapper object for manipulating Mach-O object files.
|
||||
///
|
||||
/// This class is designed to implement a full-featured, efficient, portable,
|
||||
/// and robust Mach-O interface to Mach-O object files. It does not attempt to
|
||||
/// smooth over rough edges in the Mach-O format or generalize access to object
|
||||
/// independent features.
|
||||
///
|
||||
/// The class is designed around accessing the Mach-O object which is expected
|
||||
/// to be fully loaded into memory.
|
||||
///
|
||||
/// This class is *not* suitable for concurrent use. For efficient operation,
|
||||
/// the class uses APIs which rely on the ability to cache the results of
|
||||
/// certain calls in internal objects which are not safe for concurrent
|
||||
/// access. This allows the API to be zero-copy on the common paths.
|
||||
//
|
||||
// FIXME: It would be cool if we supported a "paged" MemoryBuffer
|
||||
// implementation. This would allow us to implement a more sensible version of
|
||||
// MemoryObject which can work like a MemoryBuffer, but be more efficient for
|
||||
// objects which are in the current address space.
|
||||
class MachOObject {
|
||||
public:
|
||||
struct LoadCommandInfo {
|
||||
/// The load command information.
|
||||
macho::LoadCommand Command;
|
||||
|
||||
/// The offset to the start of the load command in memory.
|
||||
uint64_t Offset;
|
||||
};
|
||||
|
||||
private:
|
||||
OwningPtr<MemoryBuffer> Buffer;
|
||||
|
||||
/// Whether the object is little endian.
|
||||
bool IsLittleEndian;
|
||||
/// Whether the object is 64-bit.
|
||||
bool Is64Bit;
|
||||
/// Whether the object is swapped endianness from the host.
|
||||
bool IsSwappedEndian;
|
||||
/// Whether the string table has been registered.
|
||||
bool HasStringTable;
|
||||
|
||||
/// The cached information on the load commands.
|
||||
LoadCommandInfo *LoadCommands;
|
||||
mutable unsigned NumLoadedCommands;
|
||||
|
||||
/// The cached copy of the header.
|
||||
macho::Header Header;
|
||||
macho::Header64Ext Header64Ext;
|
||||
|
||||
/// Cache string table information.
|
||||
StringRef StringTable;
|
||||
|
||||
private:
|
||||
MachOObject(MemoryBuffer *Buffer, bool IsLittleEndian, bool Is64Bit);
|
||||
|
||||
public:
|
||||
~MachOObject();
|
||||
|
||||
/// \brief Load a Mach-O object from a MemoryBuffer object.
|
||||
///
|
||||
/// \param Buffer - The buffer to load the object from. This routine takes
|
||||
/// exclusive ownership of the buffer (which is passed to the returned object
|
||||
/// on success).
|
||||
/// \param ErrorStr [out] - If given, will be set to a user readable error
|
||||
/// message on failure.
|
||||
/// \returns The loaded object, or null on error.
|
||||
static MachOObject *LoadFromBuffer(MemoryBuffer *Buffer,
|
||||
std::string *ErrorStr = 0);
|
||||
|
||||
/// @name File Information
|
||||
/// @{
|
||||
|
||||
bool isLittleEndian() const { return IsLittleEndian; }
|
||||
bool isSwappedEndian() const { return IsSwappedEndian; }
|
||||
bool is64Bit() const { return Is64Bit; }
|
||||
|
||||
unsigned getHeaderSize() const {
|
||||
return Is64Bit ? macho::Header64Size : macho::Header32Size;
|
||||
}
|
||||
|
||||
StringRef getData(size_t Offset, size_t Size) const;
|
||||
|
||||
/// @}
|
||||
/// @name String Table Data
|
||||
/// @{
|
||||
|
||||
StringRef getStringTableData() const {
|
||||
assert(HasStringTable && "String table has not been registered!");
|
||||
return StringTable;
|
||||
}
|
||||
|
||||
StringRef getStringAtIndex(unsigned Index) const {
|
||||
size_t End = getStringTableData().find('\0', Index);
|
||||
return getStringTableData().slice(Index, End);
|
||||
}
|
||||
|
||||
void RegisterStringTable(macho::SymtabLoadCommand &SLC);
|
||||
|
||||
/// @}
|
||||
/// @name Object Header Access
|
||||
/// @{
|
||||
|
||||
const macho::Header &getHeader() const { return Header; }
|
||||
const macho::Header64Ext &getHeader64Ext() const {
|
||||
assert(is64Bit() && "Invalid access!");
|
||||
return Header64Ext;
|
||||
}
|
||||
|
||||
/// @}
|
||||
/// @name Object Structure Access
|
||||
/// @{
|
||||
|
||||
// TODO: Would be useful to have an iterator based version
|
||||
// of this.
|
||||
/// \brief Retrieve the information for the given load command.
|
||||
const LoadCommandInfo &getLoadCommandInfo(unsigned Index) const;
|
||||
|
||||
void ReadSegmentLoadCommand(
|
||||
const LoadCommandInfo &LCI,
|
||||
InMemoryStruct<macho::SegmentLoadCommand> &Res) const;
|
||||
void ReadSegment64LoadCommand(
|
||||
const LoadCommandInfo &LCI,
|
||||
InMemoryStruct<macho::Segment64LoadCommand> &Res) const;
|
||||
void ReadSymtabLoadCommand(
|
||||
const LoadCommandInfo &LCI,
|
||||
InMemoryStruct<macho::SymtabLoadCommand> &Res) const;
|
||||
void ReadDysymtabLoadCommand(
|
||||
const LoadCommandInfo &LCI,
|
||||
InMemoryStruct<macho::DysymtabLoadCommand> &Res) const;
|
||||
void ReadLinkeditDataLoadCommand(
|
||||
const LoadCommandInfo &LCI,
|
||||
InMemoryStruct<macho::LinkeditDataLoadCommand> &Res) const;
|
||||
void ReadLinkerOptionsLoadCommand(
|
||||
const LoadCommandInfo &LCI,
|
||||
InMemoryStruct<macho::LinkerOptionsLoadCommand> &Res) const;
|
||||
void ReadIndirectSymbolTableEntry(
|
||||
const macho::DysymtabLoadCommand &DLC,
|
||||
unsigned Index,
|
||||
InMemoryStruct<macho::IndirectSymbolTableEntry> &Res) const;
|
||||
void ReadSection(
|
||||
const LoadCommandInfo &LCI,
|
||||
unsigned Index,
|
||||
InMemoryStruct<macho::Section> &Res) const;
|
||||
void ReadSection64(
|
||||
const LoadCommandInfo &LCI,
|
||||
unsigned Index,
|
||||
InMemoryStruct<macho::Section64> &Res) const;
|
||||
void ReadRelocationEntry(
|
||||
uint64_t RelocationTableOffset, unsigned Index,
|
||||
InMemoryStruct<macho::RelocationEntry> &Res) const;
|
||||
void ReadSymbolTableEntry(
|
||||
uint64_t SymbolTableOffset, unsigned Index,
|
||||
InMemoryStruct<macho::SymbolTableEntry> &Res) const;
|
||||
void ReadSymbol64TableEntry(
|
||||
uint64_t SymbolTableOffset, unsigned Index,
|
||||
InMemoryStruct<macho::Symbol64TableEntry> &Res) const;
|
||||
void ReadDataInCodeTableEntry(
|
||||
uint64_t TableOffset, unsigned Index,
|
||||
InMemoryStruct<macho::DataInCodeTableEntry> &Res) const;
|
||||
void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Object Dump Facilities
|
||||
/// @{
|
||||
/// dump - Support for debugging, callable in GDB: V->dump()
|
||||
//
|
||||
void dump() const;
|
||||
void dumpHeader() const;
|
||||
|
||||
/// print - Implement operator<< on Value.
|
||||
///
|
||||
void print(raw_ostream &O) const;
|
||||
void printHeader(raw_ostream &O) const;
|
||||
|
||||
/// @}
|
||||
};
|
||||
|
||||
inline raw_ostream &operator<<(raw_ostream &OS, const MachOObject &V) {
|
||||
V.print(OS);
|
||||
return OS;
|
||||
}
|
||||
|
||||
} // end namespace object
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
619
thirdparty/clang/include/llvm/Object/ObjectFile.h
vendored
Normal file
619
thirdparty/clang/include/llvm/Object/ObjectFile.h
vendored
Normal file
@@ -0,0 +1,619 @@
|
||||
//===- ObjectFile.h - File format independent object file -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares a file format independent ObjectFile class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_OBJECT_OBJECTFILE_H
|
||||
#define LLVM_OBJECT_OBJECTFILE_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Object/Binary.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
namespace object {
|
||||
|
||||
class ObjectFile;
|
||||
|
||||
union DataRefImpl {
|
||||
struct {
|
||||
// ELF needs this for relocations. This entire union should probably be a
|
||||
// char[max(8, sizeof(uintptr_t))] and require the impl to cast.
|
||||
uint16_t a, b;
|
||||
uint32_t c;
|
||||
} w;
|
||||
struct {
|
||||
uint32_t a, b;
|
||||
} d;
|
||||
uintptr_t p;
|
||||
DataRefImpl() {
|
||||
std::memset(this, 0, sizeof(DataRefImpl));
|
||||
}
|
||||
};
|
||||
|
||||
template<class content_type>
|
||||
class content_iterator {
|
||||
content_type Current;
|
||||
public:
|
||||
content_iterator(content_type symb)
|
||||
: Current(symb) {}
|
||||
|
||||
const content_type* operator->() const {
|
||||
return &Current;
|
||||
}
|
||||
|
||||
const content_type &operator*() const {
|
||||
return Current;
|
||||
}
|
||||
|
||||
bool operator==(const content_iterator &other) const {
|
||||
return Current == other.Current;
|
||||
}
|
||||
|
||||
bool operator!=(const content_iterator &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
content_iterator& increment(error_code &err) {
|
||||
content_type next;
|
||||
if (error_code ec = Current.getNext(next))
|
||||
err = ec;
|
||||
else
|
||||
Current = next;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
|
||||
// Check bitwise identical. This is the only legal way to compare a union w/o
|
||||
// knowing which member is in use.
|
||||
return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
|
||||
}
|
||||
|
||||
inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
|
||||
// Check bitwise identical. This is the only legal way to compare a union w/o
|
||||
// knowing which member is in use.
|
||||
return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
|
||||
}
|
||||
|
||||
class SymbolRef;
|
||||
|
||||
/// RelocationRef - This is a value type class that represents a single
|
||||
/// relocation in the list of relocations in the object file.
|
||||
class RelocationRef {
|
||||
DataRefImpl RelocationPimpl;
|
||||
const ObjectFile *OwningObject;
|
||||
|
||||
public:
|
||||
RelocationRef() : OwningObject(NULL) { }
|
||||
|
||||
RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
|
||||
|
||||
bool operator==(const RelocationRef &Other) const;
|
||||
|
||||
error_code getNext(RelocationRef &Result) const;
|
||||
|
||||
error_code getAddress(uint64_t &Result) const;
|
||||
error_code getOffset(uint64_t &Result) const;
|
||||
error_code getSymbol(SymbolRef &Result) const;
|
||||
error_code getType(uint64_t &Result) const;
|
||||
|
||||
/// @brief Indicates whether this relocation should hidden when listing
|
||||
/// relocations, usually because it is the trailing part of a multipart
|
||||
/// relocation that will be printed as part of the leading relocation.
|
||||
error_code getHidden(bool &Result) const;
|
||||
|
||||
/// @brief Get a string that represents the type of this relocation.
|
||||
///
|
||||
/// This is for display purposes only.
|
||||
error_code getTypeName(SmallVectorImpl<char> &Result) const;
|
||||
error_code getAdditionalInfo(int64_t &Result) const;
|
||||
|
||||
/// @brief Get a string that represents the calculation of the value of this
|
||||
/// relocation.
|
||||
///
|
||||
/// This is for display purposes only.
|
||||
error_code getValueString(SmallVectorImpl<char> &Result) const;
|
||||
|
||||
DataRefImpl getRawDataRefImpl() const;
|
||||
};
|
||||
typedef content_iterator<RelocationRef> relocation_iterator;
|
||||
|
||||
/// SectionRef - This is a value type class that represents a single section in
|
||||
/// the list of sections in the object file.
|
||||
class SectionRef {
|
||||
friend class SymbolRef;
|
||||
DataRefImpl SectionPimpl;
|
||||
const ObjectFile *OwningObject;
|
||||
|
||||
public:
|
||||
SectionRef() : OwningObject(NULL) { }
|
||||
|
||||
SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
|
||||
|
||||
bool operator==(const SectionRef &Other) const;
|
||||
bool operator<(const SectionRef &Other) const;
|
||||
|
||||
error_code getNext(SectionRef &Result) const;
|
||||
|
||||
error_code getName(StringRef &Result) const;
|
||||
error_code getAddress(uint64_t &Result) const;
|
||||
error_code getSize(uint64_t &Result) const;
|
||||
error_code getContents(StringRef &Result) const;
|
||||
|
||||
/// @brief Get the alignment of this section as the actual value (not log 2).
|
||||
error_code getAlignment(uint64_t &Result) const;
|
||||
|
||||
// FIXME: Move to the normalization layer when it's created.
|
||||
error_code isText(bool &Result) const;
|
||||
error_code isData(bool &Result) const;
|
||||
error_code isBSS(bool &Result) const;
|
||||
error_code isRequiredForExecution(bool &Result) const;
|
||||
error_code isVirtual(bool &Result) const;
|
||||
error_code isZeroInit(bool &Result) const;
|
||||
error_code isReadOnlyData(bool &Result) const;
|
||||
|
||||
error_code containsSymbol(SymbolRef S, bool &Result) const;
|
||||
|
||||
relocation_iterator begin_relocations() const;
|
||||
relocation_iterator end_relocations() const;
|
||||
|
||||
DataRefImpl getRawDataRefImpl() const;
|
||||
};
|
||||
typedef content_iterator<SectionRef> section_iterator;
|
||||
|
||||
/// SymbolRef - This is a value type class that represents a single symbol in
|
||||
/// the list of symbols in the object file.
|
||||
class SymbolRef {
|
||||
friend class SectionRef;
|
||||
DataRefImpl SymbolPimpl;
|
||||
const ObjectFile *OwningObject;
|
||||
|
||||
public:
|
||||
SymbolRef() : OwningObject(NULL) { }
|
||||
|
||||
enum Type {
|
||||
ST_Unknown, // Type not specified
|
||||
ST_Data,
|
||||
ST_Debug,
|
||||
ST_File,
|
||||
ST_Function,
|
||||
ST_Other
|
||||
};
|
||||
|
||||
enum Flags {
|
||||
SF_None = 0,
|
||||
SF_Undefined = 1U << 0, // Symbol is defined in another object file
|
||||
SF_Global = 1U << 1, // Global symbol
|
||||
SF_Weak = 1U << 2, // Weak symbol
|
||||
SF_Absolute = 1U << 3, // Absolute symbol
|
||||
SF_ThreadLocal = 1U << 4, // Thread local symbol
|
||||
SF_Common = 1U << 5, // Symbol has common linkage
|
||||
SF_FormatSpecific = 1U << 31 // Specific to the object file format
|
||||
// (e.g. section symbols)
|
||||
};
|
||||
|
||||
SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
|
||||
|
||||
bool operator==(const SymbolRef &Other) const;
|
||||
bool operator<(const SymbolRef &Other) const;
|
||||
|
||||
error_code getNext(SymbolRef &Result) const;
|
||||
|
||||
error_code getName(StringRef &Result) const;
|
||||
/// Returns the symbol virtual address (i.e. address at which it will be
|
||||
/// mapped).
|
||||
error_code getAddress(uint64_t &Result) const;
|
||||
error_code getFileOffset(uint64_t &Result) const;
|
||||
error_code getSize(uint64_t &Result) const;
|
||||
error_code getType(SymbolRef::Type &Result) const;
|
||||
|
||||
/// Returns the ascii char that should be displayed in a symbol table dump via
|
||||
/// nm for this symbol.
|
||||
error_code getNMTypeChar(char &Result) const;
|
||||
|
||||
/// Get symbol flags (bitwise OR of SymbolRef::Flags)
|
||||
error_code getFlags(uint32_t &Result) const;
|
||||
|
||||
/// @brief Return true for common symbols such as uninitialized globals
|
||||
error_code isCommon(bool &Result) const;
|
||||
|
||||
/// @brief Get section this symbol is defined in reference to. Result is
|
||||
/// end_sections() if it is undefined or is an absolute symbol.
|
||||
error_code getSection(section_iterator &Result) const;
|
||||
|
||||
/// @brief Get value of the symbol in the symbol table.
|
||||
error_code getValue(uint64_t &Val) const;
|
||||
|
||||
DataRefImpl getRawDataRefImpl() const;
|
||||
};
|
||||
typedef content_iterator<SymbolRef> symbol_iterator;
|
||||
|
||||
/// LibraryRef - This is a value type class that represents a single library in
|
||||
/// the list of libraries needed by a shared or dynamic object.
|
||||
class LibraryRef {
|
||||
friend class SectionRef;
|
||||
DataRefImpl LibraryPimpl;
|
||||
const ObjectFile *OwningObject;
|
||||
|
||||
public:
|
||||
LibraryRef() : OwningObject(NULL) { }
|
||||
|
||||
LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner);
|
||||
|
||||
bool operator==(const LibraryRef &Other) const;
|
||||
bool operator<(const LibraryRef &Other) const;
|
||||
|
||||
error_code getNext(LibraryRef &Result) const;
|
||||
|
||||
// Get the path to this library, as stored in the object file.
|
||||
error_code getPath(StringRef &Result) const;
|
||||
|
||||
DataRefImpl getRawDataRefImpl() const;
|
||||
};
|
||||
typedef content_iterator<LibraryRef> library_iterator;
|
||||
|
||||
const uint64_t UnknownAddressOrSize = ~0ULL;
|
||||
|
||||
/// ObjectFile - This class is the base class for all object file types.
|
||||
/// Concrete instances of this object are created by createObjectFile, which
|
||||
/// figures out which type to create.
|
||||
class ObjectFile : public Binary {
|
||||
virtual void anchor();
|
||||
ObjectFile() LLVM_DELETED_FUNCTION;
|
||||
ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION;
|
||||
|
||||
protected:
|
||||
ObjectFile(unsigned int Type, MemoryBuffer *source);
|
||||
|
||||
const uint8_t *base() const {
|
||||
return reinterpret_cast<const uint8_t *>(Data->getBufferStart());
|
||||
}
|
||||
|
||||
// These functions are for SymbolRef to call internally. The main goal of
|
||||
// this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
|
||||
// entry in the memory mapped object file. SymbolPimpl cannot contain any
|
||||
// virtual functions because then it could not point into the memory mapped
|
||||
// file.
|
||||
//
|
||||
// Implementations assume that the DataRefImpl is valid and has not been
|
||||
// modified externally. It's UB otherwise.
|
||||
friend class SymbolRef;
|
||||
virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const = 0;
|
||||
virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0;
|
||||
virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const = 0;
|
||||
virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res)const=0;
|
||||
virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0;
|
||||
virtual error_code getSymbolType(DataRefImpl Symb,
|
||||
SymbolRef::Type &Res) const = 0;
|
||||
virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const = 0;
|
||||
virtual error_code getSymbolFlags(DataRefImpl Symb,
|
||||
uint32_t &Res) const = 0;
|
||||
virtual error_code getSymbolSection(DataRefImpl Symb,
|
||||
section_iterator &Res) const = 0;
|
||||
virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const = 0;
|
||||
|
||||
// Same as above for SectionRef.
|
||||
friend class SectionRef;
|
||||
virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const = 0;
|
||||
virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const = 0;
|
||||
virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const =0;
|
||||
virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const = 0;
|
||||
virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res)const=0;
|
||||
virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res)const=0;
|
||||
virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0;
|
||||
virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const = 0;
|
||||
virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const = 0;
|
||||
virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
|
||||
bool &Res) const = 0;
|
||||
// A section is 'virtual' if its contents aren't present in the object image.
|
||||
virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const = 0;
|
||||
virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const = 0;
|
||||
virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const =0;
|
||||
virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
|
||||
bool &Result) const = 0;
|
||||
virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const = 0;
|
||||
virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const = 0;
|
||||
|
||||
|
||||
// Same as above for RelocationRef.
|
||||
friend class RelocationRef;
|
||||
virtual error_code getRelocationNext(DataRefImpl Rel,
|
||||
RelocationRef &Res) const = 0;
|
||||
virtual error_code getRelocationAddress(DataRefImpl Rel,
|
||||
uint64_t &Res) const =0;
|
||||
virtual error_code getRelocationOffset(DataRefImpl Rel,
|
||||
uint64_t &Res) const =0;
|
||||
virtual error_code getRelocationSymbol(DataRefImpl Rel,
|
||||
SymbolRef &Res) const = 0;
|
||||
virtual error_code getRelocationType(DataRefImpl Rel,
|
||||
uint64_t &Res) const = 0;
|
||||
virtual error_code getRelocationTypeName(DataRefImpl Rel,
|
||||
SmallVectorImpl<char> &Result) const = 0;
|
||||
virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
|
||||
int64_t &Res) const = 0;
|
||||
virtual error_code getRelocationValueString(DataRefImpl Rel,
|
||||
SmallVectorImpl<char> &Result) const = 0;
|
||||
virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const {
|
||||
Result = false;
|
||||
return object_error::success;
|
||||
}
|
||||
|
||||
// Same for LibraryRef
|
||||
friend class LibraryRef;
|
||||
virtual error_code getLibraryNext(DataRefImpl Lib, LibraryRef &Res) const = 0;
|
||||
virtual error_code getLibraryPath(DataRefImpl Lib, StringRef &Res) const = 0;
|
||||
|
||||
public:
|
||||
|
||||
virtual symbol_iterator begin_symbols() const = 0;
|
||||
virtual symbol_iterator end_symbols() const = 0;
|
||||
|
||||
virtual symbol_iterator begin_dynamic_symbols() const = 0;
|
||||
virtual symbol_iterator end_dynamic_symbols() const = 0;
|
||||
|
||||
virtual section_iterator begin_sections() const = 0;
|
||||
virtual section_iterator end_sections() const = 0;
|
||||
|
||||
virtual library_iterator begin_libraries_needed() const = 0;
|
||||
virtual library_iterator end_libraries_needed() const = 0;
|
||||
|
||||
/// @brief The number of bytes used to represent an address in this object
|
||||
/// file format.
|
||||
virtual uint8_t getBytesInAddress() const = 0;
|
||||
|
||||
virtual StringRef getFileFormatName() const = 0;
|
||||
virtual /* Triple::ArchType */ unsigned getArch() const = 0;
|
||||
|
||||
/// For shared objects, returns the name which this object should be
|
||||
/// loaded from at runtime. This corresponds to DT_SONAME on ELF and
|
||||
/// LC_ID_DYLIB (install name) on MachO.
|
||||
virtual StringRef getLoadName() const = 0;
|
||||
|
||||
/// @returns Pointer to ObjectFile subclass to handle this type of object.
|
||||
/// @param ObjectPath The path to the object file. ObjectPath.isObject must
|
||||
/// return true.
|
||||
/// @brief Create ObjectFile from path.
|
||||
static ObjectFile *createObjectFile(StringRef ObjectPath);
|
||||
static ObjectFile *createObjectFile(MemoryBuffer *Object);
|
||||
|
||||
static inline bool classof(const Binary *v) {
|
||||
return v->isObject();
|
||||
}
|
||||
|
||||
public:
|
||||
static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object);
|
||||
static ObjectFile *createELFObjectFile(MemoryBuffer *Object);
|
||||
static ObjectFile *createMachOObjectFile(MemoryBuffer *Object);
|
||||
};
|
||||
|
||||
// Inline function definitions.
|
||||
inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
|
||||
: SymbolPimpl(SymbolP)
|
||||
, OwningObject(Owner) {}
|
||||
|
||||
inline bool SymbolRef::operator==(const SymbolRef &Other) const {
|
||||
return SymbolPimpl == Other.SymbolPimpl;
|
||||
}
|
||||
|
||||
inline bool SymbolRef::operator<(const SymbolRef &Other) const {
|
||||
return SymbolPimpl < Other.SymbolPimpl;
|
||||
}
|
||||
|
||||
inline error_code SymbolRef::getNext(SymbolRef &Result) const {
|
||||
return OwningObject->getSymbolNext(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SymbolRef::getName(StringRef &Result) const {
|
||||
return OwningObject->getSymbolName(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SymbolRef::getAddress(uint64_t &Result) const {
|
||||
return OwningObject->getSymbolAddress(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SymbolRef::getFileOffset(uint64_t &Result) const {
|
||||
return OwningObject->getSymbolFileOffset(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SymbolRef::getSize(uint64_t &Result) const {
|
||||
return OwningObject->getSymbolSize(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SymbolRef::getNMTypeChar(char &Result) const {
|
||||
return OwningObject->getSymbolNMTypeChar(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SymbolRef::getFlags(uint32_t &Result) const {
|
||||
return OwningObject->getSymbolFlags(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SymbolRef::getSection(section_iterator &Result) const {
|
||||
return OwningObject->getSymbolSection(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SymbolRef::getType(SymbolRef::Type &Result) const {
|
||||
return OwningObject->getSymbolType(SymbolPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SymbolRef::getValue(uint64_t &Val) const {
|
||||
return OwningObject->getSymbolValue(SymbolPimpl, Val);
|
||||
}
|
||||
|
||||
inline DataRefImpl SymbolRef::getRawDataRefImpl() const {
|
||||
return SymbolPimpl;
|
||||
}
|
||||
|
||||
|
||||
/// SectionRef
|
||||
inline SectionRef::SectionRef(DataRefImpl SectionP,
|
||||
const ObjectFile *Owner)
|
||||
: SectionPimpl(SectionP)
|
||||
, OwningObject(Owner) {}
|
||||
|
||||
inline bool SectionRef::operator==(const SectionRef &Other) const {
|
||||
return SectionPimpl == Other.SectionPimpl;
|
||||
}
|
||||
|
||||
inline bool SectionRef::operator<(const SectionRef &Other) const {
|
||||
return SectionPimpl < Other.SectionPimpl;
|
||||
}
|
||||
|
||||
inline error_code SectionRef::getNext(SectionRef &Result) const {
|
||||
return OwningObject->getSectionNext(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SectionRef::getName(StringRef &Result) const {
|
||||
return OwningObject->getSectionName(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SectionRef::getAddress(uint64_t &Result) const {
|
||||
return OwningObject->getSectionAddress(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SectionRef::getSize(uint64_t &Result) const {
|
||||
return OwningObject->getSectionSize(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SectionRef::getContents(StringRef &Result) const {
|
||||
return OwningObject->getSectionContents(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SectionRef::getAlignment(uint64_t &Result) const {
|
||||
return OwningObject->getSectionAlignment(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SectionRef::isText(bool &Result) const {
|
||||
return OwningObject->isSectionText(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SectionRef::isData(bool &Result) const {
|
||||
return OwningObject->isSectionData(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SectionRef::isBSS(bool &Result) const {
|
||||
return OwningObject->isSectionBSS(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SectionRef::isRequiredForExecution(bool &Result) const {
|
||||
return OwningObject->isSectionRequiredForExecution(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SectionRef::isVirtual(bool &Result) const {
|
||||
return OwningObject->isSectionVirtual(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SectionRef::isZeroInit(bool &Result) const {
|
||||
return OwningObject->isSectionZeroInit(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SectionRef::isReadOnlyData(bool &Result) const {
|
||||
return OwningObject->isSectionReadOnlyData(SectionPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const {
|
||||
return OwningObject->sectionContainsSymbol(SectionPimpl, S.SymbolPimpl,
|
||||
Result);
|
||||
}
|
||||
|
||||
inline relocation_iterator SectionRef::begin_relocations() const {
|
||||
return OwningObject->getSectionRelBegin(SectionPimpl);
|
||||
}
|
||||
|
||||
inline relocation_iterator SectionRef::end_relocations() const {
|
||||
return OwningObject->getSectionRelEnd(SectionPimpl);
|
||||
}
|
||||
|
||||
inline DataRefImpl SectionRef::getRawDataRefImpl() const {
|
||||
return SectionPimpl;
|
||||
}
|
||||
|
||||
/// RelocationRef
|
||||
inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
|
||||
const ObjectFile *Owner)
|
||||
: RelocationPimpl(RelocationP)
|
||||
, OwningObject(Owner) {}
|
||||
|
||||
inline bool RelocationRef::operator==(const RelocationRef &Other) const {
|
||||
return RelocationPimpl == Other.RelocationPimpl;
|
||||
}
|
||||
|
||||
inline error_code RelocationRef::getNext(RelocationRef &Result) const {
|
||||
return OwningObject->getRelocationNext(RelocationPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code RelocationRef::getAddress(uint64_t &Result) const {
|
||||
return OwningObject->getRelocationAddress(RelocationPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code RelocationRef::getOffset(uint64_t &Result) const {
|
||||
return OwningObject->getRelocationOffset(RelocationPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code RelocationRef::getSymbol(SymbolRef &Result) const {
|
||||
return OwningObject->getRelocationSymbol(RelocationPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code RelocationRef::getType(uint64_t &Result) const {
|
||||
return OwningObject->getRelocationType(RelocationPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code RelocationRef::getTypeName(SmallVectorImpl<char> &Result)
|
||||
const {
|
||||
return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code RelocationRef::getAdditionalInfo(int64_t &Result) const {
|
||||
return OwningObject->getRelocationAdditionalInfo(RelocationPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code RelocationRef::getValueString(SmallVectorImpl<char> &Result)
|
||||
const {
|
||||
return OwningObject->getRelocationValueString(RelocationPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code RelocationRef::getHidden(bool &Result) const {
|
||||
return OwningObject->getRelocationHidden(RelocationPimpl, Result);
|
||||
}
|
||||
|
||||
inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
|
||||
return RelocationPimpl;
|
||||
}
|
||||
|
||||
// Inline function definitions.
|
||||
inline LibraryRef::LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner)
|
||||
: LibraryPimpl(LibraryP)
|
||||
, OwningObject(Owner) {}
|
||||
|
||||
inline bool LibraryRef::operator==(const LibraryRef &Other) const {
|
||||
return LibraryPimpl == Other.LibraryPimpl;
|
||||
}
|
||||
|
||||
inline bool LibraryRef::operator<(const LibraryRef &Other) const {
|
||||
return LibraryPimpl < Other.LibraryPimpl;
|
||||
}
|
||||
|
||||
inline error_code LibraryRef::getNext(LibraryRef &Result) const {
|
||||
return OwningObject->getLibraryNext(LibraryPimpl, Result);
|
||||
}
|
||||
|
||||
inline error_code LibraryRef::getPath(StringRef &Result) const {
|
||||
return OwningObject->getLibraryPath(LibraryPimpl, Result);
|
||||
}
|
||||
|
||||
} // end namespace object
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
209
thirdparty/clang/include/llvm/Object/RelocVisitor.h
vendored
Normal file
209
thirdparty/clang/include/llvm/Object/RelocVisitor.h
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
//===-- RelocVisitor.h - Visitor for object file relocations -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides a wrapper around all the different types of relocations
|
||||
// in different file formats, such that a client can handle them in a unified
|
||||
// manner by only implementing a minimal number of functions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_OBJECT_RELOCVISITOR_H
|
||||
#define LLVM_OBJECT_RELOCVISITOR_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ELF.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace object {
|
||||
|
||||
struct RelocToApply {
|
||||
// The computed value after applying the relevant relocations.
|
||||
int64_t Value;
|
||||
|
||||
// The width of the value; how many bytes to touch when applying the
|
||||
// relocation.
|
||||
char Width;
|
||||
RelocToApply(const RelocToApply &In) : Value(In.Value), Width(In.Width) {}
|
||||
RelocToApply(int64_t Value, char Width) : Value(Value), Width(Width) {}
|
||||
RelocToApply() : Value(0), Width(0) {}
|
||||
};
|
||||
|
||||
/// @brief Base class for object file relocation visitors.
|
||||
class RelocVisitor {
|
||||
public:
|
||||
explicit RelocVisitor(StringRef FileFormat)
|
||||
: FileFormat(FileFormat), HasError(false) {}
|
||||
|
||||
// TODO: Should handle multiple applied relocations via either passing in the
|
||||
// previously computed value or just count paired relocations as a single
|
||||
// visit.
|
||||
RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t SecAddr = 0,
|
||||
uint64_t Value = 0) {
|
||||
if (FileFormat == "ELF64-x86-64") {
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_X86_64_NONE:
|
||||
return visitELF_X86_64_NONE(R);
|
||||
case llvm::ELF::R_X86_64_64:
|
||||
return visitELF_X86_64_64(R, Value);
|
||||
case llvm::ELF::R_X86_64_PC32:
|
||||
return visitELF_X86_64_PC32(R, Value, SecAddr);
|
||||
case llvm::ELF::R_X86_64_32:
|
||||
return visitELF_X86_64_32(R, Value);
|
||||
case llvm::ELF::R_X86_64_32S:
|
||||
return visitELF_X86_64_32S(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
} else if (FileFormat == "ELF32-i386") {
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_386_NONE:
|
||||
return visitELF_386_NONE(R);
|
||||
case llvm::ELF::R_386_32:
|
||||
return visitELF_386_32(R, Value);
|
||||
case llvm::ELF::R_386_PC32:
|
||||
return visitELF_386_PC32(R, Value, SecAddr);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
} else if (FileFormat == "ELF64-ppc64") {
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_PPC64_ADDR32:
|
||||
return visitELF_PPC64_ADDR32(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
} else if (FileFormat == "ELF32-mips") {
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_MIPS_32:
|
||||
return visitELF_MIPS_32(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
} else if (FileFormat == "ELF64-aarch64") {
|
||||
switch (RelocType) {
|
||||
case llvm::ELF::R_AARCH64_ABS32:
|
||||
return visitELF_AARCH64_ABS32(R, Value);
|
||||
case llvm::ELF::R_AARCH64_ABS64:
|
||||
return visitELF_AARCH64_ABS64(R, Value);
|
||||
default:
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
}
|
||||
HasError = true;
|
||||
return RelocToApply();
|
||||
}
|
||||
|
||||
bool error() { return HasError; }
|
||||
|
||||
private:
|
||||
StringRef FileFormat;
|
||||
bool HasError;
|
||||
|
||||
/// Operations
|
||||
|
||||
/// 386-ELF
|
||||
RelocToApply visitELF_386_NONE(RelocationRef R) {
|
||||
return RelocToApply(0, 0);
|
||||
}
|
||||
|
||||
// Ideally the Addend here will be the addend in the data for
|
||||
// the relocation. It's not actually the case for Rel relocations.
|
||||
RelocToApply visitELF_386_32(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend;
|
||||
R.getAdditionalInfo(Addend);
|
||||
return RelocToApply(Value + Addend, 4);
|
||||
}
|
||||
|
||||
RelocToApply visitELF_386_PC32(RelocationRef R, uint64_t Value,
|
||||
uint64_t SecAddr) {
|
||||
int64_t Addend;
|
||||
R.getAdditionalInfo(Addend);
|
||||
uint64_t Address;
|
||||
R.getAddress(Address);
|
||||
return RelocToApply(Value + Addend - Address, 4);
|
||||
}
|
||||
|
||||
/// X86-64 ELF
|
||||
RelocToApply visitELF_X86_64_NONE(RelocationRef R) {
|
||||
return RelocToApply(0, 0);
|
||||
}
|
||||
RelocToApply visitELF_X86_64_64(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend;
|
||||
R.getAdditionalInfo(Addend);
|
||||
return RelocToApply(Value + Addend, 8);
|
||||
}
|
||||
RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value,
|
||||
uint64_t SecAddr) {
|
||||
int64_t Addend;
|
||||
R.getAdditionalInfo(Addend);
|
||||
uint64_t Address;
|
||||
R.getAddress(Address);
|
||||
return RelocToApply(Value + Addend - Address, 4);
|
||||
}
|
||||
RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend;
|
||||
R.getAdditionalInfo(Addend);
|
||||
uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
|
||||
return RelocToApply(Res, 4);
|
||||
}
|
||||
RelocToApply visitELF_X86_64_32S(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend;
|
||||
R.getAdditionalInfo(Addend);
|
||||
int32_t Res = (Value + Addend) & 0xFFFFFFFF;
|
||||
return RelocToApply(Res, 4);
|
||||
}
|
||||
|
||||
/// PPC64 ELF
|
||||
RelocToApply visitELF_PPC64_ADDR32(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend;
|
||||
R.getAdditionalInfo(Addend);
|
||||
uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
|
||||
return RelocToApply(Res, 4);
|
||||
}
|
||||
|
||||
/// MIPS ELF
|
||||
RelocToApply visitELF_MIPS_32(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend;
|
||||
R.getAdditionalInfo(Addend);
|
||||
uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
|
||||
return RelocToApply(Res, 4);
|
||||
}
|
||||
|
||||
// AArch64 ELF
|
||||
RelocToApply visitELF_AARCH64_ABS32(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend;
|
||||
R.getAdditionalInfo(Addend);
|
||||
int64_t Res = Value + Addend;
|
||||
|
||||
// Overflow check allows for both signed and unsigned interpretation.
|
||||
if (Res < INT32_MIN || Res > UINT32_MAX)
|
||||
HasError = true;
|
||||
|
||||
return RelocToApply(static_cast<uint32_t>(Res), 4);
|
||||
}
|
||||
|
||||
RelocToApply visitELF_AARCH64_ABS64(RelocationRef R, uint64_t Value) {
|
||||
int64_t Addend;
|
||||
R.getAdditionalInfo(Addend);
|
||||
return RelocToApply(Value + Addend, 8);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user