1*87a02909SRafael Espindola //===------ utils/obj2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===//
2*87a02909SRafael Espindola //
3*87a02909SRafael Espindola //                     The LLVM Compiler Infrastructure
4*87a02909SRafael Espindola //
5*87a02909SRafael Espindola // This file is distributed under the University of Illinois Open Source
6*87a02909SRafael Espindola // License. See LICENSE.TXT for details.
7*87a02909SRafael Espindola //
8*87a02909SRafael Espindola //===----------------------------------------------------------------------===//
9*87a02909SRafael Espindola 
10*87a02909SRafael Espindola #include "obj2yaml.h"
11*87a02909SRafael Espindola #include "llvm/ADT/OwningPtr.h"
12*87a02909SRafael Espindola #include "llvm/Object/Archive.h"
13*87a02909SRafael Espindola #include "llvm/Object/COFF.h"
14*87a02909SRafael Espindola #include "llvm/Support/CommandLine.h"
15*87a02909SRafael Espindola #include "llvm/Support/ManagedStatic.h"
16*87a02909SRafael Espindola #include "llvm/Support/PrettyStackTrace.h"
17*87a02909SRafael Espindola #include "llvm/Support/Signals.h"
18*87a02909SRafael Espindola 
19*87a02909SRafael Espindola const char endl = '\n';
20*87a02909SRafael Espindola 
21*87a02909SRafael Espindola namespace yaml {  // generic yaml-writing specific routines
22*87a02909SRafael Espindola 
23*87a02909SRafael Espindola unsigned char printable(unsigned char Ch) {
24*87a02909SRafael Espindola   return Ch >= ' ' && Ch <= '~' ? Ch : '.';
25*87a02909SRafael Espindola }
26*87a02909SRafael Espindola 
27*87a02909SRafael Espindola llvm::raw_ostream &writeHexStream(llvm::raw_ostream &Out,
28*87a02909SRafael Espindola                                      const llvm::ArrayRef<uint8_t> arr) {
29*87a02909SRafael Espindola   const char *hex = "0123456789ABCDEF";
30*87a02909SRafael Espindola   Out << " !hex \"";
31*87a02909SRafael Espindola 
32*87a02909SRafael Espindola   typedef llvm::ArrayRef<uint8_t>::const_iterator iter_t;
33*87a02909SRafael Espindola   const iter_t end = arr.end();
34*87a02909SRafael Espindola   for (iter_t iter = arr.begin(); iter != end; ++iter)
35*87a02909SRafael Espindola     Out << hex[(*iter >> 4) & 0x0F] << hex[(*iter & 0x0F)];
36*87a02909SRafael Espindola 
37*87a02909SRafael Espindola   Out << "\" # |";
38*87a02909SRafael Espindola   for (iter_t iter = arr.begin(); iter != end; ++iter)
39*87a02909SRafael Espindola     Out << printable(*iter);
40*87a02909SRafael Espindola   Out << "|" << endl;
41*87a02909SRafael Espindola 
42*87a02909SRafael Espindola   return Out;
43*87a02909SRafael Espindola   }
44*87a02909SRafael Espindola 
45*87a02909SRafael Espindola llvm::raw_ostream &writeHexNumber(llvm::raw_ostream &Out, unsigned long long N) {
46*87a02909SRafael Espindola   if (N >= 10)
47*87a02909SRafael Espindola     Out << "0x";
48*87a02909SRafael Espindola   Out.write_hex(N);
49*87a02909SRafael Espindola   return Out;
50*87a02909SRafael Espindola }
51*87a02909SRafael Espindola 
52*87a02909SRafael Espindola }
53*87a02909SRafael Espindola 
54*87a02909SRafael Espindola 
55*87a02909SRafael Espindola using namespace llvm;
56*87a02909SRafael Espindola enum ObjectFileType { coff };
57*87a02909SRafael Espindola 
58*87a02909SRafael Espindola cl::opt<ObjectFileType> InputFormat(
59*87a02909SRafael Espindola   cl::desc("Choose input format"),
60*87a02909SRafael Espindola     cl::values(
61*87a02909SRafael Espindola       clEnumVal(coff, "process COFF object files"),
62*87a02909SRafael Espindola     clEnumValEnd));
63*87a02909SRafael Espindola 
64*87a02909SRafael Espindola cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
65*87a02909SRafael Espindola 
66*87a02909SRafael Espindola int main(int argc, char * argv[]) {
67*87a02909SRafael Espindola   cl::ParseCommandLineOptions(argc, argv);
68*87a02909SRafael Espindola   sys::PrintStackTraceOnErrorSignal();
69*87a02909SRafael Espindola   PrettyStackTraceProgram X(argc, argv);
70*87a02909SRafael Espindola   llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
71*87a02909SRafael Espindola 
72*87a02909SRafael Espindola // Process the input file
73*87a02909SRafael Espindola   OwningPtr<MemoryBuffer> buf;
74*87a02909SRafael Espindola 
75*87a02909SRafael Espindola // TODO: If this is an archive, then burst it and dump each entry
76*87a02909SRafael Espindola   if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, buf))
77*87a02909SRafael Espindola     llvm::errs() << "Error: '" << ec.message() << "' opening file '"
78*87a02909SRafael Espindola               << InputFilename << "'" << endl;
79*87a02909SRafael Espindola   else {
80*87a02909SRafael Espindola     ec = coff2yaml(llvm::outs(), buf.take());
81*87a02909SRafael Espindola     if (ec)
82*87a02909SRafael Espindola       llvm::errs() << "Error: " << ec.message() << " dumping COFF file" << endl;
83*87a02909SRafael Espindola   }
84*87a02909SRafael Espindola 
85*87a02909SRafael Espindola   return 0;
86*87a02909SRafael Espindola }
87