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 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 Optional<XCOFF::StorageMappingClass> 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 None; 53 54 auto CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef(); 55 if (!CsectAuxEntOrErr) 56 return None; 57 58 return CsectAuxEntOrErr.get().getStorageMappingClass(); 59 } 60 61 Optional<object::SymbolRef> 62 objdump::getXCOFFSymbolContainingSymbolRef(const XCOFFObjectFile *Obj, 63 const SymbolRef &Sym) { 64 65 const XCOFFSymbolRef SymRef = Obj->toSymbolRef(Sym.getRawDataRefImpl()); 66 if (!SymRef.isCsectSymbol()) 67 return None; 68 69 Expected<XCOFFCsectAuxRef> CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef(); 70 if (!CsectAuxEntOrErr || !CsectAuxEntOrErr.get().isLabel()) 71 return None; 72 uint32_t Idx = 73 static_cast<uint32_t>(CsectAuxEntOrErr.get().getSectionOrLength()); 74 DataRefImpl DRI; 75 DRI.p = Obj->getSymbolByIndex(Idx); 76 return SymbolRef(DRI, Obj); 77 } 78 79 bool objdump::isLabel(const XCOFFObjectFile *Obj, const SymbolRef &Sym) { 80 81 const XCOFFSymbolRef SymRef = Obj->toSymbolRef(Sym.getRawDataRefImpl()); 82 83 if (!SymRef.isCsectSymbol()) 84 return false; 85 86 auto CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef(); 87 if (!CsectAuxEntOrErr) 88 return false; 89 90 return CsectAuxEntOrErr.get().isLabel(); 91 } 92 93 std::string objdump::getXCOFFSymbolDescription(const SymbolInfoTy &SymbolInfo, 94 StringRef SymbolName) { 95 assert(SymbolInfo.isXCOFF() && "Must be a XCOFFSymInfo."); 96 97 std::string Result; 98 // Dummy symbols have no symbol index. 99 if (SymbolInfo.XCOFFSymInfo.Index) 100 Result = ("(idx: " + Twine(SymbolInfo.XCOFFSymInfo.Index.getValue()) + 101 ") " + SymbolName) 102 .str(); 103 else 104 Result.append(SymbolName.begin(), SymbolName.end()); 105 106 if (SymbolInfo.XCOFFSymInfo.StorageMappingClass && 107 !SymbolInfo.XCOFFSymInfo.IsLabel) { 108 const XCOFF::StorageMappingClass Smc = 109 SymbolInfo.XCOFFSymInfo.StorageMappingClass.getValue(); 110 Result.append(("[" + XCOFF::getMappingClassString(Smc) + "]").str()); 111 } 112 113 return Result; 114 } 115