blob: 2a70cec09d9aacce77ecfbb799e79f371235a0b1 [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 Espindolada177ce2013-04-20 02:55:00 +000016using namespace llvm;
Marshall Clowc57b8882012-06-19 18:02:35 +000017
Rafael Espindola2bbe3782013-05-17 22:58:42 +000018namespace {
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 StringRef getHexString(ArrayRef<uint8_t> Data);
27 std::vector<std::string> Strings;
28
29public:
30 COFFDumper(const object::COFFObjectFile &Obj);
31 COFFYAML::Object &getYAMLObj();
Marshall Clowc57b8882012-06-19 18:02:35 +000032};
33
Marshall Clowc57b8882012-06-19 18:02:35 +000034}
35
Rafael Espindola2bbe3782013-05-17 22:58:42 +000036static void check(error_code ec) {
37 if (ec)
38 report_fatal_error(ec.message());
Marshall Clowc57b8882012-06-19 18:02:35 +000039}
40
Rafael Espindola2bbe3782013-05-17 22:58:42 +000041COFFDumper::COFFDumper(const object::COFFObjectFile &Obj) : Obj(Obj) {
42 const object::coff_file_header *Header;
43 check(Obj.getHeader(Header));
44 dumpHeader(Header);
45 dumpSections(Header->NumberOfSections);
46 dumpSymbols(Header->NumberOfSymbols);
Marshall Clowc57b8882012-06-19 18:02:35 +000047}
48
Rafael Espindola2bbe3782013-05-17 22:58:42 +000049void COFFDumper::dumpHeader(const object::coff_file_header *Header) {
50 YAMLObj.Header.Machine = Header->Machine;
51 YAMLObj.Header.Characteristics = Header->Characteristics;
Marshall Clowc57b8882012-06-19 18:02:35 +000052}
53
Rafael Espindola2bbe3782013-05-17 22:58:42 +000054void COFFDumper::dumpSections(unsigned NumSections) {
55 std::vector<COFFYAML::Section> &Sections = YAMLObj.Sections;
Rafael Espindolada177ce2013-04-20 02:55:00 +000056 error_code ec;
Rafael Espindolada177ce2013-04-20 02:55:00 +000057 for (object::section_iterator iter = Obj.begin_sections();
58 iter != Obj.end_sections(); iter.increment(ec)) {
Rafael Espindola2bbe3782013-05-17 22:58:42 +000059 check(ec);
60 const object::coff_section *Sect = Obj.getCOFFSection(iter);
61 COFFYAML::Section Sec;
62 Sec.Name = Sect->Name; // FIXME: check the null termination!
63 uint32_t Characteristics = Sect->Characteristics;
64 Sec.Header.Characteristics = Characteristics;
65 Sec.Alignment = 1 << (((Characteristics >> 20) & 0xf) - 1);
Marshall Clowc57b8882012-06-19 18:02:35 +000066
Rafael Espindolada177ce2013-04-20 02:55:00 +000067 ArrayRef<uint8_t> sectionData;
Rafael Espindola2bbe3782013-05-17 22:58:42 +000068 Obj.getSectionContents(Sect, sectionData);
69 Sec.SectionData = getHexString(sectionData);
70
71 std::vector<COFF::relocation> Relocations;
Rafael Espindolada177ce2013-04-20 02:55:00 +000072 for (object::relocation_iterator rIter = iter->begin_relocations();
Marshall Clowc57b8882012-06-19 18:02:35 +000073 rIter != iter->end_relocations(); rIter.increment(ec)) {
Rafael Espindolada177ce2013-04-20 02:55:00 +000074 const object::coff_relocation *reloc = Obj.getCOFFRelocation(rIter);
Rafael Espindola2bbe3782013-05-17 22:58:42 +000075 COFF::relocation Rel;
76 Rel.VirtualAddress = reloc->VirtualAddress;
77 Rel.SymbolTableIndex = reloc->SymbolTableIndex;
78 Rel.Type = reloc->Type;
79 Relocations.push_back(Rel);
80 }
81 Sec.Relocations = Relocations;
82 Sections.push_back(Sec);
Rafael Espindolada177ce2013-04-20 02:55:00 +000083 }
Marshall Clowc57b8882012-06-19 18:02:35 +000084}
85
Rafael Espindola2bbe3782013-05-17 22:58:42 +000086void COFFDumper::dumpSymbols(unsigned NumSymbols) {
Rafael Espindolada177ce2013-04-20 02:55:00 +000087 error_code ec;
Rafael Espindola2bbe3782013-05-17 22:58:42 +000088 std::vector<COFFYAML::Symbol> &Symbols = YAMLObj.Symbols;
Rafael Espindolada177ce2013-04-20 02:55:00 +000089 for (object::symbol_iterator iter = Obj.begin_symbols();
90 iter != Obj.end_symbols(); iter.increment(ec)) {
Rafael Espindola2bbe3782013-05-17 22:58:42 +000091 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 = getHexString(Obj.getSymbolAuxData(Symbol));
102 Symbols.push_back(Sym);
Marshall Clowc57b8882012-06-19 18:02:35 +0000103 }
Marshall Clowc57b8882012-06-19 18:02:35 +0000104}
105
Rafael Espindola2bbe3782013-05-17 22:58:42 +0000106StringRef COFFDumper::getHexString(ArrayRef<uint8_t> Data) {
107 std::string S;
108 for (ArrayRef<uint8_t>::iterator I = Data.begin(), E = Data.end(); I != E;
109 ++I) {
110 uint8_t Byte = *I;
111 S.push_back(hexdigit(Byte >> 4));
112 S.push_back(hexdigit(Byte & 0xf));
113 }
114 Strings.push_back(S);
115 return Strings.back();
116}
Marshall Clowc57b8882012-06-19 18:02:35 +0000117
Rafael Espindola2bbe3782013-05-17 22:58:42 +0000118COFFYAML::Object &COFFDumper::getYAMLObj() {
119 return YAMLObj;
120}
121
122error_code coff2yaml(raw_ostream &Out, MemoryBuffer *Buff) {
Rafael Espindolada177ce2013-04-20 02:55:00 +0000123 error_code ec;
Rafael Espindola2bbe3782013-05-17 22:58:42 +0000124 object::COFFObjectFile Obj(Buff, ec);
125 check(ec);
126 COFFDumper Dumper(Obj);
Rafael Espindolada177ce2013-04-20 02:55:00 +0000127
Rafael Espindola2bbe3782013-05-17 22:58:42 +0000128 yaml::Output Yout(Out);
129 Yout << Dumper.getYAMLObj();
Rafael Espindolada177ce2013-04-20 02:55:00 +0000130
Rafael Espindola2bbe3782013-05-17 22:58:42 +0000131 return object::object_error::success;
Marshall Clowc57b8882012-06-19 18:02:35 +0000132}