blob: 0bb3e24c3cad375c5b14a60abe316404ee8302c3 [file] [log] [blame]
Marshall Clowc57b8882012-06-19 18:02:35 +00001//===------ 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"
Marshall Clowc57b8882012-06-19 18:02:35 +000011#include "llvm/Object/COFF.h"
Rafael Espindola2bbe3782013-05-17 22:58:42 +000012#include "llvm/Object/COFFYaml.h"
13#include "llvm/Support/ErrorHandling.h"
14#include "llvm/Support/YAMLTraits.h"
Marshall Clowc57b8882012-06-19 18:02:35 +000015
Rafael Espindolae67c9c32013-05-21 18:53:50 +000016#include <list>
17
Rafael Espindolada177ce2013-04-20 02:55:00 +000018using namespace llvm;
Marshall Clowc57b8882012-06-19 18:02:35 +000019
Rafael Espindola2bbe3782013-05-17 22:58:42 +000020namespace {
21
22class COFFDumper {
23 const object::COFFObjectFile &Obj;
24 COFFYAML::Object YAMLObj;
25 void dumpHeader(const object::coff_file_header *Header);
26 void dumpSections(unsigned numSections);
27 void dumpSymbols(unsigned numSymbols);
28 StringRef getHexString(ArrayRef<uint8_t> Data);
Rafael Espindolae67c9c32013-05-21 18:53:50 +000029 std::list<std::string> Strings;
Rafael Espindola2bbe3782013-05-17 22:58:42 +000030
31public:
32 COFFDumper(const object::COFFObjectFile &Obj);
33 COFFYAML::Object &getYAMLObj();
Marshall Clowc57b8882012-06-19 18:02:35 +000034};
35
Marshall Clowc57b8882012-06-19 18:02:35 +000036}
37
Rafael Espindola2bbe3782013-05-17 22:58:42 +000038static void check(error_code ec) {
39 if (ec)
40 report_fatal_error(ec.message());
Marshall Clowc57b8882012-06-19 18:02:35 +000041}
42
Rafael Espindola2bbe3782013-05-17 22:58:42 +000043COFFDumper::COFFDumper(const object::COFFObjectFile &Obj) : Obj(Obj) {
44 const object::coff_file_header *Header;
45 check(Obj.getHeader(Header));
46 dumpHeader(Header);
47 dumpSections(Header->NumberOfSections);
48 dumpSymbols(Header->NumberOfSymbols);
Marshall Clowc57b8882012-06-19 18:02:35 +000049}
50
Rafael Espindola2bbe3782013-05-17 22:58:42 +000051void COFFDumper::dumpHeader(const object::coff_file_header *Header) {
52 YAMLObj.Header.Machine = Header->Machine;
53 YAMLObj.Header.Characteristics = Header->Characteristics;
Marshall Clowc57b8882012-06-19 18:02:35 +000054}
55
Rafael Espindola2bbe3782013-05-17 22:58:42 +000056void COFFDumper::dumpSections(unsigned NumSections) {
57 std::vector<COFFYAML::Section> &Sections = YAMLObj.Sections;
Rafael Espindolada177ce2013-04-20 02:55:00 +000058 error_code ec;
Rafael Espindolada177ce2013-04-20 02:55:00 +000059 for (object::section_iterator iter = Obj.begin_sections();
60 iter != Obj.end_sections(); iter.increment(ec)) {
Rafael Espindola2bbe3782013-05-17 22:58:42 +000061 check(ec);
62 const object::coff_section *Sect = Obj.getCOFFSection(iter);
63 COFFYAML::Section Sec;
64 Sec.Name = Sect->Name; // FIXME: check the null termination!
65 uint32_t Characteristics = Sect->Characteristics;
66 Sec.Header.Characteristics = Characteristics;
67 Sec.Alignment = 1 << (((Characteristics >> 20) & 0xf) - 1);
Marshall Clowc57b8882012-06-19 18:02:35 +000068
Rafael Espindolada177ce2013-04-20 02:55:00 +000069 ArrayRef<uint8_t> sectionData;
Rafael Espindola2bbe3782013-05-17 22:58:42 +000070 Obj.getSectionContents(Sect, sectionData);
71 Sec.SectionData = getHexString(sectionData);
72
73 std::vector<COFF::relocation> Relocations;
Rafael Espindolada177ce2013-04-20 02:55:00 +000074 for (object::relocation_iterator rIter = iter->begin_relocations();
Marshall Clowc57b8882012-06-19 18:02:35 +000075 rIter != iter->end_relocations(); rIter.increment(ec)) {
Rafael Espindolada177ce2013-04-20 02:55:00 +000076 const object::coff_relocation *reloc = Obj.getCOFFRelocation(rIter);
Rafael Espindola2bbe3782013-05-17 22:58:42 +000077 COFF::relocation Rel;
78 Rel.VirtualAddress = reloc->VirtualAddress;
79 Rel.SymbolTableIndex = reloc->SymbolTableIndex;
80 Rel.Type = reloc->Type;
81 Relocations.push_back(Rel);
82 }
83 Sec.Relocations = Relocations;
84 Sections.push_back(Sec);
Rafael Espindolada177ce2013-04-20 02:55:00 +000085 }
Marshall Clowc57b8882012-06-19 18:02:35 +000086}
87
Rafael Espindola2bbe3782013-05-17 22:58:42 +000088void COFFDumper::dumpSymbols(unsigned NumSymbols) {
Rafael Espindolada177ce2013-04-20 02:55:00 +000089 error_code ec;
Rafael Espindola2bbe3782013-05-17 22:58:42 +000090 std::vector<COFFYAML::Symbol> &Symbols = YAMLObj.Symbols;
Rafael Espindolada177ce2013-04-20 02:55:00 +000091 for (object::symbol_iterator iter = Obj.begin_symbols();
92 iter != Obj.end_symbols(); iter.increment(ec)) {
Rafael Espindola2bbe3782013-05-17 22:58:42 +000093 check(ec);
94 const object::coff_symbol *Symbol = Obj.getCOFFSymbol(iter);
95 COFFYAML::Symbol Sym;
96 Obj.getSymbolName(Symbol, Sym.Name);
97 Sym.SimpleType = COFF::SymbolBaseType(Symbol->getBaseType());
98 Sym.ComplexType = COFF::SymbolComplexType(Symbol->getComplexType());
99 Sym.Header.StorageClass = Symbol->StorageClass;
100 Sym.Header.Value = Symbol->Value;
101 Sym.Header.SectionNumber = Symbol->SectionNumber;
102 Sym.Header.NumberOfAuxSymbols = Symbol->NumberOfAuxSymbols;
103 Sym.AuxiliaryData = getHexString(Obj.getSymbolAuxData(Symbol));
104 Symbols.push_back(Sym);
Marshall Clowc57b8882012-06-19 18:02:35 +0000105 }
Marshall Clowc57b8882012-06-19 18:02:35 +0000106}
107
Rafael Espindola2bbe3782013-05-17 22:58:42 +0000108StringRef COFFDumper::getHexString(ArrayRef<uint8_t> Data) {
109 std::string S;
110 for (ArrayRef<uint8_t>::iterator I = Data.begin(), E = Data.end(); I != E;
111 ++I) {
112 uint8_t Byte = *I;
113 S.push_back(hexdigit(Byte >> 4));
114 S.push_back(hexdigit(Byte & 0xf));
115 }
116 Strings.push_back(S);
117 return Strings.back();
118}
Marshall Clowc57b8882012-06-19 18:02:35 +0000119
Rafael Espindola2bbe3782013-05-17 22:58:42 +0000120COFFYAML::Object &COFFDumper::getYAMLObj() {
121 return YAMLObj;
122}
123
124error_code coff2yaml(raw_ostream &Out, MemoryBuffer *Buff) {
Rafael Espindolada177ce2013-04-20 02:55:00 +0000125 error_code ec;
Rafael Espindola2bbe3782013-05-17 22:58:42 +0000126 object::COFFObjectFile Obj(Buff, ec);
127 check(ec);
128 COFFDumper Dumper(Obj);
Rafael Espindolada177ce2013-04-20 02:55:00 +0000129
Rafael Espindola2bbe3782013-05-17 22:58:42 +0000130 yaml::Output Yout(Out);
131 Yout << Dumper.getYAMLObj();
Rafael Espindolada177ce2013-04-20 02:55:00 +0000132
Rafael Espindola2bbe3782013-05-17 22:58:42 +0000133 return object::object_error::success;
Marshall Clowc57b8882012-06-19 18:02:35 +0000134}