1 //===-- XCOFFDump.cpp - XCOFF-specific dumper -----------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file implements the XCOFF-specific dumper for llvm-objdump.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "XCOFFDump.h"
15
16 #include "llvm-objdump.h"
17 #include "llvm/Demangle/Demangle.h"
18
19 using namespace llvm;
20 using namespace llvm::object;
21
getXCOFFRelocationValueString(const XCOFFObjectFile & Obj,const RelocationRef & Rel,SmallVectorImpl<char> & Result)22 Error objdump::getXCOFFRelocationValueString(const XCOFFObjectFile &Obj,
23 const RelocationRef &Rel,
24 SmallVectorImpl<char> &Result) {
25 symbol_iterator SymI = Rel.getSymbol();
26 if (SymI == Obj.symbol_end())
27 return make_error<GenericBinaryError>(
28 "invalid symbol reference in relocation entry",
29 object_error::parse_failed);
30
31 Expected<StringRef> SymNameOrErr = SymI->getName();
32 if (!SymNameOrErr)
33 return SymNameOrErr.takeError();
34
35 std::string SymName = (*SymNameOrErr).str();
36 if (Demangle)
37 SymName = demangle(SymName);
38
39 if (SymbolDescription)
40 SymName = getXCOFFSymbolDescription(createSymbolInfo(Obj, *SymI), SymName);
41
42 Result.append(SymName.begin(), SymName.end());
43 return Error::success();
44 }
45
46 std::optional<XCOFF::StorageMappingClass>
getXCOFFSymbolCsectSMC(const XCOFFObjectFile & Obj,const SymbolRef & Sym)47 objdump::getXCOFFSymbolCsectSMC(const XCOFFObjectFile &Obj,
48 const SymbolRef &Sym) {
49 const XCOFFSymbolRef SymRef = Obj.toSymbolRef(Sym.getRawDataRefImpl());
50
51 if (!SymRef.isCsectSymbol())
52 return std::nullopt;
53
54 auto CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef();
55 if (!CsectAuxEntOrErr)
56 return std::nullopt;
57
58 return CsectAuxEntOrErr.get().getStorageMappingClass();
59 }
60
61 std::optional<object::SymbolRef>
getXCOFFSymbolContainingSymbolRef(const XCOFFObjectFile & Obj,const SymbolRef & Sym)62 objdump::getXCOFFSymbolContainingSymbolRef(const XCOFFObjectFile &Obj,
63 const SymbolRef &Sym) {
64 const XCOFFSymbolRef SymRef = Obj.toSymbolRef(Sym.getRawDataRefImpl());
65 if (!SymRef.isCsectSymbol())
66 return std::nullopt;
67
68 Expected<XCOFFCsectAuxRef> CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef();
69 if (!CsectAuxEntOrErr || !CsectAuxEntOrErr.get().isLabel())
70 return std::nullopt;
71 uint32_t Idx =
72 static_cast<uint32_t>(CsectAuxEntOrErr.get().getSectionOrLength());
73 DataRefImpl DRI;
74 DRI.p = Obj.getSymbolByIndex(Idx);
75 return SymbolRef(DRI, &Obj);
76 }
77
isLabel(const XCOFFObjectFile & Obj,const SymbolRef & Sym)78 bool objdump::isLabel(const XCOFFObjectFile &Obj, const SymbolRef &Sym) {
79 const XCOFFSymbolRef SymRef = Obj.toSymbolRef(Sym.getRawDataRefImpl());
80 if (!SymRef.isCsectSymbol())
81 return false;
82
83 auto CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef();
84 if (!CsectAuxEntOrErr)
85 return false;
86
87 return CsectAuxEntOrErr.get().isLabel();
88 }
89
getXCOFFSymbolDescription(const SymbolInfoTy & SymbolInfo,StringRef SymbolName)90 std::string objdump::getXCOFFSymbolDescription(const SymbolInfoTy &SymbolInfo,
91 StringRef SymbolName) {
92 assert(SymbolInfo.isXCOFF() && "Must be a XCOFFSymInfo.");
93
94 std::string Result;
95 // Dummy symbols have no symbol index.
96 if (SymbolInfo.XCOFFSymInfo.Index)
97 Result =
98 ("(idx: " + Twine(*SymbolInfo.XCOFFSymInfo.Index) + ") " + SymbolName)
99 .str();
100 else
101 Result.append(SymbolName.begin(), SymbolName.end());
102
103 if (SymbolInfo.XCOFFSymInfo.StorageMappingClass &&
104 !SymbolInfo.XCOFFSymInfo.IsLabel) {
105 const XCOFF::StorageMappingClass Smc =
106 *SymbolInfo.XCOFFSymInfo.StorageMappingClass;
107 Result.append(("[" + XCOFF::getMappingClassString(Smc) + "]").str());
108 }
109
110 return Result;
111 }
112