diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/Object/COFF.h | 2 | ||||
| -rw-r--r-- | llvm/include/llvm/Object/MachO.h | 2 | ||||
| -rw-r--r-- | llvm/lib/Object/COFFObjectFile.cpp | 15 | ||||
| -rw-r--r-- | llvm/lib/Object/MachOObjectFile.cpp | 21 | ||||
| -rw-r--r-- | llvm/test/tools/llvm-readobj/print-hex.test | 20 | ||||
| -rw-r--r-- | llvm/tools/llvm-readobj/COFFDumper.cpp | 23 | ||||
| -rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 18 | ||||
| -rw-r--r-- | llvm/tools/llvm-readobj/MachODumper.cpp | 21 | ||||
| -rw-r--r-- | llvm/tools/llvm-readobj/ObjDumper.cpp | 42 | ||||
| -rw-r--r-- | llvm/tools/llvm-readobj/ObjDumper.h | 2 | ||||
| -rw-r--r-- | llvm/tools/llvm-readobj/llvm-readobj.cpp | 10 | 
11 files changed, 176 insertions, 0 deletions
diff --git a/llvm/include/llvm/Object/COFF.h b/llvm/include/llvm/Object/COFF.h index 50a73d24c28..df9bf607b12 100644 --- a/llvm/include/llvm/Object/COFF.h +++ b/llvm/include/llvm/Object/COFF.h @@ -965,6 +965,8 @@ public:    std::error_code getDataDirectory(uint32_t index,                                     const data_directory *&Res) const;    std::error_code getSection(int32_t index, const coff_section *&Res) const; +  std::error_code getSection(StringRef SectionName, +                             const coff_section *&Res) const;    template <typename coff_symbol_type>    std::error_code getSymbol(uint32_t Index, diff --git a/llvm/include/llvm/Object/MachO.h b/llvm/include/llvm/Object/MachO.h index bfd3462bf69..531b3d24903 100644 --- a/llvm/include/llvm/Object/MachO.h +++ b/llvm/include/llvm/Object/MachO.h @@ -304,6 +304,8 @@ public:    std::error_code getSectionContents(DataRefImpl Sec,                                       StringRef &Res) const override;    uint64_t getSectionAlignment(DataRefImpl Sec) const override; +  Expected<SectionRef> getSection(unsigned SectionIndex) const; +  Expected<SectionRef> getSection(StringRef SectionName) const;    bool isSectionCompressed(DataRefImpl Sec) const override;    bool isSectionText(DataRefImpl Sec) const override;    bool isSectionData(DataRefImpl Sec) const override; diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp index e622c17ca3e..26194888ac0 100644 --- a/llvm/lib/Object/COFFObjectFile.cpp +++ b/llvm/lib/Object/COFFObjectFile.cpp @@ -979,6 +979,21 @@ std::error_code COFFObjectFile::getSection(int32_t Index,    return object_error::parse_failed;  } +std::error_code COFFObjectFile::getSection(StringRef SectionName, +                                           const coff_section *&Result) const { +  Result = nullptr; +  StringRef SecName; +  for (const SectionRef &Section : sections()) { +    if (std::error_code E = Section.getName(SecName)) +      return E; +    if (SecName == SectionName) { +      Result = getCOFFSection(Section); +      return std::error_code(); +    } +  } +  return object_error::parse_failed; +} +  std::error_code COFFObjectFile::getString(uint32_t Offset,                                            StringRef &Result) const {    if (StringTableSize <= 4) diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp index 731ff4e01fd..e422903f280 100644 --- a/llvm/lib/Object/MachOObjectFile.cpp +++ b/llvm/lib/Object/MachOObjectFile.cpp @@ -1939,6 +1939,27 @@ uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {    return uint64_t(1) << Align;  } +Expected<SectionRef> MachOObjectFile::getSection(unsigned SectionIndex) const { +  if (SectionIndex < 1 || SectionIndex > Sections.size()) +    return malformedError("bad section index: " + Twine((int)SectionIndex)); + +  DataRefImpl DRI; +  DRI.d.a = SectionIndex - 1; +  return SectionRef(DRI, this); +} + +Expected<SectionRef> MachOObjectFile::getSection(StringRef SectionName) const { +  StringRef SecName; +  for (const SectionRef &Section : sections()) { +    if (std::error_code E = Section.getName(SecName)) +      return errorCodeToError(E); +    if (SecName == SectionName) { +      return Section; +    } +  } +  return errorCodeToError(object_error::parse_failed); +} +  bool MachOObjectFile::isSectionCompressed(DataRefImpl Sec) const {    return false;  } diff --git a/llvm/test/tools/llvm-readobj/print-hex.test b/llvm/test/tools/llvm-readobj/print-hex.test new file mode 100644 index 00000000000..754c87b0789 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/print-hex.test @@ -0,0 +1,20 @@ +RUN: llvm-readobj -x .strtab %p/Inputs/trivial.obj.elf-x86-64 \ +RUN:     | FileCheck %s --check-prefix ELF + +ELF: 0x00000000 00747269 7669616c 2e6c6c00 6d61696e .trivial.ll.main +ELF: 0x00000010 002e4c2e 73747200 70757473 00536f6d ..L.str.puts.Som +ELF: 0x00000020 654f7468 65724675 6e637469 6f6e005f eOtherFunction._ +ELF: 0x00000030 474c4f42 414c5f4f 46465345 545f5441 GLOBAL_OFFSET_TA +ELF: 0x00000040 424c455f 00                         BLE_. + +RUN: llvm-readobj -x 1 %p/Inputs/trivial.obj.coff-x86-64 \ +RUN:     | FileCheck %s --check-prefix COFF + +COFF: 0x00000000 4883ec28 488d0d00 000000e8 00000000 H..(H........... +COFF: 0x00000010 e8000000 0031c048 83c428c3          .....1.H..(. + +RUN: llvm-readobj -x 1 %p/Inputs/trivial.obj.macho-x86-64 \ +RUN:     | FileCheck %s --check-prefix MACHO + +MACHO: 0x00000000 50488d3d 00000000 e8000000 00e80000 PH.=............ +MACHO: 0x00000010 000031c0 5ac3                       ..1.Z. diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp index 0ed4ccd09f6..c840d7efb84 100644 --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -83,6 +83,7 @@ public:    void printSymbols() override;    void printDynamicSymbols() override;    void printUnwindInfo() override; +  void printSectionAsHex(StringRef StringName) override;    void printNeededLibraries() override; @@ -654,6 +655,28 @@ void COFFDumper::printFileHeaders() {      printDOSHeader(DH);  } +void COFFDumper::printSectionAsHex(StringRef SectionName) { +  char *StrPtr; +  long SectionIndex = strtol(SectionName.data(), &StrPtr, 10); +  const coff_section *Sec; +  if (*StrPtr) +    error(Obj->getSection(SectionName, Sec)); +  else { +    error(Obj->getSection((int)SectionIndex, Sec)); +    if (!Sec) +      return error(object_error::parse_failed); +  } + +  StringRef SecName; +  error(Obj->getSectionName(Sec, SecName)); + +  ArrayRef<uint8_t> Content; +  error(Obj->getSectionContents(Sec, Content)); +  const uint8_t *SecContent = Content.data(); + +  SectionHexDump(SecName, SecContent, Content.size()); +} +  void COFFDumper::printDOSHeader(const dos_header *DH) {    DictScope D(W, "DOSHeader");    W.printString("Magic", StringRef(DH->Magic, sizeof(DH->Magic))); diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 9a2be3100ac..ce41e9a48b5 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -152,6 +152,7 @@ public:    void printNeededLibraries() override;    void printProgramHeaders() override;    void printSectionAsString(StringRef StringName) override; +  void printSectionAsHex(StringRef StringName) override;    void printHashTable() override;    void printGnuHashTable() override;    void printLoadName() override; @@ -282,6 +283,23 @@ public:  };  template <class ELFT> +void ELFDumper<ELFT>::printSectionAsHex(StringRef SectionName) { +  char *StrPtr; +  long SectionIndex = strtol(SectionName.data(), &StrPtr, 10); +  const Elf_Shdr *Sec; +  if (*StrPtr) +    Sec = unwrapOrError(Obj->getSection(SectionName)); +  else +    Sec = unwrapOrError(Obj->getSection((unsigned int)SectionIndex)); + +  StringRef SecName = unwrapOrError(Obj->getSectionName(Sec)); +  const uint8_t *SecContent = +      reinterpret_cast<const uint8_t *>(Obj->base() + Sec->sh_offset); + +  SectionHexDump(SecName, SecContent, Sec->sh_size); +} + +template <class ELFT>  void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic) const {    StringRef StrTable, SymtabName;    size_t Entries = 0; diff --git a/llvm/tools/llvm-readobj/MachODumper.cpp b/llvm/tools/llvm-readobj/MachODumper.cpp index 69ef1556f78..c97f598bdd7 100644 --- a/llvm/tools/llvm-readobj/MachODumper.cpp +++ b/llvm/tools/llvm-readobj/MachODumper.cpp @@ -38,6 +38,7 @@ public:    void printDynamicSymbols() override;    void printUnwindInfo() override;    void printStackMap() const override; +  void printSectionAsHex(StringRef SectionName) override;    void printNeededLibraries() override; @@ -676,6 +677,26 @@ void MachODumper::printStackMap() const {                          StackMapV2Parser<support::big>(StackMapContentsArray));  } +void MachODumper::printSectionAsHex(StringRef SectionName) { +  char *StrPtr; +  long SectionIndex = strtol(SectionName.data(), &StrPtr, 10); +  SectionRef SecTmp; +  const SectionRef *Sec = &SecTmp; +  if (*StrPtr) +    SecTmp = unwrapOrError(Obj->getSection(SectionName)); +  else +    SecTmp = unwrapOrError(Obj->getSection((unsigned int)SectionIndex)); + +  StringRef SecName; +  error(Sec->getName(SecName)); + +  StringRef Data; +  error(Sec->getContents(Data)); +  const uint8_t *SecContent = reinterpret_cast<const uint8_t *>(Data.data()); + +  SectionHexDump(SecName, SecContent, Data.size()); +} +  void MachODumper::printNeededLibraries() {    ListScope D(W, "NeededLibraries"); diff --git a/llvm/tools/llvm-readobj/ObjDumper.cpp b/llvm/tools/llvm-readobj/ObjDumper.cpp index 95a6d0325e2..3eb24bdf791 100644 --- a/llvm/tools/llvm-readobj/ObjDumper.cpp +++ b/llvm/tools/llvm-readobj/ObjDumper.cpp @@ -25,4 +25,46 @@ ObjDumper::ObjDumper(ScopedPrinter &Writer) : W(Writer) {}  ObjDumper::~ObjDumper() {  } +void ObjDumper::SectionHexDump(StringRef SecName, const uint8_t *Section, +                               size_t Size) { +  const uint8_t *SecContent = Section; +  const uint8_t *SecEnd = Section + Size; +  W.startLine() << "Hex dump of section '" << SecName << "':\n"; + +  for (const uint8_t *SecPtr = SecContent; SecPtr < SecEnd; SecPtr += 16) { +    const uint8_t *TmpSecPtr = SecPtr; +    uint8_t i; +    uint8_t k; + +    W.startLine() << format_hex(SecPtr - SecContent, 10); +    W.startLine() << ' '; +    for (i = 0; TmpSecPtr < SecEnd && i < 4; ++i) { +      for (k = 0; TmpSecPtr < SecEnd && k < 4; k++, TmpSecPtr++) { +        uint8_t Val = *(reinterpret_cast<const uint8_t *>(TmpSecPtr)); +        W.startLine() << format_hex_no_prefix(Val, 2); +      } +      W.startLine() << ' '; +    } + +    // We need to print the correct amount of spaces to match the format. +    // We are adding the (4 - i) last rows that are 8 characters each. +    // Then, the (4 - i) spaces that are in between the rows. +    // Least, if we cut in a middle of a row, we add the remaining characters, +    // which is (8 - (k * 2)) +    if (i < 4) +      W.startLine() << format("%*c", (4 - i) * 8 + (4 - i) + (8 - (k * 2)), +                              ' '); + +    TmpSecPtr = SecPtr; +    for (i = 0; TmpSecPtr + i < SecEnd && i < 16; ++i) { +      if (isprint(TmpSecPtr[i])) +        W.startLine() << TmpSecPtr[i]; +      else +        W.startLine() << '.'; +    } + +    W.startLine() << '\n'; +  } +} +  } // namespace llvm diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h index 57e59372ee5..09c8acb7493 100644 --- a/llvm/tools/llvm-readobj/ObjDumper.h +++ b/llvm/tools/llvm-readobj/ObjDumper.h @@ -44,6 +44,7 @@ public:    virtual void printNeededLibraries() { }    virtual void printProgramHeaders() { }    virtual void printSectionAsString(StringRef SectionName) {} +  virtual void printSectionAsHex(StringRef SectionName) {}    virtual void printHashTable() { }    virtual void printGnuHashTable() { }    virtual void printLoadName() {} @@ -88,6 +89,7 @@ public:  protected:    ScopedPrinter &W; +  void SectionHexDump(StringRef SecName, const uint8_t *Section, size_t Size);  };  std::error_code createCOFFDumper(const object::ObjectFile *Obj, diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp index aa2cc762daf..39567b80235 100644 --- a/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -152,6 +152,12 @@ namespace opts {    cl::alias StringDumpShort("p", cl::desc("Alias for --string-dump"),                              cl::aliasopt(StringDump)); +  // -hex-dump +  cl::list<std::string> HexDump("hex-dump", cl::desc("<number|name>"), +                                cl::ZeroOrMore); +  cl::alias HexDumpShort("x", cl::desc("Alias for --hex-dump"), +                         cl::aliasopt(HexDump)); +    // -hash-table    cl::opt<bool> HashTable("hash-table",      cl::desc("Display ELF hash table")); @@ -431,6 +437,10 @@ static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer) {      llvm::for_each(opts::StringDump, [&Dumper](StringRef SectionName) {        Dumper->printSectionAsString(SectionName);      }); +  if (!opts::HexDump.empty()) +    llvm::for_each(opts::HexDump, [&Dumper](StringRef SectionName) { +      Dumper->printSectionAsHex(SectionName); +    });    if (opts::HashTable)      Dumper->printHashTable();    if (opts::GnuHashTable)  | 

