xref: /freebsd-src/contrib/llvm-project/llvm/tools/llvm-objdump/XCOFFDump.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
15ffd83dbSDimitry Andric //===-- XCOFFDump.cpp - XCOFF-specific dumper -----------------------------===//
25ffd83dbSDimitry Andric //
35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65ffd83dbSDimitry Andric //
75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
85ffd83dbSDimitry Andric ///
95ffd83dbSDimitry Andric /// \file
105ffd83dbSDimitry Andric /// This file implements the XCOFF-specific dumper for llvm-objdump.
115ffd83dbSDimitry Andric ///
125ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
135ffd83dbSDimitry Andric 
145ffd83dbSDimitry Andric #include "XCOFFDump.h"
155ffd83dbSDimitry Andric 
165ffd83dbSDimitry Andric #include "llvm-objdump.h"
175ffd83dbSDimitry Andric #include "llvm/Demangle/Demangle.h"
185ffd83dbSDimitry Andric 
195ffd83dbSDimitry Andric using namespace llvm;
205ffd83dbSDimitry Andric using namespace llvm::object;
215ffd83dbSDimitry Andric 
225ffd83dbSDimitry Andric Error objdump::getXCOFFRelocationValueString(const XCOFFObjectFile *Obj,
235ffd83dbSDimitry Andric                                              const RelocationRef &Rel,
245ffd83dbSDimitry Andric                                              SmallVectorImpl<char> &Result) {
255ffd83dbSDimitry Andric   symbol_iterator SymI = Rel.getSymbol();
265ffd83dbSDimitry Andric   if (SymI == Obj->symbol_end())
275ffd83dbSDimitry Andric     return make_error<GenericBinaryError>(
285ffd83dbSDimitry Andric         "invalid symbol reference in relocation entry",
295ffd83dbSDimitry Andric         object_error::parse_failed);
305ffd83dbSDimitry Andric 
315ffd83dbSDimitry Andric   Expected<StringRef> SymNameOrErr = SymI->getName();
325ffd83dbSDimitry Andric   if (!SymNameOrErr)
335ffd83dbSDimitry Andric     return SymNameOrErr.takeError();
345ffd83dbSDimitry Andric 
355ffd83dbSDimitry Andric   std::string SymName = (*SymNameOrErr).str();
365ffd83dbSDimitry Andric   if (Demangle)
375ffd83dbSDimitry Andric     SymName = demangle(SymName);
385ffd83dbSDimitry Andric 
395ffd83dbSDimitry Andric   if (SymbolDescription)
405ffd83dbSDimitry Andric     SymName = getXCOFFSymbolDescription(createSymbolInfo(Obj, *SymI), SymName);
415ffd83dbSDimitry Andric 
425ffd83dbSDimitry Andric   Result.append(SymName.begin(), SymName.end());
435ffd83dbSDimitry Andric   return Error::success();
445ffd83dbSDimitry Andric }
455ffd83dbSDimitry Andric 
465ffd83dbSDimitry Andric Optional<XCOFF::StorageMappingClass>
475ffd83dbSDimitry Andric objdump::getXCOFFSymbolCsectSMC(const XCOFFObjectFile *Obj,
485ffd83dbSDimitry Andric                                 const SymbolRef &Sym) {
49fe6060f1SDimitry Andric   const XCOFFSymbolRef SymRef = Obj->toSymbolRef(Sym.getRawDataRefImpl());
505ffd83dbSDimitry Andric 
51fe6060f1SDimitry Andric   if (!SymRef.isCsectSymbol())
525ffd83dbSDimitry Andric     return None;
53fe6060f1SDimitry Andric 
54fe6060f1SDimitry Andric   auto CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef();
55fe6060f1SDimitry Andric   if (!CsectAuxEntOrErr)
56fe6060f1SDimitry Andric     return None;
57fe6060f1SDimitry Andric 
58fe6060f1SDimitry Andric   return CsectAuxEntOrErr.get().getStorageMappingClass();
595ffd83dbSDimitry Andric }
605ffd83dbSDimitry Andric 
61349cc55cSDimitry Andric Optional<object::SymbolRef>
62349cc55cSDimitry Andric objdump::getXCOFFSymbolContainingSymbolRef(const XCOFFObjectFile *Obj,
63349cc55cSDimitry Andric                                            const SymbolRef &Sym) {
64349cc55cSDimitry Andric 
65349cc55cSDimitry Andric   const XCOFFSymbolRef SymRef = Obj->toSymbolRef(Sym.getRawDataRefImpl());
66349cc55cSDimitry Andric   if (!SymRef.isCsectSymbol())
67349cc55cSDimitry Andric     return None;
68349cc55cSDimitry Andric 
69349cc55cSDimitry Andric   Expected<XCOFFCsectAuxRef> CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef();
70349cc55cSDimitry Andric   if (!CsectAuxEntOrErr || !CsectAuxEntOrErr.get().isLabel())
71349cc55cSDimitry Andric     return None;
72349cc55cSDimitry Andric   uint32_t Idx =
73349cc55cSDimitry Andric       static_cast<uint32_t>(CsectAuxEntOrErr.get().getSectionOrLength());
74349cc55cSDimitry Andric   DataRefImpl DRI;
75349cc55cSDimitry Andric   DRI.p = Obj->getSymbolByIndex(Idx);
76349cc55cSDimitry Andric   return SymbolRef(DRI, Obj);
77349cc55cSDimitry Andric }
78349cc55cSDimitry Andric 
795ffd83dbSDimitry Andric bool objdump::isLabel(const XCOFFObjectFile *Obj, const SymbolRef &Sym) {
805ffd83dbSDimitry Andric 
81fe6060f1SDimitry Andric   const XCOFFSymbolRef SymRef = Obj->toSymbolRef(Sym.getRawDataRefImpl());
825ffd83dbSDimitry Andric 
83fe6060f1SDimitry Andric   if (!SymRef.isCsectSymbol())
845ffd83dbSDimitry Andric     return false;
85fe6060f1SDimitry Andric 
86fe6060f1SDimitry Andric   auto CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef();
87fe6060f1SDimitry Andric   if (!CsectAuxEntOrErr)
88fe6060f1SDimitry Andric     return false;
89fe6060f1SDimitry Andric 
90fe6060f1SDimitry Andric   return CsectAuxEntOrErr.get().isLabel();
915ffd83dbSDimitry Andric }
925ffd83dbSDimitry Andric 
935ffd83dbSDimitry Andric std::string objdump::getXCOFFSymbolDescription(const SymbolInfoTy &SymbolInfo,
945ffd83dbSDimitry Andric                                                StringRef SymbolName) {
955ffd83dbSDimitry Andric   assert(SymbolInfo.isXCOFF() && "Must be a XCOFFSymInfo.");
965ffd83dbSDimitry Andric 
975ffd83dbSDimitry Andric   std::string Result;
985ffd83dbSDimitry Andric   // Dummy symbols have no symbol index.
995ffd83dbSDimitry Andric   if (SymbolInfo.XCOFFSymInfo.Index)
1005ffd83dbSDimitry Andric     Result = ("(idx: " + Twine(SymbolInfo.XCOFFSymInfo.Index.getValue()) +
1015ffd83dbSDimitry Andric               ") " + SymbolName)
1025ffd83dbSDimitry Andric                  .str();
1035ffd83dbSDimitry Andric   else
1045ffd83dbSDimitry Andric     Result.append(SymbolName.begin(), SymbolName.end());
1055ffd83dbSDimitry Andric 
1065ffd83dbSDimitry Andric   if (SymbolInfo.XCOFFSymInfo.StorageMappingClass &&
1075ffd83dbSDimitry Andric       !SymbolInfo.XCOFFSymInfo.IsLabel) {
1085ffd83dbSDimitry Andric     const XCOFF::StorageMappingClass Smc =
109*81ad6265SDimitry Andric         *SymbolInfo.XCOFFSymInfo.StorageMappingClass;
1105ffd83dbSDimitry Andric     Result.append(("[" + XCOFF::getMappingClassString(Smc) + "]").str());
1115ffd83dbSDimitry Andric   }
1125ffd83dbSDimitry Andric 
1135ffd83dbSDimitry Andric   return Result;
1145ffd83dbSDimitry Andric }
115