[llvm] r328274 - For llvm-nm and Mach-O files also use function starts info in some
Kevin Enderby via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 22 16:59:35 PDT 2018
Author: enderby
Date: Thu Mar 22 16:59:35 2018
New Revision: 328274
URL: http://llvm.org/viewvc/llvm-project?rev=328274&view=rev
Log:
For llvm-nm and Mach-O files also use function starts info in some
cases when printing symbols. As an improvement to:
r305733 - Change llvm-nm for Mach-O files to use dyld info in some cases when printing symbols
it could be made a bit better if it also read the function starts and faked
up nlist entries to those address not already faked up by the other
dyld info. This would help with stripped static functions.
rdar://38761029
Added:
llvm/trunk/test/tools/llvm-nm/X86/Inputs/Strip-N.hello.exe.macho-x86_64 (with props)
Modified:
llvm/trunk/test/tools/llvm-nm/X86/dyldinfo.test
llvm/trunk/tools/llvm-nm/llvm-nm.cpp
Added: llvm/trunk/test/tools/llvm-nm/X86/Inputs/Strip-N.hello.exe.macho-x86_64
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-nm/X86/Inputs/Strip-N.hello.exe.macho-x86_64?rev=328274&view=auto
==============================================================================
Binary file - no diff available.
Propchange: llvm/trunk/test/tools/llvm-nm/X86/Inputs/Strip-N.hello.exe.macho-x86_64
------------------------------------------------------------------------------
svn:executable = *
Propchange: llvm/trunk/test/tools/llvm-nm/X86/Inputs/Strip-N.hello.exe.macho-x86_64
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified: llvm/trunk/test/tools/llvm-nm/X86/dyldinfo.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-nm/X86/dyldinfo.test?rev=328274&r1=328273&r2=328274&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-nm/X86/dyldinfo.test (original)
+++ llvm/trunk/test/tools/llvm-nm/X86/dyldinfo.test Thu Mar 22 16:59:35 2018
@@ -1,6 +1,7 @@
# RUN: llvm-nm %p/Inputs/Strip-ST.dylib.macho-x86_64 | FileCheck --check-prefix=DEFAULT %s
# RUN: llvm-nm -no-dyldinfo %p/Inputs/Strip-ST.dylib.macho-x86_64 | FileCheck --check-prefix=NO-DYLDINFO %s
# RUN: llvm-nm -dyldinfo-only %p/Inputs/Strip-ST.dylib.macho-x86_64 | FileCheck --check-prefix=DYLDINFO-ONLY %s
+# RUN: llvm-nm %p/Inputs/Strip-N.hello.exe.macho-x86_64 | FileCheck --check-prefix=FUNC-STARTS %s
# DEFAULT: 0000000000000f90 T __Bob_is_slow
# DEFAULT: 0000000000001008 D __T0ims_data
@@ -16,3 +17,10 @@
# DYLDINFO-ONLY: 0000000000001008 D __T0ims_data
# DYLDINFO-ONLY: 0000000000000f80 T __T0om_is_not_swift
# DYLDINFO-ONLY-NOT: U dyld_stub_binder
+
+# FUNC-STARTS: 0000000100000f70 t <redacted function 1>
+# FUNC-STARTS: 0000000100000f80 t <redacted function 2>
+# FUNC-STARTS: 0000000100000000 T __mh_execute_header
+# FUNC-STARTS: 0000000100000f30 T _main
+# FUNC-STARTS: U _printf
+# FUNC-STARTS: U dyld_stub_binder
Modified: llvm/trunk/tools/llvm-nm/llvm-nm.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-nm/llvm-nm.cpp?rev=328274&r1=328273&r2=328274&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-nm/llvm-nm.cpp (original)
+++ llvm/trunk/tools/llvm-nm/llvm-nm.cpp Thu Mar 22 16:59:35 2018
@@ -270,8 +270,16 @@ struct NMSymbol {
} // anonymous namespace
static bool compareSymbolAddress(const NMSymbol &A, const NMSymbol &B) {
- bool ADefined = !(A.Sym.getFlags() & SymbolRef::SF_Undefined);
- bool BDefined = !(B.Sym.getFlags() & SymbolRef::SF_Undefined);
+ bool ADefined;
+ if (A.Sym.getRawDataRefImpl().p)
+ ADefined = !(A.Sym.getFlags() & SymbolRef::SF_Undefined);
+ else
+ ADefined = A.TypeChar != 'U';
+ bool BDefined;
+ if (B.Sym.getRawDataRefImpl().p)
+ BDefined = !(B.Sym.getFlags() & SymbolRef::SF_Undefined);
+ else
+ BDefined = B.TypeChar != 'U';
return std::make_tuple(ADefined, A.Address, A.Name, A.Size) <
std::make_tuple(BDefined, B.Address, B.Name, B.Size);
}
@@ -1207,6 +1215,8 @@ dumpSymbolNamesFromObject(SymbolicFile &
raw_string_ostream LOS(LazysNameBuffer);
std::string WeaksNameBuffer;
raw_string_ostream WOS(WeaksNameBuffer);
+ std::string FunctionStartsNameBuffer;
+ raw_string_ostream FOS(FunctionStartsNameBuffer);
if (MachO && !NoDyldInfo) {
MachO::mach_header H;
MachO::mach_header_64 H_64;
@@ -1571,6 +1581,84 @@ dumpSymbolNamesFromObject(SymbolicFile &
SymbolList[I].Name = Q;
Q += strlen(Q) + 1;
if (SymbolList[I].TypeChar == 'I') {
+ SymbolList[I].IndirectName = Q;
+ Q += strlen(Q) + 1;
+ }
+ I++;
+ }
+ }
+
+ // Trying adding symbol from the function starts table.
+ SmallVector<uint64_t, 8> FoundFns;
+ for (const auto &Command : MachO->load_commands()) {
+ if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) {
+ // We found a function starts segment, parse the addresses for
+ // consumption.
+ MachO::linkedit_data_command LLC =
+ MachO->getLinkeditDataLoadCommand(Command);
+
+ MachO->ReadULEB128s(LLC.dataoff, FoundFns);
+ }
+ }
+ // See if these addresses are already in the symbol table.
+ unsigned FunctionStartsAdded = 0;
+ for (uint64_t f = 0; f < FoundFns.size(); f++) {
+ bool found = false;
+ for (unsigned J = 0; J < SymbolList.size() && !found; ++J) {
+ if (SymbolList[J].Address == FoundFns[f] + BaseSegmentAddress)
+ found = true;
+ }
+ // See this address is not already in the symbol table fake up an
+ // nlist for it.
+ if (!found) {
+ NMSymbol F;
+ memset(&F, '\0', sizeof(NMSymbol));
+ F.Name = "<redacted function X>";
+ F.Address = FoundFns[f] + BaseSegmentAddress;
+ F.Size = 0;
+ // There is no symbol in the nlist symbol table for this so we set
+ // Sym effectivly to null and the rest of code in here must test for
+ // it and not do things like Sym.getFlags() for it.
+ F.Sym = BasicSymbolRef();
+ F.SymFlags = 0;
+ F.NType = MachO::N_SECT;
+ F.NSect = 0;
+ StringRef SegmentName = StringRef();
+ StringRef SectionName = StringRef();
+ for (const SectionRef &Section : MachO->sections()) {
+ Section.getName(SectionName);
+ SegmentName = MachO->getSectionFinalSegmentName(
+ Section.getRawDataRefImpl());
+ F.NSect++;
+ if (F.Address >= Section.getAddress() &&
+ F.Address < Section.getAddress() + Section.getSize()) {
+ F.Section = Section;
+ break;
+ }
+ }
+ if (SegmentName == "__TEXT" && SectionName == "__text")
+ F.TypeChar = 't';
+ else if (SegmentName == "__DATA" && SectionName == "__data")
+ F.TypeChar = 'd';
+ else if (SegmentName == "__DATA" && SectionName == "__bss")
+ F.TypeChar = 'b';
+ else
+ F.TypeChar = 's';
+ F.NDesc = 0;
+ F.IndirectName = StringRef();
+ SymbolList.push_back(F);
+ FOS << "<redacted function " << f << ">";
+ FOS << '\0';
+ FunctionStartsAdded++;
+ }
+ }
+ if (FunctionStartsAdded) {
+ FOS.flush();
+ const char *Q = FunctionStartsNameBuffer.c_str();
+ for (unsigned K = 0; K < FunctionStartsAdded; K++) {
+ SymbolList[I].Name = Q;
+ Q += strlen(Q) + 1;
+ if (SymbolList[I].TypeChar == 'I') {
SymbolList[I].IndirectName = Q;
Q += strlen(Q) + 1;
}
More information about the llvm-commits
mailing list