llvm.org GIT mirror llvm / 7f50100
Add the "-s" flag to llvm-nm for Mach-O files that prints symbols only in the specified section. This is same functionality as darwin’s nm(1) "-s" flag. There is one FIXME in the code and I’m all ears to anyone that can help me with that. This option takes exactly two strings and should be allowed anywhere on the command line. Such that "llvm-nm -s __TEXT __text foo.o" would work. But that does not as the CommandLine Library does not have a way to make this work as far as I can tell. For now the "-s __TEXT __text" has to be last on the command line. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212842 91177308-0d34-0410-b5e6-96231b3b80d8 Kevin Enderby 5 years ago
2 changed file(s) with 78 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
2121 RUN: | FileCheck %s -check-prefix macho-j
2222 RUN: llvm-nm -r %p/Inputs/macho-text-data-bss.macho-x86_64 \
2323 RUN: | FileCheck %s -check-prefix macho-r
24 RUN: llvm-nm %p/Inputs/macho-text-data-bss.macho-x86_64 -s __DATA __data \
25 RUN: | FileCheck %s -check-prefix macho-s
2426 RUN: llvm-nm %p/Inputs/common.coff-i386 \
2527 RUN: | FileCheck %s -check-prefix COFF-COMMON
2628 RUN: llvm-nm %p/Inputs/relocatable-with-section-address.elf-x86-64 \
98100 macho-r-NEXT: 0000000000000070 b _b
99101 macho-r-NEXT: 0000000000000030 s EH_frame0
100102
103 macho-s: 000000000000000c D _d
104 macho-s-NOT: 0000000000000048 S _t.eh
105 macho-s-NOT: 0000000000000000 T _t
106 macho-s-NOT: 0000000000000070 b _b
107 macho-s-NOT: 0000000000000030 s EH_frame0
108
101109 Test that nm uses addresses even with ELF .o files.
102110 ELF-SEC-ADDR64: 0000000000000058 D a
103111 ELF-SEC-ADDR64-NEXT: 000000000000005c D b
135135 cl::desc("Print just the symbol's name"));
136136 cl::alias JustSymbolNames("j", cl::desc("Alias for --just-symbol-name"),
137137 cl::aliasopt(JustSymbolName));
138
139 // FIXME: This option takes exactly two strings and should be allowed anywhere
140 // on the command line. Such that "llvm-nm -s __TEXT __text foo.o" would work.
141 // But that does not as the CommandLine Library does not have a way to make
142 // this work. For now the "-s __TEXT __text" has to be last on the command
143 // line.
144 cl::list SegSect("s", cl::Positional, cl::ZeroOrMore,
145 cl::desc("Dump only symbols from this segment "
146 "and section name, Mach-O only"));
147
138148 bool PrintAddress = true;
139149
140150 bool MultipleFiles = false;
713723 return Ret;
714724 }
715725
726 // getNsectForSegSect() is used to implement the Mach-O "-s segname sectname"
727 // option to dump only those symbols from that section in a Mach-O file.
728 // It is called once for each Mach-O file from dumpSymbolNamesFromObject()
729 // to get the section number for that named section from the command line
730 // arguments. It returns the section number for that section in the Mach-O
731 // file or zero it is not present.
732 static unsigned getNsectForSegSect(MachOObjectFile *Obj) {
733 unsigned Nsect = 1;
734 for (section_iterator I = Obj->section_begin(), E = Obj->section_end();
735 I != E; ++I) {
736 DataRefImpl Ref = I->getRawDataRefImpl();
737 StringRef SectionName;
738 Obj->getSectionName(Ref, SectionName);
739 StringRef SegmentName = Obj->getSectionFinalSegmentName(Ref);
740 if (SegmentName == SegSect[0] && SectionName == SegSect[1])
741 return Nsect;
742 Nsect++;
743 }
744 return 0;
745 }
746
747 // getNsectInMachO() is used to implement the Mach-O "-s segname sectname"
748 // option to dump only those symbols from that section in a Mach-O file.
749 // It is called once for each symbol in a Mach-O file from
750 // dumpSymbolNamesFromObject() and returns the section number for that symbol
751 // if it is in a section, else it returns 0.
752 static unsigned getNsectInMachO(MachOObjectFile &Obj, basic_symbol_iterator I) {
753 DataRefImpl Symb = I->getRawDataRefImpl();
754 if (Obj.is64Bit()) {
755 MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb);
756 if ((STE.n_type & MachO::N_TYPE) == MachO::N_SECT)
757 return STE.n_sect;
758 return 0;
759 }
760 MachO::nlist STE = Obj.getSymbolTableEntry(Symb);
761 if ((STE.n_type & MachO::N_TYPE) == MachO::N_SECT)
762 return STE.n_sect;
763 return 0;
764 }
765
716766 static void dumpSymbolNamesFromObject(SymbolicFile *Obj, bool printName) {
717767 basic_symbol_iterator IBegin = Obj->symbol_begin();
718768 basic_symbol_iterator IEnd = Obj->symbol_end();
728778 }
729779 std::string NameBuffer;
730780 raw_string_ostream OS(NameBuffer);
781 // If a "-s segname sectname" option was specified and this is a Mach-O
782 // file get the section number for that section in this object file.
783 unsigned int Nsect = 0;
784 MachOObjectFile *MachO = dyn_cast(Obj);
785 if (SegSect.size() != 0 && MachO) {
786 Nsect = getNsectForSegSect(MachO);
787 // If this section is not in the object file no symbols are printed.
788 if (Nsect == 0)
789 return;
790 }
731791 for (basic_symbol_iterator I = IBegin; I != IEnd; ++I) {
732792 uint32_t SymFlags = I->getFlags();
733793 if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific))
739799 continue;
740800 }
741801 }
802 // If a "-s segname sectname" option was specified and this is a Mach-O
803 // file and this section appears in this file, Nsect will be non-zero then
804 // see if this symbol is a symbol from that section and if not skip it.
805 if (Nsect && Nsect != getNsectInMachO(*MachO, I))
806 continue;
742807 NMSymbol S;
743808 S.Size = UnknownAddressOrSize;
744809 S.Address = UnknownAddressOrSize;
10461111 }
10471112 }
10481113
1114 if (SegSect.size() != 0 && SegSect.size() != 2)
1115 error("bad number of arguments (must be two arguments)",
1116 "for the -s option");
1117
1118
10491119 std::for_each(InputFilenames.begin(), InputFilenames.end(),
10501120 dumpSymbolNamesFromFile);
10511121