summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-readobj/ObjDumper.cpp
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2019-06-18 14:01:03 +0000
committerFangrui Song <maskray@google.com>2019-06-18 14:01:03 +0000
commit677423997d6a31e9037e41dca990508d561ad42d (patch)
tree937142b384747082e475d4785998f0da7affb497 /llvm/tools/llvm-readobj/ObjDumper.cpp
parentd204987ada42108e1d86c0418c2993998377f623 (diff)
downloadbcm5719-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.cpp209
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';
+ }
}
}
OpenPOWER on IntegriCloud