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
19using namespace llvm;
20using namespace llvm::object;
21
22Error 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
46Optional<XCOFF::StorageMappingClass>
47objdump::getXCOFFSymbolCsectSMC(const XCOFFObjectFile *Obj,
48                                const SymbolRef &Sym) {
49  XCOFFSymbolRef SymRef(Sym.getRawDataRefImpl(), Obj);
50
51  if (SymRef.hasCsectAuxEnt())
52    return SymRef.getXCOFFCsectAuxEnt32()->StorageMappingClass;
53
54  return None;
55}
56
57bool objdump::isLabel(const XCOFFObjectFile *Obj, const SymbolRef &Sym) {
58
59  XCOFFSymbolRef SymRef(Sym.getRawDataRefImpl(), Obj);
60
61  if (SymRef.hasCsectAuxEnt())
62    return SymRef.getXCOFFCsectAuxEnt32()->isLabel();
63
64  return false;
65}
66
67std::string objdump::getXCOFFSymbolDescription(const SymbolInfoTy &SymbolInfo,
68                                               StringRef SymbolName) {
69  assert(SymbolInfo.isXCOFF() && "Must be a XCOFFSymInfo.");
70
71  std::string Result;
72  // Dummy symbols have no symbol index.
73  if (SymbolInfo.XCOFFSymInfo.Index)
74    Result = ("(idx: " + Twine(SymbolInfo.XCOFFSymInfo.Index.getValue()) +
75              ") " + SymbolName)
76                 .str();
77  else
78    Result.append(SymbolName.begin(), SymbolName.end());
79
80  if (SymbolInfo.XCOFFSymInfo.StorageMappingClass &&
81      !SymbolInfo.XCOFFSymInfo.IsLabel) {
82    const XCOFF::StorageMappingClass Smc =
83        SymbolInfo.XCOFFSymInfo.StorageMappingClass.getValue();
84    Result.append(("[" + XCOFF::getMappingClassString(Smc) + "]").str());
85  }
86
87  return Result;
88}
89