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
));
58 HelpResponse("\nPass @FILE as argument to read options from FILE.\n");
60 static void strings(raw_ostream
&OS
, StringRef FileName
, StringRef Contents
) {
61 auto print
= [&OS
, FileName
](unsigned Offset
, StringRef L
) {
62 if (L
.size() < static_cast<size_t>(MinLength
))
65 OS
<< FileName
<< ": ";
70 OS
<< format("%7o ", Offset
);
73 OS
<< format("%7x ", Offset
);
76 OS
<< format("%7u ", Offset
);
82 const char *B
= Contents
.begin();
83 const char *P
= nullptr, *E
= nullptr, *S
= nullptr;
84 for (P
= Contents
.begin(), E
= Contents
.end(); P
< E
; ++P
) {
85 if (isPrint(*P
) || *P
== '\t') {
89 print(S
- B
, StringRef(S
, P
- S
));
94 print(S
- B
, StringRef(S
, E
- S
));
97 int main(int argc
, char **argv
) {
98 InitLLVM
X(argc
, argv
);
100 cl::ParseCommandLineOptions(argc
, argv
, "llvm string dumper\n");
101 if (MinLength
== 0) {
102 errs() << "invalid minimum string length 0\n";
106 if (InputFileNames
.empty())
107 InputFileNames
.push_back("-");
109 for (const auto &File
: InputFileNames
) {
110 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> Buffer
=
111 MemoryBuffer::getFileOrSTDIN(File
);
112 if (std::error_code EC
= Buffer
.getError())
113 errs() << File
<< ": " << EC
.message() << '\n';
115 strings(llvm::outs(), File
== "-" ? "{standard input}" : File
,
116 Buffer
.get()->getMemBufferRef().getBuffer());