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 
1987a02909SRafael Espindola namespace yaml {  // generic yaml-writing specific routines
2087a02909SRafael Espindola 
2187a02909SRafael Espindola unsigned char printable(unsigned char Ch) {
2287a02909SRafael Espindola   return Ch >= ' ' && Ch <= '~' ? Ch : '.';
2387a02909SRafael Espindola }
2487a02909SRafael Espindola 
2587a02909SRafael Espindola llvm::raw_ostream &writeHexStream(llvm::raw_ostream &Out,
2687a02909SRafael Espindola                                      const llvm::ArrayRef<uint8_t> arr) {
2787a02909SRafael Espindola   const char *hex = "0123456789ABCDEF";
2887a02909SRafael Espindola   Out << " !hex \"";
2987a02909SRafael Espindola 
3087a02909SRafael Espindola   typedef llvm::ArrayRef<uint8_t>::const_iterator iter_t;
3187a02909SRafael Espindola   const iter_t end = arr.end();
3287a02909SRafael Espindola   for (iter_t iter = arr.begin(); iter != end; ++iter)
3387a02909SRafael Espindola     Out << hex[(*iter >> 4) & 0x0F] << hex[(*iter & 0x0F)];
3487a02909SRafael Espindola 
3587a02909SRafael Espindola   Out << "\" # |";
3687a02909SRafael Espindola   for (iter_t iter = arr.begin(); iter != end; ++iter)
3787a02909SRafael Espindola     Out << printable(*iter);
38*741c00dfSChandler Carruth   Out << "|\n";
3987a02909SRafael Espindola 
4087a02909SRafael Espindola   return Out;
4187a02909SRafael Espindola   }
4287a02909SRafael Espindola 
4387a02909SRafael Espindola llvm::raw_ostream &writeHexNumber(llvm::raw_ostream &Out, unsigned long long N) {
4487a02909SRafael Espindola   if (N >= 10)
4587a02909SRafael Espindola     Out << "0x";
4687a02909SRafael Espindola   Out.write_hex(N);
4787a02909SRafael Espindola   return Out;
4887a02909SRafael Espindola }
4987a02909SRafael Espindola 
5087a02909SRafael Espindola }
5187a02909SRafael Espindola 
5287a02909SRafael Espindola 
5387a02909SRafael Espindola using namespace llvm;
5487a02909SRafael Espindola enum ObjectFileType { coff };
5587a02909SRafael Espindola 
5687a02909SRafael Espindola cl::opt<ObjectFileType> InputFormat(
5787a02909SRafael Espindola   cl::desc("Choose input format"),
5887a02909SRafael Espindola     cl::values(
5987a02909SRafael Espindola       clEnumVal(coff, "process COFF object files"),
6087a02909SRafael Espindola     clEnumValEnd));
6187a02909SRafael Espindola 
6287a02909SRafael Espindola cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
6387a02909SRafael Espindola 
6487a02909SRafael Espindola int main(int argc, char * argv[]) {
6587a02909SRafael Espindola   cl::ParseCommandLineOptions(argc, argv);
6687a02909SRafael Espindola   sys::PrintStackTraceOnErrorSignal();
6787a02909SRafael Espindola   PrettyStackTraceProgram X(argc, argv);
6887a02909SRafael Espindola   llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
6987a02909SRafael Espindola 
7087a02909SRafael Espindola // Process the input file
7187a02909SRafael Espindola   OwningPtr<MemoryBuffer> buf;
7287a02909SRafael Espindola 
7387a02909SRafael Espindola // TODO: If this is an archive, then burst it and dump each entry
7487a02909SRafael Espindola   if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, buf))
7587a02909SRafael Espindola     llvm::errs() << "Error: '" << ec.message() << "' opening file '"
76*741c00dfSChandler Carruth               << InputFilename << "'\n";
7787a02909SRafael Espindola   else {
7887a02909SRafael Espindola     ec = coff2yaml(llvm::outs(), buf.take());
7987a02909SRafael Espindola     if (ec)
80*741c00dfSChandler Carruth       llvm::errs() << "Error: " << ec.message() << " dumping COFF file\n";
8187a02909SRafael Espindola   }
8287a02909SRafael Espindola 
8387a02909SRafael Espindola   return 0;
8487a02909SRafael Espindola }
85