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 error_code ec; 55 for (object::section_iterator iter = Obj.begin_sections(); 56 iter != Obj.end_sections(); iter.increment(ec)) { 57 check(ec); 58 const object::coff_section *Sect = Obj.getCOFFSection(iter); 59 COFFYAML::Section Sec; 60 Sec.Name = Sect->Name; // FIXME: check the null termination! 61 uint32_t Characteristics = Sect->Characteristics; 62 Sec.Header.Characteristics = Characteristics; 63 Sec.Alignment = 1 << (((Characteristics >> 20) & 0xf) - 1); 64 65 ArrayRef<uint8_t> sectionData; 66 Obj.getSectionContents(Sect, sectionData); 67 Sec.SectionData = object::yaml::BinaryRef(sectionData); 68 69 std::vector<COFFYAML::Relocation> Relocations; 70 for (object::relocation_iterator rIter = iter->begin_relocations(); 71 rIter != iter->end_relocations(); rIter.increment(ec)) { 72 const object::coff_relocation *reloc = Obj.getCOFFRelocation(rIter); 73 COFFYAML::Relocation Rel; 74 object::symbol_iterator Sym = rIter->getSymbol(); 75 StringRef Name; 76 Sym->getName(Rel.SymbolName); 77 Rel.VirtualAddress = reloc->VirtualAddress; 78 Rel.Type = reloc->Type; 79 Relocations.push_back(Rel); 80 } 81 Sec.Relocations = Relocations; 82 Sections.push_back(Sec); 83 } 84 } 85 86 void COFFDumper::dumpSymbols(unsigned NumSymbols) { 87 error_code ec; 88 std::vector<COFFYAML::Symbol> &Symbols = YAMLObj.Symbols; 89 for (object::symbol_iterator iter = Obj.begin_symbols(); 90 iter != Obj.end_symbols(); iter.increment(ec)) { 91 check(ec); 92 const object::coff_symbol *Symbol = Obj.getCOFFSymbol(iter); 93 COFFYAML::Symbol Sym; 94 Obj.getSymbolName(Symbol, Sym.Name); 95 Sym.SimpleType = COFF::SymbolBaseType(Symbol->getBaseType()); 96 Sym.ComplexType = COFF::SymbolComplexType(Symbol->getComplexType()); 97 Sym.Header.StorageClass = Symbol->StorageClass; 98 Sym.Header.Value = Symbol->Value; 99 Sym.Header.SectionNumber = Symbol->SectionNumber; 100 Sym.Header.NumberOfAuxSymbols = Symbol->NumberOfAuxSymbols; 101 Sym.AuxiliaryData = object::yaml::BinaryRef(Obj.getSymbolAuxData(Symbol)); 102 Symbols.push_back(Sym); 103 } 104 } 105 106 COFFYAML::Object &COFFDumper::getYAMLObj() { 107 return YAMLObj; 108 } 109 110 error_code coff2yaml(raw_ostream &Out, MemoryBuffer *Buff) { 111 error_code ec; 112 object::COFFObjectFile Obj(Buff, ec); 113 check(ec); 114 COFFDumper Dumper(Obj); 115 116 yaml::Output Yout(Out); 117 Yout << Dumper.getYAMLObj(); 118 119 return object::object_error::success; 120 } 121