From: Kevin Enderby Date: Thu, 17 Jul 2014 22:47:16 +0000 (+0000) Subject: Add printing of Mach-O stabs in llvm-nm. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=c61aa0219e17ac92f1275bb42502448eb4310d5e;hp=5d83e5bdd52addadd83dafb10edc5f66194036f9;p=oota-llvm.git Add printing of Mach-O stabs in llvm-nm. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213327 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h index bd4dc2f6d1b..57d7dff8933 100644 --- a/include/llvm/Support/MachO.h +++ b/include/llvm/Support/MachO.h @@ -386,13 +386,15 @@ namespace llvm { enum StabType { // Constant values for the "n_type" field in llvm::MachO::nlist and - // llvm::MachO::nlist_64 when "(n_type & NlistMaskStab) != 0" + // llvm::MachO::nlist_64 when "(n_type & N_STAB) != 0" N_GSYM = 0x20u, N_FNAME = 0x22u, N_FUN = 0x24u, N_STSYM = 0x26u, N_LCSYM = 0x28u, N_BNSYM = 0x2Eu, + N_PC = 0x30u, + N_AST = 0x32u, N_OPT = 0x3Cu, N_RSYM = 0x40u, N_SLINE = 0x44u, diff --git a/test/Object/Inputs/macho-hello-g.macho-x86_64 b/test/Object/Inputs/macho-hello-g.macho-x86_64 new file mode 100755 index 00000000000..41be03a0e2a Binary files /dev/null and b/test/Object/Inputs/macho-hello-g.macho-x86_64 differ diff --git a/test/Object/nm-trivial-object.test b/test/Object/nm-trivial-object.test index 98bf9f92f2f..49c7683c80d 100644 --- a/test/Object/nm-trivial-object.test +++ b/test/Object/nm-trivial-object.test @@ -26,6 +26,8 @@ RUN: llvm-nm %p/Inputs/macho-text-data-bss.macho-x86_64 -s __DATA __data \ RUN: | FileCheck %s -check-prefix macho-s RUN: llvm-nm -x %p/Inputs/macho-text-data-bss.macho-x86_64 \ RUN: | FileCheck %s -check-prefix macho-x +RUN: llvm-nm -p -a %p/Inputs/macho-hello-g.macho-x86_64 \ +RUN: | FileCheck %s -check-prefix macho-pa RUN: llvm-nm %p/Inputs/common.coff-i386 \ RUN: | FileCheck %s -check-prefix COFF-COMMON RUN: llvm-nm %p/Inputs/relocatable-with-section-address.elf-x86-64 \ @@ -115,6 +117,19 @@ macho-x: 000000000000000c 0f 02 0000 00000004 _d macho-x: 0000000000000000 0f 01 0000 00000001 _t macho-x: 0000000000000048 0f 05 0000 00000007 _t.eh +macho-pa: 0000000000000000 - 00 0000 SO /Volumes/SandBox/ +macho-pa: 0000000000000000 - 00 0000 SO hello.c +macho-pa: 0000000053c8408d - 03 0001 OSO /Volumes/SandBox/hello.o +macho-pa: 0000000100000f30 - 01 0000 BNSYM +macho-pa: 0000000100000f30 - 01 0000 FUN _main +macho-pa: 000000000000003b - 00 0000 FUN +macho-pa: 000000000000003b - 01 0000 ENSYM +macho-pa: 0000000000000000 - 01 0000 SO +macho-pa: 0000000100000000 T __mh_execute_header +macho-pa: 0000000100000f30 T _main +macho-pa: U _printf +macho-pa: U dyld_stub_binder + Test that nm uses addresses even with ELF .o files. ELF-SEC-ADDR64: 0000000000000058 D a ELF-SEC-ADDR64-NEXT: 000000000000005c D b diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index d3d4f998e64..b0336d3c8ce 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -457,6 +457,84 @@ static void darwinPrintSymbol(MachOObjectFile *MachO, SymbolListT::iterator I, outs() << "\n"; } +// Table that maps Darwin's Mach-O stab constants to strings to allow printing. +struct DarwinStabName { + uint8_t NType; + const char *Name; +}; +static const struct DarwinStabName DarwinStabNames[] = { + {MachO::N_GSYM, "GSYM"}, + {MachO::N_FNAME, "FNAME"}, + {MachO::N_FUN, "FUN"}, + {MachO::N_STSYM, "STSYM"}, + {MachO::N_LCSYM, "LCSYM"}, + {MachO::N_BNSYM, "BNSYM"}, + {MachO::N_PC, "PC"}, + {MachO::N_AST, "AST"}, + {MachO::N_OPT, "OPT"}, + {MachO::N_RSYM, "RSYM"}, + {MachO::N_SLINE, "SLINE"}, + {MachO::N_ENSYM, "ENSYM"}, + {MachO::N_SSYM, "SSYM"}, + {MachO::N_SO, "SO"}, + {MachO::N_OSO, "OSO"}, + {MachO::N_LSYM, "LSYM"}, + {MachO::N_BINCL, "BINCL"}, + {MachO::N_SOL, "SOL"}, + {MachO::N_PARAMS, "PARAM"}, + {MachO::N_VERSION, "VERS"}, + {MachO::N_OLEVEL, "OLEV"}, + {MachO::N_PSYM, "PSYM"}, + {MachO::N_EINCL, "EINCL"}, + {MachO::N_ENTRY, "ENTRY"}, + {MachO::N_LBRAC, "LBRAC"}, + {MachO::N_EXCL, "EXCL"}, + {MachO::N_RBRAC, "RBRAC"}, + {MachO::N_BCOMM, "BCOMM"}, + {MachO::N_ECOMM, "ECOMM"}, + {MachO::N_ECOML, "ECOML"}, + {MachO::N_LENG, "LENG"}, + {0, 0}}; +static const char *getDarwinStabString(uint8_t NType) { + for (unsigned i = 0; DarwinStabNames[i].Name; i++) { + if (DarwinStabNames[i].NType == NType) + return DarwinStabNames[i].Name; + } + return 0; +} + +// darwinPrintStab() prints the n_sect, n_desc along with a symbolic name of +// a stab n_type value in a Mach-O file. +static void darwinPrintStab(MachOObjectFile *MachO, SymbolListT::iterator I) { + MachO::nlist_64 STE_64; + MachO::nlist STE; + uint8_t NType; + uint8_t NSect; + uint16_t NDesc; + if (MachO->is64Bit()) { + STE_64 = MachO->getSymbol64TableEntry(I->Symb); + NType = STE_64.n_type; + NSect = STE_64.n_sect; + NDesc = STE_64.n_desc; + } else { + STE = MachO->getSymbolTableEntry(I->Symb); + NType = STE.n_type; + NSect = STE.n_sect; + NDesc = STE.n_desc; + } + + char Str[18] = ""; + format("%02x", NSect).print(Str, sizeof(Str)); + outs() << ' ' << Str << ' '; + format("%04x", NDesc).print(Str, sizeof(Str)); + outs() << Str << ' '; + if (const char *stabString = getDarwinStabString(NType)) + format("%5.5s", stabString).print(Str, sizeof(Str)); + else + format(" %02x", NType).print(Str, sizeof(Str)); + outs() << Str; +} + static void sortAndPrintSymbolList(SymbolicFile *Obj, bool printName) { if (!NoSort) { if (NumericSort) @@ -532,7 +610,10 @@ static void sortAndPrintSymbolList(SymbolicFile *Obj, bool printName) { if (I->Size != UnknownAddressOrSize) outs() << ' '; } - outs() << I->TypeChar << " " << I->Name << "\n"; + outs() << I->TypeChar; + if (I->TypeChar == '-' && MachO) + darwinPrintStab(MachO, I); + outs() << " " << I->Name << "\n"; } else if (OutputFormat == sysv) { std::string PaddedName(I->Name); while (PaddedName.length() < 20) @@ -657,6 +738,9 @@ static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) { DataRefImpl Symb = I->getRawDataRefImpl(); uint8_t NType = getNType(Obj, Symb); + if (NType & MachO::N_STAB) + return '-'; + switch (NType & MachO::N_TYPE) { case MachO::N_ABS: return 's';