<div dir="ltr"><pre><span class="gmail-stdout"><font color="#000000" face="Courier New, courier, monotype, monospace" size="3"><a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/5758/steps/check-llvm%20msan/logs/stdio">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/5758/steps/check-llvm%20msan/logs/stdio</a><br></font></span></pre><pre><span class="gmail-stdout"><font color="#000000" face="Courier New, courier, monotype, monospace" size="3"><br></font></span></pre><pre style="font-family:"Courier New",courier,monotype,monospace;color:rgb(0,0,0);font-size:medium"><span class="gmail-stdout">Command Output (stderr):
--
==28618==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x51239a in sortAndPrintSymbolList(llvm::object::SymbolicFile&, bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/llvm-nm/llvm-nm.cpp:733:21
#1 0x5043d7 in dumpSymbolNamesFromObject(llvm::object::SymbolicFile&, bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/llvm-nm/llvm-nm.cpp:1534:3
#2 0x4ef45c in dumpSymbolNamesFromFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/llvm-nm/llvm-nm.cpp:1633:11
#3 0x4e34f2 in for_each<std::__1::__wrap_iter<std::__1::basic_string<char> *>, void (*)(std::__1::basic_string<char> &)> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/libcxx_build_msan/include/c++/v1/algorithm:965:9
#4 0x4e34f2 in main /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/llvm-nm/llvm-nm.cpp:1925
#5 0x7f4274b8482f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#6 0x476fd8 in _start (/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm_build_msan/bin/llvm-nm+0x476fd8)
SUMMARY: MemorySanitizer: use-of-uninitialized-value /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/llvm-nm/llvm-nm.cpp:733:21 in sortAndPrintSymbolList(llvm::object::SymbolicFile&, bool, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Exiting
FileCheck error: '-' is empty.
FileCheck command line: /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm_build_msan/./bin/FileCheck --check-prefix=COFF-SHORT-IMPORT /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/test/Object/archive-symtab.test
--
</span></pre><div><span class="gmail-stdout"><br></span></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jun 19, 2017 at 12:38 PM, Kevin Enderby via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: enderby<br>
Date: Mon Jun 19 14:38:22 2017<br>
New Revision: 305733<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=305733&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=305733&view=rev</a><br>
Log:<br>
Change llvm-nm for Mach-O files to use dyld info in some cases when printing symbols.<br>
<br>
In order to reduce swift binary sizes, Apple is now stripping swift symbols<br>
from the nlist symbol table. llvm-nm currently only looks at the nlist symbol<br>
table and misses symbols that are present in dyld info. This makes it hard to<br>
know the set of symbols for a binary using just llvm-nm. Unless you know to<br>
run llvm-objdump -exports-trie that can output the exported symbols in the dyld<br>
info from the export trie, which does so but in a different format.<br>
<br>
Also moving forward the time may come a when a fully linked Mach-O file that<br>
uses dyld will no longer have an nlist symbol table to avoid duplicating the<br>
symbol information.<br>
<br>
This change adds three flags to llvm-nm, -add-dyldinfo, -no-dyldinfo, and<br>
-dyldinfo-only.<br>
<br>
The first, -add-dyldinfo, has the same effect as when the new bit in the Mach-O<br>
header, MH_NLIST_OUTOFSYNC_WITH_<wbr>DYLDINFO, appears in a binary. In that it<br>
looks through the dyld info from the export trie and adds symbols to be printed<br>
that are not already in its internal SymbolList variable. The -no-dyldinfo<br>
option turns this behavior off.<br>
<br>
The -dyldinfo-only option only looks at the dyld information and recreates the<br>
symbol table from the dyld info from the export trie and binding information.<br>
As if it the Mach-O file had no nlist symbol table.<br>
<br>
Also fixed a few bugs with Mach-O N_INDR symbols not correctly printing the<br>
indirect name, or in the same format as the old nm-classic program.<br>
<br>
rdar://32021551<br>
<br>
Added:<br>
llvm/trunk/test/tools/llvm-nm/<wbr>X86/Inputs/Strip-ST.dylib.<wbr>macho-x86_64 (with props)<br>
llvm/trunk/test/tools/llvm-nm/<wbr>X86/dyldinfo.test<br>
Modified:<br>
llvm/trunk/include/llvm/<wbr>BinaryFormat/MachO.h<br>
llvm/trunk/tools/llvm-nm/llvm-<wbr>nm.cpp<br>
llvm/trunk/tools/llvm-objdump/<wbr>MachODump.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/<wbr>BinaryFormat/MachO.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/MachO.h?rev=305733&r1=305732&r2=305733&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/include/<wbr>llvm/BinaryFormat/MachO.h?rev=<wbr>305733&r1=305732&r2=305733&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/<wbr>BinaryFormat/MachO.h (original)<br>
+++ llvm/trunk/include/llvm/<wbr>BinaryFormat/MachO.h Mon Jun 19 14:38:22 2017<br>
@@ -78,7 +78,8 @@ enum {<br>
MH_DEAD_STRIPPABLE_DYLIB = 0x00400000u,<br>
MH_HAS_TLV_DESCRIPTORS = 0x00800000u,<br>
MH_NO_HEAP_EXECUTION = 0x01000000u,<br>
- MH_APP_EXTENSION_SAFE = 0x02000000u<br>
+ MH_APP_EXTENSION_SAFE = 0x02000000u,<br>
+ MH_NLIST_OUTOFSYNC_WITH_<wbr>DYLDINFO = 0x04000000u<br>
};<br>
<br>
enum : uint32_t {<br>
<br>
Added: llvm/trunk/test/tools/llvm-nm/<wbr>X86/Inputs/Strip-ST.dylib.<wbr>macho-x86_64<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-nm/X86/Inputs/Strip-ST.dylib.macho-x86_64?rev=305733&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/tools/<wbr>llvm-nm/X86/Inputs/Strip-ST.<wbr>dylib.macho-x86_64?rev=305733&<wbr>view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
Binary file - no diff available.<br>
<br>
Propchange: llvm/trunk/test/tools/llvm-nm/<wbr>X86/Inputs/Strip-ST.dylib.<wbr>macho-x86_64<br>
------------------------------<wbr>------------------------------<wbr>------------------<br>
svn:executable = *<br>
<br>
Propchange: llvm/trunk/test/tools/llvm-nm/<wbr>X86/Inputs/Strip-ST.dylib.<wbr>macho-x86_64<br>
------------------------------<wbr>------------------------------<wbr>------------------<br>
svn:mime-type = application/octet-stream<br>
<br>
Added: llvm/trunk/test/tools/llvm-nm/<wbr>X86/dyldinfo.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-nm/X86/dyldinfo.test?rev=305733&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/tools/<wbr>llvm-nm/X86/dyldinfo.test?rev=<wbr>305733&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/tools/llvm-nm/<wbr>X86/dyldinfo.test (added)<br>
+++ llvm/trunk/test/tools/llvm-nm/<wbr>X86/dyldinfo.test Mon Jun 19 14:38:22 2017<br>
@@ -0,0 +1,18 @@<br>
+# RUN: llvm-nm %p/Inputs/Strip-ST.dylib.<wbr>macho-x86_64 | FileCheck --check-prefix=DEFAULT %s<br>
+# RUN: llvm-nm -no-dyldinfo %p/Inputs/Strip-ST.dylib.<wbr>macho-x86_64 | FileCheck --check-prefix=NO-DYLDINFO %s<br>
+# RUN: llvm-nm -dyldinfo-only %p/Inputs/Strip-ST.dylib.<wbr>macho-x86_64 | FileCheck --check-prefix=DYLDINFO-ONLY %s<br>
+<br>
+# DEFAULT: 0000000000000f90 T __Bob_is_slow<br>
+# DEFAULT: 0000000000001008 D __T0ims_data<br>
+# DEFAULT: 0000000000000f80 T __T0om_is_not_swift<br>
+# DEFAULT: U dyld_stub_binder<br>
+<br>
+# NO-DYLDINFO: 0000000000000f90 T __Bob_is_slow<br>
+# NO-DYLDINFO-NOT: __T0ims_data<br>
+# NO-DYLDINFO-NOT: __T0om_is_not_swift<br>
+# NO-DYLDINFO: U dyld_stub_binder<br>
+<br>
+# DYLDINFO-ONLY: 0000000000000f90 T __Bob_is_slow<br>
+# DYLDINFO-ONLY: 0000000000001008 D __T0ims_data<br>
+# DYLDINFO-ONLY: 0000000000000f80 T __T0om_is_not_swift<br>
+# DYLDINFO-ONLY-NOT: U dyld_stub_binder<br>
<br>
Modified: llvm/trunk/tools/llvm-nm/llvm-<wbr>nm.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-nm/llvm-nm.cpp?rev=305733&r1=305732&r2=305733&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/tools/llvm-<wbr>nm/llvm-nm.cpp?rev=305733&r1=<wbr>305732&r2=305733&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/tools/llvm-nm/llvm-<wbr>nm.cpp (original)<br>
+++ llvm/trunk/tools/llvm-nm/llvm-<wbr>nm.cpp Mon Jun 19 14:38:22 2017<br>
@@ -167,6 +167,15 @@ cl::list<std::string> SegSect("s", cl::P<br>
<br>
cl::opt<bool> FormatMachOasHex("x", cl::desc("Print symbol entry in hex, "<br>
"Mach-O only"), cl::Grouping);<br>
+cl::opt<bool> AddDyldInfo("add-dyldinfo",<br>
+ cl::desc("Add symbols from the dyldinfo not already "<br>
+ "in the symbol table, Mach-O only"));<br>
+cl::opt<bool> NoDyldInfo("no-dyldinfo",<br>
+ cl::desc("Don't add any symbols from the dyldinfo, "<br>
+ "Mach-O only"));<br>
+cl::opt<bool> DyldInfoOnly("dyldinfo-only",<br>
+ cl::desc("Show only symbols from the dyldinfo, "<br>
+ "Mach-O only"));<br>
<br>
cl::opt<bool> NoLLVMBitcode("no-llvm-bc",<br>
cl::desc("Disable LLVM bitcode reader"));<br>
@@ -247,6 +256,17 @@ struct NMSymbol {<br>
char TypeChar;<br>
StringRef Name;<br>
BasicSymbolRef Sym;<br>
+ // The Sym field above points to the native symbol in the object file,<br>
+ // for Mach-O when we are creating symbols from the dyld info the above<br>
+ // pointer is null as there is no native symbol. In these cases the fields<br>
+ // below are filled in to represent what would have been a Mach-O nlist<br>
+ // native symbol.<br>
+ uint32_t SymFlags;<br>
+ SectionRef Section;<br>
+ uint8_t NType;<br>
+ uint8_t NSect;<br>
+ uint16_t NDesc;<br>
+ StringRef IndirectName;<br>
};<br>
} // anonymous namespace<br>
<br>
@@ -331,22 +351,38 @@ static void darwinPrintSymbol(SymbolicFi<br>
H_64 = MachO->MachOObjectFile::<wbr>getHeader64();<br>
Filetype = H_64.filetype;<br>
Flags = H_64.flags;<br>
- MachO::nlist_64 STE_64 = MachO->getSymbol64TableEntry(<wbr>SymDRI);<br>
- NType = STE_64.n_type;<br>
- NSect = STE_64.n_sect;<br>
- NDesc = STE_64.n_desc;<br>
- NStrx = STE_64.n_strx;<br>
- NValue = STE_64.n_value;<br>
+ if (SymDRI.p){<br>
+ MachO::nlist_64 STE_64 = MachO->getSymbol64TableEntry(<wbr>SymDRI);<br>
+ NType = STE_64.n_type;<br>
+ NSect = STE_64.n_sect;<br>
+ NDesc = STE_64.n_desc;<br>
+ NStrx = STE_64.n_strx;<br>
+ NValue = STE_64.n_value;<br>
+ } else {<br>
+ NType = I->NType;<br>
+ NSect = I->NSect;<br>
+ NDesc = I->NDesc;<br>
+ NStrx = 0;<br>
+ NValue = I->Address;<br>
+ }<br>
} else {<br>
H = MachO->MachOObjectFile::<wbr>getHeader();<br>
Filetype = H.filetype;<br>
Flags = H.flags;<br>
- MachO::nlist STE = MachO->getSymbolTableEntry(<wbr>SymDRI);<br>
- NType = STE.n_type;<br>
- NSect = STE.n_sect;<br>
- NDesc = STE.n_desc;<br>
- NStrx = STE.n_strx;<br>
- NValue = STE.n_value;<br>
+ if (SymDRI.p){<br>
+ MachO::nlist STE = MachO->getSymbolTableEntry(<wbr>SymDRI);<br>
+ NType = STE.n_type;<br>
+ NSect = STE.n_sect;<br>
+ NDesc = STE.n_desc;<br>
+ NStrx = STE.n_strx;<br>
+ NValue = STE.n_value;<br>
+ } else {<br>
+ NType = I->NType;<br>
+ NSect = I->NSect;<br>
+ NDesc = I->NDesc;<br>
+ NStrx = 0;<br>
+ NValue = I->Address;<br>
+ }<br>
}<br>
}<br>
<br>
@@ -363,7 +399,22 @@ static void darwinPrintSymbol(SymbolicFi<br>
outs() << Str << ' ';<br>
format("%08x", NStrx).print(Str, sizeof(Str));<br>
outs() << Str << ' ';<br>
- outs() << I->Name << "\n";<br>
+ outs() << I->Name;<br>
+ if ((NType & MachO::N_TYPE) == MachO::N_INDR) {<br>
+ outs() << " (indirect for ";<br>
+ format(printFormat, NValue).print(Str, sizeof(Str));<br>
+ outs() << Str << ' ';<br>
+ StringRef IndirectName;<br>
+ if (I->Sym.getRawDataRefImpl().p) {<br>
+ if (MachO->getIndirectName(I-><wbr>Sym.getRawDataRefImpl(), IndirectName))<br>
+ outs() << "?)";<br>
+ else<br>
+ outs() << IndirectName << ")";<br>
+ }<br>
+ else<br>
+ outs() << I->IndirectName << ")";<br>
+ }<br>
+ outs() << "\n";<br>
return;<br>
}<br>
<br>
@@ -419,14 +470,19 @@ static void darwinPrintSymbol(SymbolicFi<br>
outs() << "(?,?) ";<br>
break;<br>
}<br>
- Expected<section_iterator> SecOrErr =<br>
- MachO->getSymbolSection(I-><wbr>Sym.getRawDataRefImpl());<br>
- if (!SecOrErr) {<br>
- consumeError(SecOrErr.<wbr>takeError());<br>
- outs() << "(?,?) ";<br>
- break;<br>
+ section_iterator Sec = SectionRef();<br>
+ if (I->Sym.getRawDataRefImpl().p) {<br>
+ Expected<section_iterator> SecOrErr =<br>
+ MachO->getSymbolSection(I-><wbr>Sym.getRawDataRefImpl());<br>
+ if (!SecOrErr) {<br>
+ consumeError(SecOrErr.<wbr>takeError());<br>
+ outs() << "(?,?) ";<br>
+ break;<br>
+ }<br>
+ Sec = *SecOrErr;<br>
+ } else {<br>
+ Sec = I->Section;<br>
}<br>
- section_iterator Sec = *SecOrErr;<br>
DataRefImpl Ref = Sec->getRawDataRefImpl();<br>
StringRef SectionName;<br>
MachO->getSectionName(Ref, SectionName);<br>
@@ -485,11 +541,17 @@ static void darwinPrintSymbol(SymbolicFi<br>
if ((NType & MachO::N_TYPE) == MachO::N_INDR) {<br>
outs() << I->Name << " (for ";<br>
StringRef IndirectName;<br>
- if (!MachO ||<br>
- MachO->getIndirectName(I->Sym.<wbr>getRawDataRefImpl(), IndirectName))<br>
+ if (MachO) {<br>
+ if (I->Sym.getRawDataRefImpl().p) {<br>
+ if (MachO->getIndirectName(I-><wbr>Sym.getRawDataRefImpl(), IndirectName))<br>
+ outs() << "?)";<br>
+ else<br>
+ outs() << IndirectName << ")";<br>
+ }<br>
+ else<br>
+ outs() << I->IndirectName << ")";<br>
+ } else<br>
outs() << "?)";<br>
- else<br>
- outs() << IndirectName << ")";<br>
} else<br>
outs() << I->Name;<br>
<br>
@@ -660,7 +722,12 @@ static void sortAndPrintSymbolList(Symbo<br>
<br>
for (SymbolListT::iterator I = SymbolList.begin(), E = SymbolList.end();<br>
I != E; ++I) {<br>
- uint32_t SymFlags = I->Sym.getFlags();<br>
+ uint32_t SymFlags;<br>
+ if (I->Sym.getRawDataRefImpl().p)<br>
+ SymFlags = I->Sym.getFlags();<br>
+ else<br>
+ SymFlags = I->SymFlags;<br>
+<br>
bool Undefined = SymFlags & SymbolRef::SF_Undefined;<br>
bool Global = SymFlags & SymbolRef::SF_Global;<br>
if ((!Undefined && UndefinedOnly) || (Undefined && DefinedOnly) ||<br>
@@ -699,10 +766,13 @@ static void sortAndPrintSymbolList(Symbo<br>
}<br>
}<br>
<br>
+ MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&<wbr>Obj);<br>
// Otherwise, print the symbol address and size.<br>
if (symbolIsDefined(*I)) {<br>
if (Obj.isIR())<br>
strcpy(SymbolAddrStr, printDashes);<br>
+ else if(MachO && I->TypeChar == 'I')<br>
+ strcpy(SymbolAddrStr, printBlanks);<br>
else<br>
format(printFormat, I->Address)<br>
.print(SymbolAddrStr, sizeof(SymbolAddrStr));<br>
@@ -714,7 +784,6 @@ static void sortAndPrintSymbolList(Symbo<br>
// nm(1) -m output or hex, else if OutputFormat is darwin or we are<br>
// printing Mach-O symbols in hex and not a Mach-O object fall back to<br>
// OutputFormat bsd (see below).<br>
- MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&<wbr>Obj);<br>
if ((OutputFormat == darwin || FormatMachOasHex) && (MachO || Obj.isIR())) {<br>
darwinPrintSymbol(Obj, I, SymbolAddrStr, printBlanks, printDashes,<br>
printFormat);<br>
@@ -734,7 +803,19 @@ static void sortAndPrintSymbolList(Symbo<br>
outs() << I->TypeChar;<br>
if (I->TypeChar == '-' && MachO)<br>
darwinPrintStab(MachO, I);<br>
- outs() << " " << I->Name << "\n";<br>
+ outs() << " " << I->Name;<br>
+ if (I->TypeChar == 'I' && MachO) {<br>
+ outs() << " (indirect for ";<br>
+ if (I->Sym.getRawDataRefImpl().p) {<br>
+ StringRef IndirectName;<br>
+ if (MachO->getIndirectName(I-><wbr>Sym.getRawDataRefImpl(), IndirectName))<br>
+ outs() << "?)";<br>
+ else<br>
+ outs() << IndirectName << ")";<br>
+ } else<br>
+ outs() << I->IndirectName << ")";<br>
+ }<br>
+ outs() << "\n";<br>
} else if (OutputFormat == sysv) {<br>
std::string PaddedName(I->Name);<br>
while (PaddedName.length() < 20)<br>
@@ -1022,51 +1103,433 @@ dumpSymbolNamesFromObject(<wbr>SymbolicFile &<br>
if (Nsect == 0)<br>
return;<br>
}<br>
- for (BasicSymbolRef Sym : Symbols) {<br>
- uint32_t SymFlags = Sym.getFlags();<br>
- if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific))<br>
- continue;<br>
- if (WithoutAliases && (SymFlags & SymbolRef::SF_Indirect))<br>
- continue;<br>
- // If a "-s segname sectname" option was specified and this is a Mach-O<br>
- // file and this section appears in this file, Nsect will be non-zero then<br>
- // see if this symbol is a symbol from that section and if not skip it.<br>
- if (Nsect && Nsect != getNsectInMachO(*MachO, Sym))<br>
- continue;<br>
- NMSymbol S;<br>
- S.Size = 0;<br>
- S.Address = 0;<br>
- if (PrintSize) {<br>
- if (isa<ELFObjectFileBase>(&Obj))<br>
- S.Size = ELFSymbolRef(Sym).getSize();<br>
- }<br>
- if (PrintAddress && isa<ObjectFile>(Obj)) {<br>
- SymbolRef SymRef(Sym);<br>
- Expected<uint64_t> AddressOrErr = SymRef.getAddress();<br>
- if (!AddressOrErr) {<br>
- consumeError(AddressOrErr.<wbr>takeError());<br>
- break;<br>
+ if (!MachO || !DyldInfoOnly) {<br>
+ for (BasicSymbolRef Sym : Symbols) {<br>
+ uint32_t SymFlags = Sym.getFlags();<br>
+ if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific))<br>
+ continue;<br>
+ if (WithoutAliases && (SymFlags & SymbolRef::SF_Indirect))<br>
+ continue;<br>
+ // If a "-s segname sectname" option was specified and this is a Mach-O<br>
+ // file and this section appears in this file, Nsect will be non-zero then<br>
+ // see if this symbol is a symbol from that section and if not skip it.<br>
+ if (Nsect && Nsect != getNsectInMachO(*MachO, Sym))<br>
+ continue;<br>
+ NMSymbol S;<br>
+ S.Size = 0;<br>
+ S.Address = 0;<br>
+ if (PrintSize) {<br>
+ if (isa<ELFObjectFileBase>(&Obj))<br>
+ S.Size = ELFSymbolRef(Sym).getSize();<br>
+ }<br>
+ if (PrintAddress && isa<ObjectFile>(Obj)) {<br>
+ SymbolRef SymRef(Sym);<br>
+ Expected<uint64_t> AddressOrErr = SymRef.getAddress();<br>
+ if (!AddressOrErr) {<br>
+ consumeError(AddressOrErr.<wbr>takeError());<br>
+ break;<br>
+ }<br>
+ S.Address = *AddressOrErr;<br>
}<br>
- S.Address = *AddressOrErr;<br>
+ S.TypeChar = getNMTypeChar(Obj, Sym);<br>
+ std::error_code EC = Sym.printName(OS);<br>
+ if (EC && MachO)<br>
+ OS << "bad string index";<br>
+ else<br>
+ error(EC);<br>
+ OS << '\0';<br>
+ S.Sym = Sym;<br>
+ SymbolList.push_back(S);<br>
}<br>
- S.TypeChar = getNMTypeChar(Obj, Sym);<br>
- std::error_code EC = Sym.printName(OS);<br>
- if (EC && MachO)<br>
- OS << "bad string index";<br>
- else<br>
- error(EC);<br>
- OS << '\0';<br>
- S.Sym = Sym;<br>
- SymbolList.push_back(S);<br>
}<br>
<br>
OS.flush();<br>
const char *P = NameBuffer.c_str();<br>
- for (unsigned I = 0; I < SymbolList.size(); ++I) {<br>
+ unsigned I;<br>
+ for (I = 0; I < SymbolList.size(); ++I) {<br>
SymbolList[I].Name = P;<br>
P += strlen(P) + 1;<br>
}<br>
<br>
+ // If this is a Mach-O file where the nlist symbol table is out of sync<br>
+ // with the dyld export trie then look through exports and fake up symbols<br>
+ // for the ones that are missing (also done with the -add-dyldinfo flag).<br>
+ // This is needed if strip(1) -T is run on a binary containing swift<br>
+ // language symbols for example. The option -only-dyldinfo will fake up<br>
+ // all symbols from the dyld export trie as well as the bind info.<br>
+ std::string ExportsNameBuffer;<br>
+ raw_string_ostream EOS(ExportsNameBuffer);<br>
+ std::string BindsNameBuffer;<br>
+ raw_string_ostream BOS(BindsNameBuffer);<br>
+ std::string LazysNameBuffer;<br>
+ raw_string_ostream LOS(LazysNameBuffer);<br>
+ std::string WeaksNameBuffer;<br>
+ raw_string_ostream WOS(WeaksNameBuffer);<br>
+ if (MachO && !NoDyldInfo) {<br>
+ MachO::mach_header H;<br>
+ MachO::mach_header_64 H_64;<br>
+ uint32_t HFlags = 0;<br>
+ if (MachO->is64Bit()) {<br>
+ H_64 = MachO->MachOObjectFile::<wbr>getHeader64();<br>
+ HFlags = H_64.flags;<br>
+ } else {<br>
+ H = MachO->MachOObjectFile::<wbr>getHeader();<br>
+ HFlags = H.flags;<br>
+ }<br>
+ uint64_t BaseSegmentAddress = 0;<br>
+ for (const auto &Command : MachO->load_commands()) {<br>
+ if (Command.C.cmd == MachO::LC_SEGMENT) {<br>
+ MachO::segment_command Seg = MachO->getSegmentLoadCommand(<wbr>Command);<br>
+ if (Seg.fileoff == 0 && Seg.filesize != 0) {<br>
+ BaseSegmentAddress = Seg.vmaddr;<br>
+ break;<br>
+ }<br>
+ } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {<br>
+ MachO::segment_command_64 Seg = MachO-><wbr>getSegment64LoadCommand(<wbr>Command);<br>
+ if (Seg.fileoff == 0 && Seg.filesize != 0) {<br>
+ BaseSegmentAddress = Seg.vmaddr;<br>
+ break;<br>
+ }<br>
+ }<br>
+ }<br>
+ if (DyldInfoOnly || AddDyldInfo ||<br>
+ HFlags & MachO::MH_NLIST_OUTOFSYNC_<wbr>WITH_DYLDINFO) {<br>
+ unsigned ExportsAdded = 0;<br>
+ for (const llvm::object::ExportEntry &Entry : MachO->exports()) {<br>
+ bool found = false;<br>
+ bool ReExport = false;<br>
+ if (!DyldInfoOnly) {<br>
+ for (unsigned J = 0; J < SymbolList.size() && !found; ++J) {<br>
+ if (SymbolList[J].Address == Entry.address() + BaseSegmentAddress &&<br>
+ SymbolList[J].Name == Entry.name())<br>
+ found = true;<br>
+ }<br>
+ }<br>
+ if (!found) {<br>
+ NMSymbol S;<br>
+ S.Address = Entry.address() + BaseSegmentAddress;<br>
+ S.Size = 0;<br>
+ S.TypeChar = '\0';<br>
+ S.Name = Entry.name();<br>
+ // There is no symbol in the nlist symbol table for this so we set<br>
+ // Sym effectivly to null and the rest of code in here must test for<br>
+ // it and not do things like Sym.getFlags() for it.<br>
+ S.Sym = BasicSymbolRef();<br>
+ S.SymFlags = SymbolRef::SF_Global;<br>
+ S.Section = SectionRef();<br>
+ S.NType = 0;<br>
+ S.NSect = 0;<br>
+ S.NDesc = 0;<br>
+ S.IndirectName = StringRef();<br>
+<br>
+ uint64_t EFlags = Entry.flags();<br>
+ bool Abs = ((EFlags & MachO::EXPORT_SYMBOL_FLAGS_<wbr>KIND_MASK) ==<br>
+ MachO::EXPORT_SYMBOL_FLAGS_<wbr>KIND_ABSOLUTE);<br>
+ bool Resolver = (EFlags &<br>
+ MachO::EXPORT_SYMBOL_FLAGS_<wbr>STUB_AND_RESOLVER);<br>
+ ReExport = (EFlags & MachO::EXPORT_SYMBOL_FLAGS_<wbr>REEXPORT);<br>
+ bool WeakDef = (EFlags & MachO::EXPORT_SYMBOL_FLAGS_<wbr>WEAK_DEFINITION);<br>
+ if (WeakDef)<br>
+ S.NDesc |= MachO::N_WEAK_DEF;<br>
+ if (Abs) {<br>
+ S.NType = MachO::N_EXT | MachO::N_ABS;<br>
+ S.TypeChar = 'A';<br>
+ } else if (ReExport) {<br>
+ S.NType = MachO::N_EXT | MachO::N_INDR;<br>
+ S.TypeChar = 'I';<br>
+ } else {<br>
+ S.NType = MachO::N_EXT | MachO::N_SECT;<br>
+ if (Resolver) {<br>
+ S.Address = Entry.other() + BaseSegmentAddress;<br>
+ if ((S.Address & 1) != 0 &&<br>
+ !MachO->is64Bit() && H.cputype == MachO::CPU_TYPE_ARM){<br>
+ S.Address &= ~1LL;<br>
+ S.NDesc |= MachO::N_ARM_THUMB_DEF;<br>
+ }<br>
+ } else {<br>
+ S.Address = Entry.address() + BaseSegmentAddress;<br>
+ }<br>
+ StringRef SegmentName = StringRef();<br>
+ StringRef SectionName = StringRef();<br>
+ for (const SectionRef &Section : MachO->sections()) {<br>
+ S.NSect++;<br>
+ Section.getName(SectionName);<br>
+ SegmentName = MachO-><wbr>getSectionFinalSegmentName(<br>
+ Section.getRawDataRefImpl());<br>
+ if (S.Address >= Section.getAddress() &&<br>
+ S.Address < Section.getAddress() + Section.getSize()) {<br>
+ S.Section = Section;<br>
+ break;<br>
+ } else if (Entry.name() == "__mh_execute_header" &&<br>
+ SegmentName == "__TEXT" && SectionName == "__text") {<br>
+ S.Section = Section;<br>
+ S.NDesc |= MachO::REFERENCED_DYNAMICALLY;<br>
+ break;<br>
+ }<br>
+ }<br>
+ if (SegmentName == "__TEXT" && SectionName == "__text")<br>
+ S.TypeChar = 'T';<br>
+ else if (SegmentName == "__DATA" && SectionName == "__data")<br>
+ S.TypeChar = 'D';<br>
+ else if (SegmentName == "__DATA" && SectionName == "__bss")<br>
+ S.TypeChar = 'B';<br>
+ else<br>
+ S.TypeChar = 'S';<br>
+ }<br>
+ SymbolList.push_back(S);<br>
+<br>
+ EOS << Entry.name();<br>
+ EOS << '\0';<br>
+ ExportsAdded++;<br>
+<br>
+ // For ReExports there are a two more things to do, first add the<br>
+ // indirect name and second create the undefined symbol using the<br>
+ // referened dynamic library.<br>
+ if (ReExport) {<br>
+<br>
+ // Add the indirect name.<br>
+ if (Entry.otherName().empty())<br>
+ EOS << Entry.name();<br>
+ else<br>
+ EOS << Entry.otherName();<br>
+ EOS << '\0';<br>
+<br>
+ // Now create the undefined symbol using the referened dynamic<br>
+ // library.<br>
+ NMSymbol U;<br>
+ U.Address = 0;<br>
+ U.Size = 0;<br>
+ U.TypeChar = 'U';<br>
+ if (Entry.otherName().empty())<br>
+ U.Name = Entry.name();<br>
+ else<br>
+ U.Name = Entry.otherName();<br>
+ // Again there is no symbol in the nlist symbol table for this so<br>
+ // we set Sym effectivly to null and the rest of code in here must<br>
+ // test for it and not do things like Sym.getFlags() for it.<br>
+ U.Sym = BasicSymbolRef();<br>
+ U.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined;<br>
+ U.Section = SectionRef();<br>
+ U.NType = MachO::N_EXT | MachO::N_UNDF;<br>
+ U.NSect = 0;<br>
+ U.NDesc = 0;<br>
+ // The library ordinal for this undefined symbol is in the export<br>
+ // trie Entry.other().<br>
+ MachO::SET_LIBRARY_ORDINAL(U.<wbr>NDesc, Entry.other());<br>
+ U.IndirectName = StringRef();<br>
+ SymbolList.push_back(U);<br>
+<br>
+ // Finally add the undefined symbol's name.<br>
+ if (Entry.otherName().empty())<br>
+ EOS << Entry.name();<br>
+ else<br>
+ EOS << Entry.otherName();<br>
+ EOS << '\0';<br>
+ ExportsAdded++;<br>
+ }<br>
+ }<br>
+ }<br>
+ // Set the symbol names and indirect names for the added symbols.<br>
+ if (ExportsAdded) {<br>
+ EOS.flush();<br>
+ const char *Q = ExportsNameBuffer.c_str();<br>
+ for (unsigned K = 0; K < ExportsAdded; K++) {<br>
+ SymbolList[I].Name = Q;<br>
+ Q += strlen(Q) + 1;<br>
+ if (SymbolList[I].TypeChar == 'I') {<br>
+ SymbolList[I].IndirectName = Q;<br>
+ Q += strlen(Q) + 1;<br>
+ }<br>
+ I++;<br>
+ }<br>
+ }<br>
+<br>
+ // Add the undefined symbols from the bind entries.<br>
+ unsigned BindsAdded = 0;<br>
+ Error BErr = Error::success();<br>
+ StringRef LastSymbolName = StringRef();<br>
+ for (const llvm::object::MachOBindEntry &Entry : MachO->bindTable(BErr)) {<br>
+ bool found = false;<br>
+ if (LastSymbolName == Entry.symbolName())<br>
+ found = true;<br>
+ else if(!DyldInfoOnly) {<br>
+ for (unsigned J = 0; J < SymbolList.size() && !found; ++J) {<br>
+ if (SymbolList[J].Name == Entry.symbolName())<br>
+ found = true;<br>
+ }<br>
+ }<br>
+ if (!found) {<br>
+ LastSymbolName = Entry.symbolName();<br>
+ NMSymbol B;<br>
+ B.Address = 0;<br>
+ B.Size = 0;<br>
+ B.TypeChar = 'U';<br>
+ // There is no symbol in the nlist symbol table for this so we set<br>
+ // Sym effectivly to null and the rest of code in here must test for<br>
+ // it and not do things like Sym.getFlags() for it.<br>
+ B.Sym = BasicSymbolRef();<br>
+ B.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined;<br>
+ B.NType = MachO::N_EXT | MachO::N_UNDF;<br>
+ B.NSect = 0;<br>
+ B.NDesc = 0;<br>
+ B.NDesc = 0;<br>
+ MachO::SET_LIBRARY_ORDINAL(B.<wbr>NDesc, Entry.ordinal());<br>
+ B.IndirectName = StringRef();<br>
+ B.Name = Entry.symbolName();<br>
+ SymbolList.push_back(B);<br>
+ BOS << Entry.symbolName();<br>
+ BOS << '\0';<br>
+ BindsAdded++;<br>
+ }<br>
+ }<br>
+ if (BErr)<br>
+ error(std::move(BErr), MachO->getFileName());<br>
+ // Set the symbol names and indirect names for the added symbols.<br>
+ if (BindsAdded) {<br>
+ BOS.flush();<br>
+ const char *Q = BindsNameBuffer.c_str();<br>
+ for (unsigned K = 0; K < BindsAdded; K++) {<br>
+ SymbolList[I].Name = Q;<br>
+ Q += strlen(Q) + 1;<br>
+ if (SymbolList[I].TypeChar == 'I') {<br>
+ SymbolList[I].IndirectName = Q;<br>
+ Q += strlen(Q) + 1;<br>
+ }<br>
+ I++;<br>
+ }<br>
+ }<br>
+<br>
+ // Add the undefined symbols from the lazy bind entries.<br>
+ unsigned LazysAdded = 0;<br>
+ Error LErr = Error::success();<br>
+ LastSymbolName = StringRef();<br>
+ for (const llvm::object::MachOBindEntry &Entry :<br>
+ MachO->lazyBindTable(LErr)) {<br>
+ bool found = false;<br>
+ if (LastSymbolName == Entry.symbolName())<br>
+ found = true;<br>
+ else {<br>
+ // Here we must check to see it this symbol is already in the<br>
+ // SymbolList as it might have already have been added above via a<br>
+ // non-lazy (bind) entry.<br>
+ for (unsigned J = 0; J < SymbolList.size() && !found; ++J) {<br>
+ if (SymbolList[J].Name == Entry.symbolName())<br>
+ found = true;<br>
+ }<br>
+ }<br>
+ if (!found) {<br>
+ LastSymbolName = Entry.symbolName();<br>
+ NMSymbol L;<br>
+ L.Name = Entry.symbolName();<br>
+ L.Address = 0;<br>
+ L.Size = 0;<br>
+ L.TypeChar = 'U';<br>
+ // There is no symbol in the nlist symbol table for this so we set<br>
+ // Sym effectivly to null and the rest of code in here must test for<br>
+ // it and not do things like Sym.getFlags() for it.<br>
+ L.Sym = BasicSymbolRef();<br>
+ L.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined;<br>
+ L.NType = MachO::N_EXT | MachO::N_UNDF;<br>
+ L.NSect = 0;<br>
+ // The REFERENCE_FLAG_UNDEFINED_LAZY is no longer used but here it<br>
+ // makes sence since we are creating this from a lazy bind entry.<br>
+ L.NDesc = MachO::REFERENCE_FLAG_<wbr>UNDEFINED_LAZY;<br>
+ MachO::SET_LIBRARY_ORDINAL(L.<wbr>NDesc, Entry.ordinal());<br>
+ L.IndirectName = StringRef();<br>
+ SymbolList.push_back(L);<br>
+ LOS << Entry.symbolName();<br>
+ LOS << '\0';<br>
+ LazysAdded++;<br>
+ }<br>
+ }<br>
+ if (LErr)<br>
+ error(std::move(LErr), MachO->getFileName());<br>
+ // Set the symbol names and indirect names for the added symbols.<br>
+ if (LazysAdded) {<br>
+ LOS.flush();<br>
+ const char *Q = LazysNameBuffer.c_str();<br>
+ for (unsigned K = 0; K < LazysAdded; K++) {<br>
+ SymbolList[I].Name = Q;<br>
+ Q += strlen(Q) + 1;<br>
+ if (SymbolList[I].TypeChar == 'I') {<br>
+ SymbolList[I].IndirectName = Q;<br>
+ Q += strlen(Q) + 1;<br>
+ }<br>
+ I++;<br>
+ }<br>
+ }<br>
+<br>
+ // Add the undefineds symbol from the weak bind entries which are not<br>
+ // strong symbols.<br>
+ unsigned WeaksAdded = 0;<br>
+ Error WErr = Error::success();<br>
+ LastSymbolName = StringRef();<br>
+ for (const llvm::object::MachOBindEntry &Entry :<br>
+ MachO->weakBindTable(WErr)) {<br>
+ bool found = false;<br>
+ unsigned J = 0;<br>
+ if (LastSymbolName == Entry.symbolName() ||<br>
+ Entry.flags() & MachO::BIND_SYMBOL_FLAGS_NON_<wbr>WEAK_DEFINITION) {<br>
+ found = true;<br>
+ } else {<br>
+ for (J = 0; J < SymbolList.size() && !found; ++J) {<br>
+ if (SymbolList[J].Name == Entry.symbolName()) {<br>
+ found = true;<br>
+ break;<br>
+ }<br>
+ }<br>
+ }<br>
+ if (!found) {<br>
+ LastSymbolName = Entry.symbolName();<br>
+ NMSymbol W;<br>
+ W.Name = Entry.symbolName();<br>
+ W.Address = 0;<br>
+ W.Size = 0;<br>
+ W.TypeChar = 'U';<br>
+ // There is no symbol in the nlist symbol table for this so we set<br>
+ // Sym effectivly to null and the rest of code in here must test for<br>
+ // it and not do things like Sym.getFlags() for it.<br>
+ W.Sym = BasicSymbolRef();<br>
+ W.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined;<br>
+ W.NType = MachO::N_EXT | MachO::N_UNDF;<br>
+ W.NSect = 0;<br>
+ // Odd that we are using N_WEAK_DEF on an undefined symbol but that is<br>
+ // what is created in this case by the linker when there are real<br>
+ // symbols in the nlist structs.<br>
+ W.NDesc = MachO::N_WEAK_DEF;<br>
+ W.IndirectName = StringRef();<br>
+ SymbolList.push_back(W);<br>
+ WOS << Entry.symbolName();<br>
+ WOS << '\0';<br>
+ WeaksAdded++;<br>
+ } else {<br>
+ // This is the case the symbol was previously been found and it could<br>
+ // have been added from a bind or lazy bind symbol. If so and not<br>
+ // a definition also mark it as weak.<br>
+ if (SymbolList[J].TypeChar == 'U')<br>
+ // See comment above about N_WEAK_DEF.<br>
+ SymbolList[J].NDesc |= MachO::N_WEAK_DEF;<br>
+ }<br>
+ }<br>
+ if (WErr)<br>
+ error(std::move(WErr), MachO->getFileName());<br>
+ // Set the symbol names and indirect names for the added symbols.<br>
+ if (WeaksAdded) {<br>
+ WOS.flush();<br>
+ const char *Q = WeaksNameBuffer.c_str();<br>
+ for (unsigned K = 0; K < WeaksAdded; K++) {<br>
+ SymbolList[I].Name = Q;<br>
+ Q += strlen(Q) + 1;<br>
+ if (SymbolList[I].TypeChar == 'I') {<br>
+ SymbolList[I].IndirectName = Q;<br>
+ Q += strlen(Q) + 1;<br>
+ }<br>
+ I++;<br>
+ }<br>
+ }<br>
+ }<br>
+ }<br>
+<br>
CurrentFilename = Obj.getFileName();<br>
sortAndPrintSymbolList(Obj, printName, ArchiveName, ArchitectureName);<br>
}<br>
@@ -1456,6 +1919,9 @@ int main(int argc, char **argv) {<br>
error("bad number of arguments (must be two arguments)",<br>
"for the -s option");<br>
<br>
+ if (NoDyldInfo && (AddDyldInfo || DyldInfoOnly))<br>
+ error("-no-dyldinfo can't be used with -add-dyldinfo or -dyldinfo-only");<br>
+<br>
std::for_each(InputFilenames.<wbr>begin(), InputFilenames.end(),<br>
dumpSymbolNamesFromFile);<br>
<br>
<br>
Modified: llvm/trunk/tools/llvm-objdump/<wbr>MachODump.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MachODump.cpp?rev=305733&r1=305732&r2=305733&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/tools/llvm-<wbr>objdump/MachODump.cpp?rev=<wbr>305733&r1=305732&r2=305733&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/tools/llvm-objdump/<wbr>MachODump.cpp (original)<br>
+++ llvm/trunk/tools/llvm-objdump/<wbr>MachODump.cpp Mon Jun 19 14:38:22 2017<br>
@@ -7634,6 +7634,10 @@ static void PrintMachHeader(uint32_t mag<br>
outs() << " APP_EXTENSION_SAFE";<br>
f &= ~MachO::MH_APP_EXTENSION_SAFE;<br>
}<br>
+ if (f & MachO::MH_NLIST_OUTOFSYNC_<wbr>WITH_DYLDINFO) {<br>
+ outs() << " NLIST_OUTOFSYNC_WITH_DYLDINFO"<wbr>;<br>
+ f &= ~MachO::MH_NLIST_OUTOFSYNC_<wbr>WITH_DYLDINFO;<br>
+ }<br>
if (f != 0 || flags == 0)<br>
outs() << format(" 0x%08" PRIx32, f);<br>
} else {<br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>