Index: tools/llvm-strings/CMakeLists.txt =================================================================== --- tools/llvm-strings/CMakeLists.txt +++ tools/llvm-strings/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + BitReader Core Object Support Index: tools/llvm-strings/llvm-strings.cpp =================================================================== --- tools/llvm-strings/llvm-strings.cpp +++ tools/llvm-strings/llvm-strings.cpp @@ -13,12 +13,14 @@ //===----------------------------------------------------------------------===// #include "llvm/Object/Binary.h" +#include "llvm/IR/Constants.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 "llvm/Bitcode/BitcodeReader.h" #include #include @@ -40,6 +42,25 @@ cl::init(4)); static cl::alias MinLengthShort("n", cl::desc(""), cl::aliasopt(MinLength)); +static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) { + raw_ostream &OS = errs(); + OS << (char *)Context << ": "; + switch (DI.getSeverity()) { + case DS_Error: + OS << "error: "; + break; + case DS_Warning: + OS << "warning: "; + break; + case DS_Remark: + OS << "remark: "; + break; + case DS_Note: + OS << "note: "; + break; + } +} + static void strings(raw_ostream &OS, StringRef FileName, StringRef Contents) { auto print = [&OS, FileName](StringRef L) { if (L.size() < static_cast(MinLength)) @@ -63,10 +84,45 @@ print(StringRef(S, E - S)); } +static void printGlobalVariablesAsString(const Module &Mod, StringRef FileName) { + raw_ostream &OS = errs(); + const Module::GlobalListType &GlobalList = Mod.getGlobalList(); + for (Module::const_global_iterator I = GlobalList.begin(), + E = GlobalList.end(); I != E; ++I) { + if (PrintFileName) + OS << FileName + ": "; + OS << I->getName() + "\n"; + if (const ConstantDataArray *CA = + dyn_cast(I->getOperandList()->get())) { + if (!CA->isString()) + continue; + StringRef PrintStr = CA->getAsString(); + PrintStr = PrintStr.ltrim("\n"); + size_t pos = PrintStr.find_first_of("\n"); + PrintStr = PrintStr.substr(0, pos); + if (PrintFileName) + OS << FileName + ": "; + OS << PrintStr + "\n"; + } + } +} + +static void printFunctionNamesAsString(const Module &Mod, + StringRef FileName) { + raw_ostream &OS = errs(); + const Module::FunctionListType &FunctionList = Mod.getFunctionList(); + for (Module::const_iterator I = FunctionList.begin(), + E = FunctionList.end(); I!=E; ++I) { + if (PrintFileName) + OS << FileName + ": "; + OS << I->getName() + "\n"; + } +} + int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(argv[0]); PrettyStackTraceProgram X(argc, argv); - + ExitOnError ExitOnErr; cl::ParseCommandLineOptions(argc, argv, "llvm string dumper\n"); if (MinLength == 0) { errs() << "invalid minimum string length 0\n"; @@ -79,12 +135,25 @@ for (const auto &File : InputFileNames) { ErrorOr> Buffer = MemoryBuffer::getFileOrSTDIN(File); - if (std::error_code EC = Buffer.getError()) + if (std::error_code EC = Buffer.getError()) { errs() << File << ": " << EC.message() << '\n'; - else - strings(llvm::outs(), File == "-" ? "{standard input}" : File, - Buffer.get()->getMemBufferRef().getBuffer()); + } else if (isBitcode((const unsigned char *) + Buffer.get().get()->getBufferStart(), + (const unsigned char *) + Buffer.get().get()->getBufferEnd())) { + LLVMContext Context; + Context.setDiagnosticHandler(diagnosticHandler, argv[0]); + std::unique_ptr M = + ExitOnErr(getOwningLazyBitcodeModule(std::move(Buffer.get()), Context, + /*ShouldLazyLoadMetadata=*/true)); + printGlobalVariablesAsString(*M, + File == "-" ? "{standard input}" : File); + printFunctionNamesAsString(*M, + File == "-" ? "{standard input}" : File); + } else { + strings(llvm::outs(), File == "-" ? "{standard input}" : File, + Buffer.get()->getMemBufferRef().getBuffer()); + } } - return EXIT_SUCCESS; }