1249259Sdim//===-- ELFDumper.cpp - ELF-specific dumper ---------------------*- C++ -*-===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim/// 10249259Sdim/// \file 11249259Sdim/// \brief This file implements the ELF-specific dumper for llvm-readobj. 12249259Sdim/// 13249259Sdim//===----------------------------------------------------------------------===// 14249259Sdim 15249259Sdim#include "llvm-readobj.h" 16249259Sdim#include "Error.h" 17249259Sdim#include "ObjDumper.h" 18249259Sdim#include "StreamWriter.h" 19249259Sdim 20249259Sdim#include "llvm/ADT/SmallString.h" 21263509Sdim#include "llvm/Object/ELFObjectFile.h" 22249259Sdim#include "llvm/Support/Compiler.h" 23249259Sdim#include "llvm/Support/Format.h" 24249259Sdim#include "llvm/Support/MathExtras.h" 25249259Sdim#include "llvm/Support/raw_ostream.h" 26249259Sdim 27249259Sdimusing namespace llvm; 28249259Sdimusing namespace llvm::object; 29249259Sdimusing namespace ELF; 30249259Sdim 31249259Sdim#define LLVM_READOBJ_ENUM_CASE(ns, enum) \ 32249259Sdim case ns::enum: return #enum; 33249259Sdim 34249259Sdimnamespace { 35249259Sdim 36249259Sdimtemplate<typename ELFT> 37249259Sdimclass ELFDumper : public ObjDumper { 38249259Sdimpublic: 39263509Sdim ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer) 40263509Sdim : ObjDumper(Writer), Obj(Obj) {} 41249259Sdim 42249259Sdim virtual void printFileHeaders() LLVM_OVERRIDE; 43249259Sdim virtual void printSections() LLVM_OVERRIDE; 44249259Sdim virtual void printRelocations() LLVM_OVERRIDE; 45249259Sdim virtual void printSymbols() LLVM_OVERRIDE; 46249259Sdim virtual void printDynamicSymbols() LLVM_OVERRIDE; 47249259Sdim virtual void printUnwindInfo() LLVM_OVERRIDE; 48249259Sdim 49249259Sdim virtual void printDynamicTable() LLVM_OVERRIDE; 50249259Sdim virtual void printNeededLibraries() LLVM_OVERRIDE; 51252723Sdim virtual void printProgramHeaders() LLVM_OVERRIDE; 52249259Sdim 53249259Sdimprivate: 54263509Sdim typedef ELFFile<ELFT> ELFO; 55252723Sdim typedef typename ELFO::Elf_Shdr Elf_Shdr; 56252723Sdim typedef typename ELFO::Elf_Sym Elf_Sym; 57249259Sdim 58263509Sdim void printSymbol(typename ELFO::Elf_Sym_Iter Symbol); 59249259Sdim 60263509Sdim void printRelocations(const Elf_Shdr *Sec); 61263509Sdim void printRelocation(const Elf_Shdr *Sec, typename ELFO::Elf_Rela Rel); 62249259Sdim 63252723Sdim const ELFO *Obj; 64249259Sdim}; 65249259Sdim 66263509Sdimtemplate <class T> T errorOrDefault(ErrorOr<T> Val, T Default = T()) { 67263509Sdim if (!Val) { 68263509Sdim error(Val); 69263509Sdim return Default; 70263509Sdim } 71263509Sdim 72263509Sdim return *Val; 73263509Sdim} 74249259Sdim} // namespace 75249259Sdim 76249259Sdimnamespace llvm { 77249259Sdim 78263509Sdimtemplate <class ELFT> 79263509Sdimstatic error_code createELFDumper(const ELFFile<ELFT> *Obj, 80263509Sdim StreamWriter &Writer, 81263509Sdim OwningPtr<ObjDumper> &Result) { 82263509Sdim Result.reset(new ELFDumper<ELFT>(Obj, Writer)); 83263509Sdim return readobj_error::success; 84263509Sdim} 85263509Sdim 86249259Sdimerror_code createELFDumper(const object::ObjectFile *Obj, 87249259Sdim StreamWriter& Writer, 88249259Sdim OwningPtr<ObjDumper> &Result) { 89249259Sdim // Little-endian 32-bit 90263509Sdim if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj)) 91263509Sdim return createELFDumper(ELFObj->getELFFile(), Writer, Result); 92249259Sdim 93249259Sdim // Big-endian 32-bit 94263509Sdim if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj)) 95263509Sdim return createELFDumper(ELFObj->getELFFile(), Writer, Result); 96249259Sdim 97249259Sdim // Little-endian 64-bit 98263509Sdim if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj)) 99263509Sdim return createELFDumper(ELFObj->getELFFile(), Writer, Result); 100249259Sdim 101249259Sdim // Big-endian 64-bit 102263509Sdim if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj)) 103263509Sdim return createELFDumper(ELFObj->getELFFile(), Writer, Result); 104249259Sdim 105249259Sdim return readobj_error::unsupported_obj_file_format; 106249259Sdim} 107249259Sdim 108249259Sdim} // namespace llvm 109249259Sdim 110249259Sdimstatic const EnumEntry<unsigned> ElfClass[] = { 111249259Sdim { "None", ELF::ELFCLASSNONE }, 112249259Sdim { "32-bit", ELF::ELFCLASS32 }, 113249259Sdim { "64-bit", ELF::ELFCLASS64 }, 114249259Sdim}; 115249259Sdim 116249259Sdimstatic const EnumEntry<unsigned> ElfDataEncoding[] = { 117249259Sdim { "None", ELF::ELFDATANONE }, 118249259Sdim { "LittleEndian", ELF::ELFDATA2LSB }, 119249259Sdim { "BigEndian", ELF::ELFDATA2MSB }, 120249259Sdim}; 121249259Sdim 122249259Sdimstatic const EnumEntry<unsigned> ElfObjectFileType[] = { 123249259Sdim { "None", ELF::ET_NONE }, 124249259Sdim { "Relocatable", ELF::ET_REL }, 125249259Sdim { "Executable", ELF::ET_EXEC }, 126249259Sdim { "SharedObject", ELF::ET_DYN }, 127249259Sdim { "Core", ELF::ET_CORE }, 128249259Sdim}; 129249259Sdim 130249259Sdimstatic const EnumEntry<unsigned> ElfOSABI[] = { 131249259Sdim { "SystemV", ELF::ELFOSABI_NONE }, 132249259Sdim { "HPUX", ELF::ELFOSABI_HPUX }, 133249259Sdim { "NetBSD", ELF::ELFOSABI_NETBSD }, 134249259Sdim { "GNU/Linux", ELF::ELFOSABI_LINUX }, 135249259Sdim { "GNU/Hurd", ELF::ELFOSABI_HURD }, 136249259Sdim { "Solaris", ELF::ELFOSABI_SOLARIS }, 137249259Sdim { "AIX", ELF::ELFOSABI_AIX }, 138249259Sdim { "IRIX", ELF::ELFOSABI_IRIX }, 139249259Sdim { "FreeBSD", ELF::ELFOSABI_FREEBSD }, 140249259Sdim { "TRU64", ELF::ELFOSABI_TRU64 }, 141249259Sdim { "Modesto", ELF::ELFOSABI_MODESTO }, 142249259Sdim { "OpenBSD", ELF::ELFOSABI_OPENBSD }, 143249259Sdim { "OpenVMS", ELF::ELFOSABI_OPENVMS }, 144249259Sdim { "NSK", ELF::ELFOSABI_NSK }, 145249259Sdim { "AROS", ELF::ELFOSABI_AROS }, 146249259Sdim { "FenixOS", ELF::ELFOSABI_FENIXOS }, 147249259Sdim { "C6000_ELFABI", ELF::ELFOSABI_C6000_ELFABI }, 148249259Sdim { "C6000_LINUX" , ELF::ELFOSABI_C6000_LINUX }, 149249259Sdim { "ARM", ELF::ELFOSABI_ARM }, 150249259Sdim { "Standalone" , ELF::ELFOSABI_STANDALONE } 151249259Sdim}; 152249259Sdim 153249259Sdimstatic const EnumEntry<unsigned> ElfMachineType[] = { 154249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_NONE ), 155249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_M32 ), 156249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARC ), 157249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_386 ), 158249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_68K ), 159249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_88K ), 160249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_486 ), 161249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_860 ), 162249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS ), 163249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_S370 ), 164249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS_RS3_LE ), 165249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_PARISC ), 166249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_VPP500 ), 167249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARC32PLUS ), 168249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_960 ), 169249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_PPC ), 170249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_PPC64 ), 171249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_S390 ), 172249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_SPU ), 173249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_V800 ), 174249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_FR20 ), 175249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_RH32 ), 176249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_RCE ), 177249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ARM ), 178249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ALPHA ), 179249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_SH ), 180249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARCV9 ), 181249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_TRICORE ), 182249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC ), 183249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_300 ), 184249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_300H ), 185249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_H8S ), 186249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_500 ), 187249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_IA_64 ), 188249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS_X ), 189249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_COLDFIRE ), 190249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC12 ), 191249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_MMA ), 192249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_PCP ), 193249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_NCPU ), 194249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_NDR1 ), 195249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_STARCORE ), 196249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ME16 ), 197249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ST100 ), 198249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_TINYJ ), 199249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_X86_64 ), 200249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_PDSP ), 201249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_PDP10 ), 202249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_PDP11 ), 203249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_FX66 ), 204249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ST9PLUS ), 205249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ST7 ), 206249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC16 ), 207249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC11 ), 208249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC08 ), 209249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC05 ), 210249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_SVX ), 211249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ST19 ), 212249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_VAX ), 213249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_CRIS ), 214249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_JAVELIN ), 215249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_FIREPATH ), 216249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ZSP ), 217249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_MMIX ), 218249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_HUANY ), 219249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_PRISM ), 220249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_AVR ), 221249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_FR30 ), 222249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_D10V ), 223249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_D30V ), 224249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_V850 ), 225249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_M32R ), 226249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_MN10300 ), 227249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_MN10200 ), 228249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_PJ ), 229249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_OPENRISC ), 230249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC_COMPACT ), 231249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_XTENSA ), 232249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE ), 233249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_TMM_GPP ), 234249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_NS32K ), 235249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_TPC ), 236249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_SNP1K ), 237249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ST200 ), 238249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_IP2K ), 239249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_MAX ), 240249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_CR ), 241249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_F2MC16 ), 242249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_MSP430 ), 243249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_BLACKFIN ), 244249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_SE_C33 ), 245249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_SEP ), 246249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ARCA ), 247249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_UNICORE ), 248249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_EXCESS ), 249249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_DXP ), 250249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ALTERA_NIOS2 ), 251249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_CRX ), 252249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_XGATE ), 253249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_C166 ), 254249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_M16C ), 255249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_DSPIC30F ), 256249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_CE ), 257249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_M32C ), 258249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_TSK3000 ), 259249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_RS08 ), 260249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_SHARC ), 261249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG2 ), 262249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_SCORE7 ), 263249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_DSP24 ), 264249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE3 ), 265249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_LATTICEMICO32), 266249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_SE_C17 ), 267249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C6000 ), 268249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C2000 ), 269249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C5500 ), 270249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_MMDSP_PLUS ), 271249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_CYPRESS_M8C ), 272249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_R32C ), 273249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_TRIMEDIA ), 274249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_HEXAGON ), 275249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_8051 ), 276249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_STXP7X ), 277249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_NDS32 ), 278249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG1 ), 279249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG1X ), 280249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_MAXQ30 ), 281249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_XIMO16 ), 282249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_MANIK ), 283249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_CRAYNV2 ), 284249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_RX ), 285249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_METAG ), 286249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_MCST_ELBRUS ), 287249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG16 ), 288249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_CR16 ), 289249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ETPU ), 290249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_SLE9X ), 291249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_L10M ), 292249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_K10M ), 293249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_AARCH64 ), 294249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_AVR32 ), 295249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_STM8 ), 296249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_TILE64 ), 297249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEPRO ), 298249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_CUDA ), 299249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEGX ), 300249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_CLOUDSHIELD ), 301249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_COREA_1ST ), 302249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_COREA_2ND ), 303249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC_COMPACT2 ), 304249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_OPEN8 ), 305249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_RL78 ), 306249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE5 ), 307249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_78KOR ), 308263509Sdim LLVM_READOBJ_ENUM_ENT(ELF, EM_56800EX ) 309249259Sdim}; 310249259Sdim 311249259Sdimstatic const EnumEntry<unsigned> ElfSymbolBindings[] = { 312249259Sdim { "Local", ELF::STB_LOCAL }, 313249259Sdim { "Global", ELF::STB_GLOBAL }, 314249259Sdim { "Weak", ELF::STB_WEAK } 315249259Sdim}; 316249259Sdim 317249259Sdimstatic const EnumEntry<unsigned> ElfSymbolTypes[] = { 318249259Sdim { "None", ELF::STT_NOTYPE }, 319249259Sdim { "Object", ELF::STT_OBJECT }, 320249259Sdim { "Function", ELF::STT_FUNC }, 321249259Sdim { "Section", ELF::STT_SECTION }, 322249259Sdim { "File", ELF::STT_FILE }, 323249259Sdim { "Common", ELF::STT_COMMON }, 324249259Sdim { "TLS", ELF::STT_TLS }, 325249259Sdim { "GNU_IFunc", ELF::STT_GNU_IFUNC } 326249259Sdim}; 327249259Sdim 328249259Sdimstatic const char *getElfSectionType(unsigned Arch, unsigned Type) { 329249259Sdim switch (Arch) { 330263509Sdim case ELF::EM_ARM: 331249259Sdim switch (Type) { 332249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_EXIDX); 333249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP); 334249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES); 335249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY); 336249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION); 337249259Sdim } 338263509Sdim case ELF::EM_HEXAGON: 339263509Sdim switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED); } 340263509Sdim case ELF::EM_X86_64: 341263509Sdim switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND); } 342263509Sdim case ELF::EM_MIPS: 343263509Sdim case ELF::EM_MIPS_RS3_LE: 344249259Sdim switch (Type) { 345249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_REGINFO); 346249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_OPTIONS); 347249259Sdim } 348249259Sdim } 349249259Sdim 350249259Sdim switch (Type) { 351249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_NULL ); 352249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_PROGBITS ); 353249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB ); 354249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_STRTAB ); 355249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_RELA ); 356249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_HASH ); 357249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNAMIC ); 358249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOTE ); 359249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOBITS ); 360249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_REL ); 361249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_SHLIB ); 362249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNSYM ); 363249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_INIT_ARRAY ); 364249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_FINI_ARRAY ); 365249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_PREINIT_ARRAY ); 366249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_GROUP ); 367249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX ); 368249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES ); 369249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_HASH ); 370249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verdef ); 371249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verneed ); 372249259Sdim LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_versym ); 373249259Sdim default: return ""; 374249259Sdim } 375249259Sdim} 376249259Sdim 377249259Sdimstatic const EnumEntry<unsigned> ElfSectionFlags[] = { 378249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, SHF_WRITE ), 379249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, SHF_ALLOC ), 380263509Sdim LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXCLUDE ), 381249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXECINSTR ), 382249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, SHF_MERGE ), 383249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, SHF_STRINGS ), 384249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, SHF_INFO_LINK ), 385249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, SHF_LINK_ORDER ), 386249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, SHF_OS_NONCONFORMING), 387249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, SHF_GROUP ), 388249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, SHF_TLS ), 389249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_CP_SECTION), 390249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_DP_SECTION), 391249259Sdim LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP ) 392249259Sdim}; 393249259Sdim 394263509Sdimstatic const char *getElfSegmentType(unsigned Arch, unsigned Type) { 395263509Sdim // Check potentially overlapped processor-specific 396263509Sdim // program header type. 397263509Sdim switch (Arch) { 398263509Sdim case ELF::EM_ARM: 399263509Sdim switch (Type) { 400263509Sdim LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX); 401263509Sdim } 402263509Sdim case ELF::EM_MIPS: 403263509Sdim case ELF::EM_MIPS_RS3_LE: 404263509Sdim switch (Type) { 405263509Sdim LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO); 406263509Sdim LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC); 407263509Sdim LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS); 408263509Sdim } 409263509Sdim } 410249259Sdim 411263509Sdim switch (Type) { 412263509Sdim LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL ); 413263509Sdim LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD ); 414263509Sdim LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC); 415263509Sdim LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP ); 416263509Sdim LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE ); 417263509Sdim LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB ); 418263509Sdim LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR ); 419263509Sdim LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS ); 420252723Sdim 421263509Sdim LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME); 422263509Sdim LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND); 423252723Sdim 424263509Sdim LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK); 425263509Sdim LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO); 426263509Sdim default: return ""; 427263509Sdim } 428263509Sdim} 429252723Sdim 430252723Sdimstatic const EnumEntry<unsigned> ElfSegmentFlags[] = { 431252723Sdim LLVM_READOBJ_ENUM_ENT(ELF, PF_X), 432252723Sdim LLVM_READOBJ_ENUM_ENT(ELF, PF_W), 433252723Sdim LLVM_READOBJ_ENUM_ENT(ELF, PF_R) 434252723Sdim}; 435252723Sdim 436249259Sdimtemplate<class ELFT> 437249259Sdimvoid ELFDumper<ELFT>::printFileHeaders() { 438263509Sdim const typename ELFO::Elf_Ehdr *Header = Obj->getHeader(); 439249259Sdim 440249259Sdim { 441249259Sdim DictScope D(W, "ElfHeader"); 442249259Sdim { 443249259Sdim DictScope D(W, "Ident"); 444249259Sdim W.printBinary("Magic", makeArrayRef(Header->e_ident).slice(ELF::EI_MAG0, 445249259Sdim 4)); 446249259Sdim W.printEnum ("Class", Header->e_ident[ELF::EI_CLASS], 447249259Sdim makeArrayRef(ElfClass)); 448249259Sdim W.printEnum ("DataEncoding", Header->e_ident[ELF::EI_DATA], 449249259Sdim makeArrayRef(ElfDataEncoding)); 450249259Sdim W.printNumber("FileVersion", Header->e_ident[ELF::EI_VERSION]); 451249259Sdim W.printEnum ("OS/ABI", Header->e_ident[ELF::EI_OSABI], 452249259Sdim makeArrayRef(ElfOSABI)); 453249259Sdim W.printNumber("ABIVersion", Header->e_ident[ELF::EI_ABIVERSION]); 454249259Sdim W.printBinary("Unused", makeArrayRef(Header->e_ident).slice(ELF::EI_PAD)); 455249259Sdim } 456249259Sdim 457249259Sdim W.printEnum ("Type", Header->e_type, makeArrayRef(ElfObjectFileType)); 458249259Sdim W.printEnum ("Machine", Header->e_machine, makeArrayRef(ElfMachineType)); 459249259Sdim W.printNumber("Version", Header->e_version); 460249259Sdim W.printHex ("Entry", Header->e_entry); 461249259Sdim W.printHex ("ProgramHeaderOffset", Header->e_phoff); 462249259Sdim W.printHex ("SectionHeaderOffset", Header->e_shoff); 463249259Sdim W.printFlags ("Flags", Header->e_flags); 464249259Sdim W.printNumber("HeaderSize", Header->e_ehsize); 465249259Sdim W.printNumber("ProgramHeaderEntrySize", Header->e_phentsize); 466249259Sdim W.printNumber("ProgramHeaderCount", Header->e_phnum); 467249259Sdim W.printNumber("SectionHeaderEntrySize", Header->e_shentsize); 468249259Sdim W.printNumber("SectionHeaderCount", Header->e_shnum); 469249259Sdim W.printNumber("StringTableSectionIndex", Header->e_shstrndx); 470249259Sdim } 471249259Sdim} 472249259Sdim 473249259Sdimtemplate<class ELFT> 474249259Sdimvoid ELFDumper<ELFT>::printSections() { 475249259Sdim ListScope SectionsD(W, "Sections"); 476249259Sdim 477249259Sdim int SectionIndex = -1; 478263509Sdim for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(), 479263509Sdim SecE = Obj->end_sections(); 480263509Sdim SecI != SecE; ++SecI) { 481249259Sdim ++SectionIndex; 482249259Sdim 483263509Sdim const Elf_Shdr *Section = &*SecI; 484263509Sdim StringRef Name = errorOrDefault(Obj->getSectionName(Section)); 485249259Sdim 486249259Sdim DictScope SectionD(W, "Section"); 487249259Sdim W.printNumber("Index", SectionIndex); 488249259Sdim W.printNumber("Name", Name, Section->sh_name); 489263509Sdim W.printHex("Type", 490263509Sdim getElfSectionType(Obj->getHeader()->e_machine, Section->sh_type), 491263509Sdim Section->sh_type); 492249259Sdim W.printFlags ("Flags", Section->sh_flags, makeArrayRef(ElfSectionFlags)); 493249259Sdim W.printHex ("Address", Section->sh_addr); 494249259Sdim W.printHex ("Offset", Section->sh_offset); 495249259Sdim W.printNumber("Size", Section->sh_size); 496249259Sdim W.printNumber("Link", Section->sh_link); 497249259Sdim W.printNumber("Info", Section->sh_info); 498249259Sdim W.printNumber("AddressAlignment", Section->sh_addralign); 499249259Sdim W.printNumber("EntrySize", Section->sh_entsize); 500249259Sdim 501249259Sdim if (opts::SectionRelocations) { 502249259Sdim ListScope D(W, "Relocations"); 503263509Sdim printRelocations(Section); 504249259Sdim } 505249259Sdim 506249259Sdim if (opts::SectionSymbols) { 507249259Sdim ListScope D(W, "Symbols"); 508263509Sdim for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(), 509263509Sdim SymE = Obj->end_symbols(); 510263509Sdim SymI != SymE; ++SymI) { 511263509Sdim if (Obj->getSection(&*SymI) == Section) 512263509Sdim printSymbol(SymI); 513249259Sdim } 514249259Sdim } 515249259Sdim 516249259Sdim if (opts::SectionData) { 517263509Sdim ArrayRef<uint8_t> Data = errorOrDefault(Obj->getSectionContents(Section)); 518263509Sdim W.printBinaryBlock("SectionData", 519263509Sdim StringRef((const char *)Data.data(), Data.size())); 520249259Sdim } 521249259Sdim } 522249259Sdim} 523249259Sdim 524249259Sdimtemplate<class ELFT> 525249259Sdimvoid ELFDumper<ELFT>::printRelocations() { 526249259Sdim ListScope D(W, "Relocations"); 527249259Sdim 528249259Sdim int SectionNumber = -1; 529263509Sdim for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(), 530263509Sdim SecE = Obj->end_sections(); 531263509Sdim SecI != SecE; ++SecI) { 532263509Sdim ++SectionNumber; 533249259Sdim 534263509Sdim if (SecI->sh_type != ELF::SHT_REL && SecI->sh_type != ELF::SHT_RELA) 535249259Sdim continue; 536249259Sdim 537263509Sdim StringRef Name = errorOrDefault(Obj->getSectionName(&*SecI)); 538249259Sdim 539263509Sdim W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n"; 540263509Sdim W.indent(); 541249259Sdim 542263509Sdim printRelocations(&*SecI); 543249259Sdim 544263509Sdim W.unindent(); 545263509Sdim W.startLine() << "}\n"; 546263509Sdim } 547263509Sdim} 548263509Sdim 549263509Sdimtemplate <class ELFT> 550263509Sdimvoid ELFDumper<ELFT>::printRelocations(const Elf_Shdr *Sec) { 551263509Sdim switch (Sec->sh_type) { 552263509Sdim case ELF::SHT_REL: 553263509Sdim for (typename ELFO::Elf_Rel_Iter RI = Obj->begin_rel(Sec), 554263509Sdim RE = Obj->end_rel(Sec); 555263509Sdim RI != RE; ++RI) { 556263509Sdim typename ELFO::Elf_Rela Rela; 557263509Sdim Rela.r_offset = RI->r_offset; 558263509Sdim Rela.r_info = RI->r_info; 559263509Sdim Rela.r_addend = 0; 560263509Sdim printRelocation(Sec, Rela); 561249259Sdim } 562263509Sdim break; 563263509Sdim case ELF::SHT_RELA: 564263509Sdim for (typename ELFO::Elf_Rela_Iter RI = Obj->begin_rela(Sec), 565263509Sdim RE = Obj->end_rela(Sec); 566263509Sdim RI != RE; ++RI) { 567263509Sdim printRelocation(Sec, *RI); 568263509Sdim } 569263509Sdim break; 570249259Sdim } 571249259Sdim} 572249259Sdim 573263509Sdimtemplate <class ELFT> 574263509Sdimvoid ELFDumper<ELFT>::printRelocation(const Elf_Shdr *Sec, 575263509Sdim typename ELFO::Elf_Rela Rel) { 576249259Sdim SmallString<32> RelocName; 577263509Sdim Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName); 578249259Sdim StringRef SymbolName; 579263509Sdim std::pair<const Elf_Shdr *, const Elf_Sym *> Sym = 580263509Sdim Obj->getRelocationSymbol(Sec, &Rel); 581263509Sdim if (Sym.first) 582263509Sdim SymbolName = errorOrDefault(Obj->getSymbolName(Sym.first, Sym.second)); 583249259Sdim 584252723Sdim if (opts::ExpandRelocs) { 585252723Sdim DictScope Group(W, "Relocation"); 586263509Sdim W.printHex("Offset", Rel.r_offset); 587263509Sdim W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL())); 588252723Sdim W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-"); 589263509Sdim W.printHex("Addend", Rel.r_addend); 590252723Sdim } else { 591252723Sdim raw_ostream& OS = W.startLine(); 592263509Sdim OS << W.hex(Rel.r_offset) 593252723Sdim << " " << RelocName 594252723Sdim << " " << (SymbolName.size() > 0 ? SymbolName : "-") 595263509Sdim << " " << W.hex(Rel.r_addend) 596252723Sdim << "\n"; 597252723Sdim } 598249259Sdim} 599249259Sdim 600249259Sdimtemplate<class ELFT> 601249259Sdimvoid ELFDumper<ELFT>::printSymbols() { 602249259Sdim ListScope Group(W, "Symbols"); 603263509Sdim for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(), 604263509Sdim SymE = Obj->end_symbols(); 605263509Sdim SymI != SymE; ++SymI) { 606249259Sdim printSymbol(SymI); 607249259Sdim } 608249259Sdim} 609249259Sdim 610249259Sdimtemplate<class ELFT> 611249259Sdimvoid ELFDumper<ELFT>::printDynamicSymbols() { 612249259Sdim ListScope Group(W, "DynamicSymbols"); 613249259Sdim 614263509Sdim for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_dynamic_symbols(), 615263509Sdim SymE = Obj->end_dynamic_symbols(); 616263509Sdim SymI != SymE; ++SymI) { 617263509Sdim printSymbol(SymI); 618249259Sdim } 619249259Sdim} 620249259Sdim 621263509Sdimtemplate <class ELFT> 622263509Sdimvoid ELFDumper<ELFT>::printSymbol(typename ELFO::Elf_Sym_Iter Symbol) { 623263509Sdim StringRef SymbolName = errorOrDefault(Obj->getSymbolName(Symbol)); 624263509Sdim const Elf_Shdr *Sec = Obj->getSection(&*Symbol); 625263509Sdim StringRef SectionName = Sec ? errorOrDefault(Obj->getSectionName(Sec)) : ""; 626249259Sdim std::string FullSymbolName(SymbolName); 627263509Sdim if (Symbol.isDynamic()) { 628249259Sdim bool IsDefault; 629263509Sdim ErrorOr<StringRef> Version = Obj->getSymbolVersion(0, &*Symbol, IsDefault); 630263509Sdim if (Version) { 631249259Sdim FullSymbolName += (IsDefault ? "@@" : "@"); 632263509Sdim FullSymbolName += *Version; 633263509Sdim } else 634263509Sdim error(Version); 635249259Sdim } 636249259Sdim 637249259Sdim DictScope D(W, "Symbol"); 638249259Sdim W.printNumber("Name", FullSymbolName, Symbol->st_name); 639249259Sdim W.printHex ("Value", Symbol->st_value); 640249259Sdim W.printNumber("Size", Symbol->st_size); 641249259Sdim W.printEnum ("Binding", Symbol->getBinding(), 642249259Sdim makeArrayRef(ElfSymbolBindings)); 643249259Sdim W.printEnum ("Type", Symbol->getType(), makeArrayRef(ElfSymbolTypes)); 644249259Sdim W.printNumber("Other", Symbol->st_other); 645249259Sdim W.printHex ("Section", SectionName, Symbol->st_shndx); 646249259Sdim} 647249259Sdim 648249259Sdim#define LLVM_READOBJ_TYPE_CASE(name) \ 649249259Sdim case DT_##name: return #name 650249259Sdim 651249259Sdimstatic const char *getTypeString(uint64_t Type) { 652249259Sdim switch (Type) { 653249259Sdim LLVM_READOBJ_TYPE_CASE(BIND_NOW); 654249259Sdim LLVM_READOBJ_TYPE_CASE(DEBUG); 655249259Sdim LLVM_READOBJ_TYPE_CASE(FINI); 656249259Sdim LLVM_READOBJ_TYPE_CASE(FINI_ARRAY); 657249259Sdim LLVM_READOBJ_TYPE_CASE(FINI_ARRAYSZ); 658249259Sdim LLVM_READOBJ_TYPE_CASE(FLAGS); 659249259Sdim LLVM_READOBJ_TYPE_CASE(HASH); 660249259Sdim LLVM_READOBJ_TYPE_CASE(INIT); 661249259Sdim LLVM_READOBJ_TYPE_CASE(INIT_ARRAY); 662249259Sdim LLVM_READOBJ_TYPE_CASE(INIT_ARRAYSZ); 663249259Sdim LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAY); 664249259Sdim LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAYSZ); 665249259Sdim LLVM_READOBJ_TYPE_CASE(JMPREL); 666249259Sdim LLVM_READOBJ_TYPE_CASE(NEEDED); 667249259Sdim LLVM_READOBJ_TYPE_CASE(NULL); 668249259Sdim LLVM_READOBJ_TYPE_CASE(PLTGOT); 669249259Sdim LLVM_READOBJ_TYPE_CASE(PLTREL); 670249259Sdim LLVM_READOBJ_TYPE_CASE(PLTRELSZ); 671249259Sdim LLVM_READOBJ_TYPE_CASE(REL); 672249259Sdim LLVM_READOBJ_TYPE_CASE(RELA); 673249259Sdim LLVM_READOBJ_TYPE_CASE(RELENT); 674249259Sdim LLVM_READOBJ_TYPE_CASE(RELSZ); 675249259Sdim LLVM_READOBJ_TYPE_CASE(RELAENT); 676249259Sdim LLVM_READOBJ_TYPE_CASE(RELASZ); 677249259Sdim LLVM_READOBJ_TYPE_CASE(RPATH); 678249259Sdim LLVM_READOBJ_TYPE_CASE(RUNPATH); 679249259Sdim LLVM_READOBJ_TYPE_CASE(SONAME); 680249259Sdim LLVM_READOBJ_TYPE_CASE(STRSZ); 681249259Sdim LLVM_READOBJ_TYPE_CASE(STRTAB); 682249259Sdim LLVM_READOBJ_TYPE_CASE(SYMBOLIC); 683249259Sdim LLVM_READOBJ_TYPE_CASE(SYMENT); 684249259Sdim LLVM_READOBJ_TYPE_CASE(SYMTAB); 685249259Sdim LLVM_READOBJ_TYPE_CASE(TEXTREL); 686263509Sdim LLVM_READOBJ_TYPE_CASE(VERNEED); 687263509Sdim LLVM_READOBJ_TYPE_CASE(VERNEEDNUM); 688263509Sdim LLVM_READOBJ_TYPE_CASE(VERSYM); 689263509Sdim LLVM_READOBJ_TYPE_CASE(MIPS_RLD_VERSION); 690263509Sdim LLVM_READOBJ_TYPE_CASE(MIPS_FLAGS); 691263509Sdim LLVM_READOBJ_TYPE_CASE(MIPS_BASE_ADDRESS); 692263509Sdim LLVM_READOBJ_TYPE_CASE(MIPS_LOCAL_GOTNO); 693263509Sdim LLVM_READOBJ_TYPE_CASE(MIPS_SYMTABNO); 694263509Sdim LLVM_READOBJ_TYPE_CASE(MIPS_UNREFEXTNO); 695263509Sdim LLVM_READOBJ_TYPE_CASE(MIPS_GOTSYM); 696249259Sdim default: return "unknown"; 697249259Sdim } 698249259Sdim} 699249259Sdim 700249259Sdim#undef LLVM_READOBJ_TYPE_CASE 701249259Sdim 702263509Sdimtemplate <class ELFT> 703263509Sdimstatic void printValue(const ELFFile<ELFT> *O, uint64_t Type, uint64_t Value, 704263509Sdim bool Is64, raw_ostream &OS) { 705249259Sdim switch (Type) { 706249259Sdim case DT_PLTREL: 707249259Sdim if (Value == DT_REL) { 708249259Sdim OS << "REL"; 709249259Sdim break; 710249259Sdim } else if (Value == DT_RELA) { 711249259Sdim OS << "RELA"; 712249259Sdim break; 713249259Sdim } 714249259Sdim // Fallthrough. 715249259Sdim case DT_PLTGOT: 716249259Sdim case DT_HASH: 717249259Sdim case DT_STRTAB: 718249259Sdim case DT_SYMTAB: 719249259Sdim case DT_RELA: 720249259Sdim case DT_INIT: 721249259Sdim case DT_FINI: 722249259Sdim case DT_REL: 723249259Sdim case DT_JMPREL: 724249259Sdim case DT_INIT_ARRAY: 725249259Sdim case DT_FINI_ARRAY: 726249259Sdim case DT_PREINIT_ARRAY: 727249259Sdim case DT_DEBUG: 728263509Sdim case DT_VERNEED: 729263509Sdim case DT_VERSYM: 730249259Sdim case DT_NULL: 731263509Sdim case DT_MIPS_FLAGS: 732263509Sdim case DT_MIPS_BASE_ADDRESS: 733263509Sdim case DT_MIPS_GOTSYM: 734249259Sdim OS << format("0x%" PRIX64, Value); 735249259Sdim break; 736263509Sdim case DT_VERNEEDNUM: 737263509Sdim case DT_MIPS_RLD_VERSION: 738263509Sdim case DT_MIPS_LOCAL_GOTNO: 739263509Sdim case DT_MIPS_SYMTABNO: 740263509Sdim case DT_MIPS_UNREFEXTNO: 741263509Sdim OS << Value; 742263509Sdim break; 743249259Sdim case DT_PLTRELSZ: 744249259Sdim case DT_RELASZ: 745249259Sdim case DT_RELAENT: 746249259Sdim case DT_STRSZ: 747249259Sdim case DT_SYMENT: 748249259Sdim case DT_RELSZ: 749249259Sdim case DT_RELENT: 750249259Sdim case DT_INIT_ARRAYSZ: 751249259Sdim case DT_FINI_ARRAYSZ: 752249259Sdim case DT_PREINIT_ARRAYSZ: 753249259Sdim OS << Value << " (bytes)"; 754249259Sdim break; 755249259Sdim case DT_NEEDED: 756263509Sdim OS << "SharedLibrary (" << O->getDynamicString(Value) << ")"; 757249259Sdim break; 758249259Sdim case DT_SONAME: 759263509Sdim OS << "LibrarySoname (" << O->getDynamicString(Value) << ")"; 760249259Sdim break; 761263509Sdim case DT_RPATH: 762263509Sdim case DT_RUNPATH: 763263509Sdim OS << O->getDynamicString(Value); 764263509Sdim break; 765249259Sdim } 766249259Sdim} 767249259Sdim 768249259Sdimtemplate<class ELFT> 769249259Sdimvoid ELFDumper<ELFT>::printUnwindInfo() { 770249259Sdim W.startLine() << "UnwindInfo not implemented.\n"; 771249259Sdim} 772249259Sdim 773249259Sdimtemplate<class ELFT> 774249259Sdimvoid ELFDumper<ELFT>::printDynamicTable() { 775263509Sdim typedef typename ELFO::Elf_Dyn_Iter EDI; 776263509Sdim EDI Start = Obj->begin_dynamic_table(), End = Obj->end_dynamic_table(true); 777249259Sdim 778249259Sdim if (Start == End) 779249259Sdim return; 780249259Sdim 781249259Sdim ptrdiff_t Total = std::distance(Start, End); 782249259Sdim raw_ostream &OS = W.getOStream(); 783249259Sdim W.startLine() << "DynamicSection [ (" << Total << " entries)\n"; 784249259Sdim 785263509Sdim bool Is64 = ELFT::Is64Bits; 786249259Sdim 787249259Sdim W.startLine() 788249259Sdim << " Tag" << (Is64 ? " " : " ") << "Type" 789249259Sdim << " " << "Name/Value\n"; 790249259Sdim for (; Start != End; ++Start) { 791249259Sdim W.startLine() 792249259Sdim << " " 793249259Sdim << format(Is64 ? "0x%016" PRIX64 : "0x%08" PRIX64, Start->getTag()) 794249259Sdim << " " << format("%-21s", getTypeString(Start->getTag())); 795249259Sdim printValue(Obj, Start->getTag(), Start->getVal(), Is64, OS); 796249259Sdim OS << "\n"; 797249259Sdim } 798249259Sdim 799249259Sdim W.startLine() << "]\n"; 800249259Sdim} 801249259Sdim 802249259Sdimtemplate<class ELFT> 803249259Sdimvoid ELFDumper<ELFT>::printNeededLibraries() { 804249259Sdim ListScope D(W, "NeededLibraries"); 805249259Sdim 806263509Sdim typedef std::vector<StringRef> LibsTy; 807249259Sdim LibsTy Libs; 808249259Sdim 809263509Sdim for (typename ELFO::Elf_Dyn_Iter DynI = Obj->begin_dynamic_table(), 810263509Sdim DynE = Obj->end_dynamic_table(); 811263509Sdim DynI != DynE; ++DynI) 812263509Sdim if (DynI->d_tag == ELF::DT_NEEDED) 813263509Sdim Libs.push_back(Obj->getDynamicString(DynI->d_un.d_val)); 814249259Sdim 815263509Sdim std::stable_sort(Libs.begin(), Libs.end()); 816249259Sdim 817263509Sdim for (LibsTy::const_iterator I = Libs.begin(), E = Libs.end(); I != E; ++I) { 818263509Sdim outs() << " " << *I << "\n"; 819249259Sdim } 820249259Sdim} 821252723Sdim 822252723Sdimtemplate<class ELFT> 823252723Sdimvoid ELFDumper<ELFT>::printProgramHeaders() { 824252723Sdim ListScope L(W, "ProgramHeaders"); 825252723Sdim 826252723Sdim for (typename ELFO::Elf_Phdr_Iter PI = Obj->begin_program_headers(), 827252723Sdim PE = Obj->end_program_headers(); 828252723Sdim PI != PE; ++PI) { 829252723Sdim DictScope P(W, "ProgramHeader"); 830263509Sdim W.printHex ("Type", 831263509Sdim getElfSegmentType(Obj->getHeader()->e_machine, PI->p_type), 832263509Sdim PI->p_type); 833252723Sdim W.printHex ("Offset", PI->p_offset); 834252723Sdim W.printHex ("VirtualAddress", PI->p_vaddr); 835252723Sdim W.printHex ("PhysicalAddress", PI->p_paddr); 836252723Sdim W.printNumber("FileSize", PI->p_filesz); 837252723Sdim W.printNumber("MemSize", PI->p_memsz); 838252723Sdim W.printFlags ("Flags", PI->p_flags, makeArrayRef(ElfSegmentFlags)); 839252723Sdim W.printNumber("Alignment", PI->p_align); 840252723Sdim } 841252723Sdim} 842