X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fobj2yaml%2Fcoff2yaml.cpp;h=f675bfe4e618e16210ac1e70576522fb3a56ed28;hb=7ecd92d75cda45668b6b5fdbcdd2142826514e66;hp=0bb3e24c3cad375c5b14a60abe316404ee8302c3;hpb=e67c9c341f18a463f5c5e43f4da520c68df76e9a;p=oota-llvm.git diff --git a/tools/obj2yaml/coff2yaml.cpp b/tools/obj2yaml/coff2yaml.cpp index 0bb3e24c3ca..f675bfe4e61 100644 --- a/tools/obj2yaml/coff2yaml.cpp +++ b/tools/obj2yaml/coff2yaml.cpp @@ -9,12 +9,10 @@ #include "obj2yaml.h" #include "llvm/Object/COFF.h" -#include "llvm/Object/COFFYaml.h" +#include "llvm/Object/COFFYAML.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/YAMLTraits.h" -#include - using namespace llvm; namespace { @@ -22,11 +20,11 @@ namespace { class COFFDumper { const object::COFFObjectFile &Obj; COFFYAML::Object YAMLObj; - void dumpHeader(const object::coff_file_header *Header); + template + void dumpOptionalHeader(T OptionalHeader); + void dumpHeader(); void dumpSections(unsigned numSections); void dumpSymbols(unsigned numSymbols); - StringRef getHexString(ArrayRef Data); - std::list Strings; public: COFFDumper(const object::COFFObjectFile &Obj); @@ -35,100 +33,246 @@ public: } -static void check(error_code ec) { - if (ec) - report_fatal_error(ec.message()); +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()); } -COFFDumper::COFFDumper(const object::COFFObjectFile &Obj) : Obj(Obj) { - const object::coff_file_header *Header; - check(Obj.getHeader(Header)); - dumpHeader(Header); - dumpSections(Header->NumberOfSections); - dumpSymbols(Header->NumberOfSymbols); +template 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(const object::coff_file_header *Header) { - YAMLObj.Header.Machine = Header->Machine; - YAMLObj.Header.Characteristics = Header->Characteristics; +void COFFDumper::dumpHeader() { + YAMLObj.Header.Machine = Obj.getMachine(); + YAMLObj.Header.Characteristics = Obj.getCharacteristics(); } void COFFDumper::dumpSections(unsigned NumSections) { - std::vector &Sections = YAMLObj.Sections; - error_code ec; - for (object::section_iterator iter = Obj.begin_sections(); - iter != Obj.end_sections(); iter.increment(ec)) { - check(ec); - const object::coff_section *Sect = Obj.getCOFFSection(iter); - COFFYAML::Section Sec; - Sec.Name = Sect->Name; // FIXME: check the null termination! - uint32_t Characteristics = Sect->Characteristics; - Sec.Header.Characteristics = Characteristics; - Sec.Alignment = 1 << (((Characteristics >> 20) & 0xf) - 1); + std::vector &YAMLSections = YAMLObj.Sections; + 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.Alignment = ObjSection.getAlignment(); ArrayRef sectionData; - Obj.getSectionContents(Sect, sectionData); - Sec.SectionData = getHexString(sectionData); - - std::vector Relocations; - for (object::relocation_iterator rIter = iter->begin_relocations(); - rIter != iter->end_relocations(); rIter.increment(ec)) { - const object::coff_relocation *reloc = Obj.getCOFFRelocation(rIter); - COFF::relocation Rel; + if (!ObjSection.isBSS()) + Obj.getSectionContents(COFFSection, sectionData); + NewYAMLSection.SectionData = yaml::BinaryRef(sectionData); + + std::vector Relocations; + for (const auto &Reloc : ObjSection.relocations()) { + const object::coff_relocation *reloc = Obj.getCOFFRelocation(Reloc); + COFFYAML::Relocation Rel; + object::symbol_iterator Sym = Reloc.getSymbol(); + ErrorOr SymbolNameOrErr = Sym->getName(); + if (std::error_code EC = SymbolNameOrErr.getError()) + report_fatal_error(EC.message()); + Rel.SymbolName = *SymbolNameOrErr; Rel.VirtualAddress = reloc->VirtualAddress; - Rel.SymbolTableIndex = reloc->SymbolTableIndex; Rel.Type = reloc->Type; Relocations.push_back(Rel); } - Sec.Relocations = Relocations; - Sections.push_back(Sec); + 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) { - error_code ec; std::vector &Symbols = YAMLObj.Symbols; - for (object::symbol_iterator iter = Obj.begin_symbols(); - iter != Obj.end_symbols(); iter.increment(ec)) { - check(ec); - const object::coff_symbol *Symbol = Obj.getCOFFSymbol(iter); + 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->StorageClass; - Sym.Header.Value = Symbol->Value; - Sym.Header.SectionNumber = Symbol->SectionNumber; - Sym.Header.NumberOfAuxSymbols = Symbol->NumberOfAuxSymbols; - Sym.AuxiliaryData = getHexString(Obj.getSymbolAuxData(Symbol)); - Symbols.push_back(Sym); - } -} + 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 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( + 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( + 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!"); -StringRef COFFDumper::getHexString(ArrayRef Data) { - std::string S; - for (ArrayRef::iterator I = Data.begin(), E = Data.end(); I != E; - ++I) { - uint8_t Byte = *I; - S.push_back(hexdigit(Byte >> 4)); - S.push_back(hexdigit(Byte & 0xf)); + const object::coff_aux_weak_external *ObjWE = + reinterpret_cast( + AuxData.data()); + dumpWeakExternal(&Sym, ObjWE); + } else if (Symbol.isFileRecord()) { + // This symbol represents a file record. + Sym.File = StringRef(reinterpret_cast(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( + 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( + AuxData.data()); + dumpCLRTokenDefinition(&Sym, ObjCLRToken); + } else { + llvm_unreachable("Unhandled auxiliary symbol!"); + } + } + Symbols.push_back(Sym); } - Strings.push_back(S); - return Strings.back(); } COFFYAML::Object &COFFDumper::getYAMLObj() { return YAMLObj; } -error_code coff2yaml(raw_ostream &Out, MemoryBuffer *Buff) { - error_code ec; - object::COFFObjectFile Obj(Buff, ec); - check(ec); +std::error_code coff2yaml(raw_ostream &Out, const object::COFFObjectFile &Obj) { COFFDumper Dumper(Obj); yaml::Output Yout(Out); Yout << Dumper.getYAMLObj(); - return object::object_error::success; + return std::error_code(); }