187a02909SRafael Espindola //===------ utils/obj2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===//
287a02909SRafael Espindola //
387a02909SRafael Espindola //                     The LLVM Compiler Infrastructure
487a02909SRafael Espindola //
587a02909SRafael Espindola // This file is distributed under the University of Illinois Open Source
687a02909SRafael Espindola // License. See LICENSE.TXT for details.
787a02909SRafael Espindola //
887a02909SRafael Espindola //===----------------------------------------------------------------------===//
987a02909SRafael Espindola 
1087a02909SRafael Espindola #include "obj2yaml.h"
1187a02909SRafael Espindola #include "llvm/ADT/OwningPtr.h"
1287a02909SRafael Espindola #include "llvm/Object/Archive.h"
1387a02909SRafael Espindola #include "llvm/Object/COFF.h"
1487a02909SRafael Espindola #include "llvm/Support/CommandLine.h"
1587a02909SRafael Espindola #include "llvm/Support/ManagedStatic.h"
1687a02909SRafael Espindola #include "llvm/Support/PrettyStackTrace.h"
1787a02909SRafael Espindola #include "llvm/Support/Signals.h"
1887a02909SRafael Espindola 
19*18192896SChandler Carruth using namespace llvm;
20*18192896SChandler Carruth 
2187a02909SRafael Espindola namespace yaml {  // generic yaml-writing specific routines
2287a02909SRafael Espindola 
2387a02909SRafael Espindola unsigned char printable(unsigned char Ch) {
2487a02909SRafael Espindola   return Ch >= ' ' && Ch <= '~' ? Ch : '.';
2587a02909SRafael Espindola }
2687a02909SRafael Espindola 
27*18192896SChandler Carruth raw_ostream &writeHexStream(raw_ostream &Out, const ArrayRef<uint8_t> arr) {
2887a02909SRafael Espindola   const char *hex = "0123456789ABCDEF";
2987a02909SRafael Espindola   Out << " !hex \"";
3087a02909SRafael Espindola 
31*18192896SChandler Carruth   typedef ArrayRef<uint8_t>::const_iterator iter_t;
3287a02909SRafael Espindola   const iter_t end = arr.end();
3387a02909SRafael Espindola   for (iter_t iter = arr.begin(); iter != end; ++iter)
3487a02909SRafael Espindola     Out << hex[(*iter >> 4) & 0x0F] << hex[(*iter & 0x0F)];
3587a02909SRafael Espindola 
3687a02909SRafael Espindola   Out << "\" # |";
3787a02909SRafael Espindola   for (iter_t iter = arr.begin(); iter != end; ++iter)
3887a02909SRafael Espindola     Out << printable(*iter);
39741c00dfSChandler Carruth   Out << "|\n";
4087a02909SRafael Espindola 
4187a02909SRafael Espindola   return Out;
4287a02909SRafael Espindola }
4387a02909SRafael Espindola 
44*18192896SChandler Carruth raw_ostream &writeHexNumber(raw_ostream &Out, unsigned long long N) {
4587a02909SRafael Espindola   if (N >= 10)
4687a02909SRafael Espindola     Out << "0x";
4787a02909SRafael Espindola   Out.write_hex(N);
4887a02909SRafael Espindola   return Out;
4987a02909SRafael Espindola }
5087a02909SRafael Espindola 
51*18192896SChandler Carruth } // end namespace yaml
5287a02909SRafael Espindola 
53*18192896SChandler Carruth namespace {
54c224e25dSChandler Carruth enum ObjectFileType {
55c224e25dSChandler Carruth   coff
56c224e25dSChandler Carruth };
57*18192896SChandler Carruth }
5887a02909SRafael Espindola 
5987a02909SRafael Espindola cl::opt<ObjectFileType> InputFormat(
6087a02909SRafael Espindola     cl::desc("Choose input format"),
61c224e25dSChandler Carruth     cl::values(clEnumVal(coff, "process COFF object files"), clEnumValEnd));
6287a02909SRafael Espindola 
63c224e25dSChandler Carruth cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<input file>"),
64c224e25dSChandler Carruth                                    cl::init("-"));
6587a02909SRafael Espindola 
6687a02909SRafael Espindola int main(int argc, char *argv[]) {
6787a02909SRafael Espindola   cl::ParseCommandLineOptions(argc, argv);
6887a02909SRafael Espindola   sys::PrintStackTraceOnErrorSignal();
6987a02909SRafael Espindola   PrettyStackTraceProgram X(argc, argv);
7087a02909SRafael Espindola   llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
7187a02909SRafael Espindola 
7287a02909SRafael Espindola   // Process the input file
7387a02909SRafael Espindola   OwningPtr<MemoryBuffer> buf;
7487a02909SRafael Espindola 
7587a02909SRafael Espindola   // TODO: If this is an archive, then burst it and dump each entry
76c224e25dSChandler Carruth   if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, buf)) {
77*18192896SChandler Carruth     errs() << "Error: '" << ec.message() << "' opening file '" << InputFilename
78*18192896SChandler Carruth            << "'\n";
79c224e25dSChandler Carruth   } else {
80*18192896SChandler Carruth     ec = coff2yaml(outs(), buf.take());
8187a02909SRafael Espindola     if (ec)
82*18192896SChandler Carruth       errs() << "Error: " << ec.message() << " dumping COFF file\n";
8387a02909SRafael Espindola   }
8487a02909SRafael Espindola 
8587a02909SRafael Espindola   return 0;
8687a02909SRafael Espindola }
87