1 //===-- llvm-strings.cpp - Printable String dumping utility ---------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This program is a utility that works like binutils "strings", that is, it
10 // prints out printable strings in a binary, objdump, or archive file.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Object/Binary.h"
15 #include "llvm/Support/CommandLine.h"
16 #include "llvm/Support/Error.h"
17 #include "llvm/Support/Format.h"
18 #include "llvm/Support/InitLLVM.h"
19 #include "llvm/Support/MemoryBuffer.h"
20 #include "llvm/Support/Program.h"
25 using namespace llvm::object
;
27 static cl::list
<std::string
> InputFileNames(cl::Positional
,
28 cl::desc("<input object files>"),
32 PrintFileName("print-file-name",
33 cl::desc("Print the name of the file before each string"));
34 static cl::alias
PrintFileNameShort("f", cl::desc(""),
35 cl::aliasopt(PrintFileName
));
38 MinLength("bytes", cl::desc("Print sequences of the specified length"),
40 static cl::alias
MinLengthShort("n", cl::desc(""), cl::aliasopt(MinLength
));
44 cl::desc("Check all sections, not just the data section"));
45 static cl::alias
AllSectionsShort("a", cl::desc(""),
46 cl::aliasopt(AllSections
));
48 enum radix
{ none
, octal
, hexadecimal
, decimal
};
50 Radix("radix", cl::desc("print the offset within the file"),
51 cl::values(clEnumValN(octal
, "o", "octal"),
52 clEnumValN(hexadecimal
, "x", "hexadecimal"),
53 clEnumValN(decimal
, "d", "decimal")),
55 static cl::alias
RadixShort("t", cl::desc(""), cl::aliasopt(Radix
));
57 static void strings(raw_ostream
&OS
, StringRef FileName
, StringRef Contents
) {
58 auto print
= [&OS
, FileName
](unsigned Offset
, StringRef L
) {
59 if (L
.size() < static_cast<size_t>(MinLength
))
62 OS
<< FileName
<< ": ";
67 OS
<< format("%7o ", Offset
);
70 OS
<< format("%7x ", Offset
);
73 OS
<< format("%7u ", Offset
);
79 const char *B
= Contents
.begin();
80 const char *P
= nullptr, *E
= nullptr, *S
= nullptr;
81 for (P
= Contents
.begin(), E
= Contents
.end(); P
< E
; ++P
) {
82 if (isPrint(*P
) || *P
== '\t') {
86 print(S
- B
, StringRef(S
, P
- S
));
91 print(S
- B
, StringRef(S
, E
- S
));
94 int main(int argc
, char **argv
) {
95 InitLLVM
X(argc
, argv
);
97 cl::ParseCommandLineOptions(argc
, argv
, "llvm string dumper\n");
99 errs() << "invalid minimum string length 0\n";
103 if (InputFileNames
.empty())
104 InputFileNames
.push_back("-");
106 for (const auto &File
: InputFileNames
) {
107 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> Buffer
=
108 MemoryBuffer::getFileOrSTDIN(File
);
109 if (std::error_code EC
= Buffer
.getError())
110 errs() << File
<< ": " << EC
.message() << '\n';
112 strings(llvm::outs(), File
== "-" ? "{standard input}" : File
,
113 Buffer
.get()->getMemBufferRef().getBuffer());