llvm-nm.cpp 41 KB

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