From 15f2c50e632667e391a334e8b6026bc17556a276 Mon Sep 17 00:00:00 2001 From: Kevin Enderby Date: Wed, 16 Jul 2014 17:38:26 +0000 Subject: [PATCH] =?UTF-8?q?Add=20the=20"-x"=20flag=20to=20llvm-nm=20for=20?= =?UTF-8?q?Mach-O=20files=20that=20prints=20the=20fields=20of=20a=20symbol?= =?UTF-8?q?=20in=20hex.=20(generally=20use=20for=20debugging=20the=20tools?= =?UTF-8?q?).=20=C2=A0This=20is=20same=20functionality=20as=20darwin?= =?UTF-8?q?=E2=80=99s=20nm(1)=20"-x"=20flag.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213176 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/Object/nm-trivial-object.test | 8 +++++ tools/llvm-nm/llvm-nm.cpp | 47 ++++++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/test/Object/nm-trivial-object.test b/test/Object/nm-trivial-object.test index 93ddb0c56c1..98bf9f92f2f 100644 --- a/test/Object/nm-trivial-object.test +++ b/test/Object/nm-trivial-object.test @@ -24,6 +24,8 @@ RUN: llvm-nm -r %p/Inputs/macho-text-data-bss.macho-x86_64 \ RUN: | FileCheck %s -check-prefix macho-r 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/Inputs/common.coff-i386 \ RUN: | FileCheck %s -check-prefix COFF-COMMON RUN: llvm-nm %p/Inputs/relocatable-with-section-address.elf-x86-64 \ @@ -107,6 +109,12 @@ macho-s-NOT: 0000000000000000 T _t macho-s-NOT: 0000000000000070 b _b macho-s-NOT: 0000000000000030 s EH_frame0 +macho-x: 0000000000000030 0e 05 0000 00000010 EH_frame0 +macho-x: 0000000000000070 0e 03 0000 0000000d _b +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 + 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 e09d682d81d..d3d4f998e64 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -146,6 +146,9 @@ cl::list SegSect("s", cl::Positional, cl::ZeroOrMore, cl::desc("Dump only symbols from this segment " "and section name, Mach-O only")); +cl::opt FormatMachOasHex("x", cl::desc("Print symbol entry in hex, " + "Mach-O only")); + bool PrintAddress = true; bool MultipleFiles = false; @@ -268,8 +271,10 @@ typedef std::vector SymbolListT; static SymbolListT SymbolList; // darwinPrintSymbol() is used to print a symbol from a Mach-O file when the -// the OutputFormat is darwin. It produces the same output as darwin's nm(1) -m -// output. +// the OutputFormat is darwin or we are printing Mach-O symbols in hex. For +// the darwin format it produces the same output as darwin's nm(1) -m output +// and when printing Mach-O symbols in hex it produces the same output as +// darwin's nm(1) -x format. static void darwinPrintSymbol(MachOObjectFile *MachO, SymbolListT::iterator I, char *SymbolAddrStr, const char *printBlanks) { MachO::mach_header H; @@ -278,7 +283,9 @@ static void darwinPrintSymbol(MachOObjectFile *MachO, SymbolListT::iterator I, MachO::nlist_64 STE_64; MachO::nlist STE; uint8_t NType; + uint8_t NSect; uint16_t NDesc; + uint32_t NStrx; uint64_t NValue; if (MachO->is64Bit()) { H_64 = MachO->MachOObjectFile::getHeader64(); @@ -286,7 +293,9 @@ static void darwinPrintSymbol(MachOObjectFile *MachO, SymbolListT::iterator I, Flags = H_64.flags; STE_64 = MachO->getSymbol64TableEntry(I->Symb); NType = STE_64.n_type; + NSect = STE_64.n_sect; NDesc = STE_64.n_desc; + NStrx = STE_64.n_strx; NValue = STE_64.n_value; } else { H = MachO->MachOObjectFile::getHeader(); @@ -294,10 +303,34 @@ static void darwinPrintSymbol(MachOObjectFile *MachO, SymbolListT::iterator I, Flags = H.flags; STE = MachO->getSymbolTableEntry(I->Symb); NType = STE.n_type; + NSect = STE.n_sect; NDesc = STE.n_desc; + NStrx = STE.n_strx; NValue = STE.n_value; } + // If we are printing Mach-O symbols in hex do that and return. + if (FormatMachOasHex) { + char Str[18] = ""; + const char *printFormat; + if (MachO->is64Bit()) + printFormat = "%016" PRIx64; + else + printFormat = "%08" PRIx64; + format(printFormat, NValue).print(Str, sizeof(Str)); + outs() << Str << ' '; + format("%02x", NType).print(Str, sizeof(Str)); + outs() << Str << ' '; + format("%02x", NSect).print(Str, sizeof(Str)); + outs() << Str << ' '; + format("%04x", NDesc).print(Str, sizeof(Str)); + outs() << Str << ' '; + format("%08x", NStrx).print(Str, sizeof(Str)); + outs() << Str << ' '; + outs() << I->Name << "\n"; + return; + } + if (PrintAddress) { if ((NType & MachO::N_TYPE) == MachO::N_INDR) strcpy(SymbolAddrStr, printBlanks); @@ -480,11 +513,13 @@ static void sortAndPrintSymbolList(SymbolicFile *Obj, bool printName) { if (I->Size != UnknownAddressOrSize) format(printFormat, I->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr)); - // If OutputFormat is darwin and we have a MachOObjectFile print as darwin's - // nm(1) -m output, else if OutputFormat is darwin and not a Mach-O object - // fall back to OutputFormat bsd (see below). + // If OutputFormat is darwin or we are printing Mach-O symbols in hex and + // we have a MachOObjectFile, call darwinPrintSymbol to print as darwin's + // nm(1) -m output or hex, else if OutputFormat is darwin or we are + // printing Mach-O symbols in hex and not a Mach-O object fall back to + // OutputFormat bsd (see below). MachOObjectFile *MachO = dyn_cast(Obj); - if (OutputFormat == darwin && MachO) { + if ((OutputFormat == darwin || FormatMachOasHex) && MachO) { darwinPrintSymbol(MachO, I, SymbolAddrStr, printBlanks); } else if (OutputFormat == posix) { outs() << I->Name << " " << I->TypeChar << " " << SymbolAddrStr