Make Binary the parent of ObjectFile and update children to new interface.

llvm-svn: 133870
This commit is contained in:
Michael J. Spencer 2011-06-25 17:54:50 +00:00
parent 8cb6d93f56
commit d5934fefee
9 changed files with 222 additions and 170 deletions

View File

@ -38,10 +38,13 @@ protected:
enum { enum {
isArchive, isArchive,
// Object and children.
isObject,
isCOFF, isCOFF,
isELF, isELF,
isMachO, isMachO,
isObject lastObject
}; };
public: public:
@ -52,7 +55,7 @@ public:
// Cast methods. // Cast methods.
unsigned int getType() const { return TypeID; } unsigned int getType() const { return TypeID; }
static inline bool classof(Binary const *v) { return true; } static inline bool classof(const Binary *v) { return true; }
}; };
error_code createBinary(MemoryBuffer *Source, OwningPtr<Binary> &Result); error_code createBinary(MemoryBuffer *Source, OwningPtr<Binary> &Result);

111
include/llvm/Object/COFF.h Normal file
View File

@ -0,0 +1,111 @@
//===- 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:
uint64_t HeaderOff;
const coff_file_header *Header;
const coff_section *SectionTable;
const coff_symbol *SymbolTable;
const char *StringTable;
const coff_section *getSection(std::size_t index) const;
const char *getString(std::size_t offset) const;
protected:
virtual SymbolRef getSymbolNext(DataRefImpl Symb) const;
virtual StringRef getSymbolName(DataRefImpl Symb) const;
virtual uint64_t getSymbolAddress(DataRefImpl Symb) const;
virtual uint64_t getSymbolSize(DataRefImpl Symb) const;
virtual char getSymbolNMTypeChar(DataRefImpl Symb) const;
virtual bool isSymbolInternal(DataRefImpl Symb) const;
virtual SectionRef getSectionNext(DataRefImpl Sec) const;
virtual StringRef getSectionName(DataRefImpl Sec) const;
virtual uint64_t getSectionAddress(DataRefImpl Sec) const;
virtual uint64_t getSectionSize(DataRefImpl Sec) const;
virtual StringRef getSectionContents(DataRefImpl Sec) const;
virtual bool isSectionText(DataRefImpl Sec) 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

View File

@ -14,15 +14,13 @@
#ifndef LLVM_OBJECT_OBJECT_FILE_H #ifndef LLVM_OBJECT_OBJECT_FILE_H
#define LLVM_OBJECT_OBJECT_FILE_H #define LLVM_OBJECT_OBJECT_FILE_H
#include "llvm/Object/Binary.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
#include "llvm/Support/MemoryBuffer.h"
#include <cstring> #include <cstring>
namespace llvm { namespace llvm {
class MemoryBuffer;
class StringRef;
namespace object { namespace object {
class ObjectFile; class ObjectFile;
@ -93,16 +91,17 @@ const uint64_t UnknownAddressOrSize = ~0ULL;
/// ObjectFile - This class is the base class for all object file types. /// ObjectFile - This class is the base class for all object file types.
/// Concrete instances of this object are created by createObjectFile, which /// Concrete instances of this object are created by createObjectFile, which
/// figure out which type to create. /// figure out which type to create.
class ObjectFile { class ObjectFile : public Binary {
private: private:
ObjectFile(); // = delete ObjectFile(); // = delete
ObjectFile(const ObjectFile &other); // = delete ObjectFile(const ObjectFile &other); // = delete
protected: protected:
MemoryBuffer *MapFile; ObjectFile(unsigned int Type, MemoryBuffer *source, error_code &ec);
const uint8_t *base;
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 // These functions are for SymbolRef to call internally. The main goal of
// this is to allow SymbolRef::SymbolPimpl to point directly to the symbol // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
@ -156,8 +155,6 @@ public:
typedef content_iterator<SymbolRef> symbol_iterator; typedef content_iterator<SymbolRef> symbol_iterator;
typedef content_iterator<SectionRef> section_iterator; typedef content_iterator<SectionRef> section_iterator;
virtual ~ObjectFile();
virtual symbol_iterator begin_symbols() const = 0; virtual symbol_iterator begin_symbols() const = 0;
virtual symbol_iterator end_symbols() const = 0; virtual symbol_iterator end_symbols() const = 0;
@ -171,8 +168,6 @@ public:
virtual StringRef getFileFormatName() const = 0; virtual StringRef getFileFormatName() const = 0;
virtual /* Triple::ArchType */ unsigned getArch() const = 0; virtual /* Triple::ArchType */ unsigned getArch() const = 0;
StringRef getFilename() const;
/// @returns Pointer to ObjectFile subclass to handle this type of object. /// @returns Pointer to ObjectFile subclass to handle this type of object.
/// @param ObjectPath The path to the object file. ObjectPath.isObject must /// @param ObjectPath The path to the object file. ObjectPath.isObject must
/// return true. /// return true.
@ -180,12 +175,16 @@ public:
static ObjectFile *createObjectFile(StringRef ObjectPath); static ObjectFile *createObjectFile(StringRef ObjectPath);
static ObjectFile *createObjectFile(MemoryBuffer *Object); 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 *createCOFFObjectFile(MemoryBuffer *Object);
static ObjectFile *createELFObjectFile(MemoryBuffer *Object); static ObjectFile *createELFObjectFile(MemoryBuffer *Object);
static ObjectFile *createMachOObjectFile(MemoryBuffer *Object); static ObjectFile *createMachOObjectFile(MemoryBuffer *Object);
static ObjectFile *createArchiveObjectFile(MemoryBuffer *Object);
static ObjectFile *createLibObjectFile(MemoryBuffer *Object);
}; };
// Inline function definitions. // Inline function definitions.

View File

@ -16,6 +16,10 @@
#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h" #include "llvm/Support/Path.h"
// Include headers for createBinary.
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/COFF.h"
using namespace llvm; using namespace llvm;
using namespace object; using namespace object;
@ -37,9 +41,51 @@ StringRef Binary::getFileName() const {
error_code object::createBinary(MemoryBuffer *Source, error_code object::createBinary(MemoryBuffer *Source,
OwningPtr<Binary> &Result) { OwningPtr<Binary> &Result) {
// We don't support any at the moment. OwningPtr<MemoryBuffer> scopedSource(Source);
delete Source; if (!Source)
return object_error::invalid_file_type; return make_error_code(errc::invalid_argument);
if (Source->getBufferSize() < 64)
return object_error::invalid_file_type;
sys::LLVMFileType type = sys::IdentifyFileType(Source->getBufferStart(),
static_cast<unsigned>(Source->getBufferSize()));
error_code ec;
switch (type) {
case sys::ELF_Relocatable_FileType:
case sys::ELF_Executable_FileType:
case sys::ELF_SharedObject_FileType:
case sys::ELF_Core_FileType: {
OwningPtr<Binary> ret(
ObjectFile::createELFObjectFile(scopedSource.take()));
if (!ret)
return object_error::invalid_file_type;
Result.swap(ret);
return object_error::success;
}
case sys::Mach_O_Object_FileType:
case sys::Mach_O_Executable_FileType:
case sys::Mach_O_FixedVirtualMemorySharedLib_FileType:
case sys::Mach_O_Core_FileType:
case sys::Mach_O_PreloadExecutable_FileType:
case sys::Mach_O_DynamicallyLinkedSharedLib_FileType:
case sys::Mach_O_DynamicLinker_FileType:
case sys::Mach_O_Bundle_FileType:
case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType: {
OwningPtr<Binary> ret(
ObjectFile::createMachOObjectFile(scopedSource.take()));
if (!ret)
return object_error::invalid_file_type;
Result.swap(ret);
return object_error::success;
}
case sys::COFF_FileType: {
OwningPtr<Binary> ret(new COFFObjectFile(scopedSource.take(), ec));
if (ec) return ec;
Result.swap(ret);
return object_error::success;
}
default: // Unrecognized object file format.
return object_error::invalid_file_type;
}
} }
error_code object::createBinary(StringRef Path, OwningPtr<Binary> &Result) { error_code object::createBinary(StringRef Path, OwningPtr<Binary> &Result) {

View File

@ -11,11 +11,9 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Object/COFF.h"
#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h" #include "llvm/ADT/Triple.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/Endian.h"
using namespace llvm; using namespace llvm;
using namespace object; using namespace object;
@ -27,107 +25,6 @@ using support::ulittle32_t;
using support::little16_t; using support::little16_t;
} }
namespace {
struct coff_file_header {
ulittle16_t Machine;
ulittle16_t NumberOfSections;
ulittle32_t TimeDateStamp;
ulittle32_t PointerToSymbolTable;
ulittle32_t NumberOfSymbols;
ulittle16_t SizeOfOptionalHeader;
ulittle16_t Characteristics;
};
}
extern char coff_file_header_layout_static_assert
[sizeof(coff_file_header) == 20 ? 1 : -1];
namespace {
struct coff_symbol {
struct StringTableOffset {
ulittle32_t Zeroes;
ulittle32_t Offset;
};
union {
char ShortName[8];
StringTableOffset Offset;
} Name;
ulittle32_t Value;
little16_t SectionNumber;
struct {
ulittle8_t BaseType;
ulittle8_t ComplexType;
} Type;
ulittle8_t StorageClass;
ulittle8_t NumberOfAuxSymbols;
};
}
extern char coff_coff_symbol_layout_static_assert
[sizeof(coff_symbol) == 18 ? 1 : -1];
namespace {
struct coff_section {
char Name[8];
ulittle32_t VirtualSize;
ulittle32_t VirtualAddress;
ulittle32_t SizeOfRawData;
ulittle32_t PointerToRawData;
ulittle32_t PointerToRelocations;
ulittle32_t PointerToLinenumbers;
ulittle16_t NumberOfRelocations;
ulittle16_t NumberOfLinenumbers;
ulittle32_t Characteristics;
};
}
extern char coff_coff_section_layout_static_assert
[sizeof(coff_section) == 40 ? 1 : -1];
namespace {
class COFFObjectFile : public ObjectFile {
private:
uint64_t HeaderOff;
const coff_file_header *Header;
const coff_section *SectionTable;
const coff_symbol *SymbolTable;
const char *StringTable;
const coff_section *getSection(std::size_t index) const;
const char *getString(std::size_t offset) const;
protected:
virtual SymbolRef getSymbolNext(DataRefImpl Symb) const;
virtual StringRef getSymbolName(DataRefImpl Symb) const;
virtual uint64_t getSymbolAddress(DataRefImpl Symb) const;
virtual uint64_t getSymbolSize(DataRefImpl Symb) const;
virtual char getSymbolNMTypeChar(DataRefImpl Symb) const;
virtual bool isSymbolInternal(DataRefImpl Symb) const;
virtual SectionRef getSectionNext(DataRefImpl Sec) const;
virtual StringRef getSectionName(DataRefImpl Sec) const;
virtual uint64_t getSectionAddress(DataRefImpl Sec) const;
virtual uint64_t getSectionSize(DataRefImpl Sec) const;
virtual StringRef getSectionContents(DataRefImpl Sec) const;
virtual bool isSectionText(DataRefImpl Sec) const;
public:
COFFObjectFile(MemoryBuffer *Object);
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;
};
} // end namespace
SymbolRef COFFObjectFile::getSymbolNext(DataRefImpl Symb) const { SymbolRef COFFObjectFile::getSymbolNext(DataRefImpl Symb) const {
const coff_symbol *symb = reinterpret_cast<const coff_symbol*>(Symb.p); const coff_symbol *symb = reinterpret_cast<const coff_symbol*>(Symb.p);
symb += 1 + symb->NumberOfAuxSymbols; symb += 1 + symb->NumberOfAuxSymbols;
@ -274,7 +171,8 @@ uint64_t COFFObjectFile::getSectionSize(DataRefImpl Sec) const {
StringRef COFFObjectFile::getSectionContents(DataRefImpl Sec) const { StringRef COFFObjectFile::getSectionContents(DataRefImpl Sec) const {
const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p); const coff_section *sec = reinterpret_cast<const coff_section*>(Sec.p);
return StringRef(reinterpret_cast<const char *>(base + sec->PointerToRawData), return StringRef(reinterpret_cast<const char *>(base()
+ sec->PointerToRawData),
sec->SizeOfRawData); sec->SizeOfRawData);
} }
@ -283,29 +181,30 @@ bool COFFObjectFile::isSectionText(DataRefImpl Sec) const {
return sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE; return sec->Characteristics & COFF::IMAGE_SCN_CNT_CODE;
} }
COFFObjectFile::COFFObjectFile(MemoryBuffer *Object) COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec)
: ObjectFile(Object) { : ObjectFile(Binary::isCOFF, Object, ec) {
HeaderOff = 0; HeaderOff = 0;
if (base[0] == 0x4d && base[1] == 0x5a) { if (base()[0] == 0x4d && base()[1] == 0x5a) {
// PE/COFF, seek through MS-DOS compatibility stub and 4-byte // PE/COFF, seek through MS-DOS compatibility stub and 4-byte
// PE signature to find 'normal' COFF header. // PE signature to find 'normal' COFF header.
HeaderOff += *reinterpret_cast<const ulittle32_t *>(base + 0x3c); HeaderOff += *reinterpret_cast<const ulittle32_t *>(base() + 0x3c);
HeaderOff += 4; HeaderOff += 4;
} }
Header = reinterpret_cast<const coff_file_header *>(base + HeaderOff); Header = reinterpret_cast<const coff_file_header *>(base() + HeaderOff);
SectionTable = SectionTable =
reinterpret_cast<const coff_section *>( base reinterpret_cast<const coff_section *>( base()
+ HeaderOff + HeaderOff
+ sizeof(coff_file_header) + sizeof(coff_file_header)
+ Header->SizeOfOptionalHeader); + Header->SizeOfOptionalHeader);
SymbolTable = SymbolTable =
reinterpret_cast<const coff_symbol *>(base + Header->PointerToSymbolTable); reinterpret_cast<const coff_symbol *>(base()
+ Header->PointerToSymbolTable);
// Find string table. // Find string table.
StringTable = reinterpret_cast<const char *>(base) StringTable = reinterpret_cast<const char *>(base())
+ Header->PointerToSymbolTable + Header->PointerToSymbolTable
+ Header->NumberOfSymbols * 18; + Header->NumberOfSymbols * 18;
} }
@ -382,7 +281,8 @@ const char *COFFObjectFile::getString(std::size_t offset) const {
namespace llvm { namespace llvm {
ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) { ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) {
return new COFFObjectFile(Object); error_code ec;
return new COFFObjectFile(Object, ec);
} }
} // end namespace llvm } // end namespace llvm

View File

@ -237,7 +237,7 @@ protected:
virtual bool isSectionText(DataRefImpl Sec) const; virtual bool isSectionText(DataRefImpl Sec) const;
public: public:
ELFObjectFile(MemoryBuffer *Object); ELFObjectFile(MemoryBuffer *Object, error_code &ec);
virtual symbol_iterator begin_symbols() const; virtual symbol_iterator begin_symbols() const;
virtual symbol_iterator end_symbols() const; virtual symbol_iterator end_symbols() const;
virtual section_iterator begin_sections() const; virtual section_iterator begin_sections() const;
@ -259,9 +259,9 @@ void ELFObjectFile<target_endianness, is64Bits>
// an error object around. // an error object around.
if (!( symb if (!( symb
&& SymbolTableSection && SymbolTableSection
&& symb >= (const Elf_Sym*)(base && symb >= (const Elf_Sym*)(base()
+ SymbolTableSection->sh_offset) + SymbolTableSection->sh_offset)
&& symb < (const Elf_Sym*)(base && symb < (const Elf_Sym*)(base()
+ SymbolTableSection->sh_offset + SymbolTableSection->sh_offset
+ SymbolTableSection->sh_size))) + SymbolTableSection->sh_size)))
// FIXME: Proper error handling. // FIXME: Proper error handling.
@ -444,7 +444,7 @@ template<support::endianness target_endianness, bool is64Bits>
StringRef ELFObjectFile<target_endianness, is64Bits> StringRef ELFObjectFile<target_endianness, is64Bits>
::getSectionContents(DataRefImpl Sec) const { ::getSectionContents(DataRefImpl Sec) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p); const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
const char *start = (char*)base + sec->sh_offset; const char *start = (char*)base() + sec->sh_offset;
return StringRef(start, sec->sh_size); return StringRef(start, sec->sh_size);
} }
@ -458,21 +458,22 @@ bool ELFObjectFile<target_endianness, is64Bits>
} }
template<support::endianness target_endianness, bool is64Bits> template<support::endianness target_endianness, bool is64Bits>
ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object) ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object
: ObjectFile(Object) , error_code &ec)
: ObjectFile(Binary::isELF, Object, ec)
, SectionHeaderTable(0) , SectionHeaderTable(0)
, dot_shstrtab_sec(0) , dot_shstrtab_sec(0)
, dot_strtab_sec(0) { , dot_strtab_sec(0) {
Header = reinterpret_cast<const Elf_Ehdr *>(base); Header = reinterpret_cast<const Elf_Ehdr *>(base());
if (Header->e_shoff == 0) if (Header->e_shoff == 0)
return; return;
SectionHeaderTable = SectionHeaderTable =
reinterpret_cast<const Elf_Shdr *>(base + Header->e_shoff); reinterpret_cast<const Elf_Shdr *>(base() + Header->e_shoff);
uint32_t SectionTableSize = Header->e_shnum * Header->e_shentsize; uint32_t SectionTableSize = Header->e_shnum * Header->e_shentsize;
if (!( (const uint8_t *)SectionHeaderTable + SectionTableSize if (!( (const uint8_t *)SectionHeaderTable + SectionTableSize
<= base + MapFile->getBufferSize())) <= base() + Data->getBufferSize()))
// FIXME: Proper error handling. // FIXME: Proper error handling.
report_fatal_error("Section table goes past end of file!"); report_fatal_error("Section table goes past end of file!");
@ -491,7 +492,7 @@ ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object)
dot_shstrtab_sec = getSection(Header->e_shstrndx); dot_shstrtab_sec = getSection(Header->e_shstrndx);
if (dot_shstrtab_sec) { if (dot_shstrtab_sec) {
// Verify that the last byte in the string table in a null. // Verify that the last byte in the string table in a null.
if (((const char*)base + dot_shstrtab_sec->sh_offset) if (((const char*)base() + dot_shstrtab_sec->sh_offset)
[dot_shstrtab_sec->sh_size - 1] != 0) [dot_shstrtab_sec->sh_size - 1] != 0)
// FIXME: Proper error handling. // FIXME: Proper error handling.
report_fatal_error("String table must end with a null terminator!"); report_fatal_error("String table must end with a null terminator!");
@ -509,7 +510,7 @@ ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object)
// FIXME: Proper error handling. // FIXME: Proper error handling.
report_fatal_error("Already found section named .strtab!"); report_fatal_error("Already found section named .strtab!");
dot_strtab_sec = sh; dot_strtab_sec = sh;
const char *dot_strtab = (const char*)base + sh->sh_offset; const char *dot_strtab = (const char*)base() + sh->sh_offset;
if (dot_strtab[sh->sh_size - 1] != 0) if (dot_strtab[sh->sh_size - 1] != 0)
// FIXME: Proper error handling. // FIXME: Proper error handling.
report_fatal_error("String table must end with a null terminator!"); report_fatal_error("String table must end with a null terminator!");
@ -548,7 +549,7 @@ ObjectFile::section_iterator ELFObjectFile<target_endianness, is64Bits>
::begin_sections() const { ::begin_sections() const {
DataRefImpl ret; DataRefImpl ret;
memset(&ret, 0, sizeof(DataRefImpl)); memset(&ret, 0, sizeof(DataRefImpl));
ret.p = reinterpret_cast<intptr_t>(base + Header->e_shoff); ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff);
return section_iterator(SectionRef(ret, this)); return section_iterator(SectionRef(ret, this));
} }
@ -557,7 +558,7 @@ ObjectFile::section_iterator ELFObjectFile<target_endianness, is64Bits>
::end_sections() const { ::end_sections() const {
DataRefImpl ret; DataRefImpl ret;
memset(&ret, 0, sizeof(DataRefImpl)); memset(&ret, 0, sizeof(DataRefImpl));
ret.p = reinterpret_cast<intptr_t>(base ret.p = reinterpret_cast<intptr_t>(base()
+ Header->e_shoff + Header->e_shoff
+ (Header->e_shentsize * Header->e_shnum)); + (Header->e_shentsize * Header->e_shnum));
return section_iterator(SectionRef(ret, this)); return section_iterator(SectionRef(ret, this));
@ -613,7 +614,7 @@ const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Sym *
ELFObjectFile<target_endianness, is64Bits>::getSymbol(DataRefImpl Symb) const { ELFObjectFile<target_endianness, is64Bits>::getSymbol(DataRefImpl Symb) const {
const Elf_Shdr *sec = SymbolTableSections[Symb.d.b]; const Elf_Shdr *sec = SymbolTableSections[Symb.d.b];
return reinterpret_cast<const Elf_Sym *>( return reinterpret_cast<const Elf_Sym *>(
base base()
+ sec->sh_offset + sec->sh_offset
+ (Symb.d.a * sec->sh_entsize)); + (Symb.d.a * sec->sh_entsize));
} }
@ -656,8 +657,8 @@ const char *ELFObjectFile<target_endianness, is64Bits>
assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!"); assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!");
if (offset >= section->sh_size) if (offset >= section->sh_size)
// FIXME: Proper error handling. // FIXME: Proper error handling.
report_fatal_error("Sybol name offset outside of string table!"); report_fatal_error("Symbol name offset outside of string table!");
return (const char *)base + section->sh_offset + offset; return (const char *)base() + section->sh_offset + offset;
} }
// EI_CLASS, EI_DATA. // EI_CLASS, EI_DATA.
@ -673,14 +674,15 @@ namespace llvm {
ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) { ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object); std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
error_code ec;
if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
return new ELFObjectFile<support::little, false>(Object); return new ELFObjectFile<support::little, false>(Object, ec);
else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
return new ELFObjectFile<support::big, false>(Object); return new ELFObjectFile<support::big, false>(Object, ec);
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB)
return new ELFObjectFile<support::little, true>(Object); return new ELFObjectFile<support::little, true>(Object, ec);
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
return new ELFObjectFile<support::big, true>(Object); return new ELFObjectFile<support::big, true>(Object, ec);
// FIXME: Proper error handling. // FIXME: Proper error handling.
report_fatal_error("Not an ELF object file!"); report_fatal_error("Not an ELF object file!");
} }

View File

@ -32,8 +32,8 @@ typedef MachOObject::LoadCommandInfo LoadCommandInfo;
class MachOObjectFile : public ObjectFile { class MachOObjectFile : public ObjectFile {
public: public:
MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO) MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO, error_code &ec)
: ObjectFile(Object), : ObjectFile(Binary::isMachO, Object, ec),
MachOObj(MOO), MachOObj(MOO),
RegisteredStringTable(std::numeric_limits<uint32_t>::max()) {} RegisteredStringTable(std::numeric_limits<uint32_t>::max()) {}
@ -73,11 +73,12 @@ private:
}; };
ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
error_code ec;
std::string Err; std::string Err;
MachOObject *MachOObj = MachOObject::LoadFromBuffer(Buffer, &Err); MachOObject *MachOObj = MachOObject::LoadFromBuffer(Buffer, &Err);
if (!MachOObj) if (!MachOObj)
return NULL; return NULL;
return new MachOObjectFile(Buffer, MachOObj); return new MachOObjectFile(Buffer, MachOObj, ec);
} }
/*===-- Symbols -----------------------------------------------------------===*/ /*===-- Symbols -----------------------------------------------------------===*/

View File

@ -21,18 +21,8 @@
using namespace llvm; using namespace llvm;
using namespace object; using namespace object;
ObjectFile::ObjectFile(MemoryBuffer *Object) ObjectFile::ObjectFile(unsigned int Type, MemoryBuffer *source, error_code &ec)
: MapFile(Object) { : Binary(Type, source) {
assert(MapFile && "Must be a valid MemoryBuffer!");
base = reinterpret_cast<const uint8_t *>(MapFile->getBufferStart());
}
ObjectFile::~ObjectFile() {
delete MapFile;
}
StringRef ObjectFile::getFilename() const {
return MapFile->getBufferIdentifier();
} }
ObjectFile *ObjectFile::createObjectFile(MemoryBuffer *Object) { ObjectFile *ObjectFile::createObjectFile(MemoryBuffer *Object) {

View File

@ -277,7 +277,7 @@ static void DumpSymbolNamesFromObject(ObjectFile *obj) {
SymbolList.push_back(s); SymbolList.push_back(s);
} }
CurrentFilename = obj->getFilename(); CurrentFilename = obj->getFileName();
SortAndPrintSymbolList(); SortAndPrintSymbolList();
} }