Home | History | Annotate | Download | only in obj2yaml
      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