97 lines
2.8 KiB
C++
97 lines
2.8 KiB
C++
//===------ xcoff2yaml.cpp - XCOFF YAMLIO implementation --------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "obj2yaml.h"
|
|
#include "llvm/Object/XCOFFObjectFile.h"
|
|
#include "llvm/ObjectYAML/XCOFFYAML.h"
|
|
#include "llvm/Support/YAMLTraits.h"
|
|
|
|
using namespace llvm;
|
|
using namespace llvm::object;
|
|
namespace {
|
|
|
|
class XCOFFDumper {
|
|
const object::XCOFFObjectFile &Obj;
|
|
XCOFFYAML::Object YAMLObj;
|
|
void dumpHeader();
|
|
std::error_code dumpSymbols();
|
|
|
|
public:
|
|
XCOFFDumper(const object::XCOFFObjectFile &obj) : Obj(obj) {}
|
|
std::error_code dump();
|
|
XCOFFYAML::Object &getYAMLObj() { return YAMLObj; }
|
|
};
|
|
} // namespace
|
|
|
|
std::error_code XCOFFDumper::dump() {
|
|
dumpHeader();
|
|
return dumpSymbols();
|
|
}
|
|
|
|
void XCOFFDumper::dumpHeader() {
|
|
|
|
YAMLObj.Header.Magic = Obj.getMagic();
|
|
YAMLObj.Header.NumberOfSections = Obj.getNumberOfSections();
|
|
YAMLObj.Header.TimeStamp = Obj.getTimeStamp();
|
|
|
|
// TODO FIXME only dump 32 bit header for now.
|
|
if (Obj.is64Bit())
|
|
report_fatal_error("64-bit XCOFF files not supported yet.");
|
|
YAMLObj.Header.SymbolTableOffset = Obj.getSymbolTableOffset32();
|
|
|
|
YAMLObj.Header.NumberOfSymTableEntries =
|
|
Obj.getRawNumberOfSymbolTableEntries32();
|
|
YAMLObj.Header.AuxHeaderSize = Obj.getOptionalHeaderSize();
|
|
YAMLObj.Header.Flags = Obj.getFlags();
|
|
}
|
|
|
|
std::error_code XCOFFDumper::dumpSymbols() {
|
|
std::vector<XCOFFYAML::Symbol> &Symbols = YAMLObj.Symbols;
|
|
|
|
for (const SymbolRef &S : Obj.symbols()) {
|
|
DataRefImpl SymbolDRI = S.getRawDataRefImpl();
|
|
const XCOFFSymbolEntry *SymbolEntPtr = Obj.toSymbolEntry(SymbolDRI);
|
|
XCOFFYAML::Symbol Sym;
|
|
|
|
Expected<StringRef> SymNameRefOrErr = Obj.getSymbolName(SymbolDRI);
|
|
if (!SymNameRefOrErr) {
|
|
return errorToErrorCode(SymNameRefOrErr.takeError());
|
|
}
|
|
Sym.SymbolName = SymNameRefOrErr.get();
|
|
|
|
Sym.Value = SymbolEntPtr->Value;
|
|
|
|
Expected<StringRef> SectionNameRefOrErr =
|
|
Obj.getSymbolSectionName(SymbolEntPtr);
|
|
if (!SectionNameRefOrErr)
|
|
return errorToErrorCode(SectionNameRefOrErr.takeError());
|
|
|
|
Sym.SectionName = SectionNameRefOrErr.get();
|
|
|
|
Sym.Type = SymbolEntPtr->SymbolType;
|
|
Sym.StorageClass = SymbolEntPtr->StorageClass;
|
|
Sym.NumberOfAuxEntries = SymbolEntPtr->NumberOfAuxEntries;
|
|
Symbols.push_back(Sym);
|
|
}
|
|
|
|
return std::error_code();
|
|
}
|
|
|
|
std::error_code xcoff2yaml(raw_ostream &Out,
|
|
const object::XCOFFObjectFile &Obj) {
|
|
XCOFFDumper Dumper(Obj);
|
|
|
|
if (std::error_code EC = Dumper.dump())
|
|
return EC;
|
|
|
|
yaml::Output Yout(Out);
|
|
Yout << Dumper.getYAMLObj();
|
|
|
|
return std::error_code();
|
|
}
|