1259698Sdim//===- ELFObjectFile.h - ELF object file implementation ---------*- C++ -*-===// 2259698Sdim// 3259698Sdim// The LLVM Compiler Infrastructure 4259698Sdim// 5259698Sdim// This file is distributed under the University of Illinois Open Source 6259698Sdim// License. See LICENSE.TXT for details. 7259698Sdim// 8259698Sdim//===----------------------------------------------------------------------===// 9259698Sdim// 10259698Sdim// This file declares the ELFObjectFile template class. 11259698Sdim// 12259698Sdim//===----------------------------------------------------------------------===// 13259698Sdim 14259698Sdim#ifndef LLVM_OBJECT_ELF_OBJECT_FILE_H 15259698Sdim#define LLVM_OBJECT_ELF_OBJECT_FILE_H 16259698Sdim 17259698Sdim#include "llvm/ADT/DenseMap.h" 18259698Sdim#include "llvm/ADT/PointerIntPair.h" 19259698Sdim#include "llvm/ADT/SmallVector.h" 20259698Sdim#include "llvm/ADT/StringSwitch.h" 21259698Sdim#include "llvm/ADT/Triple.h" 22259698Sdim#include "llvm/Object/ELF.h" 23259698Sdim#include "llvm/Object/ObjectFile.h" 24259698Sdim#include "llvm/Support/Casting.h" 25259698Sdim#include "llvm/Support/ELF.h" 26259698Sdim#include "llvm/Support/Endian.h" 27259698Sdim#include "llvm/Support/ErrorHandling.h" 28259698Sdim#include "llvm/Support/MemoryBuffer.h" 29259698Sdim#include "llvm/Support/raw_ostream.h" 30259698Sdim#include <algorithm> 31259698Sdim#include <cctype> 32259698Sdim#include <limits> 33259698Sdim#include <utility> 34259698Sdim 35259698Sdimnamespace llvm { 36259698Sdimnamespace object { 37259698Sdim 38259698Sdimtemplate <class ELFT> 39259698Sdimclass ELFObjectFile : public ObjectFile { 40259698Sdimpublic: 41259698Sdim LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 42259698Sdim 43259698Sdim typedef typename ELFFile<ELFT>::uintX_t uintX_t; 44259698Sdim 45259698Sdim typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym; 46259698Sdim typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr; 47259698Sdim typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel; 48259698Sdim typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela; 49259698Sdim typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn; 50259698Sdim 51259698Sdim typedef typename ELFFile<ELFT>::Elf_Sym_Iter Elf_Sym_Iter; 52259698Sdim typedef typename ELFFile<ELFT>::Elf_Shdr_Iter Elf_Shdr_Iter; 53259698Sdim typedef typename ELFFile<ELFT>::Elf_Dyn_Iter Elf_Dyn_Iter; 54259698Sdim 55259698Sdimprotected: 56259698Sdim ELFFile<ELFT> EF; 57259698Sdim 58259698Sdim virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; 59259698Sdim virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; 60259698Sdim virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const; 61259698Sdim virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; 62259698Sdim virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const; 63259698Sdim virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; 64259698Sdim virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; 65259698Sdim virtual error_code getSymbolType(DataRefImpl Symb, 66259698Sdim SymbolRef::Type &Res) const; 67259698Sdim virtual error_code getSymbolSection(DataRefImpl Symb, 68259698Sdim section_iterator &Res) const; 69259698Sdim virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const; 70259698Sdim 71259698Sdim virtual error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) const; 72259698Sdim virtual error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const; 73259698Sdim 74259698Sdim virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; 75259698Sdim virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; 76259698Sdim virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const; 77259698Sdim virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; 78259698Sdim virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; 79259698Sdim virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const; 80259698Sdim virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; 81259698Sdim virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; 82259698Sdim virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; 83259698Sdim virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, 84259698Sdim bool &Res) const; 85259698Sdim virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; 86259698Sdim virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; 87259698Sdim virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const; 88259698Sdim virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, 89259698Sdim bool &Result) const; 90259698Sdim virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const; 91259698Sdim virtual relocation_iterator section_rel_end(DataRefImpl Sec) const; 92259698Sdim virtual section_iterator getRelocatedSection(DataRefImpl Sec) const; 93259698Sdim 94259698Sdim virtual error_code getRelocationNext(DataRefImpl Rel, 95259698Sdim RelocationRef &Res) const; 96259698Sdim virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const; 97259698Sdim virtual error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const; 98259698Sdim virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const; 99259698Sdim virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const; 100259698Sdim virtual error_code getRelocationTypeName(DataRefImpl Rel, 101259698Sdim SmallVectorImpl<char> &Result) const; 102259698Sdim virtual error_code 103259698Sdim getRelocationValueString(DataRefImpl Rel, 104259698Sdim SmallVectorImpl<char> &Result) const; 105259698Sdim 106259698Sdim uint64_t getROffset(DataRefImpl Rel) const; 107259698Sdim StringRef getRelocationTypeName(uint32_t Type) const; 108259698Sdim 109259698Sdim /// \brief Get the relocation section that contains \a Rel. 110259698Sdim const Elf_Shdr *getRelSection(DataRefImpl Rel) const { 111259698Sdim return EF.getSection(Rel.d.a); 112259698Sdim } 113259698Sdim 114259698Sdim const Elf_Rel *getRel(DataRefImpl Rel) const; 115259698Sdim const Elf_Rela *getRela(DataRefImpl Rela) const; 116259698Sdim 117259698Sdim Elf_Sym_Iter toELFSymIter(DataRefImpl Symb) const { 118259698Sdim bool IsDynamic = Symb.p & 1; 119259698Sdim if (IsDynamic) 120259698Sdim return Elf_Sym_Iter( 121259698Sdim EF.begin_dynamic_symbols().getEntSize(), 122259698Sdim reinterpret_cast<const char *>(Symb.p & ~uintptr_t(1)), IsDynamic); 123259698Sdim return Elf_Sym_Iter(EF.begin_symbols().getEntSize(), 124259698Sdim reinterpret_cast<const char *>(Symb.p), IsDynamic); 125259698Sdim } 126259698Sdim 127259698Sdim DataRefImpl toDRI(Elf_Sym_Iter Symb) const { 128259698Sdim DataRefImpl DRI; 129259698Sdim DRI.p = reinterpret_cast<uintptr_t>(Symb.get()) | 130259698Sdim static_cast<uintptr_t>(Symb.isDynamic()); 131259698Sdim return DRI; 132259698Sdim } 133259698Sdim 134259698Sdim Elf_Shdr_Iter toELFShdrIter(DataRefImpl Sec) const { 135259698Sdim return Elf_Shdr_Iter(EF.getHeader()->e_shentsize, 136259698Sdim reinterpret_cast<const char *>(Sec.p)); 137259698Sdim } 138259698Sdim 139259698Sdim DataRefImpl toDRI(Elf_Shdr_Iter Sec) const { 140259698Sdim DataRefImpl DRI; 141259698Sdim DRI.p = reinterpret_cast<uintptr_t>(Sec.get()); 142259698Sdim return DRI; 143259698Sdim } 144259698Sdim 145259698Sdim DataRefImpl toDRI(const Elf_Shdr *Sec) const { 146259698Sdim DataRefImpl DRI; 147259698Sdim DRI.p = reinterpret_cast<uintptr_t>(Sec); 148259698Sdim return DRI; 149259698Sdim } 150259698Sdim 151259698Sdim Elf_Dyn_Iter toELFDynIter(DataRefImpl Dyn) const { 152259698Sdim return Elf_Dyn_Iter(EF.begin_dynamic_table().getEntSize(), 153259698Sdim reinterpret_cast<const char *>(Dyn.p)); 154259698Sdim } 155259698Sdim 156259698Sdim DataRefImpl toDRI(Elf_Dyn_Iter Dyn) const { 157259698Sdim DataRefImpl DRI; 158259698Sdim DRI.p = reinterpret_cast<uintptr_t>(Dyn.get()); 159259698Sdim return DRI; 160259698Sdim } 161259698Sdim 162259698Sdim // This flag is used for classof, to distinguish ELFObjectFile from 163259698Sdim // its subclass. If more subclasses will be created, this flag will 164259698Sdim // have to become an enum. 165259698Sdim bool isDyldELFObject; 166259698Sdim 167259698Sdimpublic: 168259698Sdim ELFObjectFile(MemoryBuffer *Object, error_code &ec); 169259698Sdim 170259698Sdim const Elf_Sym *getSymbol(DataRefImpl Symb) const; 171259698Sdim 172259698Sdim virtual symbol_iterator begin_symbols() const; 173259698Sdim virtual symbol_iterator end_symbols() const; 174259698Sdim 175259698Sdim virtual symbol_iterator begin_dynamic_symbols() const; 176259698Sdim virtual symbol_iterator end_dynamic_symbols() const; 177259698Sdim 178259698Sdim virtual section_iterator begin_sections() const; 179259698Sdim virtual section_iterator end_sections() const; 180259698Sdim 181259698Sdim virtual library_iterator begin_libraries_needed() const; 182259698Sdim virtual library_iterator end_libraries_needed() const; 183259698Sdim 184259698Sdim error_code getRelocationAddend(DataRefImpl Rel, int64_t &Res) const; 185259698Sdim error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, 186259698Sdim bool &IsDefault) const; 187259698Sdim 188259698Sdim virtual uint8_t getBytesInAddress() const; 189259698Sdim virtual StringRef getFileFormatName() const; 190259698Sdim virtual StringRef getObjectType() const { return "ELF"; } 191259698Sdim virtual unsigned getArch() const; 192259698Sdim virtual StringRef getLoadName() const; 193259698Sdim 194259698Sdim const ELFFile<ELFT> *getELFFile() const { return &EF; } 195259698Sdim 196259698Sdim bool isDyldType() const { return isDyldELFObject; } 197259698Sdim static inline bool classof(const Binary *v) { 198259698Sdim return v->getType() == getELFType(ELFT::TargetEndianness == support::little, 199259698Sdim ELFT::Is64Bits); 200259698Sdim } 201259698Sdim}; 202259698Sdim 203259698Sdim// Use an alignment of 2 for the typedefs since that is the worst case for 204259698Sdim// ELF files in archives. 205259698Sdimtypedef ELFObjectFile<ELFType<support::little, 2, false> > ELF32LEObjectFile; 206259698Sdimtypedef ELFObjectFile<ELFType<support::little, 2, true> > ELF64LEObjectFile; 207259698Sdimtypedef ELFObjectFile<ELFType<support::big, 2, false> > ELF32BEObjectFile; 208259698Sdimtypedef ELFObjectFile<ELFType<support::big, 2, true> > ELF64BEObjectFile; 209259698Sdim 210259698Sdimtemplate <class ELFT> 211259698Sdimerror_code ELFObjectFile<ELFT>::getSymbolNext(DataRefImpl Symb, 212259698Sdim SymbolRef &Result) const { 213259698Sdim Result = SymbolRef(toDRI(++toELFSymIter(Symb)), this); 214259698Sdim return object_error::success; 215259698Sdim} 216259698Sdim 217259698Sdimtemplate <class ELFT> 218259698Sdimerror_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb, 219259698Sdim StringRef &Result) const { 220259698Sdim ErrorOr<StringRef> Name = EF.getSymbolName(toELFSymIter(Symb)); 221259698Sdim if (!Name) 222259698Sdim return Name; 223259698Sdim Result = *Name; 224259698Sdim return object_error::success; 225259698Sdim} 226259698Sdim 227259698Sdimtemplate <class ELFT> 228259698Sdimerror_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef, 229259698Sdim StringRef &Version, 230259698Sdim bool &IsDefault) const { 231259698Sdim DataRefImpl Symb = SymRef.getRawDataRefImpl(); 232259698Sdim const Elf_Sym *symb = getSymbol(Symb); 233259698Sdim ErrorOr<StringRef> Ver = 234259698Sdim EF.getSymbolVersion(EF.getSection(Symb.d.b), symb, IsDefault); 235259698Sdim if (!Ver) 236259698Sdim return Ver; 237259698Sdim Version = *Ver; 238259698Sdim return object_error::success; 239259698Sdim} 240259698Sdim 241259698Sdimtemplate <class ELFT> 242259698Sdimerror_code ELFObjectFile<ELFT>::getSymbolFileOffset(DataRefImpl Symb, 243259698Sdim uint64_t &Result) const { 244259698Sdim const Elf_Sym *ESym = getSymbol(Symb); 245259698Sdim const Elf_Shdr *ESec; 246259698Sdim switch (EF.getSymbolTableIndex(ESym)) { 247259698Sdim case ELF::SHN_COMMON: 248259698Sdim // Unintialized symbols have no offset in the object file 249259698Sdim case ELF::SHN_UNDEF: 250259698Sdim Result = UnknownAddressOrSize; 251259698Sdim return object_error::success; 252259698Sdim case ELF::SHN_ABS: 253259698Sdim Result = ESym->st_value; 254259698Sdim return object_error::success; 255259698Sdim default: 256259698Sdim ESec = EF.getSection(ESym); 257259698Sdim } 258259698Sdim 259259698Sdim switch (ESym->getType()) { 260259698Sdim case ELF::STT_SECTION: 261259698Sdim Result = ESec ? ESec->sh_offset : UnknownAddressOrSize; 262259698Sdim return object_error::success; 263259698Sdim case ELF::STT_FUNC: 264259698Sdim case ELF::STT_OBJECT: 265259698Sdim case ELF::STT_NOTYPE: 266259698Sdim Result = ESym->st_value + (ESec ? ESec->sh_offset : 0); 267259698Sdim return object_error::success; 268259698Sdim default: 269259698Sdim Result = UnknownAddressOrSize; 270259698Sdim return object_error::success; 271259698Sdim } 272259698Sdim} 273259698Sdim 274259698Sdimtemplate <class ELFT> 275259698Sdimerror_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, 276259698Sdim uint64_t &Result) const { 277259698Sdim const Elf_Sym *ESym = getSymbol(Symb); 278259698Sdim const Elf_Shdr *ESec; 279259698Sdim switch (EF.getSymbolTableIndex(ESym)) { 280259698Sdim case ELF::SHN_COMMON: 281259698Sdim case ELF::SHN_UNDEF: 282259698Sdim Result = UnknownAddressOrSize; 283259698Sdim return object_error::success; 284259698Sdim case ELF::SHN_ABS: 285259698Sdim Result = ESym->st_value; 286259698Sdim return object_error::success; 287259698Sdim default: 288259698Sdim ESec = EF.getSection(ESym); 289259698Sdim } 290259698Sdim 291259698Sdim switch (ESym->getType()) { 292259698Sdim case ELF::STT_SECTION: 293259698Sdim Result = ESec ? ESec->sh_addr : UnknownAddressOrSize; 294259698Sdim return object_error::success; 295259698Sdim case ELF::STT_FUNC: 296259698Sdim case ELF::STT_OBJECT: 297259698Sdim case ELF::STT_NOTYPE: 298259698Sdim bool IsRelocatable; 299259698Sdim switch (EF.getHeader()->e_type) { 300259698Sdim case ELF::ET_EXEC: 301259698Sdim case ELF::ET_DYN: 302259698Sdim IsRelocatable = false; 303259698Sdim break; 304259698Sdim default: 305259698Sdim IsRelocatable = true; 306259698Sdim } 307259698Sdim Result = ESym->st_value; 308259698Sdim 309259698Sdim // Clear the ARM/Thumb indicator flag. 310259698Sdim if (EF.getHeader()->e_machine == ELF::EM_ARM) 311259698Sdim Result &= ~1; 312259698Sdim 313259698Sdim if (IsRelocatable && ESec != 0) 314259698Sdim Result += ESec->sh_addr; 315259698Sdim return object_error::success; 316259698Sdim default: 317259698Sdim Result = UnknownAddressOrSize; 318259698Sdim return object_error::success; 319259698Sdim } 320259698Sdim} 321259698Sdim 322259698Sdimtemplate <class ELFT> 323259698Sdimerror_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb, 324259698Sdim uint32_t &Res) const { 325259698Sdim Elf_Sym_Iter Sym = toELFSymIter(Symb); 326259698Sdim if (Sym->st_shndx == ELF::SHN_COMMON) 327259698Sdim Res = Sym->st_value; 328259698Sdim else 329259698Sdim Res = 0; 330259698Sdim return object_error::success; 331259698Sdim} 332259698Sdim 333259698Sdimtemplate <class ELFT> 334259698Sdimerror_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb, 335259698Sdim uint64_t &Result) const { 336259698Sdim Result = toELFSymIter(Symb)->st_size; 337259698Sdim return object_error::success; 338259698Sdim} 339259698Sdim 340259698Sdimtemplate <class ELFT> 341259698Sdimerror_code ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb, 342259698Sdim SymbolRef::Type &Result) const { 343259698Sdim const Elf_Sym *ESym = getSymbol(Symb); 344259698Sdim 345259698Sdim switch (ESym->getType()) { 346259698Sdim case ELF::STT_NOTYPE: 347259698Sdim Result = SymbolRef::ST_Unknown; 348259698Sdim break; 349259698Sdim case ELF::STT_SECTION: 350259698Sdim Result = SymbolRef::ST_Debug; 351259698Sdim break; 352259698Sdim case ELF::STT_FILE: 353259698Sdim Result = SymbolRef::ST_File; 354259698Sdim break; 355259698Sdim case ELF::STT_FUNC: 356259698Sdim Result = SymbolRef::ST_Function; 357259698Sdim break; 358259698Sdim case ELF::STT_OBJECT: 359259698Sdim case ELF::STT_COMMON: 360259698Sdim case ELF::STT_TLS: 361259698Sdim Result = SymbolRef::ST_Data; 362259698Sdim break; 363259698Sdim default: 364259698Sdim Result = SymbolRef::ST_Other; 365259698Sdim break; 366259698Sdim } 367259698Sdim return object_error::success; 368259698Sdim} 369259698Sdim 370259698Sdimtemplate <class ELFT> 371259698Sdimerror_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb, 372259698Sdim uint32_t &Result) const { 373259698Sdim const Elf_Sym *ESym = getSymbol(Symb); 374259698Sdim 375259698Sdim Result = SymbolRef::SF_None; 376259698Sdim 377259698Sdim if (ESym->getBinding() != ELF::STB_LOCAL) 378259698Sdim Result |= SymbolRef::SF_Global; 379259698Sdim 380259698Sdim if (ESym->getBinding() == ELF::STB_WEAK) 381259698Sdim Result |= SymbolRef::SF_Weak; 382259698Sdim 383259698Sdim if (ESym->st_shndx == ELF::SHN_ABS) 384259698Sdim Result |= SymbolRef::SF_Absolute; 385259698Sdim 386259698Sdim if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION || 387259698Sdim ESym == &*EF.begin_symbols()) 388259698Sdim Result |= SymbolRef::SF_FormatSpecific; 389259698Sdim 390259698Sdim if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF) 391259698Sdim Result |= SymbolRef::SF_Undefined; 392259698Sdim 393259698Sdim if (ESym->getType() == ELF::STT_COMMON || 394259698Sdim EF.getSymbolTableIndex(ESym) == ELF::SHN_COMMON) 395259698Sdim Result |= SymbolRef::SF_Common; 396259698Sdim 397259698Sdim if (ESym->getType() == ELF::STT_TLS) 398259698Sdim Result |= SymbolRef::SF_ThreadLocal; 399259698Sdim 400259698Sdim return object_error::success; 401259698Sdim} 402259698Sdim 403259698Sdimtemplate <class ELFT> 404259698Sdimerror_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb, 405259698Sdim section_iterator &Res) const { 406259698Sdim const Elf_Sym *ESym = getSymbol(Symb); 407259698Sdim const Elf_Shdr *ESec = EF.getSection(ESym); 408259698Sdim if (!ESec) 409259698Sdim Res = end_sections(); 410259698Sdim else { 411259698Sdim DataRefImpl Sec; 412259698Sdim Sec.p = reinterpret_cast<intptr_t>(ESec); 413259698Sdim Res = section_iterator(SectionRef(Sec, this)); 414259698Sdim } 415259698Sdim return object_error::success; 416259698Sdim} 417259698Sdim 418259698Sdimtemplate <class ELFT> 419259698Sdimerror_code ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb, 420259698Sdim uint64_t &Val) const { 421259698Sdim const Elf_Sym *ESym = getSymbol(Symb); 422259698Sdim Val = ESym->st_value; 423259698Sdim return object_error::success; 424259698Sdim} 425259698Sdim 426259698Sdimtemplate <class ELFT> 427259698Sdimerror_code ELFObjectFile<ELFT>::getSectionNext(DataRefImpl Sec, 428259698Sdim SectionRef &Result) const { 429259698Sdim Result = SectionRef(toDRI(++toELFShdrIter(Sec)), this); 430259698Sdim return object_error::success; 431259698Sdim} 432259698Sdim 433259698Sdimtemplate <class ELFT> 434259698Sdimerror_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec, 435259698Sdim StringRef &Result) const { 436259698Sdim ErrorOr<StringRef> Name = EF.getSectionName(&*toELFShdrIter(Sec)); 437259698Sdim if (!Name) 438259698Sdim return Name; 439259698Sdim Result = *Name; 440259698Sdim return object_error::success; 441259698Sdim} 442259698Sdim 443259698Sdimtemplate <class ELFT> 444259698Sdimerror_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec, 445259698Sdim uint64_t &Result) const { 446259698Sdim Result = toELFShdrIter(Sec)->sh_addr; 447259698Sdim return object_error::success; 448259698Sdim} 449259698Sdim 450259698Sdimtemplate <class ELFT> 451259698Sdimerror_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec, 452259698Sdim uint64_t &Result) const { 453259698Sdim Result = toELFShdrIter(Sec)->sh_size; 454259698Sdim return object_error::success; 455259698Sdim} 456259698Sdim 457259698Sdimtemplate <class ELFT> 458259698Sdimerror_code ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec, 459259698Sdim StringRef &Result) const { 460259698Sdim Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); 461259698Sdim Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size); 462259698Sdim return object_error::success; 463259698Sdim} 464259698Sdim 465259698Sdimtemplate <class ELFT> 466259698Sdimerror_code ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec, 467259698Sdim uint64_t &Result) const { 468259698Sdim Result = toELFShdrIter(Sec)->sh_addralign; 469259698Sdim return object_error::success; 470259698Sdim} 471259698Sdim 472259698Sdimtemplate <class ELFT> 473259698Sdimerror_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec, 474259698Sdim bool &Result) const { 475259698Sdim Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_EXECINSTR; 476259698Sdim return object_error::success; 477259698Sdim} 478259698Sdim 479259698Sdimtemplate <class ELFT> 480259698Sdimerror_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec, 481259698Sdim bool &Result) const { 482259698Sdim Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); 483259698Sdim Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && 484259698Sdim EShdr->sh_type == ELF::SHT_PROGBITS; 485259698Sdim return object_error::success; 486259698Sdim} 487259698Sdim 488259698Sdimtemplate <class ELFT> 489259698Sdimerror_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec, 490259698Sdim bool &Result) const { 491259698Sdim Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); 492259698Sdim Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && 493259698Sdim EShdr->sh_type == ELF::SHT_NOBITS; 494259698Sdim return object_error::success; 495259698Sdim} 496259698Sdim 497259698Sdimtemplate <class ELFT> 498259698Sdimerror_code 499259698SdimELFObjectFile<ELFT>::isSectionRequiredForExecution(DataRefImpl Sec, 500259698Sdim bool &Result) const { 501259698Sdim Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_ALLOC; 502259698Sdim return object_error::success; 503259698Sdim} 504259698Sdim 505259698Sdimtemplate <class ELFT> 506259698Sdimerror_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec, 507259698Sdim bool &Result) const { 508259698Sdim Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS; 509259698Sdim return object_error::success; 510259698Sdim} 511259698Sdim 512259698Sdimtemplate <class ELFT> 513259698Sdimerror_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec, 514259698Sdim bool &Result) const { 515259698Sdim Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS; 516259698Sdim return object_error::success; 517259698Sdim} 518259698Sdim 519259698Sdimtemplate <class ELFT> 520259698Sdimerror_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec, 521259698Sdim bool &Result) const { 522259698Sdim Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); 523259698Sdim Result = !(EShdr->sh_flags & (ELF::SHF_WRITE | ELF::SHF_EXECINSTR)); 524259698Sdim return object_error::success; 525259698Sdim} 526259698Sdim 527259698Sdimtemplate <class ELFT> 528259698Sdimerror_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec, 529259698Sdim DataRefImpl Symb, 530259698Sdim bool &Result) const { 531259698Sdim Elf_Sym_Iter ESym = toELFSymIter(Symb); 532259698Sdim 533259698Sdim uintX_t Index = ESym->st_shndx; 534259698Sdim bool Reserved = Index >= ELF::SHN_LORESERVE && Index <= ELF::SHN_HIRESERVE; 535259698Sdim 536259698Sdim Result = !Reserved && (&*toELFShdrIter(Sec) == EF.getSection(ESym->st_shndx)); 537259698Sdim return object_error::success; 538259698Sdim} 539259698Sdim 540259698Sdimtemplate <class ELFT> 541259698Sdimrelocation_iterator 542259698SdimELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const { 543259698Sdim DataRefImpl RelData; 544259698Sdim uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.begin_sections().get()); 545259698Sdim RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize; 546259698Sdim RelData.d.b = 0; 547259698Sdim return relocation_iterator(RelocationRef(RelData, this)); 548259698Sdim} 549259698Sdim 550259698Sdimtemplate <class ELFT> 551259698Sdimrelocation_iterator 552259698SdimELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const { 553259698Sdim DataRefImpl RelData; 554259698Sdim uintptr_t SHT = reinterpret_cast<uintptr_t>(EF.begin_sections().get()); 555259698Sdim const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p); 556259698Sdim RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize; 557259698Sdim if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL) 558259698Sdim RelData.d.b = 0; 559259698Sdim else 560259698Sdim RelData.d.b = S->sh_size / S->sh_entsize; 561259698Sdim 562259698Sdim return relocation_iterator(RelocationRef(RelData, this)); 563259698Sdim} 564259698Sdim 565259698Sdimtemplate <class ELFT> 566259698Sdimsection_iterator 567259698SdimELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const { 568259698Sdim if (EF.getHeader()->e_type != ELF::ET_REL) 569259698Sdim return end_sections(); 570259698Sdim 571259698Sdim Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); 572259698Sdim uintX_t Type = EShdr->sh_type; 573259698Sdim if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA) 574259698Sdim return end_sections(); 575259698Sdim 576259698Sdim const Elf_Shdr *R = EF.getSection(EShdr->sh_info); 577259698Sdim return section_iterator(SectionRef(toDRI(R), this)); 578259698Sdim} 579259698Sdim 580259698Sdim// Relocations 581259698Sdimtemplate <class ELFT> 582259698Sdimerror_code ELFObjectFile<ELFT>::getRelocationNext(DataRefImpl Rel, 583259698Sdim RelocationRef &Result) const { 584259698Sdim ++Rel.d.b; 585259698Sdim Result = RelocationRef(Rel, this); 586259698Sdim return object_error::success; 587259698Sdim} 588259698Sdim 589259698Sdimtemplate <class ELFT> 590259698Sdimsymbol_iterator 591259698SdimELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const { 592259698Sdim uint32_t symbolIdx; 593259698Sdim const Elf_Shdr *sec = getRelSection(Rel); 594259698Sdim switch (sec->sh_type) { 595259698Sdim default: 596259698Sdim report_fatal_error("Invalid section type in Rel!"); 597259698Sdim case ELF::SHT_REL: { 598259698Sdim symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL()); 599259698Sdim break; 600259698Sdim } 601259698Sdim case ELF::SHT_RELA: { 602259698Sdim symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL()); 603259698Sdim break; 604259698Sdim } 605259698Sdim } 606259698Sdim if (!symbolIdx) 607259698Sdim return end_symbols(); 608259698Sdim 609259698Sdim const Elf_Shdr *SymSec = EF.getSection(sec->sh_link); 610259698Sdim 611259698Sdim DataRefImpl SymbolData; 612259698Sdim switch (SymSec->sh_type) { 613259698Sdim default: 614259698Sdim report_fatal_error("Invalid symbol table section type!"); 615259698Sdim case ELF::SHT_SYMTAB: 616259698Sdim SymbolData = toDRI(EF.begin_symbols() + symbolIdx); 617259698Sdim break; 618259698Sdim case ELF::SHT_DYNSYM: 619259698Sdim SymbolData = toDRI(EF.begin_dynamic_symbols() + symbolIdx); 620259698Sdim break; 621259698Sdim } 622259698Sdim 623259698Sdim return symbol_iterator(SymbolRef(SymbolData, this)); 624259698Sdim} 625259698Sdim 626259698Sdimtemplate <class ELFT> 627259698Sdimerror_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel, 628259698Sdim uint64_t &Result) const { 629259698Sdim Result = getROffset(Rel); 630259698Sdim return object_error::success; 631259698Sdim} 632259698Sdim 633259698Sdimtemplate <class ELFT> 634259698Sdimerror_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel, 635259698Sdim uint64_t &Result) const { 636259698Sdim Result = getROffset(Rel); 637259698Sdim return object_error::success; 638259698Sdim} 639259698Sdim 640259698Sdimtemplate <class ELFT> 641259698Sdimuint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const { 642259698Sdim const Elf_Shdr *sec = getRelSection(Rel); 643259698Sdim switch (sec->sh_type) { 644259698Sdim default: 645259698Sdim report_fatal_error("Invalid section type in Rel!"); 646259698Sdim case ELF::SHT_REL: 647259698Sdim return getRel(Rel)->r_offset; 648259698Sdim case ELF::SHT_RELA: 649259698Sdim return getRela(Rel)->r_offset; 650259698Sdim } 651259698Sdim} 652259698Sdim 653259698Sdimtemplate <class ELFT> 654259698Sdimerror_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel, 655259698Sdim uint64_t &Result) const { 656259698Sdim const Elf_Shdr *sec = getRelSection(Rel); 657259698Sdim switch (sec->sh_type) { 658259698Sdim default: 659259698Sdim report_fatal_error("Invalid section type in Rel!"); 660259698Sdim case ELF::SHT_REL: { 661259698Sdim Result = getRel(Rel)->getType(EF.isMips64EL()); 662259698Sdim break; 663259698Sdim } 664259698Sdim case ELF::SHT_RELA: { 665259698Sdim Result = getRela(Rel)->getType(EF.isMips64EL()); 666259698Sdim break; 667259698Sdim } 668259698Sdim } 669259698Sdim return object_error::success; 670259698Sdim} 671259698Sdim 672259698Sdimtemplate <class ELFT> 673259698SdimStringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const { 674259698Sdim return getELFRelocationTypeName(EF.getHeader()->e_machine, Type); 675259698Sdim} 676259698Sdim 677259698Sdimtemplate <class ELFT> 678259698Sdimerror_code ELFObjectFile<ELFT>::getRelocationTypeName( 679259698Sdim DataRefImpl Rel, SmallVectorImpl<char> &Result) const { 680259698Sdim const Elf_Shdr *sec = getRelSection(Rel); 681259698Sdim uint32_t type; 682259698Sdim switch (sec->sh_type) { 683259698Sdim default: 684259698Sdim return object_error::parse_failed; 685259698Sdim case ELF::SHT_REL: { 686259698Sdim type = getRel(Rel)->getType(EF.isMips64EL()); 687259698Sdim break; 688259698Sdim } 689259698Sdim case ELF::SHT_RELA: { 690259698Sdim type = getRela(Rel)->getType(EF.isMips64EL()); 691259698Sdim break; 692259698Sdim } 693259698Sdim } 694259698Sdim 695259698Sdim EF.getRelocationTypeName(type, Result); 696259698Sdim return object_error::success; 697259698Sdim} 698259698Sdim 699259698Sdimtemplate <class ELFT> 700259698Sdimerror_code ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel, 701259698Sdim int64_t &Result) const { 702259698Sdim const Elf_Shdr *sec = getRelSection(Rel); 703259698Sdim switch (sec->sh_type) { 704259698Sdim default: 705259698Sdim report_fatal_error("Invalid section type in Rel!"); 706259698Sdim case ELF::SHT_REL: { 707259698Sdim Result = 0; 708259698Sdim return object_error::success; 709259698Sdim } 710259698Sdim case ELF::SHT_RELA: { 711259698Sdim Result = getRela(Rel)->r_addend; 712259698Sdim return object_error::success; 713259698Sdim } 714259698Sdim } 715259698Sdim} 716259698Sdim 717259698Sdimtemplate <class ELFT> 718259698Sdimerror_code ELFObjectFile<ELFT>::getRelocationValueString( 719259698Sdim DataRefImpl Rel, SmallVectorImpl<char> &Result) const { 720259698Sdim const Elf_Shdr *sec = getRelSection(Rel); 721259698Sdim uint8_t type; 722259698Sdim StringRef res; 723259698Sdim int64_t addend = 0; 724259698Sdim uint16_t symbol_index = 0; 725259698Sdim switch (sec->sh_type) { 726259698Sdim default: 727259698Sdim return object_error::parse_failed; 728259698Sdim case ELF::SHT_REL: { 729259698Sdim type = getRel(Rel)->getType(EF.isMips64EL()); 730259698Sdim symbol_index = getRel(Rel)->getSymbol(EF.isMips64EL()); 731259698Sdim // TODO: Read implicit addend from section data. 732259698Sdim break; 733259698Sdim } 734259698Sdim case ELF::SHT_RELA: { 735259698Sdim type = getRela(Rel)->getType(EF.isMips64EL()); 736259698Sdim symbol_index = getRela(Rel)->getSymbol(EF.isMips64EL()); 737259698Sdim addend = getRela(Rel)->r_addend; 738259698Sdim break; 739259698Sdim } 740259698Sdim } 741259698Sdim const Elf_Sym *symb = 742259698Sdim EF.template getEntry<Elf_Sym>(sec->sh_link, symbol_index); 743259698Sdim ErrorOr<StringRef> SymName = 744259698Sdim EF.getSymbolName(EF.getSection(sec->sh_link), symb); 745259698Sdim if (!SymName) 746259698Sdim return SymName; 747259698Sdim switch (EF.getHeader()->e_machine) { 748259698Sdim case ELF::EM_X86_64: 749259698Sdim switch (type) { 750259698Sdim case ELF::R_X86_64_PC8: 751259698Sdim case ELF::R_X86_64_PC16: 752259698Sdim case ELF::R_X86_64_PC32: { 753259698Sdim std::string fmtbuf; 754259698Sdim raw_string_ostream fmt(fmtbuf); 755259698Sdim fmt << *SymName << (addend < 0 ? "" : "+") << addend << "-P"; 756259698Sdim fmt.flush(); 757259698Sdim Result.append(fmtbuf.begin(), fmtbuf.end()); 758259698Sdim } break; 759259698Sdim case ELF::R_X86_64_8: 760259698Sdim case ELF::R_X86_64_16: 761259698Sdim case ELF::R_X86_64_32: 762259698Sdim case ELF::R_X86_64_32S: 763259698Sdim case ELF::R_X86_64_64: { 764259698Sdim std::string fmtbuf; 765259698Sdim raw_string_ostream fmt(fmtbuf); 766259698Sdim fmt << *SymName << (addend < 0 ? "" : "+") << addend; 767259698Sdim fmt.flush(); 768259698Sdim Result.append(fmtbuf.begin(), fmtbuf.end()); 769259698Sdim } break; 770259698Sdim default: 771259698Sdim res = "Unknown"; 772259698Sdim } 773259698Sdim break; 774259698Sdim case ELF::EM_AARCH64: { 775259698Sdim std::string fmtbuf; 776259698Sdim raw_string_ostream fmt(fmtbuf); 777259698Sdim fmt << *SymName; 778259698Sdim if (addend != 0) 779259698Sdim fmt << (addend < 0 ? "" : "+") << addend; 780259698Sdim fmt.flush(); 781259698Sdim Result.append(fmtbuf.begin(), fmtbuf.end()); 782259698Sdim break; 783259698Sdim } 784259698Sdim case ELF::EM_ARM: 785259698Sdim case ELF::EM_HEXAGON: 786259698Sdim res = *SymName; 787259698Sdim break; 788259698Sdim default: 789259698Sdim res = "Unknown"; 790259698Sdim } 791259698Sdim if (Result.empty()) 792259698Sdim Result.append(res.begin(), res.end()); 793259698Sdim return object_error::success; 794259698Sdim} 795259698Sdim 796259698Sdimtemplate <class ELFT> 797259698Sdimconst typename ELFFile<ELFT>::Elf_Sym * 798259698SdimELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const { 799259698Sdim return &*toELFSymIter(Symb); 800259698Sdim} 801259698Sdim 802259698Sdimtemplate <class ELFT> 803259698Sdimconst typename ELFObjectFile<ELFT>::Elf_Rel * 804259698SdimELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const { 805259698Sdim return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b); 806259698Sdim} 807259698Sdim 808259698Sdimtemplate <class ELFT> 809259698Sdimconst typename ELFObjectFile<ELFT>::Elf_Rela * 810259698SdimELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const { 811259698Sdim return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b); 812259698Sdim} 813259698Sdim 814259698Sdimtemplate <class ELFT> 815259698SdimELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec) 816259698Sdim : ObjectFile(getELFType(static_cast<endianness>(ELFT::TargetEndianness) == 817259698Sdim support::little, 818259698Sdim ELFT::Is64Bits), 819259698Sdim Object), 820259698Sdim EF(Object, ec) {} 821259698Sdim 822259698Sdimtemplate <class ELFT> 823259698Sdimsymbol_iterator ELFObjectFile<ELFT>::begin_symbols() const { 824259698Sdim return symbol_iterator(SymbolRef(toDRI(EF.begin_symbols()), this)); 825259698Sdim} 826259698Sdim 827259698Sdimtemplate <class ELFT> 828259698Sdimsymbol_iterator ELFObjectFile<ELFT>::end_symbols() const { 829259698Sdim return symbol_iterator(SymbolRef(toDRI(EF.end_symbols()), this)); 830259698Sdim} 831259698Sdim 832259698Sdimtemplate <class ELFT> 833259698Sdimsymbol_iterator ELFObjectFile<ELFT>::begin_dynamic_symbols() const { 834259698Sdim return symbol_iterator(SymbolRef(toDRI(EF.begin_dynamic_symbols()), this)); 835259698Sdim} 836259698Sdim 837259698Sdimtemplate <class ELFT> 838259698Sdimsymbol_iterator ELFObjectFile<ELFT>::end_dynamic_symbols() const { 839259698Sdim return symbol_iterator(SymbolRef(toDRI(EF.end_dynamic_symbols()), this)); 840259698Sdim} 841259698Sdim 842259698Sdimtemplate <class ELFT> 843259698Sdimsection_iterator ELFObjectFile<ELFT>::begin_sections() const { 844259698Sdim return section_iterator(SectionRef(toDRI(EF.begin_sections()), this)); 845259698Sdim} 846259698Sdim 847259698Sdimtemplate <class ELFT> 848259698Sdimsection_iterator ELFObjectFile<ELFT>::end_sections() const { 849259698Sdim return section_iterator(SectionRef(toDRI(EF.end_sections()), this)); 850259698Sdim} 851259698Sdim 852259698Sdimtemplate <class ELFT> 853259698SdimStringRef ELFObjectFile<ELFT>::getLoadName() const { 854259698Sdim Elf_Dyn_Iter DI = EF.begin_dynamic_table(); 855259698Sdim Elf_Dyn_Iter DE = EF.end_dynamic_table(); 856259698Sdim 857259698Sdim while (DI != DE && DI->getTag() != ELF::DT_SONAME) 858259698Sdim ++DI; 859259698Sdim 860259698Sdim if (DI != DE) 861259698Sdim return EF.getDynamicString(DI->getVal()); 862259698Sdim return ""; 863259698Sdim} 864259698Sdim 865259698Sdimtemplate <class ELFT> 866259698Sdimlibrary_iterator ELFObjectFile<ELFT>::begin_libraries_needed() const { 867259698Sdim Elf_Dyn_Iter DI = EF.begin_dynamic_table(); 868259698Sdim Elf_Dyn_Iter DE = EF.end_dynamic_table(); 869259698Sdim 870259698Sdim while (DI != DE && DI->getTag() != ELF::DT_SONAME) 871259698Sdim ++DI; 872259698Sdim 873259698Sdim return library_iterator(LibraryRef(toDRI(DI), this)); 874259698Sdim} 875259698Sdim 876259698Sdimtemplate <class ELFT> 877259698Sdimerror_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data, 878259698Sdim LibraryRef &Result) const { 879259698Sdim Elf_Dyn_Iter DI = toELFDynIter(Data); 880259698Sdim Elf_Dyn_Iter DE = EF.end_dynamic_table(); 881259698Sdim 882259698Sdim // Skip to the next DT_NEEDED entry. 883259698Sdim do 884259698Sdim ++DI; 885259698Sdim while (DI != DE && DI->getTag() != ELF::DT_NEEDED); 886259698Sdim 887259698Sdim Result = LibraryRef(toDRI(DI), this); 888259698Sdim return object_error::success; 889259698Sdim} 890259698Sdim 891259698Sdimtemplate <class ELFT> 892259698Sdimerror_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data, 893259698Sdim StringRef &Res) const { 894259698Sdim Res = EF.getDynamicString(toELFDynIter(Data)->getVal()); 895259698Sdim return object_error::success; 896259698Sdim} 897259698Sdim 898259698Sdimtemplate <class ELFT> 899259698Sdimlibrary_iterator ELFObjectFile<ELFT>::end_libraries_needed() const { 900259698Sdim return library_iterator(LibraryRef(toDRI(EF.end_dynamic_table()), this)); 901259698Sdim} 902259698Sdim 903259698Sdimtemplate <class ELFT> 904259698Sdimuint8_t ELFObjectFile<ELFT>::getBytesInAddress() const { 905259698Sdim return ELFT::Is64Bits ? 8 : 4; 906259698Sdim} 907259698Sdim 908259698Sdimtemplate <class ELFT> 909259698SdimStringRef ELFObjectFile<ELFT>::getFileFormatName() const { 910259698Sdim switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) { 911259698Sdim case ELF::ELFCLASS32: 912259698Sdim switch (EF.getHeader()->e_machine) { 913259698Sdim case ELF::EM_386: 914259698Sdim return "ELF32-i386"; 915259698Sdim case ELF::EM_X86_64: 916259698Sdim return "ELF32-x86-64"; 917259698Sdim case ELF::EM_ARM: 918259698Sdim return "ELF32-arm"; 919259698Sdim case ELF::EM_HEXAGON: 920259698Sdim return "ELF32-hexagon"; 921259698Sdim case ELF::EM_MIPS: 922259698Sdim return "ELF32-mips"; 923259698Sdim case ELF::EM_PPC: 924259698Sdim return "ELF32-ppc"; 925263763Sdim case ELF::EM_SPARC: 926263763Sdim case ELF::EM_SPARC32PLUS: 927263763Sdim return "ELF32-sparc"; 928259698Sdim default: 929259698Sdim return "ELF32-unknown"; 930259698Sdim } 931259698Sdim case ELF::ELFCLASS64: 932259698Sdim switch (EF.getHeader()->e_machine) { 933259698Sdim case ELF::EM_386: 934259698Sdim return "ELF64-i386"; 935259698Sdim case ELF::EM_X86_64: 936259698Sdim return "ELF64-x86-64"; 937259698Sdim case ELF::EM_AARCH64: 938259698Sdim return "ELF64-aarch64"; 939259698Sdim case ELF::EM_PPC64: 940259698Sdim return "ELF64-ppc64"; 941259698Sdim case ELF::EM_S390: 942259698Sdim return "ELF64-s390"; 943263763Sdim case ELF::EM_SPARCV9: 944263763Sdim return "ELF64-sparc"; 945259698Sdim default: 946259698Sdim return "ELF64-unknown"; 947259698Sdim } 948259698Sdim default: 949259698Sdim // FIXME: Proper error handling. 950259698Sdim report_fatal_error("Invalid ELFCLASS!"); 951259698Sdim } 952259698Sdim} 953259698Sdim 954259698Sdimtemplate <class ELFT> 955259698Sdimunsigned ELFObjectFile<ELFT>::getArch() const { 956259698Sdim switch (EF.getHeader()->e_machine) { 957259698Sdim case ELF::EM_386: 958259698Sdim return Triple::x86; 959259698Sdim case ELF::EM_X86_64: 960259698Sdim return Triple::x86_64; 961259698Sdim case ELF::EM_AARCH64: 962259698Sdim return Triple::aarch64; 963259698Sdim case ELF::EM_ARM: 964259698Sdim return Triple::arm; 965259698Sdim case ELF::EM_HEXAGON: 966259698Sdim return Triple::hexagon; 967259698Sdim case ELF::EM_MIPS: 968259698Sdim return (ELFT::TargetEndianness == support::little) ? Triple::mipsel 969259698Sdim : Triple::mips; 970259698Sdim case ELF::EM_PPC64: 971259698Sdim return (ELFT::TargetEndianness == support::little) ? Triple::ppc64le 972259698Sdim : Triple::ppc64; 973259698Sdim case ELF::EM_S390: 974259698Sdim return Triple::systemz; 975263763Sdim 976263763Sdim case ELF::EM_SPARC: 977263763Sdim case ELF::EM_SPARC32PLUS: 978263763Sdim return Triple::sparc; 979263763Sdim case ELF::EM_SPARCV9: 980263763Sdim return Triple::sparcv9; 981263763Sdim 982259698Sdim default: 983259698Sdim return Triple::UnknownArch; 984259698Sdim } 985259698Sdim} 986259698Sdim 987259698Sdim/// FIXME: Maybe we should have a base ElfObjectFile that is not a template 988259698Sdim/// and make these member functions? 989259698Sdimstatic inline error_code getELFRelocationAddend(const RelocationRef R, 990259698Sdim int64_t &Addend) { 991259698Sdim const ObjectFile *Obj = R.getObjectFile(); 992259698Sdim DataRefImpl DRI = R.getRawDataRefImpl(); 993259698Sdim // Little-endian 32-bit 994259698Sdim if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj)) 995259698Sdim return ELFObj->getRelocationAddend(DRI, Addend); 996259698Sdim 997259698Sdim // Big-endian 32-bit 998259698Sdim if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj)) 999259698Sdim return ELFObj->getRelocationAddend(DRI, Addend); 1000259698Sdim 1001259698Sdim // Little-endian 64-bit 1002259698Sdim if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj)) 1003259698Sdim return ELFObj->getRelocationAddend(DRI, Addend); 1004259698Sdim 1005259698Sdim // Big-endian 64-bit 1006259698Sdim if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj)) 1007259698Sdim return ELFObj->getRelocationAddend(DRI, Addend); 1008259698Sdim 1009259698Sdim llvm_unreachable("Object passed to getELFRelocationAddend() is not ELF"); 1010259698Sdim} 1011259698Sdim 1012259698Sdim/// This is a generic interface for retrieving GNU symbol version 1013259698Sdim/// information from an ELFObjectFile. 1014259698Sdimstatic inline error_code GetELFSymbolVersion(const ObjectFile *Obj, 1015259698Sdim const SymbolRef &Sym, 1016259698Sdim StringRef &Version, 1017259698Sdim bool &IsDefault) { 1018259698Sdim // Little-endian 32-bit 1019259698Sdim if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj)) 1020259698Sdim return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 1021259698Sdim 1022259698Sdim // Big-endian 32-bit 1023259698Sdim if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj)) 1024259698Sdim return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 1025259698Sdim 1026259698Sdim // Little-endian 64-bit 1027259698Sdim if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj)) 1028259698Sdim return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 1029259698Sdim 1030259698Sdim // Big-endian 64-bit 1031259698Sdim if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj)) 1032259698Sdim return ELFObj->getSymbolVersion(Sym, Version, IsDefault); 1033259698Sdim 1034259698Sdim llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF"); 1035259698Sdim} 1036259698Sdim} 1037259698Sdim} 1038259698Sdim 1039259698Sdim#endif 1040