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