1 //===-- ObjDumper.cpp - Base dumper class -----------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// This file implements ObjDumper. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #include "ObjDumper.h" 16 #include "Error.h" 17 #include "llvm-readobj.h" 18 #include "llvm/Object/ObjectFile.h" 19 #include "llvm/Support/Error.h" 20 #include "llvm/Support/ScopedPrinter.h" 21 #include "llvm/Support/raw_ostream.h" 22 23 namespace llvm { 24 25 ObjDumper::ObjDumper(ScopedPrinter &Writer) : W(Writer) {} 26 27 ObjDumper::~ObjDumper() { 28 } 29 30 static void printAsPrintable(raw_ostream &W, const uint8_t *Start, size_t Len) { 31 for (size_t i = 0; i < Len; i++) 32 W << (isPrint(Start[i]) ? static_cast<char>(Start[i]) : '.'); 33 } 34 35 static Expected<object::SectionRef> 36 getSecNameOrIndexAsSecRef(const object::ObjectFile *Obj, StringRef SecName) { 37 char *StrPtr; 38 long SectionIndex = strtol(SecName.data(), &StrPtr, 10); 39 object::SectionRef Section; 40 long SecIndex; 41 if (Obj->isELF()) 42 SecIndex = 0; 43 else 44 SecIndex = 1; 45 for (object::SectionRef SecRef : Obj->sections()) { 46 if (*StrPtr) { 47 StringRef SectionName; 48 49 if (std::error_code E = SecRef.getName(SectionName)) 50 return errorCodeToError(E); 51 52 if (SectionName == SecName) 53 return SecRef; 54 } else if (SecIndex == SectionIndex) 55 return SecRef; 56 57 SecIndex++; 58 } 59 return make_error<StringError>("invalid section reference", 60 object::object_error::parse_failed); 61 } 62 63 void ObjDumper::printSectionAsString(const object::ObjectFile *Obj, 64 StringRef SecName) { 65 Expected<object::SectionRef> SectionRefOrError = 66 getSecNameOrIndexAsSecRef(Obj, SecName); 67 if (!SectionRefOrError) 68 error(std::move(SectionRefOrError)); 69 object::SectionRef Section = *SectionRefOrError; 70 StringRef SectionName; 71 72 if (std::error_code E = Section.getName(SectionName)) 73 error(E); 74 W.startLine() << "String dump of section '" << SectionName << "':\n"; 75 76 StringRef SectionContent; 77 Section.getContents(SectionContent); 78 79 const uint8_t *SecContent = SectionContent.bytes_begin(); 80 const uint8_t *CurrentWord = SecContent; 81 const uint8_t *SecEnd = SectionContent.bytes_end(); 82 83 while (CurrentWord <= SecEnd) { 84 size_t WordSize = strnlen(reinterpret_cast<const char *>(CurrentWord), 85 SecEnd - CurrentWord); 86 if (!WordSize) { 87 CurrentWord++; 88 continue; 89 } 90 W.startLine() << format("[%6tx] ", CurrentWord - SecContent); 91 printAsPrintable(W.startLine(), CurrentWord, WordSize); 92 W.startLine() << '\n'; 93 CurrentWord += WordSize + 1; 94 } 95 } 96 97 void ObjDumper::printSectionAsHex(const object::ObjectFile *Obj, 98 StringRef SecName) { 99 Expected<object::SectionRef> SectionRefOrError = 100 getSecNameOrIndexAsSecRef(Obj, SecName); 101 if (!SectionRefOrError) 102 error(std::move(SectionRefOrError)); 103 object::SectionRef Section = *SectionRefOrError; 104 StringRef SectionName; 105 106 if (std::error_code E = Section.getName(SectionName)) 107 error(E); 108 W.startLine() << "Hex dump of section '" << SectionName << "':\n"; 109 110 StringRef SectionContent; 111 Section.getContents(SectionContent); 112 const uint8_t *SecContent = SectionContent.bytes_begin(); 113 const uint8_t *SecEnd = SecContent + SectionContent.size(); 114 115 for (const uint8_t *SecPtr = SecContent; SecPtr < SecEnd; SecPtr += 16) { 116 const uint8_t *TmpSecPtr = SecPtr; 117 uint8_t i; 118 uint8_t k; 119 120 W.startLine() << format_hex(SecPtr - SecContent, 10); 121 W.startLine() << ' '; 122 for (i = 0; TmpSecPtr < SecEnd && i < 4; ++i) { 123 for (k = 0; TmpSecPtr < SecEnd && k < 4; k++, TmpSecPtr++) { 124 uint8_t Val = *(reinterpret_cast<const uint8_t *>(TmpSecPtr)); 125 W.startLine() << format_hex_no_prefix(Val, 2); 126 } 127 W.startLine() << ' '; 128 } 129 130 // We need to print the correct amount of spaces to match the format. 131 // We are adding the (4 - i) last rows that are 8 characters each. 132 // Then, the (4 - i) spaces that are in between the rows. 133 // Least, if we cut in a middle of a row, we add the remaining characters, 134 // which is (8 - (k * 2)) 135 if (i < 4) 136 W.startLine() << format("%*c", (4 - i) * 8 + (4 - i) + (8 - (k * 2)), 137 ' '); 138 139 TmpSecPtr = SecPtr; 140 for (i = 0; TmpSecPtr + i < SecEnd && i < 16; ++i) 141 W.startLine() << (isPrint(TmpSecPtr[i]) ? static_cast<char>(TmpSecPtr[i]) 142 : '.'); 143 144 W.startLine() << '\n'; 145 } 146 } 147 148 } // namespace llvm 149