diff options
Diffstat (limited to 'contrib/libs/llvm12/tools/obj2yaml/xcoff2yaml.cpp')
-rw-r--r-- | contrib/libs/llvm12/tools/obj2yaml/xcoff2yaml.cpp | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/contrib/libs/llvm12/tools/obj2yaml/xcoff2yaml.cpp b/contrib/libs/llvm12/tools/obj2yaml/xcoff2yaml.cpp new file mode 100644 index 0000000000..dd9d8e8750 --- /dev/null +++ b/contrib/libs/llvm12/tools/obj2yaml/xcoff2yaml.cpp @@ -0,0 +1,96 @@ +//===------ 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(); +} |