summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r--contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp547
1 files changed, 504 insertions, 43 deletions
diff --git a/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp b/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp
index e442ac0..1152a15 100644
--- a/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -32,12 +32,14 @@
#include "llvm/MC/MCRelocationInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Object/Archive.h"
+#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/GraphWriter.h"
@@ -147,6 +149,10 @@ static cl::alias
PrivateHeadersShort("p", cl::desc("Alias for --private-headers"),
cl::aliasopt(PrivateHeaders));
+cl::opt<bool>
+ llvm::PrintImmHex("print-imm-hex",
+ cl::desc("Use hex format for immediate values"));
+
static StringRef ToolName;
static int ReturnValue = EXIT_SUCCESS;
@@ -160,6 +166,12 @@ bool llvm::error(std::error_code EC) {
return true;
}
+static void report_error(StringRef File, std::error_code EC) {
+ assert(EC);
+ errs() << ToolName << ": '" << File << "': " << EC.message() << ".\n";
+ ReturnValue = EXIT_FAILURE;
+}
+
static const Target *getTarget(const ObjectFile *Obj = nullptr) {
// Figure out the target triple.
llvm::Triple TheTriple("unknown-unknown-unknown");
@@ -194,19 +206,6 @@ static const Target *getTarget(const ObjectFile *Obj = nullptr) {
return TheTarget;
}
-void llvm::DumpBytes(ArrayRef<uint8_t> bytes) {
- static const char hex_rep[] = "0123456789abcdef";
- SmallString<64> output;
-
- for (char i: bytes) {
- output.push_back(hex_rep[(i & 0xF0) >> 4]);
- output.push_back(hex_rep[i & 0xF]);
- output.push_back(' ');
- }
-
- outs() << output.c_str();
-}
-
bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) {
uint64_t a_addr, b_addr;
if (error(a.getOffset(a_addr))) return false;
@@ -214,6 +213,474 @@ bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) {
return a_addr < b_addr;
}
+namespace {
+class PrettyPrinter {
+public:
+ virtual ~PrettyPrinter(){}
+ virtual void printInst(MCInstPrinter &IP, const MCInst *MI,
+ ArrayRef<uint8_t> Bytes, uint64_t Address,
+ raw_ostream &OS, StringRef Annot,
+ MCSubtargetInfo const &STI) {
+ outs() << format("%8" PRIx64 ":", Address);
+ if (!NoShowRawInsn) {
+ outs() << "\t";
+ dumpBytes(Bytes, outs());
+ }
+ IP.printInst(MI, outs(), "", STI);
+ }
+};
+PrettyPrinter PrettyPrinterInst;
+class HexagonPrettyPrinter : public PrettyPrinter {
+public:
+ void printLead(ArrayRef<uint8_t> Bytes, uint64_t Address,
+ raw_ostream &OS) {
+ uint32_t opcode =
+ (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | Bytes[0];
+ OS << format("%8" PRIx64 ":", Address);
+ if (!NoShowRawInsn) {
+ OS << "\t";
+ dumpBytes(Bytes.slice(0, 4), OS);
+ OS << format("%08" PRIx32, opcode);
+ }
+ }
+ void printInst(MCInstPrinter &IP, const MCInst *MI,
+ ArrayRef<uint8_t> Bytes, uint64_t Address,
+ raw_ostream &OS, StringRef Annot,
+ MCSubtargetInfo const &STI) override {
+ std::string Buffer;
+ {
+ raw_string_ostream TempStream(Buffer);
+ IP.printInst(MI, TempStream, "", STI);
+ }
+ StringRef Contents(Buffer);
+ // Split off bundle attributes
+ auto PacketBundle = Contents.rsplit('\n');
+ // Split off first instruction from the rest
+ auto HeadTail = PacketBundle.first.split('\n');
+ auto Preamble = " { ";
+ auto Separator = "";
+ while(!HeadTail.first.empty()) {
+ OS << Separator;
+ Separator = "\n";
+ printLead(Bytes, Address, OS);
+ OS << Preamble;
+ Preamble = " ";
+ StringRef Inst;
+ auto Duplex = HeadTail.first.split('\v');
+ if(!Duplex.second.empty()){
+ OS << Duplex.first;
+ OS << "; ";
+ Inst = Duplex.second;
+ }
+ else
+ Inst = HeadTail.first;
+ OS << Inst;
+ Bytes = Bytes.slice(4);
+ Address += 4;
+ HeadTail = HeadTail.second.split('\n');
+ }
+ OS << " } " << PacketBundle.second;
+ }
+};
+HexagonPrettyPrinter HexagonPrettyPrinterInst;
+PrettyPrinter &selectPrettyPrinter(Triple const &Triple) {
+ switch(Triple.getArch()) {
+ default:
+ return PrettyPrinterInst;
+ case Triple::hexagon:
+ return HexagonPrettyPrinterInst;
+ }
+}
+}
+
+template <class ELFT>
+static const typename ELFObjectFile<ELFT>::Elf_Rel *
+getRel(const ELFFile<ELFT> &EF, DataRefImpl Rel) {
+ typedef typename ELFObjectFile<ELFT>::Elf_Rel Elf_Rel;
+ return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
+}
+
+template <class ELFT>
+static const typename ELFObjectFile<ELFT>::Elf_Rela *
+getRela(const ELFFile<ELFT> &EF, DataRefImpl Rela) {
+ typedef typename ELFObjectFile<ELFT>::Elf_Rela Elf_Rela;
+ return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
+}
+
+template <class ELFT>
+static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
+ DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) {
+ typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
+ typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr;
+ const ELFFile<ELFT> &EF = *Obj->getELFFile();
+
+ const Elf_Shdr *sec = EF.getSection(Rel.d.a);
+ uint8_t type;
+ StringRef res;
+ int64_t addend = 0;
+ uint16_t symbol_index = 0;
+ 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());
+ // 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;
+ break;
+ }
+ }
+ const Elf_Sym *symb =
+ EF.template getEntry<Elf_Sym>(sec->sh_link, symbol_index);
+ StringRef Target;
+ const Elf_Shdr *SymSec = EF.getSection(symb);
+ if (symb->getType() == ELF::STT_SECTION) {
+ ErrorOr<StringRef> SecName = EF.getSectionName(SymSec);
+ if (std::error_code EC = SecName.getError())
+ return EC;
+ Target = *SecName;
+ } else {
+ ErrorOr<StringRef> SymName =
+ EF.getSymbolName(EF.getSection(sec->sh_link), symb);
+ if (!SymName)
+ return SymName.getError();
+ Target = *SymName;
+ }
+ switch (EF.getHeader()->e_machine) {
+ case ELF::EM_X86_64:
+ switch (type) {
+ case ELF::R_X86_64_PC8:
+ case ELF::R_X86_64_PC16:
+ case ELF::R_X86_64_PC32: {
+ std::string fmtbuf;
+ raw_string_ostream fmt(fmtbuf);
+ fmt << Target << (addend < 0 ? "" : "+") << addend << "-P";
+ fmt.flush();
+ Result.append(fmtbuf.begin(), fmtbuf.end());
+ } break;
+ case ELF::R_X86_64_8:
+ case ELF::R_X86_64_16:
+ case ELF::R_X86_64_32:
+ case ELF::R_X86_64_32S:
+ case ELF::R_X86_64_64: {
+ std::string fmtbuf;
+ raw_string_ostream fmt(fmtbuf);
+ fmt << Target << (addend < 0 ? "" : "+") << addend;
+ fmt.flush();
+ Result.append(fmtbuf.begin(), fmtbuf.end());
+ } break;
+ default:
+ res = "Unknown";
+ }
+ break;
+ case ELF::EM_AARCH64: {
+ std::string fmtbuf;
+ raw_string_ostream fmt(fmtbuf);
+ fmt << Target;
+ if (addend != 0)
+ fmt << (addend < 0 ? "" : "+") << addend;
+ fmt.flush();
+ Result.append(fmtbuf.begin(), fmtbuf.end());
+ break;
+ }
+ case ELF::EM_386:
+ case ELF::EM_ARM:
+ case ELF::EM_HEXAGON:
+ case ELF::EM_MIPS:
+ res = Target;
+ break;
+ default:
+ res = "Unknown";
+ }
+ if (Result.empty())
+ Result.append(res.begin(), res.end());
+ return std::error_code();
+}
+
+static std::error_code getRelocationValueString(const ELFObjectFileBase *Obj,
+ const RelocationRef &RelRef,
+ SmallVectorImpl<char> &Result) {
+ DataRefImpl Rel = RelRef.getRawDataRefImpl();
+ if (auto *ELF32LE = dyn_cast<ELF32LEObjectFile>(Obj))
+ return getRelocationValueString(ELF32LE, Rel, Result);
+ if (auto *ELF64LE = dyn_cast<ELF64LEObjectFile>(Obj))
+ return getRelocationValueString(ELF64LE, Rel, Result);
+ if (auto *ELF32BE = dyn_cast<ELF32BEObjectFile>(Obj))
+ return getRelocationValueString(ELF32BE, Rel, Result);
+ auto *ELF64BE = cast<ELF64BEObjectFile>(Obj);
+ return getRelocationValueString(ELF64BE, Rel, Result);
+}
+
+static std::error_code getRelocationValueString(const COFFObjectFile *Obj,
+ const RelocationRef &Rel,
+ SmallVectorImpl<char> &Result) {
+ symbol_iterator SymI = Rel.getSymbol();
+ StringRef SymName;
+ if (std::error_code EC = SymI->getName(SymName))
+ return EC;
+ Result.append(SymName.begin(), SymName.end());
+ return std::error_code();
+}
+
+static void printRelocationTargetName(const MachOObjectFile *O,
+ const MachO::any_relocation_info &RE,
+ raw_string_ostream &fmt) {
+ bool IsScattered = O->isRelocationScattered(RE);
+
+ // Target of a scattered relocation is an address. In the interest of
+ // generating pretty output, scan through the symbol table looking for a
+ // symbol that aligns with that address. If we find one, print it.
+ // Otherwise, we just print the hex address of the target.
+ if (IsScattered) {
+ uint32_t Val = O->getPlainRelocationSymbolNum(RE);
+
+ for (const SymbolRef &Symbol : O->symbols()) {
+ std::error_code ec;
+ uint64_t Addr;
+ StringRef Name;
+
+ if ((ec = Symbol.getAddress(Addr)))
+ report_fatal_error(ec.message());
+ if (Addr != Val)
+ continue;
+ if ((ec = Symbol.getName(Name)))
+ report_fatal_error(ec.message());
+ fmt << Name;
+ return;
+ }
+
+ // If we couldn't find a symbol that this relocation refers to, try
+ // to find a section beginning instead.
+ for (const SectionRef &Section : O->sections()) {
+ std::error_code ec;
+
+ StringRef Name;
+ uint64_t Addr = Section.getAddress();
+ if (Addr != Val)
+ continue;
+ if ((ec = Section.getName(Name)))
+ report_fatal_error(ec.message());
+ fmt << Name;
+ return;
+ }
+
+ fmt << format("0x%x", Val);
+ return;
+ }
+
+ StringRef S;
+ bool isExtern = O->getPlainRelocationExternal(RE);
+ uint64_t Val = O->getPlainRelocationSymbolNum(RE);
+
+ if (isExtern) {
+ symbol_iterator SI = O->symbol_begin();
+ advance(SI, Val);
+ SI->getName(S);
+ } else {
+ section_iterator SI = O->section_begin();
+ // Adjust for the fact that sections are 1-indexed.
+ advance(SI, Val - 1);
+ SI->getName(S);
+ }
+
+ fmt << S;
+}
+
+static std::error_code getRelocationValueString(const MachOObjectFile *Obj,
+ const RelocationRef &RelRef,
+ SmallVectorImpl<char> &Result) {
+ DataRefImpl Rel = RelRef.getRawDataRefImpl();
+ MachO::any_relocation_info RE = Obj->getRelocation(Rel);
+
+ unsigned Arch = Obj->getArch();
+
+ std::string fmtbuf;
+ raw_string_ostream fmt(fmtbuf);
+ unsigned Type = Obj->getAnyRelocationType(RE);
+ bool IsPCRel = Obj->getAnyRelocationPCRel(RE);
+
+ // Determine any addends that should be displayed with the relocation.
+ // These require decoding the relocation type, which is triple-specific.
+
+ // X86_64 has entirely custom relocation types.
+ if (Arch == Triple::x86_64) {
+ bool isPCRel = Obj->getAnyRelocationPCRel(RE);
+
+ switch (Type) {
+ case MachO::X86_64_RELOC_GOT_LOAD:
+ case MachO::X86_64_RELOC_GOT: {
+ printRelocationTargetName(Obj, RE, fmt);
+ fmt << "@GOT";
+ if (isPCRel)
+ fmt << "PCREL";
+ break;
+ }
+ case MachO::X86_64_RELOC_SUBTRACTOR: {
+ DataRefImpl RelNext = Rel;
+ Obj->moveRelocationNext(RelNext);
+ MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
+
+ // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
+ // X86_64_RELOC_UNSIGNED.
+ // NOTE: Scattered relocations don't exist on x86_64.
+ unsigned RType = Obj->getAnyRelocationType(RENext);
+ if (RType != MachO::X86_64_RELOC_UNSIGNED)
+ report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
+ "X86_64_RELOC_SUBTRACTOR.");
+
+ // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
+ // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
+ printRelocationTargetName(Obj, RENext, fmt);
+ fmt << "-";
+ printRelocationTargetName(Obj, RE, fmt);
+ break;
+ }
+ case MachO::X86_64_RELOC_TLV:
+ printRelocationTargetName(Obj, RE, fmt);
+ fmt << "@TLV";
+ if (isPCRel)
+ fmt << "P";
+ break;
+ case MachO::X86_64_RELOC_SIGNED_1:
+ printRelocationTargetName(Obj, RE, fmt);
+ fmt << "-1";
+ break;
+ case MachO::X86_64_RELOC_SIGNED_2:
+ printRelocationTargetName(Obj, RE, fmt);
+ fmt << "-2";
+ break;
+ case MachO::X86_64_RELOC_SIGNED_4:
+ printRelocationTargetName(Obj, RE, fmt);
+ fmt << "-4";
+ break;
+ default:
+ printRelocationTargetName(Obj, RE, fmt);
+ break;
+ }
+ // X86 and ARM share some relocation types in common.
+ } else if (Arch == Triple::x86 || Arch == Triple::arm ||
+ Arch == Triple::ppc) {
+ // Generic relocation types...
+ switch (Type) {
+ case MachO::GENERIC_RELOC_PAIR: // prints no info
+ return std::error_code();
+ case MachO::GENERIC_RELOC_SECTDIFF: {
+ DataRefImpl RelNext = Rel;
+ Obj->moveRelocationNext(RelNext);
+ MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
+
+ // X86 sect diff's must be followed by a relocation of type
+ // GENERIC_RELOC_PAIR.
+ unsigned RType = Obj->getAnyRelocationType(RENext);
+
+ if (RType != MachO::GENERIC_RELOC_PAIR)
+ report_fatal_error("Expected GENERIC_RELOC_PAIR after "
+ "GENERIC_RELOC_SECTDIFF.");
+
+ printRelocationTargetName(Obj, RE, fmt);
+ fmt << "-";
+ printRelocationTargetName(Obj, RENext, fmt);
+ break;
+ }
+ }
+
+ if (Arch == Triple::x86 || Arch == Triple::ppc) {
+ switch (Type) {
+ case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
+ DataRefImpl RelNext = Rel;
+ Obj->moveRelocationNext(RelNext);
+ MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
+
+ // X86 sect diff's must be followed by a relocation of type
+ // GENERIC_RELOC_PAIR.
+ unsigned RType = Obj->getAnyRelocationType(RENext);
+ if (RType != MachO::GENERIC_RELOC_PAIR)
+ report_fatal_error("Expected GENERIC_RELOC_PAIR after "
+ "GENERIC_RELOC_LOCAL_SECTDIFF.");
+
+ printRelocationTargetName(Obj, RE, fmt);
+ fmt << "-";
+ printRelocationTargetName(Obj, RENext, fmt);
+ break;
+ }
+ case MachO::GENERIC_RELOC_TLV: {
+ printRelocationTargetName(Obj, RE, fmt);
+ fmt << "@TLV";
+ if (IsPCRel)
+ fmt << "P";
+ break;
+ }
+ default:
+ printRelocationTargetName(Obj, RE, fmt);
+ }
+ } else { // ARM-specific relocations
+ switch (Type) {
+ case MachO::ARM_RELOC_HALF:
+ case MachO::ARM_RELOC_HALF_SECTDIFF: {
+ // Half relocations steal a bit from the length field to encode
+ // whether this is an upper16 or a lower16 relocation.
+ bool isUpper = Obj->getAnyRelocationLength(RE) >> 1;
+
+ if (isUpper)
+ fmt << ":upper16:(";
+ else
+ fmt << ":lower16:(";
+ printRelocationTargetName(Obj, RE, fmt);
+
+ DataRefImpl RelNext = Rel;
+ Obj->moveRelocationNext(RelNext);
+ MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
+
+ // ARM half relocs must be followed by a relocation of type
+ // ARM_RELOC_PAIR.
+ unsigned RType = Obj->getAnyRelocationType(RENext);
+ if (RType != MachO::ARM_RELOC_PAIR)
+ report_fatal_error("Expected ARM_RELOC_PAIR after "
+ "ARM_RELOC_HALF");
+
+ // NOTE: The half of the target virtual address is stashed in the
+ // address field of the secondary relocation, but we can't reverse
+ // engineer the constant offset from it without decoding the movw/movt
+ // instruction to find the other half in its immediate field.
+
+ // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
+ // symbol/section pointer of the follow-on relocation.
+ if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
+ fmt << "-";
+ printRelocationTargetName(Obj, RENext, fmt);
+ }
+
+ fmt << ")";
+ break;
+ }
+ default: { printRelocationTargetName(Obj, RE, fmt); }
+ }
+ }
+ } else
+ printRelocationTargetName(Obj, RE, fmt);
+
+ fmt.flush();
+ Result.append(fmtbuf.begin(), fmtbuf.end());
+ return std::error_code();
+}
+
+static std::error_code getRelocationValueString(const RelocationRef &Rel,
+ SmallVectorImpl<char> &Result) {
+ const ObjectFile *Obj = Rel.getObjectFile();
+ if (auto *ELF = dyn_cast<ELFObjectFileBase>(Obj))
+ return getRelocationValueString(ELF, Rel, Result);
+ if (auto *COFF = dyn_cast<COFFObjectFile>(Obj))
+ return getRelocationValueString(COFF, Rel, Result);
+ auto *MachO = cast<MachOObjectFile>(Obj);
+ return getRelocationValueString(MachO, Rel, Result);
+}
+
static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
const Target *TheTarget = getTarget(Obj);
// getTarget() will have already issued a diagnostic if necessary, so
@@ -280,6 +747,8 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
<< '\n';
return;
}
+ IP->setPrintImmHex(PrintImmHex);
+ PrettyPrinter &PIP = selectPrettyPrinter(Triple(TripleName));
StringRef Fmt = Obj->getBytesInAddress() > 4 ? "\t\t%016" PRIx64 ": " :
"\t\t\t%08" PRIx64 ": ";
@@ -352,11 +821,9 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
outs() << SegmentName << ",";
outs() << name << ':';
- // If the section has no symbols just insert a dummy one and disassemble
- // the whole section.
- if (Symbols.empty())
- Symbols.push_back(std::make_pair(0, name));
-
+ // If the section has no symbol at the start, just insert a dummy one.
+ if (Symbols.empty() || Symbols[0].first != 0)
+ Symbols.insert(Symbols.begin(), std::make_pair(0, name));
SmallString<40> Comments;
raw_svector_ostream CommentStream(Comments);
@@ -396,12 +863,9 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
if (DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
SectionAddr + Index, DebugOut,
CommentStream)) {
- outs() << format("%8" PRIx64 ":", SectionAddr + Index);
- if (!NoShowRawInsn) {
- outs() << "\t";
- DumpBytes(ArrayRef<uint8_t>(Bytes.data() + Index, Size));
- }
- IP->printInst(&Inst, outs(), "", *STI);
+ PIP.printInst(*IP, &Inst,
+ Bytes.slice(Index, Size),
+ SectionAddr + Index, outs(), "", *STI);
outs() << CommentStream.str();
Comments.clear();
outs() << "\n";
@@ -426,8 +890,8 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
// 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;
- if (error(rel_cur->getValueString(val))) goto skip_print_rel;
-
+ if (error(getRelocationValueString(*rel_cur, val)))
+ goto skip_print_rel;
outs() << format(Fmt.data(), SectionAddr + addr) << name
<< "\t" << val << "\n";
@@ -467,7 +931,7 @@ void llvm::PrintRelocations(const ObjectFile *Obj) {
continue;
if (error(Reloc.getOffset(address)))
continue;
- if (error(Reloc.getValueString(valuestr)))
+ if (error(getRelocationValueString(Reloc, valuestr)))
continue;
outs() << format(Fmt.data(), address) << " " << relocname << " "
<< valuestr << "\n";
@@ -608,22 +1072,23 @@ void llvm::PrintSymbolTable(const ObjectFile *o) {
return;
}
for (const SymbolRef &Symbol : o->symbols()) {
- StringRef Name;
uint64_t Address;
SymbolRef::Type Type;
- uint64_t Size;
uint32_t Flags = Symbol.getFlags();
section_iterator Section = o->section_end();
- if (error(Symbol.getName(Name)))
- continue;
if (error(Symbol.getAddress(Address)))
continue;
if (error(Symbol.getType(Type)))
continue;
- if (error(Symbol.getSize(Size)))
- continue;
+ uint64_t Size = Symbol.getSize();
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;
+ }
bool Global = Flags & SymbolRef::SF_Global;
bool Weak = Flags & SymbolRef::SF_Weak;
@@ -632,9 +1097,7 @@ void llvm::PrintSymbolTable(const ObjectFile *o) {
bool Hidden = Flags & SymbolRef::SF_Hidden;
if (Common) {
- uint32_t Alignment;
- if (error(Symbol.getAlignment(Alignment)))
- Alignment = 0;
+ uint32_t Alignment = Symbol.getAlignment();
Address = Size;
Size = Alignment;
}
@@ -812,15 +1275,13 @@ static void DumpArchive(const Archive *a) {
if (std::error_code EC = ChildOrErr.getError()) {
// Ignore non-object files.
if (EC != object_error::invalid_file_type)
- errs() << ToolName << ": '" << a->getFileName() << "': " << EC.message()
- << ".\n";
+ report_error(a->getFileName(), EC);
continue;
}
if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
DumpObject(o);
else
- errs() << ToolName << ": '" << a->getFileName() << "': "
- << "Unrecognized file type.\n";
+ report_error(a->getFileName(), object_error::invalid_file_type);
}
}
@@ -828,7 +1289,7 @@ static void DumpArchive(const Archive *a) {
static void DumpInput(StringRef file) {
// If file isn't stdin, check that it exists.
if (file != "-" && !sys::fs::exists(file)) {
- errs() << ToolName << ": '" << file << "': " << "No such file\n";
+ report_error(file, errc::no_such_file_or_directory);
return;
}
@@ -843,7 +1304,7 @@ static void DumpInput(StringRef file) {
// Attempt to open the binary.
ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
if (std::error_code EC = BinaryOrErr.getError()) {
- errs() << ToolName << ": '" << file << "': " << EC.message() << ".\n";
+ report_error(file, EC);
return;
}
Binary &Binary = *BinaryOrErr.get().getBinary();
@@ -853,7 +1314,7 @@ static void DumpInput(StringRef file) {
else if (ObjectFile *o = dyn_cast<ObjectFile>(&Binary))
DumpObject(o);
else
- errs() << ToolName << ": '" << file << "': " << "Unrecognized file type.\n";
+ report_error(file, object_error::invalid_file_type);
}
int main(int argc, char **argv) {
OpenPOWER on IntegriCloud