blob: b41edc1e8a01ae0d56f3d98bb4ce018b791c4e24 [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);
Rafael Espindola2bbe3782013-05-17 22:58:42 +000026
27public:
28 COFFDumper(const object::COFFObjectFile &Obj);
29 COFFYAML::Object &getYAMLObj();
Marshall Clowc57b8882012-06-19 18:02:35 +000030};
31
Marshall Clowc57b8882012-06-19 18:02:35 +000032}
33
Rafael Espindola2bbe3782013-05-17 22:58:42 +000034static void check(error_code ec) {
35 if (ec)
36 report_fatal_error(ec.message());
Marshall Clowc57b8882012-06-19 18:02:35 +000037}
38
Rafael Espindola2bbe3782013-05-17 22:58:42 +000039COFFDumper::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);
Marshall Clowc57b8882012-06-19 18:02:35 +000045}
46
Rafael Espindola2bbe3782013-05-17 22:58:42 +000047void COFFDumper::dumpHeader(const object::coff_file_header *Header) {
48 YAMLObj.Header.Machine = Header->Machine;
49 YAMLObj.Header.Characteristics = Header->Characteristics;
Marshall Clowc57b8882012-06-19 18:02:35 +000050}
51
Rafael Espindola2bbe3782013-05-17 22:58:42 +000052void COFFDumper::dumpSections(unsigned NumSections) {
53 std::vector<COFFYAML::Section> &Sections = YAMLObj.Sections;
Rafael Espindolada177ce2013-04-20 02:55:00 +000054 error_code ec;
Rafael Espindolada177ce2013-04-20 02:55:00 +000055 for (object::section_iterator iter = Obj.begin_sections();
56 iter != Obj.end_sections(); iter.increment(ec)) {
Rafael Espindola2bbe3782013-05-17 22:58:42 +000057 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);
Marshall Clowc57b8882012-06-19 18:02:35 +000064
Rafael Espindolada177ce2013-04-20 02:55:00 +000065 ArrayRef<uint8_t> sectionData;
Rafael Espindola2bbe3782013-05-17 22:58:42 +000066 Obj.getSectionContents(Sect, sectionData);
Rafael Espindola05bc4a62013-05-31 20:26:44 +000067 Sec.SectionData = COFFYAML::BinaryRef(sectionData);
Rafael Espindola2bbe3782013-05-17 22:58:42 +000068
69 std::vector<COFF::relocation> Relocations;
Rafael Espindolada177ce2013-04-20 02:55:00 +000070 for (object::relocation_iterator rIter = iter->begin_relocations();
Marshall Clowc57b8882012-06-19 18:02:35 +000071 rIter != iter->end_relocations(); rIter.increment(ec)) {
Rafael Espindolada177ce2013-04-20 02:55:00 +000072 const object::coff_relocation *reloc = Obj.getCOFFRelocation(rIter);
Rafael Espindola2bbe3782013-05-17 22:58:42 +000073 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);
Rafael Espindolada177ce2013-04-20 02:55:00 +000081 }
Marshall Clowc57b8882012-06-19 18:02:35 +000082}
83
Rafael Espindola2bbe3782013-05-17 22:58:42 +000084void COFFDumper::dumpSymbols(unsigned NumSymbols) {
Rafael Espindolada177ce2013-04-20 02:55:00 +000085 error_code ec;
Rafael Espindola2bbe3782013-05-17 22:58:42 +000086 std::vector<COFFYAML::Symbol> &Symbols = YAMLObj.Symbols;
Rafael Espindolada177ce2013-04-20 02:55:00 +000087 for (object::symbol_iterator iter = Obj.begin_symbols();
88 iter != Obj.end_symbols(); iter.increment(ec)) {
Rafael Espindola2bbe3782013-05-17 22:58:42 +000089 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;
Rafael Espindola05bc4a62013-05-31 20:26:44 +000099 Sym.AuxiliaryData = COFFYAML::BinaryRef(Obj.getSymbolAuxData(Symbol));
Rafael Espindola2bbe3782013-05-17 22:58:42 +0000100 Symbols.push_back(Sym);
Marshall Clowc57b8882012-06-19 18:02:35 +0000101 }
Marshall Clowc57b8882012-06-19 18:02:35 +0000102}
103
Rafael Espindola2bbe3782013-05-17 22:58:42 +0000104COFFYAML::Object &COFFDumper::getYAMLObj() {
105 return YAMLObj;
106}
107
108error_code coff2yaml(raw_ostream &Out, MemoryBuffer *Buff) {
Rafael Espindolada177ce2013-04-20 02:55:00 +0000109 error_code ec;
Rafael Espindola2bbe3782013-05-17 22:58:42 +0000110 object::COFFObjectFile Obj(Buff, ec);
111 check(ec);
112 COFFDumper Dumper(Obj);
Rafael Espindolada177ce2013-04-20 02:55:00 +0000113
Rafael Espindola2bbe3782013-05-17 22:58:42 +0000114 yaml::Output Yout(Out);
115 Yout << Dumper.getYAMLObj();
Rafael Espindolada177ce2013-04-20 02:55:00 +0000116
Rafael Espindola2bbe3782013-05-17 22:58:42 +0000117 return object::object_error::success;
Marshall Clowc57b8882012-06-19 18:02:35 +0000118}