aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-objdump
diff options
context:
space:
mode:
authordiggerlin <digger.llvm@gmail.com>2020-04-06 10:09:12 -0400
committerdiggerlin <digger.llvm@gmail.com>2020-04-06 10:10:10 -0400
commita26a441b99ff313a56c3e35ee526342d3f43c8b8 (patch)
tree07bc61735f4bebd4559fcc0662a8322f9b259553 /llvm/tools/llvm-objdump
parent9072df8ac1431dba51394b77ead766aada82867f (diff)
downloadllvm-a26a441b99ff313a56c3e35ee526342d3f43c8b8.zip
llvm-a26a441b99ff313a56c3e35ee526342d3f43c8b8.tar.gz
llvm-a26a441b99ff313a56c3e35ee526342d3f43c8b8.tar.bz2
[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
Diffstat (limited to 'llvm/tools/llvm-objdump')
-rw-r--r--llvm/tools/llvm-objdump/XCOFFDump.cpp52
-rw-r--r--llvm/tools/llvm-objdump/XCOFFDump.h33
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp70
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.h4
4 files changed, 130 insertions, 29 deletions
diff --git a/llvm/tools/llvm-objdump/XCOFFDump.cpp b/llvm/tools/llvm-objdump/XCOFFDump.cpp
index 6712391..eedb8da 100644
--- a/llvm/tools/llvm-objdump/XCOFFDump.cpp
+++ b/llvm/tools/llvm-objdump/XCOFFDump.cpp
@@ -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.
// See https://llvm.org/LICENSE.txt for license information.
@@ -11,14 +11,15 @@
///
//===----------------------------------------------------------------------===//
-#include "llvm-objdump.h"
-#include "llvm/Object/XCOFFObjectFile.h"
+#include "XCOFFDump.h"
+#include "llvm/MC/MCDisassembler/MCDisassembler.h"
+using namespace llvm;
using namespace llvm::object;
-llvm::Error llvm::getXCOFFRelocationValueString(const XCOFFObjectFile *Obj,
- const RelocationRef &Rel,
- SmallVectorImpl<char> &Result) {
+Error objdump::getXCOFFRelocationValueString(const XCOFFObjectFile *Obj,
+ const RelocationRef &Rel,
+ SmallVectorImpl<char> &Result) {
symbol_iterator SymI = Rel.getSymbol();
if (SymI == Obj->symbol_end())
return make_error<GenericBinaryError>(
@@ -32,3 +33,42 @@ llvm::Error llvm::getXCOFFRelocationValueString(const XCOFFObjectFile *Obj,
Result.append(SymName.begin(), SymName.end());
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) << "]";
+ }
+}
diff --git a/llvm/tools/llvm-objdump/XCOFFDump.h b/llvm/tools/llvm-objdump/XCOFFDump.h
new file mode 100644
index 0000000..17441a6
--- /dev/null
+++ b/llvm/tools/llvm-objdump/XCOFFDump.h
@@ -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
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index b1be6d5..5c2bf29 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -17,6 +17,7 @@
#include "llvm-objdump.h"
#include "COFFDump.h"
+#include "XCOFFDump.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetOperations.h"
@@ -46,7 +47,6 @@
#include "llvm/Object/MachO.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/Object/XCOFFObjectFile.h"
#include "llvm/Object/Wasm.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
@@ -146,6 +146,12 @@ static cl::alias DisassembleAllShort("D",
cl::NotHidden, cl::Grouping,
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>
DisassembleSymbols("disassemble-symbols", cl::CommaSeparated,
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,
MCContext &Ctx, MCDisassembler *PrimaryDisAsm,
MCDisassembler *SecondaryDisAsm,
@@ -1184,20 +1218,14 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
const StringRef FileName = Obj->getFileName();
const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj);
for (const SymbolRef &Symbol : Obj->symbols()) {
- uint64_t Address = unwrapOrError(Symbol.getAddress(), FileName);
-
StringRef Name = unwrapOrError(Symbol.getName(), FileName);
- if (Name.empty())
+ if (Name.empty() && !(Obj->isXCOFF() && SymbolDescription))
continue;
- uint8_t SymbolType = ELF::STT_NOTYPE;
- if (Obj->isELF()) {
- SymbolType = getElfSymbolType(Obj, Symbol);
- if (SymbolType == ELF::STT_SECTION)
- continue;
- }
+ if (Obj->isELF() && getElfSymbolType(Obj, Symbol) == 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
// the symbol may error trying to load a section that does not exist.
if (MachO) {
@@ -1211,10 +1239,11 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
section_iterator SecI = unwrapOrError(Symbol.getSection(), FileName);
if (SecI != Obj->section_end())
- AllSymbols[*SecI].emplace_back(Address, Name, SymbolType);
+ AllSymbols[*SecI].push_back(createSymbolInfo(Obj, Symbol));
else
- AbsoluteSymbols.emplace_back(Address, Name, SymbolType);
+ AbsoluteSymbols.push_back(createSymbolInfo(Obj, Symbol));
}
+
if (AllSymbols.empty() && Obj->isELF())
addDynamicElfSymbols(Obj, AllSymbols);
@@ -1316,10 +1345,10 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
StringRef SectionName = unwrapOrError(Section.getName(), Obj->getFileName());
// If the section has no symbol at the start, just insert a dummy one.
if (Symbols.empty() || Symbols[0].Addr != 0) {
- Symbols.insert(
- Symbols.begin(),
- SymbolInfoTy(SectionAddr, SectionName,
- Section.isText() ? ELF::STT_FUNC : ELF::STT_OBJECT));
+ Symbols.insert(Symbols.begin(),
+ createDummySymbolInfo(Obj, SectionAddr, SectionName,
+ Section.isText() ? ELF::STT_FUNC
+ : ELF::STT_OBJECT));
}
SmallString<40> Comments;
@@ -1394,8 +1423,11 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
if (!NoLeadingAddr)
outs() << format(Is64Bits ? "%016" PRIx64 " " : "%08" PRIx64 " ",
SectionAddr + Start + VMAAdjustment);
-
- outs() << '<' << SymbolName << ">:\n";
+ if (Obj->isXCOFF() && SymbolDescription) {
+ printXCOFFSymbolDescription(Symbols[SI], SymbolName);
+ outs() << ":\n";
+ } else
+ outs() << '<' << SymbolName << ">:\n";
// Don't print raw contents of a virtual section. A virtual section
// doesn't have any contents in the file.
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h
index 7863689..429a607 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.h
+++ b/llvm/tools/llvm-objdump/llvm-objdump.h
@@ -23,7 +23,6 @@ class ELFSectionRef;
class MachOObjectFile;
class MachOUniversalBinary;
class RelocationRef;
-class XCOFFObjectFile;
}
extern cl::opt<bool> Demangle;
@@ -101,9 +100,6 @@ Error getWasmRelocationValueString(const object::WasmObjectFile *Obj,
Error getMachORelocationValueString(const object::MachOObjectFile *Obj,
const object::RelocationRef &RelRef,
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);