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