[llvm-objdump][XCOFF] Use symbol index+symbol name + storage mapping class as label for -D

SUMMARY:

For the llvm-objdump -D, the symbol name is used as a label in the disassembly for the specific address (when a symbol address is equal to the virtual address in the dump).

In XCOFF, multiple symbols may have the same name, being differentiated by their storage mapping class. It is helpful to print the QualName and not just the name when forming the output label for a csect symbol. The symbol index further removes any ambiguity caused by duplicate names.

To maintain compatibility with the binutils objdump, the XCOFF-specific --symbol-description option is added to enable the enhanced format.

Reviewers: hubert.reinterpretcast, James Henderson, Jason Liu ,daltenty
Subscribers: wuzish, nemanjai, hiraditya

Differential Revision: https://reviews.llvm.org/D72973
This commit is contained in:
diggerlin 2020-04-06 10:09:12 -04:00
parent 9072df8ac1
commit a26a441b99
10 changed files with 287 additions and 57 deletions

View File

@ -325,6 +325,13 @@ MACH-O ONLY OPTIONS AND COMMANDS
Display weak binding information. Display weak binding information.
XCOFF ONLY OPTIONS AND COMMANDS
---------------------------------
.. option:: --symbol-description
Add symbol description to disassembly output.
BUGS BUGS
---- ----

View File

@ -9,7 +9,9 @@
#ifndef LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H #ifndef LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H
#define LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H #define LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/XCOFF.h"
#include "llvm/MC/MCDisassembler/MCSymbolizer.h" #include "llvm/MC/MCDisassembler/MCSymbolizer.h"
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
@ -17,23 +19,49 @@
namespace llvm { namespace llvm {
struct XCOFFSymbolInfo {
Optional<XCOFF::StorageMappingClass> StorageMappingClass;
Optional<uint32_t> Index;
bool IsLabel;
XCOFFSymbolInfo(Optional<XCOFF::StorageMappingClass> Smc,
Optional<uint32_t> Idx, bool Label)
: StorageMappingClass(Smc), Index(Idx), IsLabel(Label) {}
};
struct SymbolInfoTy { struct SymbolInfoTy {
uint64_t Addr; uint64_t Addr;
StringRef Name; StringRef Name;
uint8_t Type; union {
uint8_t Type;
XCOFFSymbolInfo XCOFFSymInfo;
};
SymbolInfoTy(uint64_t Addr, StringRef Name, uint8_t Type) private:
: Addr(Addr), Name(Name), Type(Type){}; bool IsXCOFF;
friend bool operator<(const SymbolInfoTy &P1, const SymbolInfoTy &P2) { public:
return std::tie(P1.Addr, P1.Name, P1.Type) < SymbolInfoTy(uint64_t Addr, StringRef Name,
std::tie(P2.Addr, P2.Name, P2.Type); Optional<XCOFF::StorageMappingClass> Smc, Optional<uint32_t> Idx,
} bool Label)
: Addr(Addr), Name(Name), XCOFFSymInfo(Smc, Idx, Label), IsXCOFF(true) {}
SymbolInfoTy(uint64_t Addr, StringRef Name, uint8_t Type)
: Addr(Addr), Name(Name), Type(Type), IsXCOFF(false) {}
bool isXCOFF() const { return IsXCOFF; }
private:
friend bool operator<(const SymbolInfoTy &P1, const SymbolInfoTy &P2) {
assert(P1.IsXCOFF == P2.IsXCOFF &&
"P1.IsXCOFF should be equal to P2.IsXCOFF.");
if (P1.IsXCOFF)
return std::tie(P1.Addr, P1.Name) < std::tie(P2.Addr, P2.Name);
else
return std::tie(P1.Addr, P1.Name, P1.Type) <
std::tie(P2.Addr, P2.Name, P2.Type);
}
}; };
using SectionSymbolsTy = std::vector<SymbolInfoTy>; using SectionSymbolsTy = std::vector<SymbolInfoTy>;
template <typename T> class ArrayRef; template <typename T> class ArrayRef;
class MCContext; class MCContext;
class MCInst; class MCInst;

View File

@ -129,6 +129,8 @@ struct XCOFFStringTable {
}; };
struct XCOFFCsectAuxEnt32 { struct XCOFFCsectAuxEnt32 {
static constexpr uint8_t SymbolTypeMask = 0x07;
support::ubig32_t support::ubig32_t
SectionOrLength; // If the symbol type is XTY_SD or XTY_CM, the csect SectionOrLength; // If the symbol type is XTY_SD or XTY_CM, the csect
// length. // length.
@ -141,6 +143,12 @@ struct XCOFFCsectAuxEnt32 {
XCOFF::StorageMappingClass StorageMappingClass; XCOFF::StorageMappingClass StorageMappingClass;
support::ubig32_t StabInfoIndex; support::ubig32_t StabInfoIndex;
support::ubig16_t StabSectNum; support::ubig16_t StabSectNum;
uint8_t getSymbolType() const {
return SymbolAlignmentAndType & SymbolTypeMask;
};
bool isLabel() const { return getSymbolType() == XCOFF::XTY_LD; }
}; };
struct XCOFFFileAuxEnt { struct XCOFFFileAuxEnt {

View File

@ -10,27 +10,37 @@
using namespace llvm; using namespace llvm;
#define SMC_CASE(A) \
case XCOFF::XMC_##A: \
return #A;
StringRef XCOFF::getMappingClassString(XCOFF::StorageMappingClass SMC) { StringRef XCOFF::getMappingClassString(XCOFF::StorageMappingClass SMC) {
switch (SMC) { switch (SMC) {
case XCOFF::XMC_DS: SMC_CASE(PR)
return "DS"; SMC_CASE(RO)
case XCOFF::XMC_RW: SMC_CASE(DB)
return "RW"; SMC_CASE(GL)
case XCOFF::XMC_PR: SMC_CASE(XO)
return "PR"; SMC_CASE(SV)
case XCOFF::XMC_TC0: SMC_CASE(SV64)
return "TC0"; SMC_CASE(SV3264)
case XCOFF::XMC_BS: SMC_CASE(TI)
return "BS"; SMC_CASE(TB)
case XCOFF::XMC_RO: SMC_CASE(RW)
return "RO"; SMC_CASE(TC0)
case XCOFF::XMC_UA: SMC_CASE(TC)
return "UA"; SMC_CASE(TD)
case XCOFF::XMC_TC: SMC_CASE(DS)
return "TC"; SMC_CASE(UA)
default: SMC_CASE(BS)
report_fatal_error("Unhandled storage-mapping class."); SMC_CASE(UC)
SMC_CASE(TL)
SMC_CASE(UL)
SMC_CASE(TE)
#undef SMC_CASE
} }
// TODO: need to add a test case for "Unknown" and other SMC.
return "Unknown";
} }
#define RELOC_CASE(A) \ #define RELOC_CASE(A) \

View File

@ -766,6 +766,8 @@ uint8_t XCOFFSymbolRef::getNumberOfAuxEntries() const {
return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->NumberOfAuxEntries; return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->NumberOfAuxEntries;
} }
// TODO: The function needs to return an error if there is no csect auxiliary
// entry.
const XCOFFCsectAuxEnt32 *XCOFFSymbolRef::getXCOFFCsectAuxEnt32() const { const XCOFFCsectAuxEnt32 *XCOFFSymbolRef::getXCOFFCsectAuxEnt32() const {
assert(!OwningObjectPtr->is64Bit() && assert(!OwningObjectPtr->is64Bit() &&
"32-bit interface called on 64-bit object file."); "32-bit interface called on 64-bit object file.");
@ -791,6 +793,8 @@ int16_t XCOFFSymbolRef::getSectionNumber() const {
return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SectionNumber; return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SectionNumber;
} }
// TODO: The function name needs to be changed to express the purpose of the
// function.
bool XCOFFSymbolRef::hasCsectAuxEnt() const { bool XCOFFSymbolRef::hasCsectAuxEnt() const {
XCOFF::StorageClass SC = getStorageClass(); XCOFF::StorageClass SC = getStorageClass();
return (SC == XCOFF::C_EXT || SC == XCOFF::C_WEAKEXT || return (SC == XCOFF::C_EXT || SC == XCOFF::C_WEAKEXT ||

View File

@ -0,0 +1,72 @@
# REQUIRES: powerpc-registered-target
# RUN: llvm-objdump -D %p/Inputs/xcoff-section-headers.o | \
# RUN: FileCheck --check-prefixes=COMMON,PLAIN %s
# RUN: llvm-objdump -D --symbol-description %p/Inputs/xcoff-section-headers.o | \
# RUN: FileCheck --check-prefixes=COMMON,DESC %s
# xcoff-section-headers.o Compiled with IBM XL C/C++ for AIX, V16.1.0
# compiler command: xlc -qtls -o xcoff-section-headers.o -c test.c
## test.c:
## int a;
## int b = 12345;
## __thread int c;
## __thread double d = 3.14159;
##
## int func(void) {
## return a;
## }
COMMON: Inputs/xcoff-section-headers.o: file format aixcoff-rs6000
COMMON: Disassembly of section .text:
PLAIN: 00000000 <.text>:
DESC: 00000000 (idx: 4) .text:
COMMON-NEXT: 0: 80 62 00 04 lwz 3, 4(2)
COMMON-NEXT: 4: 80 63 00 00 lwz 3, 0(3)
COMMON-NEXT: 8: 4e 80 00 20 blr
COMMON-NEXT: c: 00 00 00 00 <unknown>
COMMON-NEXT: 10: 00 00 20 40 <unknown>
COMMON-NEXT: 14: 00 00 00 01 <unknown>
COMMON-NEXT: 18: 00 00 00 0c <unknown>
COMMON-NEXT: 1c: 00 04 66 75 <unknown>
COMMON-NEXT: 20: 6e 63 00 00 xoris 3, 19, 0
COMMON-NEXT: ...
COMMON: Disassembly of section .data:
PLAIN: 00000080 <func>:
DESC: 00000080 (idx: 22) func[TC]:
COMMON-NEXT: 80: 00 00 00 94 <unknown>
PLAIN: 00000084 <a>:
DESC: 00000084 (idx: 26) a[TC]:
COMMON-NEXT: 84: 00 00 00 a4 <unknown>
PLAIN: 00000088 <b>:
DESC: 00000088 (idx: 30) b[TC]:
COMMON-NEXT: 88: 00 00 00 a0 <unknown>
PLAIN: 0000008c <c>:
DESC: 0000008c (idx: 34) c[TC]:
COMMON-NEXT: 8c: 00 00 00 08 <unknown>
PLAIN: 00000090 <d>:
DESC: 00000090 (idx: 38) d[TC]:
COMMON-NEXT: 90: 00 00 00 00 <unknown>
PLAIN: 00000094 <func>:
DESC: 00000094 (idx: 20) func[DS]:
COMMON-NEXT: 94: 00 00 00 00 <unknown>
COMMON-NEXT: 98: 00 00 00 80 <unknown>
COMMON-NEXT: 9c: 00 00 00 00 <unknown>
PLAIN: 000000a0 <b>:
DESC: 000000a0 (idx: 28) b[RW]:
COMMON-NEXT: a0: 00 00 30 39 <unknown>
COMMON: Disassembly of section .bss:
PLAIN: 000000a4 <a>:
DESC: 000000a4 (idx: 24) a[RW]:
COMMON-NEXT: ...
COMMON: Disassembly of section .tdata:
PLAIN: 00000000 <d>:
DESC: 00000000 (idx: 36) d[TL]:
COMMON-NEXT: 0: 40 09 21 f9 bdnzfl 9, 0x21f8
COMMON-NEXT: 4: f0 1b 86 6e <unknown>
COMMON: Disassembly of section .tbss:
PLAIN: 00000008 <c>:
DESC: 00000008 (idx: 32) c[UL]:
COMMON-NEXT: ...

View File

@ -1,4 +1,4 @@
//===-- XCOFFDump.cpp - XCOFF-specific dumper -------------------*- C++ -*-===// //===-- XCOFFDump.cpp - XCOFF-specific dumper -----------------------------===//
// //
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information. // See https://llvm.org/LICENSE.txt for license information.
@ -11,14 +11,15 @@
/// ///
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm-objdump.h" #include "XCOFFDump.h"
#include "llvm/Object/XCOFFObjectFile.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h"
using namespace llvm;
using namespace llvm::object; using namespace llvm::object;
llvm::Error llvm::getXCOFFRelocationValueString(const XCOFFObjectFile *Obj, Error objdump::getXCOFFRelocationValueString(const XCOFFObjectFile *Obj,
const RelocationRef &Rel, const RelocationRef &Rel,
SmallVectorImpl<char> &Result) { SmallVectorImpl<char> &Result) {
symbol_iterator SymI = Rel.getSymbol(); symbol_iterator SymI = Rel.getSymbol();
if (SymI == Obj->symbol_end()) if (SymI == Obj->symbol_end())
return make_error<GenericBinaryError>( return make_error<GenericBinaryError>(
@ -32,3 +33,42 @@ llvm::Error llvm::getXCOFFRelocationValueString(const XCOFFObjectFile *Obj,
Result.append(SymName.begin(), SymName.end()); Result.append(SymName.begin(), SymName.end());
return Error::success(); return Error::success();
} }
Optional<XCOFF::StorageMappingClass>
objdump::getXCOFFSymbolCsectSMC(const XCOFFObjectFile *Obj,
const SymbolRef &Sym) {
XCOFFSymbolRef SymRef(Sym.getRawDataRefImpl(), Obj);
if (SymRef.hasCsectAuxEnt())
return SymRef.getXCOFFCsectAuxEnt32()->StorageMappingClass;
return None;
}
bool objdump::isLabel(const XCOFFObjectFile *Obj, const SymbolRef &Sym) {
XCOFFSymbolRef SymRef(Sym.getRawDataRefImpl(), Obj);
if (SymRef.hasCsectAuxEnt())
return SymRef.getXCOFFCsectAuxEnt32()->isLabel();
return false;
}
void objdump::printXCOFFSymbolDescription(const SymbolInfoTy &SymbolInfo,
StringRef SymbolName) {
assert(SymbolInfo.isXCOFF() && "Must be a XCOFFSymInfo.");
// Dummy symbols have no symbol index.
if (SymbolInfo.XCOFFSymInfo.Index)
outs() << "(idx: " << SymbolInfo.XCOFFSymInfo.Index.getValue() << ") ";
outs() << SymbolName;
if (SymbolInfo.XCOFFSymInfo.StorageMappingClass &&
!SymbolInfo.XCOFFSymInfo.IsLabel) {
const XCOFF::StorageMappingClass Smc =
SymbolInfo.XCOFFSymInfo.StorageMappingClass.getValue();
outs() << "[" << XCOFF::getMappingClassString(Smc) << "]";
}
}

View File

@ -0,0 +1,33 @@
//===-- XCOFFDump.h ---------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TOOLS_LLVM_OBJDUMP_XCOFFDUMP_H
#define LLVM_TOOLS_LLVM_OBJDUMP_XCOFFDUMP_H
#include "llvm/Object/XCOFFObjectFile.h"
namespace llvm {
class SymbolInfoTy;
namespace objdump {
Optional<XCOFF::StorageMappingClass>
getXCOFFSymbolCsectSMC(const object::XCOFFObjectFile *Obj,
const object::SymbolRef &Sym);
bool isLabel(const object::XCOFFObjectFile *Obj, const object::SymbolRef &Sym);
void printXCOFFSymbolDescription(const SymbolInfoTy &SymbolInfo,
StringRef SymbolName);
Error getXCOFFRelocationValueString(const object::XCOFFObjectFile *Obj,
const object::RelocationRef &RelRef,
llvm::SmallVectorImpl<char> &Result);
} // namespace objdump
} // namespace llvm
#endif

View File

@ -17,6 +17,7 @@
#include "llvm-objdump.h" #include "llvm-objdump.h"
#include "COFFDump.h" #include "COFFDump.h"
#include "XCOFFDump.h"
#include "llvm/ADT/Optional.h" #include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetOperations.h" #include "llvm/ADT/SetOperations.h"
@ -46,7 +47,6 @@
#include "llvm/Object/MachO.h" #include "llvm/Object/MachO.h"
#include "llvm/Object/MachOUniversal.h" #include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ObjectFile.h" #include "llvm/Object/ObjectFile.h"
#include "llvm/Object/XCOFFObjectFile.h"
#include "llvm/Object/Wasm.h" #include "llvm/Object/Wasm.h"
#include "llvm/Support/Casting.h" #include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
@ -146,6 +146,12 @@ static cl::alias DisassembleAllShort("D",
cl::NotHidden, cl::Grouping, cl::NotHidden, cl::Grouping,
cl::aliasopt(DisassembleAll)); cl::aliasopt(DisassembleAll));
cl::opt<bool>
SymbolDescription("symbol-description",
cl::desc("Add symbol description for disassembly. This "
"option is for XCOFF files only"),
cl::init(false), cl::cat(ObjdumpCat));
static cl::list<std::string> static cl::list<std::string>
DisassembleSymbols("disassemble-symbols", cl::CommaSeparated, DisassembleSymbols("disassemble-symbols", cl::CommaSeparated,
cl::desc("List of symbols to disassemble. " cl::desc("List of symbols to disassemble. "
@ -1158,6 +1164,34 @@ static void dumpELFData(uint64_t SectionAddr, uint64_t Index, uint64_t End,
} }
} }
SymbolInfoTy createSymbolInfo(const ObjectFile *Obj, const SymbolRef &Symbol) {
const StringRef FileName = Obj->getFileName();
const uint64_t Addr = unwrapOrError(Symbol.getAddress(), FileName);
const StringRef Name = unwrapOrError(Symbol.getName(), FileName);
if (Obj->isXCOFF() && SymbolDescription) {
const auto *XCOFFObj = cast<XCOFFObjectFile>(Obj);
DataRefImpl SymbolDRI = Symbol.getRawDataRefImpl();
const uint32_t SymbolIndex = XCOFFObj->getSymbolIndex(SymbolDRI.p);
Optional<XCOFF::StorageMappingClass> Smc =
getXCOFFSymbolCsectSMC(XCOFFObj, Symbol);
return SymbolInfoTy(Addr, Name, Smc, SymbolIndex,
isLabel(XCOFFObj, Symbol));
} else
return SymbolInfoTy(Addr, Name,
Obj->isELF() ? getElfSymbolType(Obj, Symbol)
: (uint8_t)ELF::STT_NOTYPE);
}
SymbolInfoTy createDummySymbolInfo(const ObjectFile *Obj, const uint64_t Addr,
StringRef &Name, uint8_t Type) {
if (Obj->isXCOFF() && SymbolDescription)
return SymbolInfoTy(Addr, Name, None, None, false);
else
return SymbolInfoTy(Addr, Name, Type);
}
static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj, static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
MCContext &Ctx, MCDisassembler *PrimaryDisAsm, MCContext &Ctx, MCDisassembler *PrimaryDisAsm,
MCDisassembler *SecondaryDisAsm, MCDisassembler *SecondaryDisAsm,
@ -1184,20 +1218,14 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
const StringRef FileName = Obj->getFileName(); const StringRef FileName = Obj->getFileName();
const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj); const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj);
for (const SymbolRef &Symbol : Obj->symbols()) { for (const SymbolRef &Symbol : Obj->symbols()) {
uint64_t Address = unwrapOrError(Symbol.getAddress(), FileName);
StringRef Name = unwrapOrError(Symbol.getName(), FileName); StringRef Name = unwrapOrError(Symbol.getName(), FileName);
if (Name.empty()) if (Name.empty() && !(Obj->isXCOFF() && SymbolDescription))
continue; continue;
uint8_t SymbolType = ELF::STT_NOTYPE; if (Obj->isELF() && getElfSymbolType(Obj, Symbol) == ELF::STT_SECTION)
if (Obj->isELF()) { continue;
SymbolType = getElfSymbolType(Obj, Symbol);
if (SymbolType == ELF::STT_SECTION)
continue;
}
// Don't ask a Mach-O STAB symbol for its section unless you know that // Don't ask a Mach-O STAB symbol for its section unless you know that
// STAB symbol's section field refers to a valid section index. Otherwise // STAB symbol's section field refers to a valid section index. Otherwise
// the symbol may error trying to load a section that does not exist. // the symbol may error trying to load a section that does not exist.
if (MachO) { if (MachO) {
@ -1211,10 +1239,11 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
section_iterator SecI = unwrapOrError(Symbol.getSection(), FileName); section_iterator SecI = unwrapOrError(Symbol.getSection(), FileName);
if (SecI != Obj->section_end()) if (SecI != Obj->section_end())
AllSymbols[*SecI].emplace_back(Address, Name, SymbolType); AllSymbols[*SecI].push_back(createSymbolInfo(Obj, Symbol));
else else
AbsoluteSymbols.emplace_back(Address, Name, SymbolType); AbsoluteSymbols.push_back(createSymbolInfo(Obj, Symbol));
} }
if (AllSymbols.empty() && Obj->isELF()) if (AllSymbols.empty() && Obj->isELF())
addDynamicElfSymbols(Obj, AllSymbols); addDynamicElfSymbols(Obj, AllSymbols);
@ -1316,10 +1345,10 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
StringRef SectionName = unwrapOrError(Section.getName(), Obj->getFileName()); StringRef SectionName = unwrapOrError(Section.getName(), Obj->getFileName());
// If the section has no symbol at the start, just insert a dummy one. // If the section has no symbol at the start, just insert a dummy one.
if (Symbols.empty() || Symbols[0].Addr != 0) { if (Symbols.empty() || Symbols[0].Addr != 0) {
Symbols.insert( Symbols.insert(Symbols.begin(),
Symbols.begin(), createDummySymbolInfo(Obj, SectionAddr, SectionName,
SymbolInfoTy(SectionAddr, SectionName, Section.isText() ? ELF::STT_FUNC
Section.isText() ? ELF::STT_FUNC : ELF::STT_OBJECT)); : ELF::STT_OBJECT));
} }
SmallString<40> Comments; SmallString<40> Comments;
@ -1394,8 +1423,11 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
if (!NoLeadingAddr) if (!NoLeadingAddr)
outs() << format(Is64Bits ? "%016" PRIx64 " " : "%08" PRIx64 " ", outs() << format(Is64Bits ? "%016" PRIx64 " " : "%08" PRIx64 " ",
SectionAddr + Start + VMAAdjustment); SectionAddr + Start + VMAAdjustment);
if (Obj->isXCOFF() && SymbolDescription) {
outs() << '<' << SymbolName << ">:\n"; printXCOFFSymbolDescription(Symbols[SI], SymbolName);
outs() << ":\n";
} else
outs() << '<' << SymbolName << ">:\n";
// Don't print raw contents of a virtual section. A virtual section // Don't print raw contents of a virtual section. A virtual section
// doesn't have any contents in the file. // doesn't have any contents in the file.

View File

@ -23,7 +23,6 @@ class ELFSectionRef;
class MachOObjectFile; class MachOObjectFile;
class MachOUniversalBinary; class MachOUniversalBinary;
class RelocationRef; class RelocationRef;
class XCOFFObjectFile;
} }
extern cl::opt<bool> Demangle; extern cl::opt<bool> Demangle;
@ -101,9 +100,6 @@ Error getWasmRelocationValueString(const object::WasmObjectFile *Obj,
Error getMachORelocationValueString(const object::MachOObjectFile *Obj, Error getMachORelocationValueString(const object::MachOObjectFile *Obj,
const object::RelocationRef &RelRef, const object::RelocationRef &RelRef,
llvm::SmallVectorImpl<char> &Result); llvm::SmallVectorImpl<char> &Result);
Error getXCOFFRelocationValueString(const object::XCOFFObjectFile *Obj,
const object::RelocationRef &RelRef,
llvm::SmallVectorImpl<char> &Result);
uint64_t getELFSectionLMA(const object::ELFSectionRef& Sec); uint64_t getELFSectionLMA(const object::ELFSectionRef& Sec);