coff2yaml.cpp revision 5fd5fe0f7bfac0f7973475fcf7a5f8061d983538
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
16using namespace llvm;
17
18namespace {
19
20class 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
27public:
28  COFFDumper(const object::COFFObjectFile &Obj);
29  COFFYAML::Object &getYAMLObj();
30};
31
32}
33
34static void check(error_code ec) {
35  if (ec)
36    report_fatal_error(ec.message());
37}
38
39COFFDumper::COFFDumper(const object::COFFObjectFile &Obj) : Obj(Obj) {
40  const object::coff_file_header *Header;
41  check(Obj.getHeader(Header));
42  dumpHeader(Header);
43  dumpSections(Header->NumberOfSections);
44  dumpSymbols(Header->NumberOfSymbols);
45}
46
47void COFFDumper::dumpHeader(const object::coff_file_header *Header) {
48  YAMLObj.Header.Machine = Header->Machine;
49  YAMLObj.Header.Characteristics = Header->Characteristics;
50}
51
52void 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<COFF::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      COFF::relocation Rel;
74      Rel.VirtualAddress = reloc->VirtualAddress;
75      Rel.SymbolTableIndex = reloc->SymbolTableIndex;
76      Rel.Type = reloc->Type;
77      Relocations.push_back(Rel);
78    }
79    Sec.Relocations = Relocations;
80    Sections.push_back(Sec);
81  }
82}
83
84void COFFDumper::dumpSymbols(unsigned NumSymbols) {
85  error_code ec;
86  std::vector<COFFYAML::Symbol> &Symbols = YAMLObj.Symbols;
87  for (object::symbol_iterator iter = Obj.begin_symbols();
88       iter != Obj.end_symbols(); iter.increment(ec)) {
89    check(ec);
90    const object::coff_symbol *Symbol = Obj.getCOFFSymbol(iter);
91    COFFYAML::Symbol Sym;
92    Obj.getSymbolName(Symbol, Sym.Name);
93    Sym.SimpleType = COFF::SymbolBaseType(Symbol->getBaseType());
94    Sym.ComplexType = COFF::SymbolComplexType(Symbol->getComplexType());
95    Sym.Header.StorageClass = Symbol->StorageClass;
96    Sym.Header.Value = Symbol->Value;
97    Sym.Header.SectionNumber = Symbol->SectionNumber;
98    Sym.Header.NumberOfAuxSymbols = Symbol->NumberOfAuxSymbols;
99    Sym.AuxiliaryData = object::yaml::BinaryRef(Obj.getSymbolAuxData(Symbol));
100    Symbols.push_back(Sym);
101  }
102}
103
104COFFYAML::Object &COFFDumper::getYAMLObj() {
105  return YAMLObj;
106}
107
108error_code coff2yaml(raw_ostream &Out, MemoryBuffer *Buff) {
109  error_code ec;
110  object::COFFObjectFile Obj(Buff, ec);
111  check(ec);
112  COFFDumper Dumper(Obj);
113
114  yaml::Output Yout(Out);
115  Yout << Dumper.getYAMLObj();
116
117  return object::object_error::success;
118}
119