Imported Upstream version 5.18.0.246

Former-commit-id: 0c7ce5b1a7851e13f22acfd379b7f9fb304e4833
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2019-01-23 08:21:40 +00:00
parent a7724cd563
commit 279aa8f685
28482 changed files with 3866972 additions and 44 deletions

View File

@@ -0,0 +1,17 @@
set(LLVM_LINK_COMPONENTS
DebugInfoCodeView
DebugInfoDWARF
Object
ObjectYAML
Support
)
add_llvm_tool(obj2yaml
obj2yaml.cpp
coff2yaml.cpp
dwarf2yaml.cpp
elf2yaml.cpp
macho2yaml.cpp
wasm2yaml.cpp
Error.cpp
)

62
external/llvm/tools/obj2yaml/Error.cpp vendored Normal file
View File

@@ -0,0 +1,62 @@
//===- Error.cpp - system_error extensions for obj2yaml ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "Error.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
namespace {
// FIXME: This class is only here to support the transition to llvm::Error. It
// will be removed once this transition is complete. Clients should prefer to
// deal with the Error value directly, rather than converting to error_code.
class _obj2yaml_error_category : public std::error_category {
public:
const char *name() const noexcept override;
std::string message(int ev) const override;
};
} // namespace
const char *_obj2yaml_error_category::name() const noexcept {
return "obj2yaml";
}
std::string _obj2yaml_error_category::message(int ev) const {
switch (static_cast<obj2yaml_error>(ev)) {
case obj2yaml_error::success:
return "Success";
case obj2yaml_error::file_not_found:
return "No such file.";
case obj2yaml_error::unrecognized_file_format:
return "Unrecognized file type.";
case obj2yaml_error::unsupported_obj_file_format:
return "Unsupported object file format.";
case obj2yaml_error::not_implemented:
return "Feature not yet implemented.";
}
llvm_unreachable("An enumerator of obj2yaml_error does not have a message "
"defined.");
}
namespace llvm {
const std::error_category &obj2yaml_category() {
static _obj2yaml_error_category o;
return o;
}
char Obj2YamlError::ID = 0;
void Obj2YamlError::log(raw_ostream &OS) const { OS << ErrMsg << "\n"; }
std::error_code Obj2YamlError::convertToErrorCode() const {
return std::error_code(static_cast<int>(Code), obj2yaml_category());
}
} // namespace llvm

54
external/llvm/tools/obj2yaml/Error.h vendored Normal file
View File

@@ -0,0 +1,54 @@
//===- Error.h - system_error extensions for obj2yaml -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TOOLS_OBJ2YAML_ERROR_H
#define LLVM_TOOLS_OBJ2YAML_ERROR_H
#include "llvm/Support/Error.h"
#include <system_error>
namespace llvm {
const std::error_category &obj2yaml_category();
enum class obj2yaml_error {
success = 0,
file_not_found,
unrecognized_file_format,
unsupported_obj_file_format,
not_implemented
};
inline std::error_code make_error_code(obj2yaml_error e) {
return std::error_code(static_cast<int>(e), obj2yaml_category());
}
class Obj2YamlError : public ErrorInfo<Obj2YamlError> {
public:
static char ID;
Obj2YamlError(obj2yaml_error C) : Code(C) {}
Obj2YamlError(std::string ErrMsg) : ErrMsg(std::move(ErrMsg)) {}
Obj2YamlError(obj2yaml_error C, std::string ErrMsg)
: ErrMsg(std::move(ErrMsg)), Code(C) {}
void log(raw_ostream &OS) const override;
const std::string &getErrorMessage() const { return ErrMsg; }
std::error_code convertToErrorCode() const override;
private:
std::string ErrMsg;
obj2yaml_error Code;
};
} // namespace llvm
namespace std {
template <> struct is_error_code_enum<llvm::obj2yaml_error> : std::true_type {};
}
#endif

View File

@@ -0,0 +1,342 @@
//===------ utils/obj2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "obj2yaml.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
#include "llvm/Object/COFF.h"
#include "llvm/ObjectYAML/COFFYAML.h"
#include "llvm/ObjectYAML/CodeViewYAMLTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/YAMLTraits.h"
using namespace llvm;
namespace {
class COFFDumper {
const object::COFFObjectFile &Obj;
COFFYAML::Object YAMLObj;
template <typename T>
void dumpOptionalHeader(T OptionalHeader);
void dumpHeader();
void dumpSections(unsigned numSections);
void dumpSymbols(unsigned numSymbols);
public:
COFFDumper(const object::COFFObjectFile &Obj);
COFFYAML::Object &getYAMLObj();
};
}
COFFDumper::COFFDumper(const object::COFFObjectFile &Obj) : Obj(Obj) {
const object::pe32_header *PE32Header = nullptr;
Obj.getPE32Header(PE32Header);
if (PE32Header) {
dumpOptionalHeader(PE32Header);
} else {
const object::pe32plus_header *PE32PlusHeader = nullptr;
Obj.getPE32PlusHeader(PE32PlusHeader);
if (PE32PlusHeader) {
dumpOptionalHeader(PE32PlusHeader);
}
}
dumpHeader();
dumpSections(Obj.getNumberOfSections());
dumpSymbols(Obj.getNumberOfSymbols());
}
template <typename T> void COFFDumper::dumpOptionalHeader(T OptionalHeader) {
YAMLObj.OptionalHeader = COFFYAML::PEHeader();
YAMLObj.OptionalHeader->Header.AddressOfEntryPoint =
OptionalHeader->AddressOfEntryPoint;
YAMLObj.OptionalHeader->Header.AddressOfEntryPoint =
OptionalHeader->AddressOfEntryPoint;
YAMLObj.OptionalHeader->Header.ImageBase = OptionalHeader->ImageBase;
YAMLObj.OptionalHeader->Header.SectionAlignment =
OptionalHeader->SectionAlignment;
YAMLObj.OptionalHeader->Header.FileAlignment = OptionalHeader->FileAlignment;
YAMLObj.OptionalHeader->Header.MajorOperatingSystemVersion =
OptionalHeader->MajorOperatingSystemVersion;
YAMLObj.OptionalHeader->Header.MinorOperatingSystemVersion =
OptionalHeader->MinorOperatingSystemVersion;
YAMLObj.OptionalHeader->Header.MajorImageVersion =
OptionalHeader->MajorImageVersion;
YAMLObj.OptionalHeader->Header.MinorImageVersion =
OptionalHeader->MinorImageVersion;
YAMLObj.OptionalHeader->Header.MajorSubsystemVersion =
OptionalHeader->MajorSubsystemVersion;
YAMLObj.OptionalHeader->Header.MinorSubsystemVersion =
OptionalHeader->MinorSubsystemVersion;
YAMLObj.OptionalHeader->Header.Subsystem = OptionalHeader->Subsystem;
YAMLObj.OptionalHeader->Header.DLLCharacteristics =
OptionalHeader->DLLCharacteristics;
YAMLObj.OptionalHeader->Header.SizeOfStackReserve =
OptionalHeader->SizeOfStackReserve;
YAMLObj.OptionalHeader->Header.SizeOfStackCommit =
OptionalHeader->SizeOfStackCommit;
YAMLObj.OptionalHeader->Header.SizeOfHeapReserve =
OptionalHeader->SizeOfHeapReserve;
YAMLObj.OptionalHeader->Header.SizeOfHeapCommit =
OptionalHeader->SizeOfHeapCommit;
unsigned I = 0;
for (auto &DestDD : YAMLObj.OptionalHeader->DataDirectories) {
const object::data_directory *DD;
if (Obj.getDataDirectory(I++, DD))
continue;
DestDD = COFF::DataDirectory();
DestDD->RelativeVirtualAddress = DD->RelativeVirtualAddress;
DestDD->Size = DD->Size;
}
}
void COFFDumper::dumpHeader() {
YAMLObj.Header.Machine = Obj.getMachine();
YAMLObj.Header.Characteristics = Obj.getCharacteristics();
}
static void
initializeFileAndStringTable(const llvm::object::COFFObjectFile &Obj,
codeview::StringsAndChecksumsRef &SC) {
ExitOnError Err("Invalid .debug$S section!");
// Iterate all .debug$S sections looking for the checksums and string table.
// Exit as soon as both sections are found.
for (const auto &S : Obj.sections()) {
if (SC.hasStrings() && SC.hasChecksums())
break;
StringRef SectionName;
S.getName(SectionName);
ArrayRef<uint8_t> sectionData;
if (SectionName != ".debug$S")
continue;
const object::coff_section *COFFSection = Obj.getCOFFSection(S);
Obj.getSectionContents(COFFSection, sectionData);
BinaryStreamReader Reader(sectionData, support::little);
uint32_t Magic;
Err(Reader.readInteger(Magic));
assert(Magic == COFF::DEBUG_SECTION_MAGIC && "Invalid .debug$S section!");
codeview::DebugSubsectionArray Subsections;
Err(Reader.readArray(Subsections, Reader.bytesRemaining()));
SC.initialize(Subsections);
}
}
void COFFDumper::dumpSections(unsigned NumSections) {
std::vector<COFFYAML::Section> &YAMLSections = YAMLObj.Sections;
codeview::StringsAndChecksumsRef SC;
initializeFileAndStringTable(Obj, SC);
for (const auto &ObjSection : Obj.sections()) {
const object::coff_section *COFFSection = Obj.getCOFFSection(ObjSection);
COFFYAML::Section NewYAMLSection;
ObjSection.getName(NewYAMLSection.Name);
NewYAMLSection.Header.Characteristics = COFFSection->Characteristics;
NewYAMLSection.Header.VirtualAddress = ObjSection.getAddress();
NewYAMLSection.Header.VirtualSize = COFFSection->VirtualSize;
NewYAMLSection.Header.NumberOfLineNumbers =
COFFSection->NumberOfLinenumbers;
NewYAMLSection.Header.NumberOfRelocations =
COFFSection->NumberOfRelocations;
NewYAMLSection.Header.PointerToLineNumbers =
COFFSection->PointerToLinenumbers;
NewYAMLSection.Header.PointerToRawData = COFFSection->PointerToRawData;
NewYAMLSection.Header.PointerToRelocations =
COFFSection->PointerToRelocations;
NewYAMLSection.Header.SizeOfRawData = COFFSection->SizeOfRawData;
NewYAMLSection.Alignment = ObjSection.getAlignment();
assert(NewYAMLSection.Alignment <= 8192);
ArrayRef<uint8_t> sectionData;
if (!ObjSection.isBSS())
Obj.getSectionContents(COFFSection, sectionData);
NewYAMLSection.SectionData = yaml::BinaryRef(sectionData);
if (NewYAMLSection.Name == ".debug$S")
NewYAMLSection.DebugS = CodeViewYAML::fromDebugS(sectionData, SC);
else if (NewYAMLSection.Name == ".debug$T")
NewYAMLSection.DebugT = CodeViewYAML::fromDebugT(sectionData);
else if (NewYAMLSection.Name == ".debug$H")
NewYAMLSection.DebugH = CodeViewYAML::fromDebugH(sectionData);
std::vector<COFFYAML::Relocation> Relocations;
for (const auto &Reloc : ObjSection.relocations()) {
const object::coff_relocation *reloc = Obj.getCOFFRelocation(Reloc);
COFFYAML::Relocation Rel;
object::symbol_iterator Sym = Reloc.getSymbol();
Expected<StringRef> SymbolNameOrErr = Sym->getName();
if (!SymbolNameOrErr) {
std::string Buf;
raw_string_ostream OS(Buf);
logAllUnhandledErrors(SymbolNameOrErr.takeError(), OS, "");
OS.flush();
report_fatal_error(Buf);
}
Rel.SymbolName = *SymbolNameOrErr;
Rel.VirtualAddress = reloc->VirtualAddress;
Rel.Type = reloc->Type;
Relocations.push_back(Rel);
}
NewYAMLSection.Relocations = Relocations;
YAMLSections.push_back(NewYAMLSection);
}
}
static void
dumpFunctionDefinition(COFFYAML::Symbol *Sym,
const object::coff_aux_function_definition *ObjFD) {
COFF::AuxiliaryFunctionDefinition YAMLFD;
YAMLFD.TagIndex = ObjFD->TagIndex;
YAMLFD.TotalSize = ObjFD->TotalSize;
YAMLFD.PointerToLinenumber = ObjFD->PointerToLinenumber;
YAMLFD.PointerToNextFunction = ObjFD->PointerToNextFunction;
Sym->FunctionDefinition = YAMLFD;
}
static void
dumpbfAndEfLineInfo(COFFYAML::Symbol *Sym,
const object::coff_aux_bf_and_ef_symbol *ObjBES) {
COFF::AuxiliarybfAndefSymbol YAMLAAS;
YAMLAAS.Linenumber = ObjBES->Linenumber;
YAMLAAS.PointerToNextFunction = ObjBES->PointerToNextFunction;
Sym->bfAndefSymbol = YAMLAAS;
}
static void dumpWeakExternal(COFFYAML::Symbol *Sym,
const object::coff_aux_weak_external *ObjWE) {
COFF::AuxiliaryWeakExternal YAMLWE;
YAMLWE.TagIndex = ObjWE->TagIndex;
YAMLWE.Characteristics = ObjWE->Characteristics;
Sym->WeakExternal = YAMLWE;
}
static void
dumpSectionDefinition(COFFYAML::Symbol *Sym,
const object::coff_aux_section_definition *ObjSD,
bool IsBigObj) {
COFF::AuxiliarySectionDefinition YAMLASD;
int32_t AuxNumber = ObjSD->getNumber(IsBigObj);
YAMLASD.Length = ObjSD->Length;
YAMLASD.NumberOfRelocations = ObjSD->NumberOfRelocations;
YAMLASD.NumberOfLinenumbers = ObjSD->NumberOfLinenumbers;
YAMLASD.CheckSum = ObjSD->CheckSum;
YAMLASD.Number = AuxNumber;
YAMLASD.Selection = ObjSD->Selection;
Sym->SectionDefinition = YAMLASD;
}
static void
dumpCLRTokenDefinition(COFFYAML::Symbol *Sym,
const object::coff_aux_clr_token *ObjCLRToken) {
COFF::AuxiliaryCLRToken YAMLCLRToken;
YAMLCLRToken.AuxType = ObjCLRToken->AuxType;
YAMLCLRToken.SymbolTableIndex = ObjCLRToken->SymbolTableIndex;
Sym->CLRToken = YAMLCLRToken;
}
void COFFDumper::dumpSymbols(unsigned NumSymbols) {
std::vector<COFFYAML::Symbol> &Symbols = YAMLObj.Symbols;
for (const auto &S : Obj.symbols()) {
object::COFFSymbolRef Symbol = Obj.getCOFFSymbol(S);
COFFYAML::Symbol Sym;
Obj.getSymbolName(Symbol, Sym.Name);
Sym.SimpleType = COFF::SymbolBaseType(Symbol.getBaseType());
Sym.ComplexType = COFF::SymbolComplexType(Symbol.getComplexType());
Sym.Header.StorageClass = Symbol.getStorageClass();
Sym.Header.Value = Symbol.getValue();
Sym.Header.SectionNumber = Symbol.getSectionNumber();
Sym.Header.NumberOfAuxSymbols = Symbol.getNumberOfAuxSymbols();
if (Symbol.getNumberOfAuxSymbols() > 0) {
ArrayRef<uint8_t> AuxData = Obj.getSymbolAuxData(Symbol);
if (Symbol.isFunctionDefinition()) {
// This symbol represents a function definition.
assert(Symbol.getNumberOfAuxSymbols() == 1 &&
"Expected a single aux symbol to describe this function!");
const object::coff_aux_function_definition *ObjFD =
reinterpret_cast<const object::coff_aux_function_definition *>(
AuxData.data());
dumpFunctionDefinition(&Sym, ObjFD);
} else if (Symbol.isFunctionLineInfo()) {
// This symbol describes function line number information.
assert(Symbol.getNumberOfAuxSymbols() == 1 &&
"Expected a single aux symbol to describe this function!");
const object::coff_aux_bf_and_ef_symbol *ObjBES =
reinterpret_cast<const object::coff_aux_bf_and_ef_symbol *>(
AuxData.data());
dumpbfAndEfLineInfo(&Sym, ObjBES);
} else if (Symbol.isAnyUndefined()) {
// This symbol represents a weak external definition.
assert(Symbol.getNumberOfAuxSymbols() == 1 &&
"Expected a single aux symbol to describe this weak symbol!");
const object::coff_aux_weak_external *ObjWE =
reinterpret_cast<const object::coff_aux_weak_external *>(
AuxData.data());
dumpWeakExternal(&Sym, ObjWE);
} else if (Symbol.isFileRecord()) {
// This symbol represents a file record.
Sym.File = StringRef(reinterpret_cast<const char *>(AuxData.data()),
Symbol.getNumberOfAuxSymbols() *
Obj.getSymbolTableEntrySize())
.rtrim(StringRef("\0", /*length=*/1));
} else if (Symbol.isSectionDefinition()) {
// This symbol represents a section definition.
assert(Symbol.getNumberOfAuxSymbols() == 1 &&
"Expected a single aux symbol to describe this section!");
const object::coff_aux_section_definition *ObjSD =
reinterpret_cast<const object::coff_aux_section_definition *>(
AuxData.data());
dumpSectionDefinition(&Sym, ObjSD, Symbol.isBigObj());
} else if (Symbol.isCLRToken()) {
// This symbol represents a CLR token definition.
assert(Symbol.getNumberOfAuxSymbols() == 1 &&
"Expected a single aux symbol to describe this CLR Token!");
const object::coff_aux_clr_token *ObjCLRToken =
reinterpret_cast<const object::coff_aux_clr_token *>(
AuxData.data());
dumpCLRTokenDefinition(&Sym, ObjCLRToken);
} else {
llvm_unreachable("Unhandled auxiliary symbol!");
}
}
Symbols.push_back(Sym);
}
}
COFFYAML::Object &COFFDumper::getYAMLObj() {
return YAMLObj;
}
std::error_code coff2yaml(raw_ostream &Out, const object::COFFObjectFile &Obj) {
COFFDumper Dumper(Obj);
yaml::Output Yout(Out);
Yout << Dumper.getYAMLObj();
return std::error_code();
}

View File

@@ -0,0 +1,357 @@
//===------ dwarf2yaml.cpp - obj2yaml conversion tool -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "Error.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/ObjectYAML/DWARFYAML.h"
#include <algorithm>
using namespace llvm;
void dumpInitialLength(DataExtractor &Data, uint32_t &Offset,
DWARFYAML::InitialLength &InitialLength) {
InitialLength.TotalLength = Data.getU32(&Offset);
if (InitialLength.isDWARF64())
InitialLength.TotalLength64 = Data.getU64(&Offset);
}
void dumpDebugAbbrev(DWARFContext &DCtx, DWARFYAML::Data &Y) {
auto AbbrevSetPtr = DCtx.getDebugAbbrev();
if (AbbrevSetPtr) {
for (auto AbbrvDeclSet : *AbbrevSetPtr) {
for (auto AbbrvDecl : AbbrvDeclSet.second) {
DWARFYAML::Abbrev Abbrv;
Abbrv.Code = AbbrvDecl.getCode();
Abbrv.Tag = AbbrvDecl.getTag();
Abbrv.Children = AbbrvDecl.hasChildren() ? dwarf::DW_CHILDREN_yes
: dwarf::DW_CHILDREN_no;
for (auto Attribute : AbbrvDecl.attributes()) {
DWARFYAML::AttributeAbbrev AttAbrv;
AttAbrv.Attribute = Attribute.Attr;
AttAbrv.Form = Attribute.Form;
if (AttAbrv.Form == dwarf::DW_FORM_implicit_const)
AttAbrv.Value = Attribute.getImplicitConstValue();
Abbrv.Attributes.push_back(AttAbrv);
}
Y.AbbrevDecls.push_back(Abbrv);
}
}
}
}
void dumpDebugStrings(DWARFContext &DCtx, DWARFYAML::Data &Y) {
StringRef RemainingTable = DCtx.getDWARFObj().getStringSection();
while (RemainingTable.size() > 0) {
auto SymbolPair = RemainingTable.split('\0');
RemainingTable = SymbolPair.second;
Y.DebugStrings.push_back(SymbolPair.first);
}
}
void dumpDebugARanges(DWARFContext &DCtx, DWARFYAML::Data &Y) {
DataExtractor ArangesData(DCtx.getDWARFObj().getARangeSection(),
DCtx.isLittleEndian(), 0);
uint32_t Offset = 0;
DWARFDebugArangeSet Set;
while (Set.extract(ArangesData, &Offset)) {
DWARFYAML::ARange Range;
Range.Length.setLength(Set.getHeader().Length);
Range.Version = Set.getHeader().Version;
Range.CuOffset = Set.getHeader().CuOffset;
Range.AddrSize = Set.getHeader().AddrSize;
Range.SegSize = Set.getHeader().SegSize;
for (auto Descriptor : Set.descriptors()) {
DWARFYAML::ARangeDescriptor Desc;
Desc.Address = Descriptor.Address;
Desc.Length = Descriptor.Length;
Range.Descriptors.push_back(Desc);
}
Y.ARanges.push_back(Range);
}
}
void dumpPubSection(DWARFContext &DCtx, DWARFYAML::PubSection &Y,
StringRef Section) {
DataExtractor PubSectionData(Section, DCtx.isLittleEndian(), 0);
uint32_t Offset = 0;
dumpInitialLength(PubSectionData, Offset, Y.Length);
Y.Version = PubSectionData.getU16(&Offset);
Y.UnitOffset = PubSectionData.getU32(&Offset);
Y.UnitSize = PubSectionData.getU32(&Offset);
while (Offset < Y.Length.getLength()) {
DWARFYAML::PubEntry NewEntry;
NewEntry.DieOffset = PubSectionData.getU32(&Offset);
if (Y.IsGNUStyle)
NewEntry.Descriptor = PubSectionData.getU8(&Offset);
NewEntry.Name = PubSectionData.getCStr(&Offset);
Y.Entries.push_back(NewEntry);
}
}
void dumpDebugPubSections(DWARFContext &DCtx, DWARFYAML::Data &Y) {
const DWARFObject &D = DCtx.getDWARFObj();
Y.PubNames.IsGNUStyle = false;
dumpPubSection(DCtx, Y.PubNames, D.getPubNamesSection());
Y.PubTypes.IsGNUStyle = false;
dumpPubSection(DCtx, Y.PubTypes, D.getPubTypesSection());
Y.GNUPubNames.IsGNUStyle = true;
dumpPubSection(DCtx, Y.GNUPubNames, D.getGnuPubNamesSection());
Y.GNUPubTypes.IsGNUStyle = true;
dumpPubSection(DCtx, Y.GNUPubTypes, D.getGnuPubTypesSection());
}
void dumpDebugInfo(DWARFContext &DCtx, DWARFYAML::Data &Y) {
for (const auto &CU : DCtx.compile_units()) {
DWARFYAML::Unit NewUnit;
NewUnit.Length.setLength(CU->getLength());
NewUnit.Version = CU->getVersion();
if(NewUnit.Version >= 5)
NewUnit.Type = (dwarf::UnitType)CU->getUnitType();
NewUnit.AbbrOffset = CU->getAbbreviations()->getOffset();
NewUnit.AddrSize = CU->getAddressByteSize();
for (auto DIE : CU->dies()) {
DWARFYAML::Entry NewEntry;
DataExtractor EntryData = CU->getDebugInfoExtractor();
uint32_t offset = DIE.getOffset();
assert(EntryData.isValidOffset(offset) && "Invalid DIE Offset");
if (!EntryData.isValidOffset(offset))
continue;
NewEntry.AbbrCode = EntryData.getULEB128(&offset);
auto AbbrevDecl = DIE.getAbbreviationDeclarationPtr();
if (AbbrevDecl) {
for (const auto &AttrSpec : AbbrevDecl->attributes()) {
DWARFYAML::FormValue NewValue;
NewValue.Value = 0xDEADBEEFDEADBEEF;
DWARFDie DIEWrapper(CU.get(), &DIE);
auto FormValue = DIEWrapper.find(AttrSpec.Attr);
if (!FormValue)
return;
auto Form = FormValue.getValue().getForm();
bool indirect = false;
do {
indirect = false;
switch (Form) {
case dwarf::DW_FORM_addr:
case dwarf::DW_FORM_GNU_addr_index:
if (auto Val = FormValue.getValue().getAsAddress())
NewValue.Value = Val.getValue();
break;
case dwarf::DW_FORM_ref_addr:
case dwarf::DW_FORM_ref1:
case dwarf::DW_FORM_ref2:
case dwarf::DW_FORM_ref4:
case dwarf::DW_FORM_ref8:
case dwarf::DW_FORM_ref_udata:
case dwarf::DW_FORM_ref_sig8:
if (auto Val = FormValue.getValue().getAsReferenceUVal())
NewValue.Value = Val.getValue();
break;
case dwarf::DW_FORM_exprloc:
case dwarf::DW_FORM_block:
case dwarf::DW_FORM_block1:
case dwarf::DW_FORM_block2:
case dwarf::DW_FORM_block4:
if (auto Val = FormValue.getValue().getAsBlock()) {
auto BlockData = Val.getValue();
std::copy(BlockData.begin(), BlockData.end(),
std::back_inserter(NewValue.BlockData));
}
NewValue.Value = NewValue.BlockData.size();
break;
case dwarf::DW_FORM_data1:
case dwarf::DW_FORM_flag:
case dwarf::DW_FORM_data2:
case dwarf::DW_FORM_data4:
case dwarf::DW_FORM_data8:
case dwarf::DW_FORM_sdata:
case dwarf::DW_FORM_udata:
case dwarf::DW_FORM_ref_sup4:
case dwarf::DW_FORM_ref_sup8:
if (auto Val = FormValue.getValue().getAsUnsignedConstant())
NewValue.Value = Val.getValue();
break;
case dwarf::DW_FORM_string:
if (auto Val = FormValue.getValue().getAsCString())
NewValue.CStr = Val.getValue();
break;
case dwarf::DW_FORM_indirect:
indirect = true;
if (auto Val = FormValue.getValue().getAsUnsignedConstant()) {
NewValue.Value = Val.getValue();
NewEntry.Values.push_back(NewValue);
Form = static_cast<dwarf::Form>(Val.getValue());
}
break;
case dwarf::DW_FORM_strp:
case dwarf::DW_FORM_sec_offset:
case dwarf::DW_FORM_GNU_ref_alt:
case dwarf::DW_FORM_GNU_strp_alt:
case dwarf::DW_FORM_line_strp:
case dwarf::DW_FORM_strp_sup:
case dwarf::DW_FORM_GNU_str_index:
case dwarf::DW_FORM_strx:
if (auto Val = FormValue.getValue().getAsCStringOffset())
NewValue.Value = Val.getValue();
break;
case dwarf::DW_FORM_flag_present:
NewValue.Value = 1;
break;
default:
break;
}
} while (indirect);
NewEntry.Values.push_back(NewValue);
}
}
NewUnit.Entries.push_back(NewEntry);
}
Y.CompileUnits.push_back(NewUnit);
}
}
bool dumpFileEntry(DataExtractor &Data, uint32_t &Offset,
DWARFYAML::File &File) {
File.Name = Data.getCStr(&Offset);
if (File.Name.empty())
return false;
File.DirIdx = Data.getULEB128(&Offset);
File.ModTime = Data.getULEB128(&Offset);
File.Length = Data.getULEB128(&Offset);
return true;
}
void dumpDebugLines(DWARFContext &DCtx, DWARFYAML::Data &Y) {
for (const auto &CU : DCtx.compile_units()) {
auto CUDIE = CU->getUnitDIE();
if (!CUDIE)
continue;
if (auto StmtOffset =
dwarf::toSectionOffset(CUDIE.find(dwarf::DW_AT_stmt_list))) {
DWARFYAML::LineTable DebugLines;
DataExtractor LineData(DCtx.getDWARFObj().getLineSection().Data,
DCtx.isLittleEndian(), CU->getAddressByteSize());
uint32_t Offset = *StmtOffset;
dumpInitialLength(LineData, Offset, DebugLines.Length);
uint64_t LineTableLength = DebugLines.Length.getLength();
uint64_t SizeOfPrologueLength = DebugLines.Length.isDWARF64() ? 8 : 4;
DebugLines.Version = LineData.getU16(&Offset);
DebugLines.PrologueLength =
LineData.getUnsigned(&Offset, SizeOfPrologueLength);
const uint64_t EndPrologue = DebugLines.PrologueLength + Offset;
DebugLines.MinInstLength = LineData.getU8(&Offset);
if (DebugLines.Version >= 4)
DebugLines.MaxOpsPerInst = LineData.getU8(&Offset);
DebugLines.DefaultIsStmt = LineData.getU8(&Offset);
DebugLines.LineBase = LineData.getU8(&Offset);
DebugLines.LineRange = LineData.getU8(&Offset);
DebugLines.OpcodeBase = LineData.getU8(&Offset);
DebugLines.StandardOpcodeLengths.reserve(DebugLines.OpcodeBase - 1);
for (uint8_t i = 1; i < DebugLines.OpcodeBase; ++i)
DebugLines.StandardOpcodeLengths.push_back(LineData.getU8(&Offset));
while (Offset < EndPrologue) {
StringRef Dir = LineData.getCStr(&Offset);
if (!Dir.empty())
DebugLines.IncludeDirs.push_back(Dir);
else
break;
}
while (Offset < EndPrologue) {
DWARFYAML::File TmpFile;
if (dumpFileEntry(LineData, Offset, TmpFile))
DebugLines.Files.push_back(TmpFile);
else
break;
}
const uint64_t LineEnd =
LineTableLength + *StmtOffset + SizeOfPrologueLength;
while (Offset < LineEnd) {
DWARFYAML::LineTableOpcode NewOp;
NewOp.Opcode = (dwarf::LineNumberOps)LineData.getU8(&Offset);
if (NewOp.Opcode == 0) {
auto StartExt = Offset;
NewOp.ExtLen = LineData.getULEB128(&Offset);
NewOp.SubOpcode =
(dwarf::LineNumberExtendedOps)LineData.getU8(&Offset);
switch (NewOp.SubOpcode) {
case dwarf::DW_LNE_set_address:
case dwarf::DW_LNE_set_discriminator:
NewOp.Data = LineData.getAddress(&Offset);
break;
case dwarf::DW_LNE_define_file:
dumpFileEntry(LineData, Offset, NewOp.FileEntry);
break;
case dwarf::DW_LNE_end_sequence:
break;
default:
while (Offset < StartExt + NewOp.ExtLen)
NewOp.UnknownOpcodeData.push_back(LineData.getU8(&Offset));
}
} else if (NewOp.Opcode < DebugLines.OpcodeBase) {
switch (NewOp.Opcode) {
case dwarf::DW_LNS_copy:
case dwarf::DW_LNS_negate_stmt:
case dwarf::DW_LNS_set_basic_block:
case dwarf::DW_LNS_const_add_pc:
case dwarf::DW_LNS_set_prologue_end:
case dwarf::DW_LNS_set_epilogue_begin:
break;
case dwarf::DW_LNS_advance_pc:
case dwarf::DW_LNS_set_file:
case dwarf::DW_LNS_set_column:
case dwarf::DW_LNS_set_isa:
NewOp.Data = LineData.getULEB128(&Offset);
break;
case dwarf::DW_LNS_advance_line:
NewOp.SData = LineData.getSLEB128(&Offset);
break;
case dwarf::DW_LNS_fixed_advance_pc:
NewOp.Data = LineData.getU16(&Offset);
break;
default:
for (uint8_t i = 0;
i < DebugLines.StandardOpcodeLengths[NewOp.Opcode - 1]; ++i)
NewOp.StandardOpcodeData.push_back(LineData.getULEB128(&Offset));
}
}
DebugLines.Opcodes.push_back(NewOp);
}
Y.DebugLines.push_back(DebugLines);
}
}
}
std::error_code dwarf2yaml(DWARFContext &DCtx, DWARFYAML::Data &Y) {
dumpDebugAbbrev(DCtx, Y);
dumpDebugStrings(DCtx, Y);
dumpDebugARanges(DCtx, Y);
dumpDebugPubSections(DCtx, Y);
dumpDebugInfo(DCtx, Y);
dumpDebugLines(DCtx, Y);
return obj2yaml_error::success;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,76 @@
//===------ utils/obj2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "Error.h"
#include "obj2yaml.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
using namespace llvm;
using namespace llvm::object;
static std::error_code dumpObject(const ObjectFile &Obj) {
if (Obj.isCOFF())
return coff2yaml(outs(), cast<COFFObjectFile>(Obj));
if (Obj.isELF())
return elf2yaml(outs(), Obj);
if (Obj.isWasm())
return wasm2yaml(outs(), cast<WasmObjectFile>(Obj));
return obj2yaml_error::unsupported_obj_file_format;
}
static Error dumpInput(StringRef File) {
Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(File);
if (!BinaryOrErr)
return BinaryOrErr.takeError();
Binary &Binary = *BinaryOrErr.get().getBinary();
// Universal MachO is not a subclass of ObjectFile, so it needs to be handled
// here with the other binary types.
if (Binary.isMachO() || Binary.isMachOUniversalBinary())
return errorCodeToError(macho2yaml(outs(), Binary));
// TODO: If this is an archive, then burst it and dump each entry
if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary))
return errorCodeToError(dumpObject(*Obj));
return Error::success();
}
static void reportError(StringRef Input, Error Err) {
if (Input == "-")
Input = "<stdin>";
std::string ErrMsg;
raw_string_ostream OS(ErrMsg);
logAllUnhandledErrors(std::move(Err), OS, "");
OS.flush();
errs() << "Error reading file: " << Input << ": " << ErrMsg;
errs().flush();
}
cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<input file>"),
cl::init("-"));
int main(int argc, char *argv[]) {
cl::ParseCommandLineOptions(argc, argv);
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
if (Error Err = dumpInput(InputFilename)) {
reportError(InputFilename, std::move(Err));
return 1;
}
return 0;
}

40
external/llvm/tools/obj2yaml/obj2yaml.h vendored Normal file
View File

@@ -0,0 +1,40 @@
//===------ utils/obj2yaml.hpp - obj2yaml conversion tool -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
// This file declares some helper routines, and also the format-specific
// writers. To add a new format, add the declaration here, and, in a separate
// source file, implement it.
//===----------------------------------------------------------------------===//
#ifndef LLVM_TOOLS_OBJ2YAML_OBJ2YAML_H
#define LLVM_TOOLS_OBJ2YAML_OBJ2YAML_H
#include "llvm/Object/COFF.h"
#include "llvm/Object/Wasm.h"
#include "llvm/Support/raw_ostream.h"
#include <system_error>
std::error_code coff2yaml(llvm::raw_ostream &Out,
const llvm::object::COFFObjectFile &Obj);
std::error_code elf2yaml(llvm::raw_ostream &Out,
const llvm::object::ObjectFile &Obj);
std::error_code macho2yaml(llvm::raw_ostream &Out,
const llvm::object::Binary &Obj);
std::error_code wasm2yaml(llvm::raw_ostream &Out,
const llvm::object::WasmObjectFile &Obj);
// Forward decls for dwarf2yaml
namespace llvm {
class DWARFContext;
namespace DWARFYAML {
struct Data;
}
}
std::error_code dwarf2yaml(llvm::DWARFContext &DCtx, llvm::DWARFYAML::Data &Y);
#endif

View File

@@ -0,0 +1,287 @@
//===------ utils/wasm2yaml.cpp - obj2yaml conversion tool ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "obj2yaml.h"
#include "llvm/Object/COFF.h"
#include "llvm/ObjectYAML/WasmYAML.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/YAMLTraits.h"
using namespace llvm;
using object::WasmSection;
namespace {
class WasmDumper {
const object::WasmObjectFile &Obj;
public:
WasmDumper(const object::WasmObjectFile &O) : Obj(O) {}
ErrorOr<WasmYAML::Object *> dump();
std::unique_ptr<WasmYAML::CustomSection>
dumpCustomSection(const WasmSection &WasmSec);
};
} // namespace
static WasmYAML::Table make_table(const wasm::WasmTable &Table) {
WasmYAML::Table T;
T.ElemType = Table.ElemType;
T.TableLimits.Flags = Table.Limits.Flags;
T.TableLimits.Initial = Table.Limits.Initial;
T.TableLimits.Maximum = Table.Limits.Maximum;
return T;
}
static WasmYAML::Limits make_limits(const wasm::WasmLimits &Limits) {
WasmYAML::Limits L;
L.Flags = Limits.Flags;
L.Initial = Limits.Initial;
L.Maximum = Limits.Maximum;
return L;
}
std::unique_ptr<WasmYAML::CustomSection> WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
std::unique_ptr<WasmYAML::CustomSection> CustomSec;
if (WasmSec.Name == "name") {
std::unique_ptr<WasmYAML::NameSection> NameSec = make_unique<WasmYAML::NameSection>();
for (const object::SymbolRef& Sym: Obj.symbols()) {
const object::WasmSymbol Symbol = Obj.getWasmSymbol(Sym);
if (Symbol.Type != object::WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME)
continue;
WasmYAML::NameEntry NameEntry;
NameEntry.Name = Symbol.Name;
NameEntry.Index = Sym.getValue();
NameSec->FunctionNames.push_back(NameEntry);
}
CustomSec = std::move(NameSec);
} else if (WasmSec.Name == "linking") {
std::unique_ptr<WasmYAML::LinkingSection> LinkingSec = make_unique<WasmYAML::LinkingSection>();
size_t Index = 0;
for (const object::WasmSegment &Segment : Obj.dataSegments()) {
if (!Segment.Data.Name.empty()) {
WasmYAML::SegmentInfo SegmentInfo;
SegmentInfo.Name = Segment.Data.Name;
SegmentInfo.Index = Index;
SegmentInfo.Alignment = Segment.Data.Alignment;
SegmentInfo.Flags = Segment.Data.Flags;
LinkingSec->SegmentInfos.push_back(SegmentInfo);
}
Index++;
}
for (const object::SymbolRef& Sym: Obj.symbols()) {
const object::WasmSymbol Symbol = Obj.getWasmSymbol(Sym);
if (Symbol.Flags != 0) {
WasmYAML::SymbolInfo Info{Symbol.Name, Symbol.Flags};
LinkingSec->SymbolInfos.emplace_back(Info);
}
}
LinkingSec->DataSize = Obj.linkingData().DataSize;
for (const wasm::WasmInitFunc &Func : Obj.linkingData().InitFunctions) {
WasmYAML::InitFunction F{Func.Priority, Func.FunctionIndex};
LinkingSec->InitFunctions.emplace_back(F);
}
CustomSec = std::move(LinkingSec);
} else {
CustomSec = make_unique<WasmYAML::CustomSection>(WasmSec.Name);
}
CustomSec->Payload = yaml::BinaryRef(WasmSec.Content);
return CustomSec;
}
ErrorOr<WasmYAML::Object *> WasmDumper::dump() {
auto Y = make_unique<WasmYAML::Object>();
// Dump header
Y->Header.Version = Obj.getHeader().Version;
// Dump sections
for (const auto &Sec : Obj.sections()) {
const WasmSection &WasmSec = Obj.getWasmSection(Sec);
std::unique_ptr<WasmYAML::Section> S;
switch (WasmSec.Type) {
case wasm::WASM_SEC_CUSTOM: {
if (WasmSec.Name.startswith("reloc.")) {
// Relocations are attached the sections they apply to rather than
// being represented as a custom section in the YAML output.
continue;
}
S = dumpCustomSection(WasmSec);
break;
}
case wasm::WASM_SEC_TYPE: {
auto TypeSec = make_unique<WasmYAML::TypeSection>();
uint32_t Index = 0;
for (const auto &FunctionSig : Obj.types()) {
WasmYAML::Signature Sig;
Sig.Index = Index++;
Sig.ReturnType = FunctionSig.ReturnType;
for (const auto &ParamType : FunctionSig.ParamTypes)
Sig.ParamTypes.push_back(ParamType);
TypeSec->Signatures.push_back(Sig);
}
S = std::move(TypeSec);
break;
}
case wasm::WASM_SEC_IMPORT: {
auto ImportSec = make_unique<WasmYAML::ImportSection>();
for (auto &Import : Obj.imports()) {
WasmYAML::Import Im;
Im.Module = Import.Module;
Im.Field = Import.Field;
Im.Kind = Import.Kind;
switch (Im.Kind) {
case wasm::WASM_EXTERNAL_FUNCTION:
Im.SigIndex = Import.SigIndex;
break;
case wasm::WASM_EXTERNAL_GLOBAL:
Im.GlobalImport.Type = Import.Global.Type;
Im.GlobalImport.Mutable = Import.Global.Mutable;
break;
case wasm::WASM_EXTERNAL_TABLE:
Im.TableImport = make_table(Import.Table);
break;
case wasm::WASM_EXTERNAL_MEMORY:
Im.Memory = make_limits(Import.Memory);
break;
}
ImportSec->Imports.push_back(Im);
}
S = std::move(ImportSec);
break;
}
case wasm::WASM_SEC_FUNCTION: {
auto FuncSec = make_unique<WasmYAML::FunctionSection>();
for (const auto &Func : Obj.functionTypes()) {
FuncSec->FunctionTypes.push_back(Func);
}
S = std::move(FuncSec);
break;
}
case wasm::WASM_SEC_TABLE: {
auto TableSec = make_unique<WasmYAML::TableSection>();
for (const wasm::WasmTable &Table : Obj.tables()) {
TableSec->Tables.push_back(make_table(Table));
}
S = std::move(TableSec);
break;
}
case wasm::WASM_SEC_MEMORY: {
auto MemorySec = make_unique<WasmYAML::MemorySection>();
for (const wasm::WasmLimits &Memory : Obj.memories()) {
MemorySec->Memories.push_back(make_limits(Memory));
}
S = std::move(MemorySec);
break;
}
case wasm::WASM_SEC_GLOBAL: {
auto GlobalSec = make_unique<WasmYAML::GlobalSection>();
for (auto &Global : Obj.globals()) {
WasmYAML::Global G;
G.Type = Global.Type;
G.Mutable = Global.Mutable;
G.InitExpr = Global.InitExpr;
GlobalSec->Globals.push_back(G);
}
S = std::move(GlobalSec);
break;
}
case wasm::WASM_SEC_START: {
auto StartSec = make_unique<WasmYAML::StartSection>();
StartSec->StartFunction = Obj.startFunction();
S = std::move(StartSec);
break;
}
case wasm::WASM_SEC_EXPORT: {
auto ExportSec = make_unique<WasmYAML::ExportSection>();
for (auto &Export : Obj.exports()) {
WasmYAML::Export Ex;
Ex.Name = Export.Name;
Ex.Kind = Export.Kind;
Ex.Index = Export.Index;
ExportSec->Exports.push_back(Ex);
}
S = std::move(ExportSec);
break;
}
case wasm::WASM_SEC_ELEM: {
auto ElemSec = make_unique<WasmYAML::ElemSection>();
for (auto &Segment : Obj.elements()) {
WasmYAML::ElemSegment Seg;
Seg.TableIndex = Segment.TableIndex;
Seg.Offset = Segment.Offset;
for (auto &Func : Segment.Functions) {
Seg.Functions.push_back(Func);
}
ElemSec->Segments.push_back(Seg);
}
S = std::move(ElemSec);
break;
}
case wasm::WASM_SEC_CODE: {
auto CodeSec = make_unique<WasmYAML::CodeSection>();
for (auto &Func : Obj.functions()) {
WasmYAML::Function Function;
for (auto &Local : Func.Locals) {
WasmYAML::LocalDecl LocalDecl;
LocalDecl.Type = Local.Type;
LocalDecl.Count = Local.Count;
Function.Locals.push_back(LocalDecl);
}
Function.Body = yaml::BinaryRef(Func.Body);
CodeSec->Functions.push_back(Function);
}
S = std::move(CodeSec);
break;
}
case wasm::WASM_SEC_DATA: {
auto DataSec = make_unique<WasmYAML::DataSection>();
for (const object::WasmSegment &Segment : Obj.dataSegments()) {
WasmYAML::DataSegment Seg;
Seg.SectionOffset = Segment.SectionOffset;
Seg.MemoryIndex = Segment.Data.MemoryIndex;
Seg.Offset = Segment.Data.Offset;
Seg.Content = yaml::BinaryRef(Segment.Data.Content);
DataSec->Segments.push_back(Seg);
}
S = std::move(DataSec);
break;
}
default:
llvm_unreachable("Unknown section type");
break;
}
for (const wasm::WasmRelocation &Reloc: WasmSec.Relocations) {
WasmYAML::Relocation R;
R.Type = Reloc.Type;
R.Index = Reloc.Index;
R.Offset = Reloc.Offset;
R.Addend = Reloc.Addend;
S->Relocations.push_back(R);
}
Y->Sections.push_back(std::move(S));
}
return Y.release();
}
std::error_code wasm2yaml(raw_ostream &Out, const object::WasmObjectFile &Obj) {
WasmDumper Dumper(Obj);
ErrorOr<WasmYAML::Object *> YAMLOrErr = Dumper.dump();
if (std::error_code EC = YAMLOrErr.getError())
return EC;
std::unique_ptr<WasmYAML::Object> YAML(YAMLOrErr.get());
yaml::Output Yout(Out);
Yout << *YAML;
return std::error_code();
}