1 //===------ utils/obj2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "obj2yaml.h" 11 #include "llvm/Object/COFF.h" 12 #include "llvm/Object/COFFYAML.h" 13 #include "llvm/Support/ErrorHandling.h" 14 #include "llvm/Support/YAMLTraits.h" 15 16 using namespace llvm; 17 18 namespace { 19 20 class COFFDumper { 21 const object::COFFObjectFile &Obj; 22 COFFYAML::Object YAMLObj; 23 void dumpHeader(const object::coff_file_header *Header); 24 void dumpSections(unsigned numSections); 25 void dumpSymbols(unsigned numSymbols); 26 27 public: 28 COFFDumper(const object::COFFObjectFile &Obj); 29 COFFYAML::Object &getYAMLObj(); 30 }; 31 32 } 33 34 static void check(error_code ec) { 35 if (ec) 36 report_fatal_error(ec.message()); 37 } 38 39 COFFDumper::COFFDumper(const object::COFFObjectFile &Obj) : Obj(Obj) { 40 const object::coff_file_header *Header; 41 check(Obj.getCOFFHeader(Header)); 42 dumpHeader(Header); 43 dumpSections(Header->NumberOfSections); 44 dumpSymbols(Header->NumberOfSymbols); 45 } 46 47 void COFFDumper::dumpHeader(const object::coff_file_header *Header) { 48 YAMLObj.Header.Machine = Header->Machine; 49 YAMLObj.Header.Characteristics = Header->Characteristics; 50 } 51 52 void COFFDumper::dumpSections(unsigned NumSections) { 53 std::vector<COFFYAML::Section> &Sections = YAMLObj.Sections; 54 for (object::section_iterator iter = Obj.section_begin(); 55 iter != Obj.section_end(); ++iter) { 56 const object::coff_section *Sect = Obj.getCOFFSection(iter); 57 COFFYAML::Section Sec; 58 Sec.Name = Sect->Name; // FIXME: check the null termination! 59 uint32_t Characteristics = Sect->Characteristics; 60 Sec.Header.Characteristics = Characteristics; 61 Sec.Alignment = 1 << (((Characteristics >> 20) & 0xf) - 1); 62 63 ArrayRef<uint8_t> sectionData; 64 Obj.getSectionContents(Sect, sectionData); 65 Sec.SectionData = object::yaml::BinaryRef(sectionData); 66 67 std::vector<COFFYAML::Relocation> Relocations; 68 for (object::relocation_iterator rIter = iter->relocation_begin(); 69 rIter != iter->relocation_end(); ++rIter) { 70 const object::coff_relocation *reloc = Obj.getCOFFRelocation(rIter); 71 COFFYAML::Relocation Rel; 72 object::symbol_iterator Sym = rIter->getSymbol(); 73 Sym->getName(Rel.SymbolName); 74 Rel.VirtualAddress = reloc->VirtualAddress; 75 Rel.Type = reloc->Type; 76 Relocations.push_back(Rel); 77 } 78 Sec.Relocations = Relocations; 79 Sections.push_back(Sec); 80 } 81 } 82 83 void COFFDumper::dumpSymbols(unsigned NumSymbols) { 84 std::vector<COFFYAML::Symbol> &Symbols = YAMLObj.Symbols; 85 for (object::symbol_iterator iter = Obj.symbol_begin(); 86 iter != Obj.symbol_end(); ++iter) { 87 const object::coff_symbol *Symbol = Obj.getCOFFSymbol(iter); 88 COFFYAML::Symbol Sym; 89 Obj.getSymbolName(Symbol, Sym.Name); 90 Sym.SimpleType = COFF::SymbolBaseType(Symbol->getBaseType()); 91 Sym.ComplexType = COFF::SymbolComplexType(Symbol->getComplexType()); 92 Sym.Header.StorageClass = Symbol->StorageClass; 93 Sym.Header.Value = Symbol->Value; 94 Sym.Header.SectionNumber = Symbol->SectionNumber; 95 Sym.Header.NumberOfAuxSymbols = Symbol->NumberOfAuxSymbols; 96 Sym.AuxiliaryData = object::yaml::BinaryRef(Obj.getSymbolAuxData(Symbol)); 97 Symbols.push_back(Sym); 98 } 99 } 100 101 COFFYAML::Object &COFFDumper::getYAMLObj() { 102 return YAMLObj; 103 } 104 105 error_code coff2yaml(raw_ostream &Out, MemoryBuffer *Buff) { 106 error_code ec; 107 object::COFFObjectFile Obj(Buff, ec); 108 check(ec); 109 COFFDumper Dumper(Obj); 110 111 yaml::Output Yout(Out); 112 Yout << Dumper.getYAMLObj(); 113 114 return object::object_error::success; 115 } 116