diff options
author | dim <dim@FreeBSD.org> | 2011-07-17 15:36:56 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-07-17 15:36:56 +0000 |
commit | 1176aa52646fe641a4243a246aa7f960c708a274 (patch) | |
tree | c8086addb211fa670a9d2b1038d8c2e453229755 /include/llvm/Object | |
parent | ece02cd5829cea836e9365b0845a8ef042d17b0a (diff) | |
download | FreeBSD-src-1176aa52646fe641a4243a246aa7f960c708a274.zip FreeBSD-src-1176aa52646fe641a4243a246aa7f960c708a274.tar.gz |
Vendor import of llvm trunk r135360:
http://llvm.org/svn/llvm-project/llvm/trunk@135360
Diffstat (limited to 'include/llvm/Object')
-rw-r--r-- | include/llvm/Object/Binary.h | 67 | ||||
-rw-r--r-- | include/llvm/Object/COFF.h | 117 | ||||
-rw-r--r-- | include/llvm/Object/Error.h | 50 | ||||
-rw-r--r-- | include/llvm/Object/ObjectFile.h | 178 |
4 files changed, 346 insertions, 66 deletions
diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h new file mode 100644 index 0000000..cd092fd --- /dev/null +++ b/include/llvm/Object/Binary.h @@ -0,0 +1,67 @@ +//===- 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(); // = delete + Binary(const Binary &other); // = delete + + unsigned int TypeID; + +protected: + MemoryBuffer *Data; + + Binary(unsigned int Type, MemoryBuffer *Source); + + enum { + isArchive, + + // Object and children. + isObject, + isCOFF, + isELF, + isMachO, + lastObject + }; + +public: + virtual ~Binary(); + + StringRef getData() const; + StringRef getFileName() const; + + // Cast methods. + unsigned int getType() const { return TypeID; } + static inline bool classof(const Binary *v) { return true; } +}; + +error_code createBinary(MemoryBuffer *Source, OwningPtr<Binary> &Result); +error_code createBinary(StringRef Path, OwningPtr<Binary> &Result); + +} +} + +#endif diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h new file mode 100644 index 0000000..121f9e8 --- /dev/null +++ b/include/llvm/Object/COFF.h @@ -0,0 +1,117 @@ +//===- 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 { +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; + + struct { + support::ulittle8_t BaseType; + support::ulittle8_t ComplexType; + } Type; + + support::ulittle8_t StorageClass; + support::ulittle8_t NumberOfAuxSymbols; +}; + +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; +}; + +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 getSection(int32_t index, + const coff_section *&Res) const; + error_code getString(uint32_t offset, StringRef &Res) const; + + const coff_symbol *toSymb(DataRefImpl Symb) const; + const coff_section *toSec(DataRefImpl Sec) const; + +protected: + 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 getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; + virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const; + virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) 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 isSectionText(DataRefImpl Sec, bool &Res) const; + virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, + bool &Result) const; + +public: + COFFObjectFile(MemoryBuffer *Object, error_code &ec); + virtual symbol_iterator begin_symbols() const; + virtual symbol_iterator end_symbols() const; + virtual section_iterator begin_sections() const; + virtual section_iterator end_sections() const; + + virtual uint8_t getBytesInAddress() const; + virtual StringRef getFileFormatName() const; + virtual unsigned getArch() const; +}; + +} +} + +#endif diff --git a/include/llvm/Object/Error.h b/include/llvm/Object/Error.h new file mode 100644 index 0000000..fbaf71c --- /dev/null +++ b/include/llvm/Object/Error.h @@ -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 diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index eee9d44..98ac067 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -14,15 +14,14 @@ #ifndef LLVM_OBJECT_OBJECT_FILE_H #define LLVM_OBJECT_OBJECT_FILE_H +#include "llvm/Object/Binary.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MemoryBuffer.h" #include <cstring> namespace llvm { - -class MemoryBuffer; -class StringRef; - namespace object { class ObjectFile; @@ -31,7 +30,7 @@ union DataRefImpl { struct { uint32_t a, b; } d; - intptr_t p; + uintptr_t p; }; static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) { @@ -40,52 +39,80 @@ static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) { return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0; } +class RelocationRef { + DataRefImpl RelocationPimpl; + const ObjectFile *OwningObject; + +public: + RelocationRef() : OwningObject(NULL) { + std::memset(&RelocationPimpl, 0, sizeof(RelocationPimpl)); + } + + RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner); + + bool operator==(const RelocationRef &Other) const; + + error_code getNext(RelocationRef &Result); +}; + /// 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) { + std::memset(&SymbolPimpl, 0, sizeof(SymbolPimpl)); + } + SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner); bool operator==(const SymbolRef &Other) const; - SymbolRef getNext() const; + error_code getNext(SymbolRef &Result) const; - StringRef getName() const; - uint64_t getAddress() const; - uint64_t getSize() const; + error_code getName(StringRef &Result) const; + error_code getAddress(uint64_t &Result) const; + error_code getSize(uint64_t &Result) const; /// Returns the ascii char that should be displayed in a symbol table dump via /// nm for this symbol. - char getNMTypeChar() const; + error_code getNMTypeChar(char &Result) const; /// Returns true for symbols that are internal to the object file format such /// as section symbols. - bool isInternal() const; + error_code isInternal(bool &Result) const; }; /// 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) { + std::memset(&SectionPimpl, 0, sizeof(SectionPimpl)); + } + SectionRef(DataRefImpl SectionP, const ObjectFile *Owner); bool operator==(const SectionRef &Other) const; - SectionRef getNext() const; + error_code getNext(SectionRef &Result) const; - StringRef getName() const; - uint64_t getAddress() const; - uint64_t getSize() const; - StringRef getContents() 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; // FIXME: Move to the normalization layer when it's created. - bool isText() const; + error_code isText(bool &Result) const; + + error_code containsSymbol(SymbolRef S, bool &Result) const; }; const uint64_t UnknownAddressOrSize = ~0ULL; @@ -93,38 +120,44 @@ 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 /// figure out which type to create. -class ObjectFile { +class ObjectFile : public Binary { private: ObjectFile(); // = delete ObjectFile(const ObjectFile &other); // = delete protected: - MemoryBuffer *MapFile; - const uint8_t *base; + ObjectFile(unsigned int Type, MemoryBuffer *source, error_code &ec); - ObjectFile(MemoryBuffer *Object); + 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 SymbolRef getSymbolNext(DataRefImpl Symb) const = 0; - virtual StringRef getSymbolName(DataRefImpl Symb) const = 0; - virtual uint64_t getSymbolAddress(DataRefImpl Symb) const = 0; - virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0; - virtual char getSymbolNMTypeChar(DataRefImpl Symb) const = 0; - virtual bool isSymbolInternal(DataRefImpl Symb) const = 0; + 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 getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0; + virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const = 0; + virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const = 0; // Same as above for SectionRef. friend class SectionRef; - virtual SectionRef getSectionNext(DataRefImpl Sec) const = 0; - virtual StringRef getSectionName(DataRefImpl Sec) const = 0; - virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0; - virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0; - virtual StringRef getSectionContents(DataRefImpl Sec) const = 0; - virtual bool isSectionText(DataRefImpl Sec) const = 0; + 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 isSectionText(DataRefImpl Sec, bool &Res) const = 0; + virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, + bool &Result) const = 0; public: @@ -139,6 +172,10 @@ public: return &Current; } + const content_type &operator*() const { + return Current; + } + bool operator==(const content_iterator &other) const { return Current == other.Current; } @@ -147,8 +184,12 @@ public: return !(*this == other); } - content_iterator& operator++() { // Preincrement - Current = Current.getNext(); + content_iterator& increment(error_code &err) { + content_type next; + if (error_code ec = Current.getNext(next)) + err = ec; + else + Current = next; return *this; } }; @@ -156,8 +197,6 @@ public: typedef content_iterator<SymbolRef> symbol_iterator; typedef content_iterator<SectionRef> section_iterator; - virtual ~ObjectFile(); - virtual symbol_iterator begin_symbols() const = 0; virtual symbol_iterator end_symbols() const = 0; @@ -171,8 +210,6 @@ public: virtual StringRef getFileFormatName() const = 0; virtual /* Triple::ArchType */ unsigned getArch() const = 0; - StringRef getFilename() const; - /// @returns Pointer to ObjectFile subclass to handle this type of object. /// @param ObjectPath The path to the object file. ObjectPath.isObject must /// return true. @@ -180,12 +217,16 @@ public: static ObjectFile *createObjectFile(StringRef ObjectPath); static ObjectFile *createObjectFile(MemoryBuffer *Object); -private: + static inline bool classof(const Binary *v) { + return v->getType() >= isObject && + v->getType() < lastObject; + } + static inline bool classof(const ObjectFile *v) { return true; } + +public: static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object); static ObjectFile *createELFObjectFile(MemoryBuffer *Object); static ObjectFile *createMachOObjectFile(MemoryBuffer *Object); - static ObjectFile *createArchiveObjectFile(MemoryBuffer *Object); - static ObjectFile *createLibObjectFile(MemoryBuffer *Object); }; // Inline function definitions. @@ -197,28 +238,28 @@ inline bool SymbolRef::operator==(const SymbolRef &Other) const { return SymbolPimpl == Other.SymbolPimpl; } -inline SymbolRef SymbolRef::getNext() const { - return OwningObject->getSymbolNext(SymbolPimpl); +inline error_code SymbolRef::getNext(SymbolRef &Result) const { + return OwningObject->getSymbolNext(SymbolPimpl, Result); } -inline StringRef SymbolRef::getName() const { - return OwningObject->getSymbolName(SymbolPimpl); +inline error_code SymbolRef::getName(StringRef &Result) const { + return OwningObject->getSymbolName(SymbolPimpl, Result); } -inline uint64_t SymbolRef::getAddress() const { - return OwningObject->getSymbolAddress(SymbolPimpl); +inline error_code SymbolRef::getAddress(uint64_t &Result) const { + return OwningObject->getSymbolAddress(SymbolPimpl, Result); } -inline uint64_t SymbolRef::getSize() const { - return OwningObject->getSymbolSize(SymbolPimpl); +inline error_code SymbolRef::getSize(uint64_t &Result) const { + return OwningObject->getSymbolSize(SymbolPimpl, Result); } -inline char SymbolRef::getNMTypeChar() const { - return OwningObject->getSymbolNMTypeChar(SymbolPimpl); +inline error_code SymbolRef::getNMTypeChar(char &Result) const { + return OwningObject->getSymbolNMTypeChar(SymbolPimpl, Result); } -inline bool SymbolRef::isInternal() const { - return OwningObject->isSymbolInternal(SymbolPimpl); +inline error_code SymbolRef::isInternal(bool &Result) const { + return OwningObject->isSymbolInternal(SymbolPimpl, Result); } @@ -232,28 +273,33 @@ inline bool SectionRef::operator==(const SectionRef &Other) const { return SectionPimpl == Other.SectionPimpl; } -inline SectionRef SectionRef::getNext() const { - return OwningObject->getSectionNext(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 StringRef SectionRef::getName() const { - return OwningObject->getSectionName(SectionPimpl); +inline error_code SectionRef::getAddress(uint64_t &Result) const { + return OwningObject->getSectionAddress(SectionPimpl, Result); } -inline uint64_t SectionRef::getAddress() const { - return OwningObject->getSectionAddress(SectionPimpl); +inline error_code SectionRef::getSize(uint64_t &Result) const { + return OwningObject->getSectionSize(SectionPimpl, Result); } -inline uint64_t SectionRef::getSize() const { - return OwningObject->getSectionSize(SectionPimpl); +inline error_code SectionRef::getContents(StringRef &Result) const { + return OwningObject->getSectionContents(SectionPimpl, Result); } -inline StringRef SectionRef::getContents() const { - return OwningObject->getSectionContents(SectionPimpl); +inline error_code SectionRef::isText(bool &Result) const { + return OwningObject->isSectionText(SectionPimpl, Result); } -inline bool SectionRef::isText() const { - return OwningObject->isSectionText(SectionPimpl); +inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const { + return OwningObject->sectionContainsSymbol(SectionPimpl, S.SymbolPimpl, + Result); } } // end namespace object |