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