diff options
author | Fangrui Song <maskray@google.com> | 2019-06-18 14:01:03 +0000 |
---|---|---|
committer | Fangrui Song <maskray@google.com> | 2019-06-18 14:01:03 +0000 |
commit | 677423997d6a31e9037e41dca990508d561ad42d (patch) | |
tree | 937142b384747082e475d4785998f0da7affb497 /llvm/tools/llvm-readobj/ObjDumper.cpp | |
parent | d204987ada42108e1d86c0418c2993998377f623 (diff) | |
download | bcm5719-llvm-677423997d6a31e9037e41dca990508d561ad42d.tar.gz bcm5719-llvm-677423997d6a31e9037e41dca990508d561ad42d.zip |
[llvm-readobj] Allow --hex-dump/--string-dump to dump multiple sections
1) `-x foo` currently dumps one `foo`. This change makes it dump all `foo`.
2) `-x foo -x foo` currently dumps `foo` twice. This change makes it dump `foo` once.
In addition, if foo has section index 9, `-x foo -x 9` dumps `foo` once.
3) Give a warning instead of an error if `foo` does not exist.
The new behaviors match GNU readelf.
Also, print a new line as a separator between two section dumps.
GNU readelf uses two lines, but one seems good enough.
Reviewed By: grimar, jhenderson
Differential Revision: https://reviews.llvm.org/D63475
llvm-svn: 363683
Diffstat (limited to 'llvm/tools/llvm-readobj/ObjDumper.cpp')
-rw-r--r-- | llvm/tools/llvm-readobj/ObjDumper.cpp | 209 |
1 files changed, 111 insertions, 98 deletions
diff --git a/llvm/tools/llvm-readobj/ObjDumper.cpp b/llvm/tools/llvm-readobj/ObjDumper.cpp index 4f73cbdf281..0a9e22c8a71 100644 --- a/llvm/tools/llvm-readobj/ObjDumper.cpp +++ b/llvm/tools/llvm-readobj/ObjDumper.cpp @@ -19,6 +19,7 @@ #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/raw_ostream.h" +#include <map> namespace llvm { @@ -32,115 +33,127 @@ static void printAsPrintable(raw_ostream &W, const uint8_t *Start, size_t Len) { W << (isPrint(Start[i]) ? static_cast<char>(Start[i]) : '.'); } -static Expected<object::SectionRef> -getSecNameOrIndexAsSecRef(const object::ObjectFile *Obj, StringRef SecName) { - char *StrPtr; - long SectionIndex = strtol(SecName.data(), &StrPtr, 10); - long SecIndex; - if (Obj->isELF()) - SecIndex = 0; - else - SecIndex = 1; - for (object::SectionRef SecRef : Obj->sections()) { - if (*StrPtr) { - StringRef SectionName; - - if (std::error_code E = SecRef.getName(SectionName)) - return errorCodeToError(E); - - if (SectionName == SecName) - return SecRef; - } else if (SecIndex == SectionIndex) - return SecRef; +static std::vector<object::SectionRef> +getSectionRefsByNameOrIndex(const object::ObjectFile *Obj, + ArrayRef<std::string> Sections) { + std::vector<object::SectionRef> Ret; + std::map<std::string, bool> SecNames; + std::map<unsigned, bool> SecIndices; + unsigned SecIndex; + for (StringRef Section : Sections) { + if (!Section.getAsInteger(0, SecIndex)) + SecIndices.emplace(SecIndex, false); + else + SecNames.emplace(Section, false); + } + SecIndex = Obj->isELF() ? 0 : 1; + for (object::SectionRef SecRef : Obj->sections()) { + StringRef SecName; + error(SecRef.getName(SecName)); + auto NameIt = SecNames.find(SecName); + if (NameIt != SecNames.end()) + NameIt->second = true; + auto IndexIt = SecIndices.find(SecIndex); + if (IndexIt != SecIndices.end()) + IndexIt->second = true; + if (NameIt != SecNames.end() || IndexIt != SecIndices.end()) + Ret.push_back(SecRef); SecIndex++; } - return make_error<StringError>( - formatv("could not find section '{0}'", SecName), - object::object_error::parse_failed); + + for (const std::pair<std::string, bool> &S : SecNames) + if (!S.second) + reportWarning(formatv("could not find section '{0}'", S.first).str()); + for (std::pair<unsigned, bool> S : SecIndices) + if (!S.second) + reportWarning(formatv("could not find section {0}", S.first).str()); + + return Ret; } -void ObjDumper::printSectionAsString(const object::ObjectFile *Obj, - StringRef SecName) { - Expected<object::SectionRef> SectionRefOrError = - getSecNameOrIndexAsSecRef(Obj, SecName); - if (!SectionRefOrError) - error(std::move(SectionRefOrError)); - object::SectionRef Section = *SectionRefOrError; - StringRef SectionName; - - if (std::error_code E = Section.getName(SectionName)) - error(E); - W.startLine() << "String dump of section '" << SectionName << "':\n"; - - StringRef SectionContent = unwrapOrError(Section.getContents()); - - const uint8_t *SecContent = SectionContent.bytes_begin(); - const uint8_t *CurrentWord = SecContent; - const uint8_t *SecEnd = SectionContent.bytes_end(); - - while (CurrentWord <= SecEnd) { - size_t WordSize = strnlen(reinterpret_cast<const char *>(CurrentWord), - SecEnd - CurrentWord); - if (!WordSize) { - CurrentWord++; - continue; +void ObjDumper::printSectionsAsString(const object::ObjectFile *Obj, + ArrayRef<std::string> Sections) { + bool First = true; + for (object::SectionRef Section : + getSectionRefsByNameOrIndex(Obj, Sections)) { + StringRef SectionName; + error(Section.getName(SectionName)); + if (!First) + W.startLine() << '\n'; + First = false; + W.startLine() << "String dump of section '" << SectionName << "':\n"; + + StringRef SectionContent = unwrapOrError(Section.getContents()); + + const uint8_t *SecContent = SectionContent.bytes_begin(); + const uint8_t *CurrentWord = SecContent; + const uint8_t *SecEnd = SectionContent.bytes_end(); + + while (CurrentWord <= SecEnd) { + size_t WordSize = strnlen(reinterpret_cast<const char *>(CurrentWord), + SecEnd - CurrentWord); + if (!WordSize) { + CurrentWord++; + continue; + } + W.startLine() << format("[%6tx] ", CurrentWord - SecContent); + printAsPrintable(W.startLine(), CurrentWord, WordSize); + W.startLine() << '\n'; + CurrentWord += WordSize + 1; } - W.startLine() << format("[%6tx] ", CurrentWord - SecContent); - printAsPrintable(W.startLine(), CurrentWord, WordSize); - W.startLine() << '\n'; - CurrentWord += WordSize + 1; } } -void ObjDumper::printSectionAsHex(const object::ObjectFile *Obj, - StringRef SecName) { - Expected<object::SectionRef> SectionRefOrError = - getSecNameOrIndexAsSecRef(Obj, SecName); - if (!SectionRefOrError) - error(std::move(SectionRefOrError)); - object::SectionRef Section = *SectionRefOrError; - StringRef SectionName; - - if (std::error_code E = Section.getName(SectionName)) - error(E); - W.startLine() << "Hex dump of section '" << SectionName << "':\n"; - - StringRef SectionContent = unwrapOrError(Section.getContents()); - const uint8_t *SecContent = SectionContent.bytes_begin(); - const uint8_t *SecEnd = SecContent + SectionContent.size(); - - 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(Section.getAddress() + (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); - } +void ObjDumper::printSectionsAsHex(const object::ObjectFile *Obj, + ArrayRef<std::string> Sections) { + bool First = true; + for (object::SectionRef Section : + getSectionRefsByNameOrIndex(Obj, Sections)) { + StringRef SectionName; + error(Section.getName(SectionName)); + if (!First) + W.startLine() << '\n'; + First = false; + W.startLine() << "Hex dump of section '" << SectionName << "':\n"; + + StringRef SectionContent = unwrapOrError(Section.getContents()); + const uint8_t *SecContent = SectionContent.bytes_begin(); + const uint8_t *SecEnd = SecContent + SectionContent.size(); + + 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(Section.getAddress() + (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) - W.startLine() << (isPrint(TmpSecPtr[i]) ? static_cast<char>(TmpSecPtr[i]) - : '.'); - - W.startLine() << '\n'; + // 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) + W.startLine() << (isPrint(TmpSecPtr[i]) + ? static_cast<char>(TmpSecPtr[i]) + : '.'); + + W.startLine() << '\n'; + } } } |