diff options
Diffstat (limited to 'tools/obj2yaml/coff2yaml.cpp')
-rw-r--r-- | tools/obj2yaml/coff2yaml.cpp | 161 |
1 files changed, 108 insertions, 53 deletions
diff --git a/tools/obj2yaml/coff2yaml.cpp b/tools/obj2yaml/coff2yaml.cpp index fed4533..5baa644 100644 --- a/tools/obj2yaml/coff2yaml.cpp +++ b/tools/obj2yaml/coff2yaml.cpp @@ -20,7 +20,9 @@ namespace { class COFFDumper { const object::COFFObjectFile &Obj; COFFYAML::Object YAMLObj; - void dumpHeader(const object::coff_file_header *Header); + template <typename T> + void dumpOptionalHeader(T OptionalHeader); + void dumpHeader(); void dumpSections(unsigned numSections); void dumpSymbols(unsigned numSymbols); @@ -31,40 +33,90 @@ public: } -static void check(std::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.getCOFFHeader(Header)); - dumpHeader(Header); - dumpSections(Header->NumberOfSections); - dumpSymbols(Header->NumberOfSymbols); +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(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<COFFYAML::Section> &Sections = YAMLObj.Sections; - for (const auto &Section : Obj.sections()) { - const object::coff_section *Sect = Obj.getCOFFSection(Section); - 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<COFFYAML::Section> &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<uint8_t> sectionData; - Obj.getSectionContents(Sect, sectionData); - Sec.SectionData = yaml::BinaryRef(sectionData); + if (!ObjSection.isBSS()) + Obj.getSectionContents(COFFSection, sectionData); + NewYAMLSection.SectionData = yaml::BinaryRef(sectionData); std::vector<COFFYAML::Relocation> Relocations; - for (const auto &Reloc : Section.relocations()) { + for (const auto &Reloc : ObjSection.relocations()) { const object::coff_relocation *reloc = Obj.getCOFFRelocation(Reloc); COFFYAML::Relocation Rel; object::symbol_iterator Sym = Reloc.getSymbol(); @@ -73,8 +125,8 @@ void COFFDumper::dumpSections(unsigned NumSections) { Rel.Type = reloc->Type; Relocations.push_back(Rel); } - Sec.Relocations = Relocations; - Sections.push_back(Sec); + NewYAMLSection.Relocations = Relocations; + YAMLSections.push_back(NewYAMLSection); } } @@ -111,13 +163,15 @@ static void dumpWeakExternal(COFFYAML::Symbol *Sym, static void dumpSectionDefinition(COFFYAML::Symbol *Sym, - const object::coff_aux_section_definition *ObjSD) { + 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 = ObjSD->Number; + YAMLASD.Number = AuxNumber; YAMLASD.Selection = ObjSD->Selection; Sym->SectionDefinition = YAMLASD; @@ -136,63 +190,64 @@ dumpCLRTokenDefinition(COFFYAML::Symbol *Sym, void COFFDumper::dumpSymbols(unsigned NumSymbols) { std::vector<COFFYAML::Symbol> &Symbols = YAMLObj.Symbols; for (const auto &S : Obj.symbols()) { - const object::coff_symbol *Symbol = Obj.getCOFFSymbol(S); + 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; - - if (Symbol->NumberOfAuxSymbols > 0) { + 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()) { + if (Symbol.isFunctionDefinition()) { // This symbol represents a function definition. - assert(Symbol->NumberOfAuxSymbols == 1 && + 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()) { + } else if (Symbol.isFunctionLineInfo()) { // This symbol describes function line number information. - assert(Symbol->NumberOfAuxSymbols == 1 && - "Exepected a single aux symbol to describe this section!"); + 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->isWeakExternal()) { + } else if (Symbol.isAnyUndefined()) { // This symbol represents a weak external definition. - assert(Symbol->NumberOfAuxSymbols == 1 && - "Exepected a single aux symbol to describe this section!"); + 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()) { + } else if (Symbol.isFileRecord()) { // This symbol represents a file record. Sym.File = StringRef(reinterpret_cast<const char *>(AuxData.data()), - Symbol->NumberOfAuxSymbols * COFF::SymbolSize) + Symbol.getNumberOfAuxSymbols() * + Obj.getSymbolTableEntrySize()) .rtrim(StringRef("\0", /*length=*/1)); - } else if (Symbol->isSectionDefinition()) { + } else if (Symbol.isSectionDefinition()) { // This symbol represents a section definition. - assert(Symbol->NumberOfAuxSymbols == 1 && + 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); - } else if (Symbol->isCLRToken()) { + dumpSectionDefinition(&Sym, ObjSD, Symbol.isBigObj()); + } else if (Symbol.isCLRToken()) { // This symbol represents a CLR token definition. - assert(Symbol->NumberOfAuxSymbols == 1 && - "Expected a single aux symbol to describe this CLR Token"); + 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 *>( |