summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-strings/llvm-strings.cpp
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2016-11-11 03:44:12 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2016-11-11 03:44:12 +0000
commit030ff0f2155b5b1f34a8edd650402cd322b11de0 (patch)
tree122b7eff9046f2139f251dc6c1e0b3a1f2e5fe79 /llvm/tools/llvm-strings/llvm-strings.cpp
parent03a856807c463102755ac4c280272c44fb01ffa7 (diff)
downloadbcm5719-llvm-030ff0f2155b5b1f34a8edd650402cd322b11de0.tar.gz
bcm5719-llvm-030ff0f2155b5b1f34a8edd650402cd322b11de0.zip
llvm-strings: introduce basic strings tool
This is a replacement to binutils' string tool. It prints strings found in a binary (object file, executable, or archive library). It is rather bare and not functionally equivalent, however, it lays the groundwork necessary for the strings tool, enabling iterative development of features to reach feature parity. llvm-svn: 286556
Diffstat (limited to 'llvm/tools/llvm-strings/llvm-strings.cpp')
-rw-r--r--llvm/tools/llvm-strings/llvm-strings.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/llvm/tools/llvm-strings/llvm-strings.cpp b/llvm/tools/llvm-strings/llvm-strings.cpp
new file mode 100644
index 00000000000..daabcd6e6d9
--- /dev/null
+++ b/llvm/tools/llvm-strings/llvm-strings.cpp
@@ -0,0 +1,120 @@
+//===-- llvm-strings.cpp - Printable String dumping utility ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This program is a utility that works like binutils "strings", that is, it
+// prints out printable strings in a binary, objdump, or archive file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/Object/Archive.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/Signals.h"
+#include <string>
+
+using namespace llvm;
+using namespace llvm::object;
+
+static cl::list<std::string> InputFileNames(cl::Positional,
+ cl::desc("<input object files>"),
+ cl::ZeroOrMore);
+
+static void dump(raw_ostream &OS, StringRef Contents) {
+ const char *S = nullptr;
+ for (const char *P = Contents.begin(), *E = Contents.end(); P < E; ++P) {
+ if (std::isgraph(*P) || std::isblank(*P)) {
+ if (S == nullptr)
+ S = P;
+ } else if (S) {
+ if (P - S > 3)
+ OS << StringRef(S, P - S) << '\n';
+ S = nullptr;
+ }
+ }
+}
+
+namespace {
+class Strings {
+ LLVMContext Context;
+ raw_ostream &OS;
+
+ void dump(const ObjectFile *O) {
+ for (const auto &S : O->sections()) {
+ StringRef Contents;
+ if (!S.getContents(Contents))
+ ::dump(OS, Contents);
+ }
+ }
+
+ void dump(const Archive *A) {
+ Error E;
+ for (auto &Element : A->children(E)) {
+ if (Expected<std::unique_ptr<Binary>> Child =
+ Element.getAsBinary(&Context)) {
+ dump(dyn_cast<ObjectFile>(&**Child));
+ } else {
+ if (auto E = isNotObjectErrorInvalidFileType(Child.takeError())) {
+ errs() << A->getFileName();
+ if (Expected<StringRef> Name = Element.getName())
+ errs() << '(' << *Name << ')';
+ logAllUnhandledErrors(std::move(E), errs(), "");
+ errs() << '\n';
+ }
+ }
+ }
+ static_cast<bool>(E);
+ }
+
+public:
+ Strings(raw_ostream &S) : OS(S) {}
+
+ void scan(StringRef File) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
+ MemoryBuffer::getFileOrSTDIN(File);
+ if (std::error_code EC = Buffer.getError()) {
+ errs() << File << ": " << EC.message() << '\n';
+ return;
+ }
+
+ if (Expected<std::unique_ptr<Binary>> B =
+ createBinary(Buffer.get()->getMemBufferRef(), &Context)) {
+ if (auto *A = dyn_cast<Archive>(&**B))
+ return dump(A);
+ if (auto *O = dyn_cast<ObjectFile>(&**B))
+ return dump(O);
+ ::dump(OS, Buffer.get()->getMemBufferRef().getBuffer());
+ } else {
+ consumeError(B.takeError());
+ ::dump(OS, Buffer.get()->getMemBufferRef().getBuffer());
+ }
+ }
+};
+}
+
+int main(int argc, char **argv) {
+ sys::PrintStackTraceOnErrorSignal(argv[0]);
+ PrettyStackTraceProgram X(argc, argv);
+
+ cl::ParseCommandLineOptions(argc, argv, "llvm string dumper\n");
+
+ if (InputFileNames.empty())
+ InputFileNames.push_back("-");
+
+ Strings S(llvm::outs());
+ std::for_each(InputFileNames.begin(), InputFileNames.end(),
+ [&S](StringRef F) { S.scan(F); });
+ return EXIT_SUCCESS;
+}
+
OpenPOWER on IntegriCloud