X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=tools%2Fllvm-objdump%2Fllvm-objdump.cpp;h=81deefe651dede41a8761e79ca4d37d0db980a18;hp=614998742f911626b5463c8faeb6cdf17da419d0;hb=a46a5bf8ab9441304f9e9670ce8b1be93710782c;hpb=8bb10c6ad80e8801b7bfea542e1903eae41df222 diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 614998742f9..81deefe651d 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -21,6 +21,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Triple.h" +#include "llvm/CodeGen/FaultMaps.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler.h" @@ -34,7 +35,6 @@ #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Object/Archive.h" #include "llvm/Object/ELFObjectFile.h" -#include "llvm/Object/FaultMapParser.h" #include "llvm/Object/COFF.h" #include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" @@ -212,10 +212,7 @@ static const Target *getTarget(const ObjectFile *Obj = nullptr) { } bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) { - uint64_t a_addr, b_addr; - if (error(a.getOffset(a_addr))) return false; - if (error(b.getOffset(b_addr))) return false; - return a_addr < b_addr; + return a.getOffset() < b.getOffset(); } namespace { @@ -298,61 +295,69 @@ PrettyPrinter &selectPrettyPrinter(Triple const &Triple) { } } -template -static const typename ELFObjectFile::Elf_Rel * -getRel(const ELFFile &EF, DataRefImpl Rel) { - typedef typename ELFObjectFile::Elf_Rel Elf_Rel; - return EF.template getEntry(Rel.d.a, Rel.d.b); -} - -template -static const typename ELFObjectFile::Elf_Rela * -getRela(const ELFFile &EF, DataRefImpl Rela) { - typedef typename ELFObjectFile::Elf_Rela Elf_Rela; - return EF.template getEntry(Rela.d.a, Rela.d.b); -} - template static std::error_code getRelocationValueString(const ELFObjectFile *Obj, DataRefImpl Rel, SmallVectorImpl &Result) { typedef typename ELFObjectFile::Elf_Sym Elf_Sym; typedef typename ELFObjectFile::Elf_Shdr Elf_Shdr; + typedef typename ELFObjectFile::Elf_Rel Elf_Rel; + typedef typename ELFObjectFile::Elf_Rela Elf_Rela; + const ELFFile &EF = *Obj->getELFFile(); - const Elf_Shdr *sec = EF.getSection(Rel.d.a); + ErrorOr SecOrErr = EF.getSection(Rel.d.a); + if (std::error_code EC = SecOrErr.getError()) + return EC; + const Elf_Shdr *Sec = *SecOrErr; + ErrorOr SymTabOrErr = EF.getSection(Sec->sh_link); + if (std::error_code EC = SymTabOrErr.getError()) + return EC; + const Elf_Shdr *SymTab = *SymTabOrErr; + assert(SymTab->sh_type == ELF::SHT_SYMTAB || + SymTab->sh_type == ELF::SHT_DYNSYM); + ErrorOr StrTabSec = EF.getSection(SymTab->sh_link); + if (std::error_code EC = StrTabSec.getError()) + return EC; + ErrorOr StrTabOrErr = EF.getStringTable(*StrTabSec); + if (std::error_code EC = StrTabOrErr.getError()) + return EC; + StringRef StrTab = *StrTabOrErr; uint8_t type; StringRef res; int64_t addend = 0; uint16_t symbol_index = 0; - switch (sec->sh_type) { + switch (Sec->sh_type) { default: return object_error::parse_failed; case ELF::SHT_REL: { - type = getRel(EF, Rel)->getType(EF.isMips64EL()); - symbol_index = getRel(EF, Rel)->getSymbol(EF.isMips64EL()); + const Elf_Rel *ERel = Obj->getRel(Rel); + type = ERel->getType(EF.isMips64EL()); + symbol_index = ERel->getSymbol(EF.isMips64EL()); // TODO: Read implicit addend from section data. break; } case ELF::SHT_RELA: { - type = getRela(EF, Rel)->getType(EF.isMips64EL()); - symbol_index = getRela(EF, Rel)->getSymbol(EF.isMips64EL()); - addend = getRela(EF, Rel)->r_addend; + const Elf_Rela *ERela = Obj->getRela(Rel); + type = ERela->getType(EF.isMips64EL()); + symbol_index = ERela->getSymbol(EF.isMips64EL()); + addend = ERela->r_addend; break; } } const Elf_Sym *symb = - EF.template getEntry(sec->sh_link, symbol_index); + EF.template getEntry(Sec->sh_link, symbol_index); StringRef Target; - const Elf_Shdr *SymSec = EF.getSection(symb); + ErrorOr SymSec = EF.getSection(symb); + if (std::error_code EC = SymSec.getError()) + return EC; if (symb->getType() == ELF::STT_SECTION) { - ErrorOr SecName = EF.getSectionName(SymSec); + ErrorOr SecName = EF.getSectionName(*SymSec); if (std::error_code EC = SecName.getError()) return EC; Target = *SecName; } else { - ErrorOr SymName = - EF.getSymbolName(EF.getSection(sec->sh_link), symb); + ErrorOr SymName = symb->getName(StrTab); if (!SymName) return SymName.getError(); Target = *SymName; @@ -426,9 +431,10 @@ static std::error_code getRelocationValueString(const COFFObjectFile *Obj, const RelocationRef &Rel, SmallVectorImpl &Result) { symbol_iterator SymI = Rel.getSymbol(); - StringRef SymName; - if (std::error_code EC = SymI->getName(SymName)) + ErrorOr SymNameOrErr = SymI->getName(); + if (std::error_code EC = SymNameOrErr.getError()) return EC; + StringRef SymName = *SymNameOrErr; Result.append(SymName.begin(), SymName.end()); return std::error_code(); } @@ -447,16 +453,15 @@ static void printRelocationTargetName(const MachOObjectFile *O, for (const SymbolRef &Symbol : O->symbols()) { std::error_code ec; - uint64_t Addr; - StringRef Name; - - if ((ec = Symbol.getAddress(Addr))) + ErrorOr Addr = Symbol.getAddress(); + if ((ec = Addr.getError())) report_fatal_error(ec.message()); - if (Addr != Val) + if (*Addr != Val) continue; - if ((ec = Symbol.getName(Name))) - report_fatal_error(ec.message()); - fmt << Name; + ErrorOr Name = Symbol.getName(); + if (std::error_code EC = Name.getError()) + report_fatal_error(EC.message()); + fmt << *Name; return; } @@ -486,7 +491,9 @@ static void printRelocationTargetName(const MachOObjectFile *O, if (isExtern) { symbol_iterator SI = O->symbol_begin(); advance(SI, Val); - SI->getName(S); + ErrorOr SOrErr = SI->getName(); + if (!error(SOrErr.getError())) + S = *SOrErr; } else { section_iterator SI = O->section_begin(); // Adjust for the fact that sections are 1-indexed. @@ -677,7 +684,7 @@ static std::error_code getRelocationValueString(const MachOObjectFile *Obj, static std::error_code getRelocationValueString(const RelocationRef &Rel, SmallVectorImpl &Result) { - const ObjectFile *Obj = Rel.getObjectFile(); + const ObjectFile *Obj = Rel.getObject(); if (auto *ELF = dyn_cast(Obj)) return getRelocationValueString(ELF, Rel, Result); if (auto *COFF = dyn_cast(Obj)) @@ -686,6 +693,39 @@ static std::error_code getRelocationValueString(const RelocationRef &Rel, return getRelocationValueString(MachO, Rel, Result); } +/// @brief Indicates whether this relocation should hidden when listing +/// relocations, usually because it is the trailing part of a multipart +/// relocation that will be printed as part of the leading relocation. +static bool getHidden(RelocationRef RelRef) { + const ObjectFile *Obj = RelRef.getObject(); + auto *MachO = dyn_cast(Obj); + if (!MachO) + return false; + + unsigned Arch = MachO->getArch(); + DataRefImpl Rel = RelRef.getRawDataRefImpl(); + uint64_t Type = MachO->getRelocationType(Rel); + + // On arches that use the generic relocations, GENERIC_RELOC_PAIR + // is always hidden. + if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) { + if (Type == MachO::GENERIC_RELOC_PAIR) + return true; + } else if (Arch == Triple::x86_64) { + // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows + // an X86_64_RELOC_SUBTRACTOR. + if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) { + DataRefImpl RelPrev = Rel; + RelPrev.d.a--; + uint64_t PrevType = MachO->getRelocationType(RelPrev); + if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR) + return true; + } + } + + return false; +} + static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { const Target *TheTarget = getTarget(Obj); // getTarget() will have already issued a diagnostic if necessary, so @@ -781,19 +821,20 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { std::vector> Symbols; for (const SymbolRef &Symbol : Obj->symbols()) { if (Section.containsSymbol(Symbol)) { - uint64_t Address; - if (error(Symbol.getAddress(Address))) + ErrorOr AddressOrErr = Symbol.getAddress(); + if (error(AddressOrErr.getError())) break; - if (Address == UnknownAddressOrSize) + uint64_t Address = *AddressOrErr; + if (Address == UnknownAddress) continue; Address -= SectionAddr; if (Address >= SectSize) continue; - StringRef Name; - if (error(Symbol.getName(Name))) + ErrorOr Name = Symbol.getName(); + if (error(Name.getError())) break; - Symbols.push_back(std::make_pair(Address, Name)); + Symbols.push_back(std::make_pair(Address, *Name)); } } @@ -882,19 +923,17 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { // Print relocation for instruction. while (rel_cur != rel_end) { - bool hidden = false; - uint64_t addr; + bool hidden = getHidden(*rel_cur); + uint64_t addr = rel_cur->getOffset(); SmallString<16> name; SmallString<32> val; // If this relocation is hidden, skip it. - if (error(rel_cur->getHidden(hidden))) goto skip_print_rel; if (hidden) goto skip_print_rel; - if (error(rel_cur->getOffset(addr))) goto skip_print_rel; // Stop when rel_cur's address is past the current instruction. if (addr >= Index + Size) break; - if (error(rel_cur->getTypeName(name))) goto skip_print_rel; + rel_cur->getTypeName(name); if (error(getRelocationValueString(*rel_cur, val))) goto skip_print_rel; outs() << format(Fmt.data(), SectionAddr + addr) << name @@ -924,18 +963,13 @@ void llvm::PrintRelocations(const ObjectFile *Obj) { continue; outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n"; for (const RelocationRef &Reloc : Section.relocations()) { - bool hidden; - uint64_t address; + bool hidden = getHidden(Reloc); + uint64_t address = Reloc.getOffset(); SmallString<32> relocname; SmallString<32> valuestr; - if (error(Reloc.getHidden(hidden))) - continue; if (hidden) continue; - if (error(Reloc.getTypeName(relocname))) - continue; - if (error(Reloc.getOffset(address))) - continue; + Reloc.getTypeName(relocname); if (error(getRelocationValueString(Reloc, valuestr))) continue; outs() << format(Fmt.data(), address) << " " << relocname << " " @@ -1077,21 +1111,23 @@ void llvm::PrintSymbolTable(const ObjectFile *o) { return; } for (const SymbolRef &Symbol : o->symbols()) { - uint64_t Address; - SymbolRef::Type Type; + ErrorOr AddressOrError = Symbol.getAddress(); + if (error(AddressOrError.getError())) + continue; + uint64_t Address = *AddressOrError; + SymbolRef::Type Type = Symbol.getType(); uint32_t Flags = Symbol.getFlags(); section_iterator Section = o->section_end(); - if (error(Symbol.getAddress(Address))) - continue; - if (error(Symbol.getType(Type))) - continue; if (error(Symbol.getSection(Section))) continue; StringRef Name; if (Type == SymbolRef::ST_Debug && Section != o->section_end()) { Section->getName(Name); - } else if (error(Symbol.getName(Name))) { - continue; + } else { + ErrorOr NameOrErr = Symbol.getName(); + if (error(NameOrErr.getError())) + continue; + Name = *NameOrErr; } bool Global = Flags & SymbolRef::SF_Global; @@ -1101,9 +1137,9 @@ void llvm::PrintSymbolTable(const ObjectFile *o) { bool Hidden = Flags & SymbolRef::SF_Hidden; if (Common) - Address = Symbol.getSize(); + Address = Symbol.getCommonSize(); - if (Address == UnknownAddressOrSize) + if (Address == UnknownAddress) Address = 0; char GlobLoc = ' '; if (Type != SymbolRef::ST_Unknown) @@ -1149,7 +1185,8 @@ void llvm::PrintSymbolTable(const ObjectFile *o) { outs() << '\t'; if (Common || isa(o)) { - uint64_t Val = Common ? Symbol.getAlignment() : Symbol.getSize(); + uint64_t Val = + Common ? Symbol.getAlignment() : ELFSymbolRef(Symbol).getSize(); outs() << format("\t %08" PRIx64 " ", Val); }