X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fllvm-nm%2Fllvm-nm.cpp;h=008c2e0431fca956121cc8abd9584a420a592f3f;hb=56867520990a4fea1353d55f71bb74a0126554e6;hp=878aa24f432e664a935a66bf65b5c63eaf486fb1;hpb=d0fde30ce850b78371fd1386338350591f9ff494;p=oota-llvm.git diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index 878aa24f432..008c2e0431f 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -1,26 +1,33 @@ //===-- llvm-nm.cpp - Symbol table dumping utility for llvm ---------------===// -// +// // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// +// 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 traditional Unix "nm", -// that is, it prints out the names of symbols in a bytecode file, +// that is, it prints out the names of symbols in a bitcode file, // along with some information about each symbol. -// +// // This "nm" does not print symbols' addresses. It supports many of // the features of GNU "nm", including its different output formats. // //===----------------------------------------------------------------------===// #include "llvm/Module.h" -#include "llvm/Bytecode/Reader.h" -#include "Support/CommandLine.h" +#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/Bitcode/Archive.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/System/Signals.h" +#include #include - +#include +#include +#include using namespace llvm; namespace { @@ -30,12 +37,13 @@ namespace { cl::desc("Specify output format"), cl::values(clEnumVal(bsd, "BSD format"), clEnumVal(sysv, "System V format"), - clEnumVal(posix, "POSIX.2 format"), 0), cl::init(bsd)); + clEnumVal(posix, "POSIX.2 format"), + clEnumValEnd), cl::init(bsd)); cl::alias OutputFormat2("f", cl::desc("Alias for --format"), cl::aliasopt(OutputFormat)); - cl::list - InputFilenames(cl::Positional, cl::desc(""), + cl::list + InputFilenames(cl::Positional, cl::desc(""), cl::ZeroOrMore); cl::opt UndefinedOnly("undefined-only", @@ -57,20 +65,26 @@ namespace { bool MultipleFiles = false; std::string ToolName; -}; - -char TypeCharForSymbol (GlobalValue &GV) { - if (GV.isExternal ()) return 'U'; - if (GV.hasLinkOnceLinkage ()) return 'C'; - if (GV.hasWeakLinkage ()) return 'W'; - if (isa (GV) && GV.hasInternalLinkage ()) return 't'; - if (isa (GV)) return 'T'; - if (isa (GV) && GV.hasInternalLinkage ()) return 'd'; - if (isa (GV)) return 'D'; - return '?'; } -void DumpSymbolNameForGlobalValue (GlobalValue &GV) { +static char TypeCharForSymbol(GlobalValue &GV) { + if (GV.isDeclaration()) return 'U'; + if (GV.hasLinkOnceLinkage()) return 'C'; + if (GV.hasCommonLinkage()) return 'C'; + if (GV.hasWeakLinkage()) return 'W'; + if (isa(GV) && GV.hasInternalLinkage()) return 't'; + if (isa(GV)) return 'T'; + if (isa(GV) && GV.hasInternalLinkage()) return 'd'; + if (isa(GV)) return 'D'; + if (const GlobalAlias *GA = dyn_cast(&GV)) { + const GlobalValue *AliasedGV = GA->getAliasedGlobal(); + if (isa(AliasedGV)) return 'T'; + if (isa(AliasedGV)) return 'D'; + } + return '?'; +} + +static void DumpSymbolNameForGlobalValue(GlobalValue &GV) { const std::string SymbolAddrStr = " "; // Not used yet... char TypeChar = TypeCharForSymbol (GV); if ((TypeChar != 'U') && UndefinedOnly) @@ -95,32 +109,66 @@ void DumpSymbolNameForGlobalValue (GlobalValue &GV) { } } -void DumpSymbolNamesFromModule (Module *M) { +static void DumpSymbolNamesFromModule(Module *M) { + const std::string &Filename = M->getModuleIdentifier (); + if (OutputFormat == posix && MultipleFiles) { + std::cout << Filename << ":\n"; + } else if (OutputFormat == bsd && MultipleFiles) { + std::cout << "\n" << Filename << ":\n"; + } else if (OutputFormat == sysv) { + std::cout << "\n\nSymbols from " << Filename << ":\n\n" + << "Name Value Class Type" + << " Size Line Section\n"; + } std::for_each (M->begin (), M->end (), DumpSymbolNameForGlobalValue); - std::for_each (M->gbegin (), M->gend (), DumpSymbolNameForGlobalValue); + std::for_each (M->global_begin (), M->global_end (), + DumpSymbolNameForGlobalValue); + std::for_each (M->alias_begin (), M->alias_end (), + DumpSymbolNameForGlobalValue); } -void DumpSymbolNamesFromFile (std::string &Filename) { +static void DumpSymbolNamesFromFile(std::string &Filename) { std::string ErrorMessage; - Module *Result = ParseBytecodeFile(Filename, &ErrorMessage); - if (Result) { - if (OutputFormat == posix && MultipleFiles) { - std::cout << Filename << ":\n"; - } else if (OutputFormat == bsd && MultipleFiles) { - std::cout << "\n" << Filename << ":\n"; - } else if (OutputFormat == sysv) { - std::cout << "\n\nSymbols from " << Filename << ":\n\n" - << "Name Value Class Type" - << " Size Line Section\n"; + sys::Path aPath(Filename); + // Note: Currently we do not support reading an archive from stdin. + if (Filename == "-" || aPath.isBitcodeFile()) { + std::auto_ptr Buffer( + MemoryBuffer::getFileOrSTDIN(Filename, &ErrorMessage)); + Module *Result = 0; + if (Buffer.get()) + Result = ParseBitcodeFile(Buffer.get(), &ErrorMessage); + + if (Result) + DumpSymbolNamesFromModule(Result); + else { + std::cerr << ToolName << ": " << Filename << ": " << ErrorMessage << "\n"; + return; } - DumpSymbolNamesFromModule (Result); + + } else if (aPath.isArchive()) { + std::string ErrMsg; + Archive* archive = Archive::OpenAndLoad(sys::Path(Filename), &ErrorMessage); + if (!archive) + std::cerr << ToolName << ": " << Filename << ": " << ErrorMessage << "\n"; + std::vector Modules; + if (archive->getAllModules(Modules, &ErrorMessage)) { + std::cerr << ToolName << ": " << Filename << ": " << ErrorMessage << "\n"; + return; + } + MultipleFiles = true; + std::for_each (Modules.begin(), Modules.end(), DumpSymbolNamesFromModule); } else { - std::cerr << ToolName << ": " << Filename << ": " << ErrorMessage << "\n"; + std::cerr << ToolName << ": " << Filename << ": " + << "unrecognizable file type\n"; + return; } } int main(int argc, char **argv) { - cl::ParseCommandLineOptions(argc, argv, " llvm symbol table dumper\n"); + llvm_shutdown_obj X; // Call llvm_shutdown() on exit. + cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n"); + sys::PrintStackTraceOnErrorSignal(); + ToolName = argv[0]; if (BSDFormat) OutputFormat = bsd; if (POSIXFormat) OutputFormat = posix; @@ -131,7 +179,7 @@ int main(int argc, char **argv) { default: MultipleFiles = true; } - std::for_each (InputFilenames.begin (), InputFilenames.end (), - DumpSymbolNamesFromFile); + std::for_each(InputFilenames.begin(), InputFilenames.end(), + DumpSymbolNamesFromFile); return 0; }