//===-- ELFDumper.cpp - ELF-specific dumper ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file implements the ELF-specific dumper for llvm-readobj.
///
//===----------------------------------------------------------------------===//
#include "llvm-readobj.h"
#include "Error.h"
#include "ObjDumper.h"
#include "StreamWriter.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace llvm::object;
using namespace ELF;
#define LLVM_READOBJ_ENUM_CASE(ns, enum) \
case ns::enum: return #enum;
namespace {
template<typename ELFT>
class ELFDumper : public ObjDumper {
public:
ELFDumper(const ELFObjectFile<ELFT> *Obj, StreamWriter& Writer)
: ObjDumper(Writer)
, Obj(Obj) { }
virtual void printFileHeaders() LLVM_OVERRIDE;
virtual void printSections() LLVM_OVERRIDE;
virtual void printRelocations() LLVM_OVERRIDE;
virtual void printSymbols() LLVM_OVERRIDE;
virtual void printDynamicSymbols() LLVM_OVERRIDE;
virtual void printUnwindInfo() LLVM_OVERRIDE;
virtual void printDynamicTable() LLVM_OVERRIDE;
virtual void printNeededLibraries() LLVM_OVERRIDE;
virtual void printProgramHeaders() LLVM_OVERRIDE;
virtual void printARMBuildAttributes() LLVM_OVERRIDE;
private:
typedef ELFObjectFile<ELFT> ELFO;
typedef typename ELFO::Elf_Shdr Elf_Shdr;
typedef typename ELFO::Elf_Sym Elf_Sym;
void printSymbol(symbol_iterator SymI, bool IsDynamic = false);
void printRelocation(section_iterator SecI, relocation_iterator RelI);
const ELFO *Obj;
};
} // namespace
namespace llvm {
error_code createELFDumper(const object::ObjectFile *Obj,
StreamWriter& Writer,
OwningPtr<ObjDumper> &Result) {
typedef ELFType<support::little, 4, false> Little32ELF;
typedef ELFType<support::big, 4, false> Big32ELF;
typedef ELFType<support::little, 4, true > Little64ELF;
typedef ELFType<support::big, 8, true > Big64ELF;
typedef ELFObjectFile<Little32ELF> LittleELF32Obj;
typedef ELFObjectFile<Big32ELF > BigELF32Obj;
typedef ELFObjectFile<Little64ELF> LittleELF64Obj;
typedef ELFObjectFile<Big64ELF > BigELF64Obj;
// Little-endian 32-bit
if (const LittleELF32Obj *ELFObj = dyn_cast<LittleELF32Obj>(Obj)) {
Result.reset(new ELFDumper<Little32ELF>(ELFObj, Writer));
return readobj_error::success;
}
// Big-endian 32-bit
if (const BigELF32Obj *ELFObj = dyn_cast<BigELF32Obj>(Obj)) {
Result.reset(new ELFDumper<Big32ELF>(ELFObj, Writer));
return readobj_error::success;
}
// Little-endian 64-bit
if (const LittleELF64Obj *ELFObj = dyn_cast<LittleELF64Obj>(Obj)) {
Result.reset(new ELFDumper<Little64ELF>(ELFObj, Writer));
return readobj_error::success;
}
// Big-endian 64-bit
if (const BigELF64Obj *ELFObj = dyn_cast<BigELF64Obj>(Obj)) {
Result.reset(new ELFDumper<Big64ELF>(ELFObj, Writer));
return readobj_error::success;
}
return readobj_error::unsupported_obj_file_format;
}
} // namespace llvm
static const EnumEntry<unsigned> ElfClass[] = {
{ "None", ELF::ELFCLASSNONE },
{ "32-bit", ELF::ELFCLASS32 },
{ "64-bit", ELF::ELFCLASS64 },
};
static const EnumEntry<unsigned> ElfDataEncoding[] = {
{ "None", ELF::ELFDATANONE },
{ "LittleEndian", ELF::ELFDATA2LSB },
{ "BigEndian", ELF::ELFDATA2MSB },
};
static const EnumEntry<unsigned> ElfObjectFileType[] = {
{ "None", ELF::ET_NONE },
{ "Relocatable", ELF::ET_REL },
{ "Executable", ELF::ET_EXEC },
{ "SharedObject", ELF::ET_DYN },
{ "Core", ELF::ET_CORE },
};
static const EnumEntry<unsigned> ElfOSABI[] = {
{ "SystemV", ELF::ELFOSABI_NONE },