1aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant//===-- llvm-nm.cpp - Symbol table dumping utility for llvm ---------------===// 2aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// 3aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// The LLVM Compiler Infrastructure 4aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// 5b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// This file is distributed under the University of Illinois Open Source 6b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// License. See LICENSE.TXT for details. 7aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// 8aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant//===----------------------------------------------------------------------===// 9aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// 10b4ed5ca01e2b984687ce560b08c20c28ec3cae98Dan Albert// This program is a utility that works like traditional Unix "nm", that is, it 11b4ed5ca01e2b984687ce560b08c20c28ec3cae98Dan Albert// prints out the names of symbols in a bitcode or object file, along with some 12aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// information about each symbol. 13aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// 14aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// This "nm" supports many of the features of GNU "nm", including its different 15aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// output formats. 16aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// 17aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant//===----------------------------------------------------------------------===// 18aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 19aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/IR/Function.h" 20aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/IR/GlobalAlias.h" 2179578cd14ff1f4579b31ae666e869d19eac97232Eric Fiselier#include "llvm/IR/GlobalVariable.h" 2279578cd14ff1f4579b31ae666e869d19eac97232Eric Fiselier#include "llvm/IR/LLVMContext.h" 2379578cd14ff1f4579b31ae666e869d19eac97232Eric Fiselier#include "llvm/IR/Module.h" 24aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/Object/Archive.h" 25aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/Object/COFF.h" 2683e2c4d877fe2d7793868b1c6a5d9525a7c4d431Marshall Clow#include "llvm/Object/ELFObjectFile.h" 27aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/Object/IRObjectFile.h" 28eda3fcaaedc2c6a13fce15fbe5fd472b642dc830Ed Schouten#include "llvm/Object/MachO.h" 29eda3fcaaedc2c6a13fce15fbe5fd472b642dc830Ed Schouten#include "llvm/Object/MachOUniversal.h" 30aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/Object/ObjectFile.h" 31aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/Support/COFF.h" 32aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/Support/CommandLine.h" 33aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/Support/FileSystem.h" 34aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/Support/Format.h" 35aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/Support/ManagedStatic.h" 36aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/Support/MemoryBuffer.h" 37aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/Support/PrettyStackTrace.h" 38aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/Support/Program.h" 39aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/Support/Signals.h" 40aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/Support/TargetSelect.h" 41aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include "llvm/Support/raw_ostream.h" 42aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include <algorithm> 43aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include <cctype> 44aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include <cerrno> 45aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include <cstring> 46aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include <system_error> 47aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant#include <vector> 48aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 49aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantusing namespace llvm; 50aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantusing namespace object; 51aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 52aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantnamespace { 53aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantenum OutputFormatTy { bsd, sysv, posix, darwin }; 54aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<OutputFormatTy> OutputFormat( 55aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant "format", cl::desc("Specify output format"), 56aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::values(clEnumVal(bsd, "BSD format"), clEnumVal(sysv, "System V format"), 57aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant clEnumVal(posix, "POSIX.2 format"), 58aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant clEnumVal(darwin, "Darwin -m format"), clEnumValEnd), 59aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::init(bsd)); 60aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::alias OutputFormat2("f", cl::desc("Alias for --format"), 61aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::aliasopt(OutputFormat)); 62aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 63aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input files>"), 64aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::ZeroOrMore); 65aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 66aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> UndefinedOnly("undefined-only", 67aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::desc("Show only undefined symbols")); 68aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::alias UndefinedOnly2("u", cl::desc("Alias for --undefined-only"), 69aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::aliasopt(UndefinedOnly), cl::Grouping); 70aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 71aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> DynamicSyms("dynamic", 72aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::desc("Display the dynamic symbols instead " 73aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant "of normal symbols.")); 74aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::alias DynamicSyms2("D", cl::desc("Alias for --dynamic"), 75aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::aliasopt(DynamicSyms), cl::Grouping); 76aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 77aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> DefinedOnly("defined-only", 78aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::desc("Show only defined symbols")); 79aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::alias DefinedOnly2("U", cl::desc("Alias for --defined-only"), 80aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::aliasopt(DefinedOnly), cl::Grouping); 81aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 82aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> ExternalOnly("extern-only", 83aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::desc("Show only external symbols")); 84aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::alias ExternalOnly2("g", cl::desc("Alias for --extern-only"), 85aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::aliasopt(ExternalOnly), cl::Grouping); 86aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 87aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> BSDFormat("B", cl::desc("Alias for --format=bsd"), 88aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::Grouping); 89aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> POSIXFormat("P", cl::desc("Alias for --format=posix"), 90aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::Grouping); 91aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> DarwinFormat("m", cl::desc("Alias for --format=darwin"), 92aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::Grouping); 93aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 94aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic cl::list<std::string> 95aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"), 96aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::ZeroOrMore); 97aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantbool ArchAll = false; 98aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 99aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> PrintFileName( 100aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant "print-file-name", 101aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::desc("Precede each symbol with the object file it came from")); 102aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 103aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::alias PrintFileNameA("A", cl::desc("Alias for --print-file-name"), 104aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::aliasopt(PrintFileName), cl::Grouping); 105aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::alias PrintFileNameo("o", cl::desc("Alias for --print-file-name"), 106aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::aliasopt(PrintFileName), cl::Grouping); 107aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 108aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> DebugSyms("debug-syms", 109aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::desc("Show all symbols, even debugger only")); 110aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::alias DebugSymsa("a", cl::desc("Alias for --debug-syms"), 111aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::aliasopt(DebugSyms), cl::Grouping); 112aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 113aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> NumericSort("numeric-sort", cl::desc("Sort symbols by address")); 114aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::alias NumericSortn("n", cl::desc("Alias for --numeric-sort"), 115aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::aliasopt(NumericSort), cl::Grouping); 116aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::alias NumericSortv("v", cl::desc("Alias for --numeric-sort"), 117aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::aliasopt(NumericSort), cl::Grouping); 118aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 119aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> NoSort("no-sort", cl::desc("Show symbols in order encountered")); 120aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::alias NoSortp("p", cl::desc("Alias for --no-sort"), cl::aliasopt(NoSort), 121aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::Grouping); 122aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 123aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> ReverseSort("reverse-sort", cl::desc("Sort in reverse order")); 124aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::alias ReverseSortr("r", cl::desc("Alias for --reverse-sort"), 125aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::aliasopt(ReverseSort), cl::Grouping); 126aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 127aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> PrintSize("print-size", 128aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::desc("Show symbol size instead of address")); 129aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::alias PrintSizeS("S", cl::desc("Alias for --print-size"), 130aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::aliasopt(PrintSize), cl::Grouping); 131aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 132aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> SizeSort("size-sort", cl::desc("Sort symbols by size")); 133aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 134aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> WithoutAliases("without-aliases", cl::Hidden, 135aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::desc("Exclude aliases from output")); 136aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 137aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> ArchiveMap("print-armap", cl::desc("Print the archive map")); 138aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::alias ArchiveMaps("M", cl::desc("Alias for --print-armap"), 139aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::aliasopt(ArchiveMap), cl::Grouping); 140aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 141aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> JustSymbolName("just-symbol-name", 142aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::desc("Print just the symbol's name")); 143aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::alias JustSymbolNames("j", cl::desc("Alias for --just-symbol-name"), 144aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::aliasopt(JustSymbolName), cl::Grouping); 145aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 146aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// FIXME: This option takes exactly two strings and should be allowed anywhere 147aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// on the command line. Such that "llvm-nm -s __TEXT __text foo.o" would work. 148aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// But that does not as the CommandLine Library does not have a way to make 149aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// this work. For now the "-s __TEXT __text" has to be last on the command 150aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// line. 151aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::list<std::string> SegSect("s", cl::Positional, cl::ZeroOrMore, 152aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::desc("Dump only symbols from this segment " 153aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant "and section name, Mach-O only")); 154aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 155aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> FormatMachOasHex("x", cl::desc("Print symbol entry in hex, " 156aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant "Mach-O only"), cl::Grouping); 157aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 158aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantcl::opt<bool> NoLLVMBitcode("no-llvm-bc", 159aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::desc("Disable LLVM bitcode reader")); 160aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 161aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantbool PrintAddress = true; 162aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 163aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantbool MultipleFiles = false; 164aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 165aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantbool HadError = false; 166aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 167aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstd::string ToolName; 168aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} // anonymous namespace 169aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 170aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic void error(Twine Message, Twine Path = Twine()) { 171aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant HadError = true; 172aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant errs() << ToolName << ": " << Path << ": " << Message << ".\n"; 173aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 174aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 175aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic bool error(std::error_code EC, Twine Path = Twine()) { 176aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (EC) { 177aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant error(EC.message(), Path); 178aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return true; 179aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 180aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return false; 181aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 182aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 183aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantnamespace { 184aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstruct NMSymbol { 185aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint64_t Address; 186aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint64_t Size; 187aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant char TypeChar; 188aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant StringRef Name; 189aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant BasicSymbolRef Sym; 190aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant}; 191aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} // anonymous namespace 192aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 193aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic bool compareSymbolAddress(const NMSymbol &A, const NMSymbol &B) { 194aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant bool ADefined = !(A.Sym.getFlags() & SymbolRef::SF_Undefined); 195aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant bool BDefined = !(B.Sym.getFlags() & SymbolRef::SF_Undefined); 196aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return std::make_tuple(ADefined, A.Address, A.Name, A.Size) < 197aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::make_tuple(BDefined, B.Address, B.Name, B.Size); 198aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 199aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 200aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic bool compareSymbolSize(const NMSymbol &A, const NMSymbol &B) { 201aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return std::make_tuple(A.Size, A.Name, A.Address) < 202aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::make_tuple(B.Size, B.Name, B.Address); 203aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 204aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 205aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic bool compareSymbolName(const NMSymbol &A, const NMSymbol &B) { 206aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return std::make_tuple(A.Name, A.Size, A.Address) < 207aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::make_tuple(B.Name, B.Size, B.Address); 208aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 209aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 210aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic char isSymbolList64Bit(SymbolicFile &Obj) { 211aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (isa<IRObjectFile>(Obj)) { 212aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant IRObjectFile *IRobj = dyn_cast<IRObjectFile>(&Obj); 213aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Module &M = IRobj->getModule(); 214aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (M.getTargetTriple().empty()) 215aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return false; 216aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Triple T(M.getTargetTriple()); 217aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return T.isArch64Bit(); 218aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 219aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (isa<COFFObjectFile>(Obj)) 220aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return false; 221aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj)) 222aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return MachO->is64Bit(); 223aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return cast<ELFObjectFileBase>(Obj).getBytesInAddress() == 8; 224aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 225aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 226aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic StringRef CurrentFilename; 227aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnanttypedef std::vector<NMSymbol> SymbolListT; 228aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic SymbolListT SymbolList; 229aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 230aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I); 231aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 232aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// darwinPrintSymbol() is used to print a symbol from a Mach-O file when the 233aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// the OutputFormat is darwin or we are printing Mach-O symbols in hex. For 234aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// the darwin format it produces the same output as darwin's nm(1) -m output 235aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// and when printing Mach-O symbols in hex it produces the same output as 236aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// darwin's nm(1) -x format. 237aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic void darwinPrintSymbol(SymbolicFile &Obj, SymbolListT::iterator I, 238aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant char *SymbolAddrStr, const char *printBlanks, 239aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant const char *printDashes, const char *printFormat) { 240aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO::mach_header H; 241aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO::mach_header_64 H_64; 242aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint32_t Filetype = MachO::MH_OBJECT; 243aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint32_t Flags = 0; 244aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint8_t NType = 0; 245aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint8_t NSect = 0; 246aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint16_t NDesc = 0; 247aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint32_t NStrx = 0; 248aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint64_t NValue = 0; 249aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj); 250aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Obj.isIR()) { 251aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint32_t SymFlags = I->Sym.getFlags(); 252aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SymFlags & SymbolRef::SF_Global) 253aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NType |= MachO::N_EXT; 254aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SymFlags & SymbolRef::SF_Hidden) 255aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NType |= MachO::N_PEXT; 256aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SymFlags & SymbolRef::SF_Undefined) 257aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NType |= MachO::N_EXT | MachO::N_UNDF; 258aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else { 259aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // Here we have a symbol definition. So to fake out a section name we 260aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // use 1, 2 and 3 for section numbers. See below where they are used to 261aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // print out fake section names. 262aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NType |= MachO::N_SECT; 263aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if(SymFlags & SymbolRef::SF_Const) 264aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NSect = 3; 265aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else { 266aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant IRObjectFile *IRobj = dyn_cast<IRObjectFile>(&Obj); 267aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant char c = getSymbolNMTypeChar(*IRobj, I->Sym); 268aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (c == 't') 269aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NSect = 1; 270aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 271aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NSect = 2; 272aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 273aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 274aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SymFlags & SymbolRef::SF_Weak) 275aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NDesc |= MachO::N_WEAK_DEF; 276aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else { 277aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant DataRefImpl SymDRI = I->Sym.getRawDataRefImpl(); 278aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (MachO->is64Bit()) { 279aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant H_64 = MachO->MachOObjectFile::getHeader64(); 280aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Filetype = H_64.filetype; 281aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Flags = H_64.flags; 282aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO::nlist_64 STE_64 = MachO->getSymbol64TableEntry(SymDRI); 283aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NType = STE_64.n_type; 284aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NSect = STE_64.n_sect; 285aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NDesc = STE_64.n_desc; 286aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NStrx = STE_64.n_strx; 287aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NValue = STE_64.n_value; 288aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else { 289aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant H = MachO->MachOObjectFile::getHeader(); 290aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Filetype = H.filetype; 291aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Flags = H.flags; 292aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO::nlist STE = MachO->getSymbolTableEntry(SymDRI); 293aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NType = STE.n_type; 294aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NSect = STE.n_sect; 295aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NDesc = STE.n_desc; 296aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NStrx = STE.n_strx; 297aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NValue = STE.n_value; 298aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 299aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 300aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 301aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // If we are printing Mach-O symbols in hex do that and return. 302aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (FormatMachOasHex) { 303aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant char Str[18] = ""; 304aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant format(printFormat, NValue).print(Str, sizeof(Str)); 305aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << Str << ' '; 306aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant format("%02x", NType).print(Str, sizeof(Str)); 307aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << Str << ' '; 308aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant format("%02x", NSect).print(Str, sizeof(Str)); 309aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << Str << ' '; 310aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant format("%04x", NDesc).print(Str, sizeof(Str)); 311aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << Str << ' '; 312aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant format("%08x", NStrx).print(Str, sizeof(Str)); 313aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << Str << ' '; 314aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << I->Name << "\n"; 315aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 316aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 317aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 318aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (PrintAddress) { 319aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if ((NType & MachO::N_TYPE) == MachO::N_INDR) 320aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant strcpy(SymbolAddrStr, printBlanks); 321aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Obj.isIR() && (NType & MachO::N_TYPE) == MachO::N_TYPE) 322aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant strcpy(SymbolAddrStr, printDashes); 323aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << SymbolAddrStr << ' '; 324aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 325aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 326aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant switch (NType & MachO::N_TYPE) { 327aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case MachO::N_UNDF: 328aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (NValue != 0) { 329aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "(common) "; 330aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (MachO::GET_COMM_ALIGN(NDesc) != 0) 331aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "(alignment 2^" << (int)MachO::GET_COMM_ALIGN(NDesc) << ") "; 332aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else { 333aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if ((NType & MachO::N_TYPE) == MachO::N_PBUD) 334aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "(prebound "; 335aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 336aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "("; 337aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if ((NDesc & MachO::REFERENCE_TYPE) == 338aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO::REFERENCE_FLAG_UNDEFINED_LAZY) 339aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "undefined [lazy bound]) "; 340aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else if ((NDesc & MachO::REFERENCE_TYPE) == 341aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO::REFERENCE_FLAG_UNDEFINED_LAZY) 342aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "undefined [private lazy bound]) "; 343aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else if ((NDesc & MachO::REFERENCE_TYPE) == 344aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY) 345aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "undefined [private]) "; 346aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 347aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "undefined) "; 348aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 349aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant break; 350aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case MachO::N_ABS: 351aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "(absolute) "; 352aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant break; 353aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case MachO::N_INDR: 354aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "(indirect) "; 355aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant break; 356aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case MachO::N_SECT: { 357aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Obj.isIR()) { 358aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // For llvm bitcode files print out a fake section name using the values 359aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // use 1, 2 and 3 for section numbers as set above. 360aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (NSect == 1) 361aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "(LTO,CODE) "; 362aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else if (NSect == 2) 363aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "(LTO,DATA) "; 364aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else if (NSect == 3) 365aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "(LTO,RODATA) "; 366aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 367aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "(?,?) "; 368aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant break; 369aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 370aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant section_iterator Sec = *MachO->getSymbolSection(I->Sym.getRawDataRefImpl()); 371aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant DataRefImpl Ref = Sec->getRawDataRefImpl(); 372aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant StringRef SectionName; 373aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO->getSectionName(Ref, SectionName); 374aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant StringRef SegmentName = MachO->getSectionFinalSegmentName(Ref); 375aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "(" << SegmentName << "," << SectionName << ") "; 376aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant break; 377aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 378aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant default: 379aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "(?) "; 380aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant break; 381aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 382aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 383aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (NType & MachO::N_EXT) { 384aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (NDesc & MachO::REFERENCED_DYNAMICALLY) 385aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "[referenced dynamically] "; 386aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (NType & MachO::N_PEXT) { 387aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if ((NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF) 388aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "weak private external "; 389aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 390aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "private external "; 391aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else { 392aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if ((NDesc & MachO::N_WEAK_REF) == MachO::N_WEAK_REF || 393aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant (NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF) { 394aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if ((NDesc & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) == 395aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) 396aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "weak external automatically hidden "; 397aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 398aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "weak external "; 399aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else 400aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "external "; 401aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 402aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else { 403aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (NType & MachO::N_PEXT) 404aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "non-external (was a private external) "; 405aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 406aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "non-external "; 407aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 408aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 409aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Filetype == MachO::MH_OBJECT && 410aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant (NDesc & MachO::N_NO_DEAD_STRIP) == MachO::N_NO_DEAD_STRIP) 411aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "[no dead strip] "; 412aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 413aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Filetype == MachO::MH_OBJECT && 414aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ((NType & MachO::N_TYPE) != MachO::N_UNDF) && 415aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant (NDesc & MachO::N_SYMBOL_RESOLVER) == MachO::N_SYMBOL_RESOLVER) 416aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "[symbol resolver] "; 417aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 418aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Filetype == MachO::MH_OBJECT && 419aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ((NType & MachO::N_TYPE) != MachO::N_UNDF) && 420aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant (NDesc & MachO::N_ALT_ENTRY) == MachO::N_ALT_ENTRY) 421aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "[alt entry] "; 422aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 423aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if ((NDesc & MachO::N_ARM_THUMB_DEF) == MachO::N_ARM_THUMB_DEF) 424aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "[Thumb] "; 425aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 426aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if ((NType & MachO::N_TYPE) == MachO::N_INDR) { 427aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << I->Name << " (for "; 428aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant StringRef IndirectName; 429aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!MachO || 430aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO->getIndirectName(I->Sym.getRawDataRefImpl(), IndirectName)) 431aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "?)"; 432aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 433aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << IndirectName << ")"; 434aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else 435aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << I->Name; 436aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 437aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if ((Flags & MachO::MH_TWOLEVEL) == MachO::MH_TWOLEVEL && 438aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant (((NType & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0) || 439aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant (NType & MachO::N_TYPE) == MachO::N_PBUD)) { 440aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint32_t LibraryOrdinal = MachO::GET_LIBRARY_ORDINAL(NDesc); 441aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (LibraryOrdinal != 0) { 442aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (LibraryOrdinal == MachO::EXECUTABLE_ORDINAL) 443aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << " (from executable)"; 444aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else if (LibraryOrdinal == MachO::DYNAMIC_LOOKUP_ORDINAL) 445aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << " (dynamically looked up)"; 446aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else { 447aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant StringRef LibraryName; 448aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!MachO || 449aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO->getLibraryShortNameByIndex(LibraryOrdinal - 1, LibraryName)) 450aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << " (from bad library ordinal " << LibraryOrdinal << ")"; 451aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 452aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << " (from " << LibraryName << ")"; 453aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 454aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 455aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 456aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 457aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "\n"; 458aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 459aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 460aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// Table that maps Darwin's Mach-O stab constants to strings to allow printing. 461aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstruct DarwinStabName { 462aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint8_t NType; 463aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant const char *Name; 464aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant}; 465aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic const struct DarwinStabName DarwinStabNames[] = { 466aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_GSYM, "GSYM"}, 467aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_FNAME, "FNAME"}, 468aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_FUN, "FUN"}, 469aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_STSYM, "STSYM"}, 470aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_LCSYM, "LCSYM"}, 471aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_BNSYM, "BNSYM"}, 472aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_PC, "PC"}, 473aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_AST, "AST"}, 474aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_OPT, "OPT"}, 475aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_RSYM, "RSYM"}, 476aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_SLINE, "SLINE"}, 477aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_ENSYM, "ENSYM"}, 478aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_SSYM, "SSYM"}, 479aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_SO, "SO"}, 480aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_OSO, "OSO"}, 481aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_LSYM, "LSYM"}, 482aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_BINCL, "BINCL"}, 483aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_SOL, "SOL"}, 484aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_PARAMS, "PARAM"}, 485aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_VERSION, "VERS"}, 486aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_OLEVEL, "OLEV"}, 487aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_PSYM, "PSYM"}, 488aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_EINCL, "EINCL"}, 489aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_ENTRY, "ENTRY"}, 490aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_LBRAC, "LBRAC"}, 491aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_EXCL, "EXCL"}, 492aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_RBRAC, "RBRAC"}, 493aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_BCOMM, "BCOMM"}, 494aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_ECOMM, "ECOMM"}, 495aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_ECOML, "ECOML"}, 496aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {MachO::N_LENG, "LENG"}, 497aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant {0, nullptr}}; 498aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 499aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic const char *getDarwinStabString(uint8_t NType) { 500aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant for (unsigned i = 0; DarwinStabNames[i].Name; i++) { 501aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (DarwinStabNames[i].NType == NType) 502aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return DarwinStabNames[i].Name; 503aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 504aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return nullptr; 505aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 506aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 507aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// darwinPrintStab() prints the n_sect, n_desc along with a symbolic name of 508aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// a stab n_type value in a Mach-O file. 509aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic void darwinPrintStab(MachOObjectFile *MachO, SymbolListT::iterator I) { 510aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO::nlist_64 STE_64; 511aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO::nlist STE; 512aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint8_t NType; 513aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint8_t NSect; 514aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint16_t NDesc; 515aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant DataRefImpl SymDRI = I->Sym.getRawDataRefImpl(); 516aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (MachO->is64Bit()) { 517aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant STE_64 = MachO->getSymbol64TableEntry(SymDRI); 518aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NType = STE_64.n_type; 519aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NSect = STE_64.n_sect; 520aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NDesc = STE_64.n_desc; 521aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else { 522aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant STE = MachO->getSymbolTableEntry(SymDRI); 523aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NType = STE.n_type; 524aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NSect = STE.n_sect; 525aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NDesc = STE.n_desc; 526aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 527aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 528aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant char Str[18] = ""; 529aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant format("%02x", NSect).print(Str, sizeof(Str)); 530aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << ' ' << Str << ' '; 531aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant format("%04x", NDesc).print(Str, sizeof(Str)); 532aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << Str << ' '; 533aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (const char *stabString = getDarwinStabString(NType)) 534aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant format("%5.5s", stabString).print(Str, sizeof(Str)); 535aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 536aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant format(" %02x", NType).print(Str, sizeof(Str)); 537aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << Str; 538aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 539aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 540aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName, 541aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::string ArchiveName, 542aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::string ArchitectureName) { 543aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!NoSort) { 544aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::function<bool(const NMSymbol &, const NMSymbol &)> Cmp; 545aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (NumericSort) 546aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Cmp = compareSymbolAddress; 547aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else if (SizeSort) 548aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Cmp = compareSymbolSize; 549aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 550aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Cmp = compareSymbolName; 551aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 552aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (ReverseSort) 553aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Cmp = [=](const NMSymbol &A, const NMSymbol &B) { return Cmp(B, A); }; 554aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::sort(SymbolList.begin(), SymbolList.end(), Cmp); 555aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 556aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 557aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!PrintFileName) { 558aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (OutputFormat == posix && MultipleFiles && printName) { 559aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << '\n' << CurrentFilename << ":\n"; 560aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else if (OutputFormat == bsd && MultipleFiles && printName) { 561aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "\n" << CurrentFilename << ":\n"; 562aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else if (OutputFormat == sysv) { 563aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "\n\nSymbols from " << CurrentFilename << ":\n\n" 564aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant << "Name Value Class Type" 565aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant << " Size Line Section\n"; 566aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 567aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 568aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 569aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant const char *printBlanks, *printDashes, *printFormat; 570aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (isSymbolList64Bit(Obj)) { 571aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant printBlanks = " "; 572aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant printDashes = "----------------"; 573aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant printFormat = "%016" PRIx64; 574aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else { 575aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant printBlanks = " "; 576aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant printDashes = "--------"; 577aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant printFormat = "%08" PRIx64; 578aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 579aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 580aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant for (SymbolListT::iterator I = SymbolList.begin(), E = SymbolList.end(); 581aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant I != E; ++I) { 582aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint32_t SymFlags = I->Sym.getFlags(); 583aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant bool Undefined = SymFlags & SymbolRef::SF_Undefined; 584aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!Undefined && UndefinedOnly) 585aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant continue; 586aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Undefined && DefinedOnly) 587aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant continue; 588aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant bool Global = SymFlags & SymbolRef::SF_Global; 589aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!Global && ExternalOnly) 590aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant continue; 591aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SizeSort && !PrintAddress) 592aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant continue; 593aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (PrintFileName) { 594aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!ArchitectureName.empty()) 595aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "(for architecture " << ArchitectureName << "):"; 596aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!ArchiveName.empty()) 597aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << ArchiveName << ":"; 598aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << CurrentFilename << ": "; 599aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 600aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if ((JustSymbolName || (UndefinedOnly && isa<MachOObjectFile>(Obj) && 601aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant OutputFormat != darwin)) && OutputFormat != posix) { 602aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << I->Name << "\n"; 603aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant continue; 604aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 605aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 606aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant char SymbolAddrStr[18] = ""; 607aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant char SymbolSizeStr[18] = ""; 608aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 609aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (OutputFormat == sysv || I->TypeChar == 'U') 610aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant strcpy(SymbolAddrStr, printBlanks); 611aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (OutputFormat == sysv) 612aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant strcpy(SymbolSizeStr, printBlanks); 613aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 614aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (I->TypeChar != 'U') { 615aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Obj.isIR()) 616aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant strcpy(SymbolAddrStr, printDashes); 617aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 618aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant format(printFormat, I->Address) 619aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant .print(SymbolAddrStr, sizeof(SymbolAddrStr)); 620aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 621aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant format(printFormat, I->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr)); 622aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 623eda3fcaaedc2c6a13fce15fbe5fd472b642dc830Ed Schouten // If OutputFormat is darwin or we are printing Mach-O symbols in hex and 624aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // we have a MachOObjectFile, call darwinPrintSymbol to print as darwin's 625aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // nm(1) -m output or hex, else if OutputFormat is darwin or we are 626aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // printing Mach-O symbols in hex and not a Mach-O object fall back to 627aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // OutputFormat bsd (see below). 628aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj); 629aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if ((OutputFormat == darwin || FormatMachOasHex) && (MachO || Obj.isIR())) { 630aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant darwinPrintSymbol(Obj, I, SymbolAddrStr, printBlanks, printDashes, 631aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant printFormat); 632aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else if (OutputFormat == posix) { 633aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << I->Name << " " << I->TypeChar << " "; 634aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (MachO) 635aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << I->Address << " " << "0" /* SymbolSizeStr */ << "\n"; 636aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 637aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << SymbolAddrStr << SymbolSizeStr << "\n"; 638aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else if (OutputFormat == bsd || (OutputFormat == darwin && !MachO)) { 639aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (PrintAddress) 640aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << SymbolAddrStr << ' '; 641aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (PrintSize) { 642aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << SymbolSizeStr; 643aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << ' '; 644aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 645aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << I->TypeChar; 646aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (I->TypeChar == '-' && MachO) 647aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant darwinPrintStab(MachO, I); 648aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << " " << I->Name << "\n"; 649aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else if (OutputFormat == sysv) { 650aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::string PaddedName(I->Name); 651aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant while (PaddedName.length() < 20) 652aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant PaddedName += " "; 653aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << PaddedName << "|" << SymbolAddrStr << "| " << I->TypeChar 654aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant << " | |" << SymbolSizeStr << "| |\n"; 655aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 656aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 657aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 658aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant SymbolList.clear(); 659aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 660aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 661aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic char getSymbolNMTypeChar(ELFObjectFileBase &Obj, 662aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant basic_symbol_iterator I) { 663aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // OK, this is ELF 664aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant elf_symbol_iterator SymI(I); 665aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 666aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ErrorOr<elf_section_iterator> SecIOrErr = SymI->getSection(); 667aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (error(SecIOrErr.getError())) 668aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return '?'; 669aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 670aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant elf_section_iterator SecI = *SecIOrErr; 671aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SecI != Obj.section_end()) { 672aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant switch (SecI->getType()) { 673aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case ELF::SHT_PROGBITS: 674aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case ELF::SHT_DYNAMIC: 675aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant switch (SecI->getFlags()) { 676aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR): 677aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 't'; 678aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case (ELF::SHF_TLS | ELF::SHF_ALLOC | ELF::SHF_WRITE): 679aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case (ELF::SHF_ALLOC | ELF::SHF_WRITE): 680aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 'd'; 681aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case ELF::SHF_ALLOC: 682aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case (ELF::SHF_ALLOC | ELF::SHF_MERGE): 683aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS): 684aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 'r'; 685aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 686aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant break; 687aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case ELF::SHT_NOBITS: 688aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 'b'; 689aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 690aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 691aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 692aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SymI->getELFType() == ELF::STT_SECTION) { 693aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ErrorOr<StringRef> Name = SymI->getName(); 694aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (error(Name.getError())) 695aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return '?'; 696aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return StringSwitch<char>(*Name) 697aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant .StartsWith(".debug", 'N') 698aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant .StartsWith(".note", 'n') 699aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant .Default('?'); 700aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 701aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 702aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 'n'; 703aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 704aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 705aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { 706aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant COFFSymbolRef Symb = Obj.getCOFFSymbol(*I); 707aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // OK, this is COFF. 708aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant symbol_iterator SymI(I); 709aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 710aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ErrorOr<StringRef> Name = SymI->getName(); 711aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (error(Name.getError())) 712aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return '?'; 713aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 714aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant char Ret = StringSwitch<char>(*Name) 715aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant .StartsWith(".debug", 'N') 716aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant .StartsWith(".sxdata", 'N') 717aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant .Default('?'); 718aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 719aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Ret != '?') 720aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return Ret; 721aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 722aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint32_t Characteristics = 0; 723aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) { 724aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ErrorOr<section_iterator> SecIOrErr = SymI->getSection(); 725aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (error(SecIOrErr.getError())) 726aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return '?'; 727aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant section_iterator SecI = *SecIOrErr; 728aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant const coff_section *Section = Obj.getCOFFSection(*SecI); 729aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Characteristics = Section->Characteristics; 730aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 731aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 732aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant switch (Symb.getSectionNumber()) { 733aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case COFF::IMAGE_SYM_DEBUG: 734aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 'n'; 735aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant default: 736aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // Check section type. 737aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) 738aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 't'; 739aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) 740aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return Characteristics & COFF::IMAGE_SCN_MEM_WRITE ? 'd' : 'r'; 741aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) 742aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 'b'; 743aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) 744aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 'i'; 745aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // Check for section symbol. 746aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Symb.isSectionDefinition()) 747aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 's'; 748aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 749aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 750aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return '?'; 751aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 752aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 753aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic uint8_t getNType(MachOObjectFile &Obj, DataRefImpl Symb) { 754aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Obj.is64Bit()) { 755aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb); 756aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return STE.n_type; 757aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 758aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO::nlist STE = Obj.getSymbolTableEntry(Symb); 759aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return STE.n_type; 760aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 761aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 762aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) { 763aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant DataRefImpl Symb = I->getRawDataRefImpl(); 764aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint8_t NType = getNType(Obj, Symb); 765aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 766aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (NType & MachO::N_STAB) 767aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return '-'; 768aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 769aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant switch (NType & MachO::N_TYPE) { 770aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case MachO::N_ABS: 771aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 's'; 772aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case MachO::N_INDR: 773aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 'i'; 774aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case MachO::N_SECT: { 775aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant section_iterator Sec = *Obj.getSymbolSection(Symb); 776aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant DataRefImpl Ref = Sec->getRawDataRefImpl(); 777aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant StringRef SectionName; 778aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Obj.getSectionName(Ref, SectionName); 779aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant StringRef SegmentName = Obj.getSectionFinalSegmentName(Ref); 780aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SegmentName == "__TEXT" && SectionName == "__text") 781aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 't'; 782aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else if (SegmentName == "__DATA" && SectionName == "__data") 783aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 'd'; 784aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else if (SegmentName == "__DATA" && SectionName == "__bss") 785aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 'b'; 786aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 787aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 's'; 788aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 789aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 790aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 791aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return '?'; 792aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 793aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 794aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic char getSymbolNMTypeChar(const GlobalValue &GV) { 795aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (GV.getType()->getElementType()->isFunctionTy()) 796aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 't'; 797aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // FIXME: should we print 'b'? At the IR level we cannot be sure if this 798aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // will be in bss or not, but we could approximate. 799aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 'd'; 800aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 801aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 802aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) { 803aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant const GlobalValue *GV = Obj.getSymbolGV(I->getRawDataRefImpl()); 804aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!GV) 805aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 't'; 806aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return getSymbolNMTypeChar(*GV); 807aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 808aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 809aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic bool isObject(SymbolicFile &Obj, basic_symbol_iterator I) { 810aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant auto *ELF = dyn_cast<ELFObjectFileBase>(&Obj); 811aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!ELF) 812aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return false; 813aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 814aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return elf_symbol_iterator(I)->getELFType() == ELF::STT_OBJECT; 815aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 816aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 817aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic char getNMTypeChar(SymbolicFile &Obj, basic_symbol_iterator I) { 818aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint32_t Symflags = I->getFlags(); 819aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if ((Symflags & object::SymbolRef::SF_Weak) && !isa<MachOObjectFile>(Obj)) { 820aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant char Ret = isObject(Obj, I) ? 'v' : 'w'; 821aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!(Symflags & object::SymbolRef::SF_Undefined)) 822aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Ret = toupper(Ret); 823aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return Ret; 824aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 825aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 826aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Symflags & object::SymbolRef::SF_Undefined) 827aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 'U'; 828aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 829aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Symflags & object::SymbolRef::SF_Common) 830aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 'C'; 831aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 832aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant char Ret = '?'; 833aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Symflags & object::SymbolRef::SF_Absolute) 834aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Ret = 'a'; 835aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj)) { 836aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Ret = getSymbolNMTypeChar(*IR, I); 837aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Triple Host(sys::getDefaultTargetTriple()); 838aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Ret == 'd' && Host.isOSDarwin()) { 839aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if(Symflags & SymbolRef::SF_Const) 840aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Ret = 's'; 841aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 842aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 843aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(&Obj)) 844aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Ret = getSymbolNMTypeChar(*COFF, I); 845aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj)) 846aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Ret = getSymbolNMTypeChar(*MachO, I); 847aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 848aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Ret = getSymbolNMTypeChar(cast<ELFObjectFileBase>(Obj), I); 849aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 850aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Symflags & object::SymbolRef::SF_Global) 851aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Ret = toupper(Ret); 852aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 853aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return Ret; 854aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 855aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 856aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// getNsectForSegSect() is used to implement the Mach-O "-s segname sectname" 857aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// option to dump only those symbols from that section in a Mach-O file. 858aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// It is called once for each Mach-O file from dumpSymbolNamesFromObject() 859aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// to get the section number for that named section from the command line 860aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// arguments. It returns the section number for that section in the Mach-O 861aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// file or zero it is not present. 862aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic unsigned getNsectForSegSect(MachOObjectFile *Obj) { 863aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant unsigned Nsect = 1; 864aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant for (section_iterator I = Obj->section_begin(), E = Obj->section_end(); 865aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant I != E; ++I) { 866aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant DataRefImpl Ref = I->getRawDataRefImpl(); 867aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant StringRef SectionName; 868aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Obj->getSectionName(Ref, SectionName); 869aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant StringRef SegmentName = Obj->getSectionFinalSegmentName(Ref); 870aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SegmentName == SegSect[0] && SectionName == SegSect[1]) 871aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return Nsect; 872aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Nsect++; 873aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 874aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 0; 875aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 876aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 877aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// getNsectInMachO() is used to implement the Mach-O "-s segname sectname" 878aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// option to dump only those symbols from that section in a Mach-O file. 879aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// It is called once for each symbol in a Mach-O file from 880aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// dumpSymbolNamesFromObject() and returns the section number for that symbol 881aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// if it is in a section, else it returns 0. 882aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic unsigned getNsectInMachO(MachOObjectFile &Obj, BasicSymbolRef Sym) { 883aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant DataRefImpl Symb = Sym.getRawDataRefImpl(); 884aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Obj.is64Bit()) { 885aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb); 886aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if ((STE.n_type & MachO::N_TYPE) == MachO::N_SECT) 887aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return STE.n_sect; 888aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 0; 889aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 890aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO::nlist STE = Obj.getSymbolTableEntry(Symb); 891aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if ((STE.n_type & MachO::N_TYPE) == MachO::N_SECT) 892aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return STE.n_sect; 893aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 0; 894aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 895aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 896aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, 897aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::string ArchiveName = std::string(), 898aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::string ArchitectureName = 899aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::string()) { 900aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant auto Symbols = Obj.symbols(); 901aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (DynamicSyms) { 902aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant const auto *E = dyn_cast<ELFObjectFileBase>(&Obj); 903aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!E) { 904aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant error("File format has no dynamic symbol table", Obj.getFileName()); 905aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 906aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 907aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant auto DynSymbols = E->getDynamicSymbolIterators(); 908aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Symbols = 909aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant make_range<basic_symbol_iterator>(DynSymbols.begin(), DynSymbols.end()); 910aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 911aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::string NameBuffer; 912aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant raw_string_ostream OS(NameBuffer); 913aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // If a "-s segname sectname" option was specified and this is a Mach-O 914aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // file get the section number for that section in this object file. 915aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant unsigned int Nsect = 0; 916aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj); 917aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SegSect.size() != 0 && MachO) { 918aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Nsect = getNsectForSegSect(MachO); 919aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // If this section is not in the object file no symbols are printed. 920aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Nsect == 0) 921aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 922aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 923aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant for (BasicSymbolRef Sym : Symbols) { 924aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant uint32_t SymFlags = Sym.getFlags(); 925aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific)) 926aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant continue; 927aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (WithoutAliases) { 928aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj)) { 929aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant const GlobalValue *GV = IR->getSymbolGV(Sym.getRawDataRefImpl()); 930aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (GV && isa<GlobalAlias>(GV)) 931aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant continue; 932aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 933aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 934aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // If a "-s segname sectname" option was specified and this is a Mach-O 935aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // file and this section appears in this file, Nsect will be non-zero then 936aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // see if this symbol is a symbol from that section and if not skip it. 937aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Nsect && Nsect != getNsectInMachO(*MachO, Sym)) 938aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant continue; 939aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant NMSymbol S; 940aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant S.Size = 0; 941aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant S.Address = 0; 942aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (PrintSize) { 943aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (isa<ELFObjectFileBase>(&Obj)) 944aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant S.Size = ELFSymbolRef(Sym).getSize(); 945aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 946aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (PrintAddress && isa<ObjectFile>(Obj)) { 947aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant SymbolRef SymRef(Sym); 948aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ErrorOr<uint64_t> AddressOrErr = SymRef.getAddress(); 949aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (error(AddressOrErr.getError())) 950aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant break; 951aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant S.Address = *AddressOrErr; 952aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 953aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant S.TypeChar = getNMTypeChar(Obj, Sym); 954aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (error(Sym.printName(OS))) 955aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant break; 956aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant OS << '\0'; 957aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant S.Sym = Sym; 958aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant SymbolList.push_back(S); 959aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 960aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 961aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant OS.flush(); 962aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant const char *P = NameBuffer.c_str(); 963aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant for (unsigned I = 0; I < SymbolList.size(); ++I) { 964aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant SymbolList[I].Name = P; 965aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant P += strlen(P) + 1; 966aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 967aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 968aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant CurrentFilename = Obj.getFileName(); 969aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant sortAndPrintSymbolList(Obj, printName, ArchiveName, ArchitectureName); 970aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 971aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 972aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// checkMachOAndArchFlags() checks to see if the SymbolicFile is a Mach-O file 973aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// and if it is and there is a list of architecture flags is specified then 974aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// check to make sure this Mach-O file is one of those architectures or all 975aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// architectures was specificed. If not then an error is generated and this 976aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant// routine returns false. Else it returns true. 977aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic bool checkMachOAndArchFlags(SymbolicFile *O, std::string &Filename) { 978aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(O); 979aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 980aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!MachO || ArchAll || ArchFlags.size() == 0) 981aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return true; 982aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 983aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO::mach_header H; 984aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MachO::mach_header_64 H_64; 985aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Triple T; 986aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (MachO->is64Bit()) { 987aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant H_64 = MachO->MachOObjectFile::getHeader64(); 988aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype); 989aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else { 990aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant H = MachO->MachOObjectFile::getHeader(); 991aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant T = MachOObjectFile::getArch(H.cputype, H.cpusubtype); 992aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 993aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (std::none_of( 994aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchFlags.begin(), ArchFlags.end(), 995aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant [&](const std::string &Name) { return Name == T.getArchName(); })) { 996aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant error("No architecture specified", Filename); 997aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return false; 998aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 999aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return true; 1000aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 1001aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 1002aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantstatic void dumpSymbolNamesFromFile(std::string &Filename) { 1003aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = 1004aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MemoryBuffer::getFileOrSTDIN(Filename); 1005aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (error(BufferOrErr.getError(), Filename)) 1006aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 1007aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 1008aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant LLVMContext &Context = getGlobalContext(); 1009aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = createBinary( 1010aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant BufferOrErr.get()->getMemBufferRef(), NoLLVMBitcode ? nullptr : &Context); 1011aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (error(BinaryOrErr.getError(), Filename)) 1012aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 1013aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Binary &Bin = *BinaryOrErr.get(); 1014aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 1015aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (Archive *A = dyn_cast<Archive>(&Bin)) { 1016aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (ArchiveMap) { 1017aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Archive::symbol_iterator I = A->symbol_begin(); 1018aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant Archive::symbol_iterator E = A->symbol_end(); 1019aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (I != E) { 1020aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "Archive map\n"; 1021aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant for (; I != E; ++I) { 1022aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ErrorOr<Archive::Child> C = I->getMember(); 1023aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (error(C.getError())) 1024aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 1025aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ErrorOr<StringRef> FileNameOrErr = C->getName(); 1026aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (error(FileNameOrErr.getError())) 1027aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 1028aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant StringRef SymName = I->getName(); 1029aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << SymName << " in " << FileNameOrErr.get() << "\n"; 1030aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1031aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "\n"; 1032aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1033aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1034aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 1035aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant for (Archive::child_iterator I = A->child_begin(), E = A->child_end(); 1036aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant I != E; ++I) { 1037aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (error(I->getError())) 1038aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 1039aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant auto &C = I->get(); 1040aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context); 1041aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (ChildOrErr.getError()) 1042aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant continue; 1043aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1044aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!checkMachOAndArchFlags(O, Filename)) 1045aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 1046aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!PrintFileName) { 1047aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "\n"; 1048aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (isa<MachOObjectFile>(O)) { 1049aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << Filename << "(" << O->getFileName() << ")"; 1050aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else 1051aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << O->getFileName(); 1052aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << ":\n"; 1053aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1054aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant dumpSymbolNamesFromObject(*O, false, Filename); 1055aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1056aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1057aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 1058aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1059aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) { 1060aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // If we have a list of architecture flags specified dump only those. 1061aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!ArchAll && ArchFlags.size() != 0) { 1062aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // Look for a slice in the universal binary that matches each ArchFlag. 1063aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant bool ArchFound; 1064aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant for (unsigned i = 0; i < ArchFlags.size(); ++i) { 1065aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchFound = false; 1066aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 1067aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant E = UB->end_objects(); 1068aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant I != E; ++I) { 1069aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (ArchFlags[i] == I->getArchTypeName()) { 1070aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchFound = true; 1071aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = 1072aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant I->getAsObjectFile(); 1073aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::string ArchiveName; 1074aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::string ArchitectureName; 1075aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchiveName.clear(); 1076aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchitectureName.clear(); 1077aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (ObjOrErr) { 1078aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ObjectFile &Obj = *ObjOrErr.get(); 1079aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (ArchFlags.size() > 1) { 1080aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (PrintFileName) 1081aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchitectureName = I->getArchTypeName(); 1082aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 1083aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "\n" << Obj.getFileName() << " (for architecture " 1084aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant << I->getArchTypeName() << ")" 1085aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant << ":\n"; 1086aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1087aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant dumpSymbolNamesFromObject(Obj, false, ArchiveName, 1088aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchitectureName); 1089aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = 1090aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant I->getAsArchive()) { 1091aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::unique_ptr<Archive> &A = *AOrErr; 1092aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant for (Archive::child_iterator AI = A->child_begin(), 1093aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant AE = A->child_end(); 1094aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant AI != AE; ++AI) { 1095aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (error(AI->getError())) 1096aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 1097aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant auto &C = AI->get(); 1098aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ErrorOr<std::unique_ptr<Binary>> ChildOrErr = 1099aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant C.getAsBinary(&Context); 1100aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (ChildOrErr.getError()) 1101aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant continue; 1102aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SymbolicFile *O = 1103aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1104aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (PrintFileName) { 1105aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchiveName = A->getFileName(); 1106aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (ArchFlags.size() > 1) 1107aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchitectureName = I->getArchTypeName(); 1108aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else { 1109aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "\n" << A->getFileName(); 1110aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "(" << O->getFileName() << ")"; 1111aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (ArchFlags.size() > 1) { 1112aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << " (for architecture " << I->getArchTypeName() 1113aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant << ")"; 1114aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1115aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << ":\n"; 1116aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1117aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant dumpSymbolNamesFromObject(*O, false, ArchiveName, 1118aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchitectureName); 1119aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1120aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1121aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1122aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1123aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1124aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!ArchFound) { 1125aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant error(ArchFlags[i], 1126aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant "file: " + Filename + " does not contain architecture"); 1127aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 1128aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1129aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1130aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 1131aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1132aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // No architecture flags were specified so if this contains a slice that 1133aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // matches the host architecture dump only that. 1134aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!ArchAll) { 1135aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant StringRef HostArchName = MachOObjectFile::getHostArch().getArchName(); 1136aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 1137aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant E = UB->end_objects(); 1138aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant I != E; ++I) { 1139aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (HostArchName == I->getArchTypeName()) { 1140aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); 1141aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::string ArchiveName; 1142aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchiveName.clear(); 1143aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (ObjOrErr) { 1144aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ObjectFile &Obj = *ObjOrErr.get(); 1145aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant dumpSymbolNamesFromObject(Obj, false); 1146aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = 1147aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant I->getAsArchive()) { 1148aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::unique_ptr<Archive> &A = *AOrErr; 1149aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant for (Archive::child_iterator AI = A->child_begin(), 1150aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant AE = A->child_end(); 1151aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant AI != AE; ++AI) { 1152aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (error(AI->getError())) 1153aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 1154aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant auto &C = AI->get(); 1155aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ErrorOr<std::unique_ptr<Binary>> ChildOrErr = 1156aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant C.getAsBinary(&Context); 1157aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (ChildOrErr.getError()) 1158aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant continue; 1159aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SymbolicFile *O = 1160aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1161aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (PrintFileName) 1162aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchiveName = A->getFileName(); 1163aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant else 1164aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "\n" << A->getFileName() << "(" << O->getFileName() 1165aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant << ")" 1166aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant << ":\n"; 1167aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant dumpSymbolNamesFromObject(*O, false, ArchiveName); 1168aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1169aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1170aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1171aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 1172aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1173aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1174aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1175aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // Either all architectures have been specified or none have been specified 1176aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // and this does not contain the host architecture so dump all the slices. 1177aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant bool moreThanOneArch = UB->getNumberOfObjects() > 1; 1178aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 1179aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant E = UB->end_objects(); 1180aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant I != E; ++I) { 1181aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); 1182aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::string ArchiveName; 1183aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::string ArchitectureName; 1184aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchiveName.clear(); 1185aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchitectureName.clear(); 1186aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (ObjOrErr) { 1187aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ObjectFile &Obj = *ObjOrErr.get(); 1188aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (PrintFileName) { 1189aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (isa<MachOObjectFile>(Obj) && moreThanOneArch) 1190aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchitectureName = I->getArchTypeName(); 1191aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else { 1192aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (moreThanOneArch) 1193aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "\n"; 1194aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << Obj.getFileName(); 1195aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (isa<MachOObjectFile>(Obj) && moreThanOneArch) 1196aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << " (for architecture " << I->getArchTypeName() << ")"; 1197aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << ":\n"; 1198aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1199aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName); 1200aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) { 1201aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::unique_ptr<Archive> &A = *AOrErr; 1202aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); 1203aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant AI != AE; ++AI) { 1204aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (error(AI->getError())) 1205aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 1206aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant auto &C = AI->get(); 1207aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context); 1208aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (ChildOrErr.getError()) 1209aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant continue; 1210aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1211aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (PrintFileName) { 1212aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchiveName = A->getFileName(); 1213aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (isa<MachOObjectFile>(O) && moreThanOneArch) 1214aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchitectureName = I->getArchTypeName(); 1215aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else { 1216aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "\n" << A->getFileName(); 1217aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (isa<MachOObjectFile>(O)) { 1218aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << "(" << O->getFileName() << ")"; 1219aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (moreThanOneArch) 1220aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << " (for architecture " << I->getArchTypeName() 1221aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant << ")"; 1222aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else 1223aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << ":" << O->getFileName(); 1224aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant outs() << ":\n"; 1225aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1226aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant dumpSymbolNamesFromObject(*O, false, ArchiveName, ArchitectureName); 1227aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1228aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1229aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1230aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1231aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 1232aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1233aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin)) { 1234aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!checkMachOAndArchFlags(O, Filename)) 1235aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 1236aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant dumpSymbolNamesFromObject(*O, true); 1237aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return; 1238aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1239aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant error("unrecognizable file type", Filename); 1240aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 1241aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 1242aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnantint main(int argc, char **argv) { 1243aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // Print a stack trace if we signal out. 1244aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant sys::PrintStackTraceOnErrorSignal(); 1245aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant PrettyStackTraceProgram X(argc, argv); 1246aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 1247aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 1248aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n"); 1249aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 1250aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // llvm-nm only reads binary files. 1251aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (error(sys::ChangeStdinToBinary())) 1252aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 1; 1253aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 1254aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant llvm::InitializeAllTargetInfos(); 1255aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant llvm::InitializeAllTargetMCs(); 1256aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant llvm::InitializeAllAsmParsers(); 1257aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 1258aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ToolName = argv[0]; 1259aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (BSDFormat) 1260aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant OutputFormat = bsd; 1261aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (POSIXFormat) 1262aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant OutputFormat = posix; 1263aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (DarwinFormat) 1264aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant OutputFormat = darwin; 1265aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 1266aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // The relative order of these is important. If you pass --size-sort it should 1267aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // only print out the size. However, if you pass -S --size-sort, it should 1268aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant // print out both the size and address. 1269aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SizeSort && !PrintSize) 1270aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant PrintAddress = false; 1271aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (OutputFormat == sysv || SizeSort) 1272aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant PrintSize = true; 1273aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 1274aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant switch (InputFilenames.size()) { 1275aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case 0: 1276aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant InputFilenames.push_back("a.out"); 1277aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant case 1: 1278aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant break; 1279aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant default: 1280aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant MultipleFiles = true; 1281aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1282aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 1283aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant for (unsigned i = 0; i < ArchFlags.size(); ++i) { 1284aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (ArchFlags[i] == "all") { 1285aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant ArchAll = true; 1286aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } else { 1287aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (!MachOObjectFile::isValidArch(ArchFlags[i])) 1288aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant error("Unknown architecture named '" + ArchFlags[i] + "'", 1289aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant "for the -arch option"); 1290aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant } 1291eda3fcaaedc2c6a13fce15fbe5fd472b642dc830Ed Schouten } 1292aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 1293aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (SegSect.size() != 0 && SegSect.size() != 2) 1294aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant error("bad number of arguments (must be two arguments)", 1295aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant "for the -s option"); 1296aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 1297aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant std::for_each(InputFilenames.begin(), InputFilenames.end(), 1298aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant dumpSymbolNamesFromFile); 1299aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 1300aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant if (HadError) 1301aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 1; 1302aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant 1303aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant return 0; 1304aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant} 1305aa78f9cdb3c8a049660deb39c9296501d2467d78Howard Hinnant