xref: /freebsd-src/contrib/llvm-project/llvm/tools/llvm-objdump/XCOFFDump.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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 
22753f127fSDimitry Andric Error objdump::getXCOFFRelocationValueString(const XCOFFObjectFile &Obj,
235ffd83dbSDimitry Andric                                              const RelocationRef &Rel,
245ffd83dbSDimitry Andric                                              SmallVectorImpl<char> &Result) {
255ffd83dbSDimitry Andric   symbol_iterator SymI = Rel.getSymbol();
26753f127fSDimitry 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 
46*bdd1243dSDimitry Andric std::optional<XCOFF::StorageMappingClass>
47753f127fSDimitry Andric objdump::getXCOFFSymbolCsectSMC(const XCOFFObjectFile &Obj,
485ffd83dbSDimitry Andric                                 const SymbolRef &Sym) {
49753f127fSDimitry Andric   const XCOFFSymbolRef SymRef = Obj.toSymbolRef(Sym.getRawDataRefImpl());
505ffd83dbSDimitry Andric 
51fe6060f1SDimitry Andric   if (!SymRef.isCsectSymbol())
52*bdd1243dSDimitry Andric     return std::nullopt;
53fe6060f1SDimitry Andric 
54fe6060f1SDimitry Andric   auto CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef();
55fe6060f1SDimitry Andric   if (!CsectAuxEntOrErr)
56*bdd1243dSDimitry Andric     return std::nullopt;
57fe6060f1SDimitry Andric 
58fe6060f1SDimitry Andric   return CsectAuxEntOrErr.get().getStorageMappingClass();
595ffd83dbSDimitry Andric }
605ffd83dbSDimitry Andric 
61*bdd1243dSDimitry Andric std::optional<object::SymbolRef>
62753f127fSDimitry Andric objdump::getXCOFFSymbolContainingSymbolRef(const XCOFFObjectFile &Obj,
63349cc55cSDimitry Andric                                            const SymbolRef &Sym) {
64753f127fSDimitry Andric   const XCOFFSymbolRef SymRef = Obj.toSymbolRef(Sym.getRawDataRefImpl());
65349cc55cSDimitry Andric   if (!SymRef.isCsectSymbol())
66*bdd1243dSDimitry Andric     return std::nullopt;
67349cc55cSDimitry Andric 
68349cc55cSDimitry Andric   Expected<XCOFFCsectAuxRef> CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef();
69349cc55cSDimitry Andric   if (!CsectAuxEntOrErr || !CsectAuxEntOrErr.get().isLabel())
70*bdd1243dSDimitry Andric     return std::nullopt;
71349cc55cSDimitry Andric   uint32_t Idx =
72349cc55cSDimitry Andric       static_cast<uint32_t>(CsectAuxEntOrErr.get().getSectionOrLength());
73349cc55cSDimitry Andric   DataRefImpl DRI;
74753f127fSDimitry Andric   DRI.p = Obj.getSymbolByIndex(Idx);
75753f127fSDimitry Andric   return SymbolRef(DRI, &Obj);
76349cc55cSDimitry Andric }
77349cc55cSDimitry Andric 
78753f127fSDimitry Andric bool objdump::isLabel(const XCOFFObjectFile &Obj, const SymbolRef &Sym) {
79753f127fSDimitry Andric   const XCOFFSymbolRef SymRef = Obj.toSymbolRef(Sym.getRawDataRefImpl());
80fe6060f1SDimitry Andric   if (!SymRef.isCsectSymbol())
815ffd83dbSDimitry Andric     return false;
82fe6060f1SDimitry Andric 
83fe6060f1SDimitry Andric   auto CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef();
84fe6060f1SDimitry Andric   if (!CsectAuxEntOrErr)
85fe6060f1SDimitry Andric     return false;
86fe6060f1SDimitry Andric 
87fe6060f1SDimitry Andric   return CsectAuxEntOrErr.get().isLabel();
885ffd83dbSDimitry Andric }
895ffd83dbSDimitry Andric 
905ffd83dbSDimitry Andric std::string objdump::getXCOFFSymbolDescription(const SymbolInfoTy &SymbolInfo,
915ffd83dbSDimitry Andric                                                StringRef SymbolName) {
925ffd83dbSDimitry Andric   assert(SymbolInfo.isXCOFF() && "Must be a XCOFFSymInfo.");
935ffd83dbSDimitry Andric 
945ffd83dbSDimitry Andric   std::string Result;
955ffd83dbSDimitry Andric   // Dummy symbols have no symbol index.
965ffd83dbSDimitry Andric   if (SymbolInfo.XCOFFSymInfo.Index)
97*bdd1243dSDimitry Andric     Result =
98*bdd1243dSDimitry Andric         ("(idx: " + Twine(*SymbolInfo.XCOFFSymInfo.Index) + ") " + SymbolName)
995ffd83dbSDimitry Andric             .str();
1005ffd83dbSDimitry Andric   else
1015ffd83dbSDimitry Andric     Result.append(SymbolName.begin(), SymbolName.end());
1025ffd83dbSDimitry Andric 
1035ffd83dbSDimitry Andric   if (SymbolInfo.XCOFFSymInfo.StorageMappingClass &&
1045ffd83dbSDimitry Andric       !SymbolInfo.XCOFFSymInfo.IsLabel) {
1055ffd83dbSDimitry Andric     const XCOFF::StorageMappingClass Smc =
10681ad6265SDimitry Andric         *SymbolInfo.XCOFFSymInfo.StorageMappingClass;
1075ffd83dbSDimitry Andric     Result.append(("[" + XCOFF::getMappingClassString(Smc) + "]").str());
1085ffd83dbSDimitry Andric   }
1095ffd83dbSDimitry Andric 
1105ffd83dbSDimitry Andric   return Result;
1115ffd83dbSDimitry Andric }
112