1 //===-- llvm-nm.cpp - Symbol table dumping utility for llvm ---------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This program is a utility that works like traditional Unix "nm", that is, it
10 // prints out the names of symbols in a bitcode or object file, along with some
11 // information about each symbol.
13 // This "nm" supports many of the features of GNU "nm", including its different
16 //===----------------------------------------------------------------------===//
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/BinaryFormat/COFF.h"
20 #include "llvm/BinaryFormat/MachO.h"
21 #include "llvm/BinaryFormat/XCOFF.h"
22 #include "llvm/DebugInfo/Symbolize/Symbolize.h"
23 #include "llvm/Demangle/Demangle.h"
24 #include "llvm/IR/Function.h"
25 #include "llvm/IR/LLVMContext.h"
26 #include "llvm/Object/Archive.h"
27 #include "llvm/Object/COFF.h"
28 #include "llvm/Object/COFFImportFile.h"
29 #include "llvm/Object/ELFObjectFile.h"
30 #include "llvm/Object/IRObjectFile.h"
31 #include "llvm/Object/MachO.h"
32 #include "llvm/Object/MachOUniversal.h"
33 #include "llvm/Object/ObjectFile.h"
34 #include "llvm/Object/SymbolicFile.h"
35 #include "llvm/Object/TapiFile.h"
36 #include "llvm/Object/TapiUniversal.h"
37 #include "llvm/Object/Wasm.h"
38 #include "llvm/Object/XCOFFObjectFile.h"
39 #include "llvm/Option/Arg.h"
40 #include "llvm/Option/ArgList.h"
41 #include "llvm/Option/Option.h"
42 #include "llvm/Support/CommandLine.h"
43 #include "llvm/Support/FileSystem.h"
44 #include "llvm/Support/Format.h"
45 #include "llvm/Support/LLVMDriver.h"
46 #include "llvm/Support/MemoryBuffer.h"
47 #include "llvm/Support/Program.h"
48 #include "llvm/Support/Signals.h"
49 #include "llvm/Support/TargetSelect.h"
50 #include "llvm/Support/WithColor.h"
51 #include "llvm/Support/raw_ostream.h"
52 #include "llvm/TargetParser/Host.h"
53 #include "llvm/TargetParser/Triple.h"
57 using namespace object
;
60 using namespace llvm::opt
; // for HelpHidden in Opts.inc
62 OPT_INVALID
= 0, // This is not an option ID.
63 #define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),
68 #define OPTTABLE_STR_TABLE_CODE
70 #undef OPTTABLE_STR_TABLE_CODE
72 #define OPTTABLE_PREFIXES_TABLE_CODE
74 #undef OPTTABLE_PREFIXES_TABLE_CODE
76 static constexpr opt::OptTable::Info InfoTable
[] = {
77 #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
82 class NmOptTable
: public opt::GenericOptTable
{
85 : opt::GenericOptTable(OptionStrTable
, OptionPrefixesTable
, InfoTable
) {
86 setGroupedShortOptions(true);
90 enum OutputFormatTy
{ bsd
, sysv
, posix
, darwin
, just_symbols
};
91 enum class BitModeTy
{ Bit32
, Bit64
, Bit32_64
, Any
};
94 static bool ArchiveMap
;
95 static BitModeTy BitMode
;
96 static bool DebugSyms
;
97 static bool DefinedOnly
;
99 static bool DynamicSyms
;
100 static bool ExportSymbols
;
101 static bool ExternalOnly
;
102 static bool LineNumbers
;
103 static OutputFormatTy OutputFormat
;
104 static bool NoLLVMBitcode
;
106 static bool NoWeakSymbols
;
107 static bool NumericSort
;
108 static bool PrintFileName
;
109 static bool PrintSize
;
111 static bool ReverseSort
;
112 static bool SpecialSyms
;
113 static bool SizeSort
;
114 static bool UndefinedOnly
;
115 static bool WithoutAliases
;
117 // XCOFF-specific options.
121 enum Radix
{ d
, o
, x
};
123 static Radix AddressRadix
;
125 // Mach-O specific options.
126 static bool ArchAll
= false;
127 static std::vector
<StringRef
> ArchFlags
;
128 static bool AddDyldInfo
;
129 static bool AddInlinedInfo
;
130 static bool DyldInfoOnly
;
131 static bool FormatMachOasHex
;
132 static bool NoDyldInfo
;
133 static std::vector
<StringRef
> SegSect
;
134 static bool MachOPrintSizeWarning
= false;
136 // Miscellaneous states.
137 static bool PrintAddress
= true;
138 static bool MultipleFiles
= false;
139 static bool HadError
= false;
141 static StringRef ToolName
;
143 static void warn(Error Err
, Twine FileName
, Twine Context
= Twine(),
144 Twine Archive
= Twine()) {
147 // Flush the standard output so that the warning isn't interleaved with other
148 // output if stdout and stderr are writing to the same place.
151 handleAllErrors(std::move(Err
), [&](const ErrorInfoBase
&EI
) {
152 WithColor::warning(errs(), ToolName
)
153 << (Archive
.str().empty() ? FileName
: Archive
+ "(" + FileName
+ ")")
154 << ": " << (Context
.str().empty() ? "" : Context
+ ": ") << EI
.message()
159 static void error(Twine Message
, Twine Path
= Twine()) {
161 WithColor::error(errs(), ToolName
) << Path
<< ": " << Message
<< "\n";
164 static bool error(std::error_code EC
, Twine Path
= Twine()) {
166 error(EC
.message(), Path
);
172 // This version of error() prints the archive name and member name, for example:
173 // "libx.a(foo.o)" after the ToolName before the error message. It sets
174 // HadError but returns allowing the code to move on to other archive members.
175 static void error(llvm::Error E
, StringRef FileName
, const Archive::Child
&C
,
176 StringRef ArchitectureName
= StringRef()) {
178 WithColor::error(errs(), ToolName
) << FileName
;
180 Expected
<StringRef
> NameOrErr
= C
.getName();
181 // TODO: if we have a error getting the name then it would be nice to print
182 // the index of which archive member this is and or its offset in the
183 // archive instead of "???" as the name.
185 consumeError(NameOrErr
.takeError());
186 errs() << "(" << "???" << ")";
188 errs() << "(" << NameOrErr
.get() << ")";
190 if (!ArchitectureName
.empty())
191 errs() << " (for architecture " << ArchitectureName
<< ")";
194 raw_string_ostream
OS(Buf
);
195 logAllUnhandledErrors(std::move(E
), OS
);
197 errs() << ": " << Buf
<< "\n";
200 // This version of error() prints the file name and which architecture slice it
201 // is from, for example: "foo.o (for architecture i386)" after the ToolName
202 // before the error message. It sets HadError but returns allowing the code to
203 // move on to other architecture slices.
204 static void error(llvm::Error E
, StringRef FileName
,
205 StringRef ArchitectureName
= StringRef()) {
207 WithColor::error(errs(), ToolName
) << FileName
;
209 if (!ArchitectureName
.empty())
210 errs() << " (for architecture " << ArchitectureName
<< ")";
213 raw_string_ostream
OS(Buf
);
214 logAllUnhandledErrors(std::move(E
), OS
);
216 errs() << ": " << Buf
<< "\n";
225 StringRef SectionName
;
228 StringRef Visibility
;
230 // The Sym field above points to the native symbol in the object file,
231 // for Mach-O when we are creating symbols from the dyld info the above
232 // pointer is null as there is no native symbol. In these cases the fields
233 // below are filled in to represent what would have been a Mach-O nlist
240 std::string IndirectName
;
242 bool isDefined() const {
243 if (Sym
.getRawDataRefImpl().p
)
244 return !(SymFlags
& SymbolRef::SF_Undefined
);
245 return TypeChar
!= 'U';
248 bool initializeFlags(const SymbolicFile
&Obj
) {
249 Expected
<uint32_t> SymFlagsOrErr
= Sym
.getFlags();
250 if (!SymFlagsOrErr
) {
251 // TODO: Test this error.
252 error(SymFlagsOrErr
.takeError(), Obj
.getFileName());
255 SymFlags
= *SymFlagsOrErr
;
259 bool shouldPrint() const {
260 bool Undefined
= SymFlags
& SymbolRef::SF_Undefined
;
261 bool Global
= SymFlags
& SymbolRef::SF_Global
;
262 bool Weak
= SymFlags
& SymbolRef::SF_Weak
;
263 bool FormatSpecific
= SymFlags
& SymbolRef::SF_FormatSpecific
;
264 if ((!Undefined
&& UndefinedOnly
) || (Undefined
&& DefinedOnly
) ||
265 (!Global
&& ExternalOnly
) || (Weak
&& NoWeakSymbols
) ||
266 (FormatSpecific
&& !(SpecialSyms
|| DebugSyms
)))
272 bool operator<(const NMSymbol
&A
, const NMSymbol
&B
) {
274 return std::make_tuple(A
.isDefined(), A
.Address
, A
.Name
, A
.Size
) <
275 std::make_tuple(B
.isDefined(), B
.Address
, B
.Name
, B
.Size
);
277 return std::make_tuple(A
.Size
, A
.Name
, A
.Address
) <
278 std::make_tuple(B
.Size
, B
.Name
, B
.Address
);
280 return std::make_tuple(A
.Name
, A
.Visibility
) <
281 std::make_tuple(B
.Name
, B
.Visibility
);
282 return std::make_tuple(A
.Name
, A
.Size
, A
.Address
) <
283 std::make_tuple(B
.Name
, B
.Size
, B
.Address
);
286 bool operator>(const NMSymbol
&A
, const NMSymbol
&B
) { return B
< A
; }
287 bool operator==(const NMSymbol
&A
, const NMSymbol
&B
) {
288 return !(A
< B
) && !(B
< A
);
290 } // anonymous namespace
292 static StringRef CurrentFilename
;
294 static char getSymbolNMTypeChar(IRObjectFile
&Obj
, basic_symbol_iterator I
);
296 // darwinPrintSymbol() is used to print a symbol from a Mach-O file when the
297 // the OutputFormat is darwin or we are printing Mach-O symbols in hex. For
298 // the darwin format it produces the same output as darwin's nm(1) -m output
299 // and when printing Mach-O symbols in hex it produces the same output as
300 // darwin's nm(1) -x format.
301 static void darwinPrintSymbol(SymbolicFile
&Obj
, const NMSymbol
&S
,
302 char *SymbolAddrStr
, const char *printBlanks
,
303 const char *printDashes
,
304 const char *printFormat
) {
305 MachO::mach_header H
;
306 MachO::mach_header_64 H_64
;
307 uint32_t Filetype
= MachO::MH_OBJECT
;
314 MachOObjectFile
*MachO
= dyn_cast
<MachOObjectFile
>(&Obj
);
316 uint32_t SymFlags
= cantFail(S
.Sym
.getFlags());
317 if (SymFlags
& SymbolRef::SF_Global
)
318 NType
|= MachO::N_EXT
;
319 if (SymFlags
& SymbolRef::SF_Hidden
)
320 NType
|= MachO::N_PEXT
;
321 if (SymFlags
& SymbolRef::SF_Undefined
)
322 NType
|= MachO::N_EXT
| MachO::N_UNDF
;
324 // Here we have a symbol definition. So to fake out a section name we
325 // use 1, 2 and 3 for section numbers. See below where they are used to
326 // print out fake section names.
327 NType
|= MachO::N_SECT
;
328 if (SymFlags
& SymbolRef::SF_Const
)
330 else if (SymFlags
& SymbolRef::SF_Executable
)
335 if (SymFlags
& SymbolRef::SF_Weak
)
336 NDesc
|= MachO::N_WEAK_DEF
;
338 DataRefImpl SymDRI
= S
.Sym
.getRawDataRefImpl();
339 if (MachO
->is64Bit()) {
340 H_64
= MachO
->MachOObjectFile::getHeader64();
341 Filetype
= H_64
.filetype
;
344 MachO::nlist_64 STE_64
= MachO
->getSymbol64TableEntry(SymDRI
);
345 NType
= STE_64
.n_type
;
346 NSect
= STE_64
.n_sect
;
347 NDesc
= STE_64
.n_desc
;
348 NStrx
= STE_64
.n_strx
;
349 NValue
= STE_64
.n_value
;
358 H
= MachO
->MachOObjectFile::getHeader();
359 Filetype
= H
.filetype
;
362 MachO::nlist STE
= MachO
->getSymbolTableEntry(SymDRI
);
367 NValue
= STE
.n_value
;
378 // If we are printing Mach-O symbols in hex do that and return.
379 if (FormatMachOasHex
) {
380 outs() << format(printFormat
, NValue
) << ' '
381 << format("%02x %02x %04x %08x", NType
, NSect
, NDesc
, NStrx
) << ' '
383 if ((NType
& MachO::N_TYPE
) == MachO::N_INDR
) {
384 outs() << " (indirect for ";
385 outs() << format(printFormat
, NValue
) << ' ';
386 StringRef IndirectName
;
387 if (S
.Sym
.getRawDataRefImpl().p
) {
388 if (MachO
->getIndirectName(S
.Sym
.getRawDataRefImpl(), IndirectName
))
391 outs() << IndirectName
<< ")";
393 outs() << S
.IndirectName
<< ")";
400 if ((NType
& MachO::N_TYPE
) == MachO::N_INDR
)
401 strcpy(SymbolAddrStr
, printBlanks
);
402 if (Obj
.isIR() && (NType
& MachO::N_TYPE
) == MachO::N_TYPE
)
403 strcpy(SymbolAddrStr
, printDashes
);
404 outs() << SymbolAddrStr
<< ' ';
407 switch (NType
& MachO::N_TYPE
) {
410 outs() << "(common) ";
411 if (MachO::GET_COMM_ALIGN(NDesc
) != 0)
412 outs() << "(alignment 2^" << (int)MachO::GET_COMM_ALIGN(NDesc
) << ") ";
414 if ((NType
& MachO::N_TYPE
) == MachO::N_PBUD
)
415 outs() << "(prebound ";
418 if ((NDesc
& MachO::REFERENCE_TYPE
) ==
419 MachO::REFERENCE_FLAG_UNDEFINED_LAZY
)
420 outs() << "undefined [lazy bound]) ";
421 else if ((NDesc
& MachO::REFERENCE_TYPE
) ==
422 MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY
)
423 outs() << "undefined [private lazy bound]) ";
424 else if ((NDesc
& MachO::REFERENCE_TYPE
) ==
425 MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY
)
426 outs() << "undefined [private]) ";
428 outs() << "undefined) ";
432 outs() << "(absolute) ";
435 outs() << "(indirect) ";
437 case MachO::N_SECT
: {
439 // For llvm bitcode files print out a fake section name using the values
440 // use 1, 2 and 3 for section numbers as set above.
442 outs() << "(LTO,CODE) ";
444 outs() << "(LTO,DATA) ";
446 outs() << "(LTO,RODATA) ";
451 section_iterator Sec
= SectionRef();
452 if (S
.Sym
.getRawDataRefImpl().p
) {
453 Expected
<section_iterator
> SecOrErr
=
454 MachO
->getSymbolSection(S
.Sym
.getRawDataRefImpl());
456 consumeError(SecOrErr
.takeError());
461 if (Sec
== MachO
->section_end()) {
468 DataRefImpl Ref
= Sec
->getRawDataRefImpl();
469 StringRef SectionName
;
470 if (Expected
<StringRef
> NameOrErr
= MachO
->getSectionName(Ref
))
471 SectionName
= *NameOrErr
;
472 StringRef SegmentName
= MachO
->getSectionFinalSegmentName(Ref
);
473 outs() << "(" << SegmentName
<< "," << SectionName
<< ") ";
481 if (NType
& MachO::N_EXT
) {
482 if (NDesc
& MachO::REFERENCED_DYNAMICALLY
)
483 outs() << "[referenced dynamically] ";
484 if (NType
& MachO::N_PEXT
) {
485 if ((NDesc
& MachO::N_WEAK_DEF
) == MachO::N_WEAK_DEF
)
486 outs() << "weak private external ";
488 outs() << "private external ";
490 if ((NDesc
& MachO::N_WEAK_REF
) == MachO::N_WEAK_REF
||
491 (NDesc
& MachO::N_WEAK_DEF
) == MachO::N_WEAK_DEF
) {
492 if ((NDesc
& (MachO::N_WEAK_REF
| MachO::N_WEAK_DEF
)) ==
493 (MachO::N_WEAK_REF
| MachO::N_WEAK_DEF
))
494 outs() << "weak external automatically hidden ";
496 outs() << "weak external ";
498 outs() << "external ";
501 if (NType
& MachO::N_PEXT
)
502 outs() << "non-external (was a private external) ";
504 outs() << "non-external ";
507 if (Filetype
== MachO::MH_OBJECT
) {
508 if (NDesc
& MachO::N_NO_DEAD_STRIP
)
509 outs() << "[no dead strip] ";
510 if ((NType
& MachO::N_TYPE
) != MachO::N_UNDF
&&
511 NDesc
& MachO::N_SYMBOL_RESOLVER
)
512 outs() << "[symbol resolver] ";
513 if ((NType
& MachO::N_TYPE
) != MachO::N_UNDF
&& NDesc
& MachO::N_ALT_ENTRY
)
514 outs() << "[alt entry] ";
515 if ((NType
& MachO::N_TYPE
) != MachO::N_UNDF
&& NDesc
& MachO::N_COLD_FUNC
)
516 outs() << "[cold func] ";
519 if ((NDesc
& MachO::N_ARM_THUMB_DEF
) == MachO::N_ARM_THUMB_DEF
)
520 outs() << "[Thumb] ";
522 if ((NType
& MachO::N_TYPE
) == MachO::N_INDR
) {
523 outs() << S
.Name
<< " (for ";
524 StringRef IndirectName
;
526 if (S
.Sym
.getRawDataRefImpl().p
) {
527 if (MachO
->getIndirectName(S
.Sym
.getRawDataRefImpl(), IndirectName
))
530 outs() << IndirectName
<< ")";
532 outs() << S
.IndirectName
<< ")";
538 if ((Flags
& MachO::MH_TWOLEVEL
) == MachO::MH_TWOLEVEL
&&
539 (((NType
& MachO::N_TYPE
) == MachO::N_UNDF
&& NValue
== 0) ||
540 (NType
& MachO::N_TYPE
) == MachO::N_PBUD
)) {
541 uint32_t LibraryOrdinal
= MachO::GET_LIBRARY_ORDINAL(NDesc
);
542 if (LibraryOrdinal
!= 0) {
543 if (LibraryOrdinal
== MachO::EXECUTABLE_ORDINAL
)
544 outs() << " (from executable)";
545 else if (LibraryOrdinal
== MachO::DYNAMIC_LOOKUP_ORDINAL
)
546 outs() << " (dynamically looked up)";
548 StringRef LibraryName
;
550 MachO
->getLibraryShortNameByIndex(LibraryOrdinal
- 1, LibraryName
))
551 outs() << " (from bad library ordinal " << LibraryOrdinal
<< ")";
553 outs() << " (from " << LibraryName
<< ")";
559 // Table that maps Darwin's Mach-O stab constants to strings to allow printing.
560 struct DarwinStabName
{
564 const struct DarwinStabName DarwinStabNames
[] = {
565 {MachO::N_GSYM
, "GSYM"}, {MachO::N_FNAME
, "FNAME"},
566 {MachO::N_FUN
, "FUN"}, {MachO::N_STSYM
, "STSYM"},
567 {MachO::N_LCSYM
, "LCSYM"}, {MachO::N_BNSYM
, "BNSYM"},
568 {MachO::N_PC
, "PC"}, {MachO::N_AST
, "AST"},
569 {MachO::N_OPT
, "OPT"}, {MachO::N_RSYM
, "RSYM"},
570 {MachO::N_SLINE
, "SLINE"}, {MachO::N_ENSYM
, "ENSYM"},
571 {MachO::N_SSYM
, "SSYM"}, {MachO::N_SO
, "SO"},
572 {MachO::N_OSO
, "OSO"}, {MachO::N_LIB
, "LIB"},
573 {MachO::N_LSYM
, "LSYM"}, {MachO::N_BINCL
, "BINCL"},
574 {MachO::N_SOL
, "SOL"}, {MachO::N_PARAMS
, "PARAM"},
575 {MachO::N_VERSION
, "VERS"}, {MachO::N_OLEVEL
, "OLEV"},
576 {MachO::N_PSYM
, "PSYM"}, {MachO::N_EINCL
, "EINCL"},
577 {MachO::N_ENTRY
, "ENTRY"}, {MachO::N_LBRAC
, "LBRAC"},
578 {MachO::N_EXCL
, "EXCL"}, {MachO::N_RBRAC
, "RBRAC"},
579 {MachO::N_BCOMM
, "BCOMM"}, {MachO::N_ECOMM
, "ECOMM"},
580 {MachO::N_ECOML
, "ECOML"}, {MachO::N_LENG
, "LENG"},
583 static const char *getDarwinStabString(uint8_t NType
) {
584 for (auto I
: ArrayRef(DarwinStabNames
))
585 if (I
.NType
== NType
)
590 // darwinPrintStab() prints the n_sect, n_desc along with a symbolic name of
591 // a stab n_type value in a Mach-O file.
592 static void darwinPrintStab(MachOObjectFile
*MachO
, const NMSymbol
&S
) {
593 MachO::nlist_64 STE_64
;
598 DataRefImpl SymDRI
= S
.Sym
.getRawDataRefImpl();
599 if (MachO
->is64Bit()) {
600 STE_64
= MachO
->getSymbol64TableEntry(SymDRI
);
601 NType
= STE_64
.n_type
;
602 NSect
= STE_64
.n_sect
;
603 NDesc
= STE_64
.n_desc
;
605 STE
= MachO
->getSymbolTableEntry(SymDRI
);
611 outs() << format(" %02x %04x ", NSect
, NDesc
);
612 if (const char *stabString
= getDarwinStabString(NType
))
613 outs() << format("%5.5s", stabString
);
615 outs() << format(" %02x", NType
);
618 static bool symbolIsDefined(const NMSymbol
&Sym
) {
619 return Sym
.TypeChar
!= 'U' && Sym
.TypeChar
!= 'w' && Sym
.TypeChar
!= 'v';
622 static void writeFileName(raw_ostream
&S
, StringRef ArchiveName
,
623 StringRef ArchitectureName
) {
624 if (!ArchitectureName
.empty())
625 S
<< "(for architecture " << ArchitectureName
<< "):";
626 if (OutputFormat
== posix
&& !ArchiveName
.empty())
627 S
<< ArchiveName
<< "[" << CurrentFilename
<< "]: ";
629 if (!ArchiveName
.empty())
630 S
<< ArchiveName
<< ":";
631 S
<< CurrentFilename
<< ": ";
635 static void sortSymbolList(std::vector
<NMSymbol
> &SymbolList
) {
640 llvm::sort(SymbolList
, std::greater
<>());
642 llvm::sort(SymbolList
);
645 static void printExportSymbolList(const std::vector
<NMSymbol
> &SymbolList
) {
646 for (const NMSymbol
&Sym
: SymbolList
) {
648 if (!Sym
.Visibility
.empty())
649 outs() << ' ' << Sym
.Visibility
;
654 static void printLineNumbers(symbolize::LLVMSymbolizer
&Symbolizer
,
656 const auto *Obj
= dyn_cast
<ObjectFile
>(S
.Sym
.getObject());
659 const SymbolRef
Sym(S
.Sym
);
660 uint64_t SectionIndex
= object::SectionedAddress::UndefSection
;
661 section_iterator Sec
= cantFail(Sym
.getSection());
662 if (Sec
!= Obj
->section_end())
663 SectionIndex
= Sec
->getIndex();
664 object::SectionedAddress Address
= {cantFail(Sym
.getAddress()), SectionIndex
};
666 std::string FileName
;
668 switch (S
.TypeChar
) {
669 // For undefined symbols, find the first relocation for that symbol with a
672 for (const SectionRef RelocsSec
: Obj
->sections()) {
673 if (RelocsSec
.relocations().empty())
675 SectionRef TextSec
= *cantFail(RelocsSec
.getRelocatedSection());
676 if (!TextSec
.isText())
678 for (const RelocationRef R
: RelocsSec
.relocations()) {
679 if (R
.getSymbol() != Sym
)
681 Expected
<DILineInfo
> ResOrErr
= Symbolizer
.symbolizeCode(
682 *Obj
, {TextSec
.getAddress() + R
.getOffset(), SectionIndex
});
684 error(ResOrErr
.takeError(), Obj
->getFileName());
687 if (ResOrErr
->FileName
== DILineInfo::BadString
)
689 FileName
= std::move(ResOrErr
->FileName
);
690 Line
= ResOrErr
->Line
;
693 if (!FileName
.empty())
696 if (FileName
.empty())
702 Expected
<DILineInfo
> ResOrErr
= Symbolizer
.symbolizeCode(*Obj
, Address
);
704 error(ResOrErr
.takeError(), Obj
->getFileName());
707 if (ResOrErr
->FileName
== DILineInfo::BadString
)
709 FileName
= std::move(ResOrErr
->FileName
);
710 Line
= ResOrErr
->Line
;
714 Expected
<DIGlobal
> ResOrErr
= Symbolizer
.symbolizeData(*Obj
, Address
);
716 error(ResOrErr
.takeError(), Obj
->getFileName());
719 if (ResOrErr
->DeclFile
.empty())
721 FileName
= std::move(ResOrErr
->DeclFile
);
722 Line
= ResOrErr
->DeclLine
;
726 outs() << '\t' << FileName
<< ':' << Line
;
729 static void printSymbolList(SymbolicFile
&Obj
,
730 std::vector
<NMSymbol
> &SymbolList
, bool printName
,
731 StringRef ArchiveName
, StringRef ArchitectureName
) {
732 std::optional
<symbolize::LLVMSymbolizer
> Symbolizer
;
734 Symbolizer
.emplace();
736 if (!PrintFileName
) {
737 if ((OutputFormat
== bsd
|| OutputFormat
== posix
||
738 OutputFormat
== just_symbols
) &&
739 MultipleFiles
&& printName
) {
740 outs() << '\n' << CurrentFilename
<< ":\n";
741 } else if (OutputFormat
== sysv
) {
742 outs() << "\n\nSymbols from " << CurrentFilename
<< ":\n\n";
744 outs() << "Name Value Class Type"
745 << " Size Line Section\n";
747 outs() << "Name Value Class Type"
748 << " Size Line Section\n";
752 const char *printBlanks
, *printDashes
, *printFormat
;
755 printDashes
= "----------------";
756 switch (AddressRadix
) {
758 printFormat
= OutputFormat
== posix
? "%" PRIo64
: "%016" PRIo64
;
761 printFormat
= OutputFormat
== posix
? "%" PRIx64
: "%016" PRIx64
;
764 printFormat
= OutputFormat
== posix
? "%" PRId64
: "%016" PRId64
;
768 printDashes
= "--------";
769 switch (AddressRadix
) {
771 printFormat
= OutputFormat
== posix
? "%" PRIo64
: "%08" PRIo64
;
774 printFormat
= OutputFormat
== posix
? "%" PRIx64
: "%08" PRIx64
;
777 printFormat
= OutputFormat
== posix
? "%" PRId64
: "%08" PRId64
;
781 for (const NMSymbol
&S
: SymbolList
) {
782 if (!S
.shouldPrint())
785 std::string Name
= S
.Name
;
786 MachOObjectFile
*MachO
= dyn_cast
<MachOObjectFile
>(&Obj
);
788 Name
= demangle(Name
);
791 writeFileName(outs(), ArchiveName
, ArchitectureName
);
792 if ((OutputFormat
== just_symbols
||
793 (UndefinedOnly
&& MachO
&& OutputFormat
!= darwin
)) &&
794 OutputFormat
!= posix
) {
795 outs() << Name
<< "\n";
799 char SymbolAddrStr
[23], SymbolSizeStr
[23];
801 // If the format is SysV or the symbol isn't defined, then print spaces.
802 if (OutputFormat
== sysv
|| !symbolIsDefined(S
)) {
803 if (OutputFormat
== posix
) {
804 format(printFormat
, S
.Address
)
805 .print(SymbolAddrStr
, sizeof(SymbolAddrStr
));
806 format(printFormat
, S
.Size
).print(SymbolSizeStr
, sizeof(SymbolSizeStr
));
808 strcpy(SymbolAddrStr
, printBlanks
);
809 strcpy(SymbolSizeStr
, printBlanks
);
813 if (symbolIsDefined(S
)) {
814 // Otherwise, print the symbol address and size.
816 strcpy(SymbolAddrStr
, printDashes
);
817 else if (MachO
&& S
.TypeChar
== 'I')
818 strcpy(SymbolAddrStr
, printBlanks
);
820 format(printFormat
, S
.Address
)
821 .print(SymbolAddrStr
, sizeof(SymbolAddrStr
));
822 format(printFormat
, S
.Size
).print(SymbolSizeStr
, sizeof(SymbolSizeStr
));
825 // If OutputFormat is darwin or we are printing Mach-O symbols in hex and
826 // we have a MachOObjectFile, call darwinPrintSymbol to print as darwin's
827 // nm(1) -m output or hex, else if OutputFormat is darwin or we are
828 // printing Mach-O symbols in hex and not a Mach-O object fall back to
829 // OutputFormat bsd (see below).
830 if ((OutputFormat
== darwin
|| FormatMachOasHex
) && (MachO
|| Obj
.isIR())) {
831 darwinPrintSymbol(Obj
, S
, SymbolAddrStr
, printBlanks
, printDashes
,
833 } else if (OutputFormat
== posix
) {
834 outs() << Name
<< " " << S
.TypeChar
<< " " << SymbolAddrStr
<< " "
835 << (MachO
? "0" : SymbolSizeStr
);
836 } else if (OutputFormat
== bsd
|| (OutputFormat
== darwin
&& !MachO
)) {
838 outs() << SymbolAddrStr
<< ' ';
840 outs() << SymbolSizeStr
<< ' ';
841 outs() << S
.TypeChar
;
842 if (S
.TypeChar
== '-' && MachO
)
843 darwinPrintStab(MachO
, S
);
844 outs() << " " << Name
;
845 if (S
.TypeChar
== 'I' && MachO
) {
846 outs() << " (indirect for ";
847 if (S
.Sym
.getRawDataRefImpl().p
) {
848 StringRef IndirectName
;
849 if (MachO
->getIndirectName(S
.Sym
.getRawDataRefImpl(), IndirectName
))
852 outs() << IndirectName
<< ")";
854 outs() << S
.IndirectName
<< ")";
856 } else if (OutputFormat
== sysv
) {
857 outs() << left_justify(Name
, 20) << "|" << SymbolAddrStr
<< "| "
858 << S
.TypeChar
<< " |" << right_justify(S
.TypeName
, 18) << "|"
859 << SymbolSizeStr
<< "| |" << S
.SectionName
;
862 printLineNumbers(*Symbolizer
, S
);
869 static char getSymbolNMTypeChar(ELFObjectFileBase
&Obj
,
870 basic_symbol_iterator I
) {
872 elf_symbol_iterator
SymI(I
);
874 Expected
<elf_section_iterator
> SecIOrErr
= SymI
->getSection();
876 consumeError(SecIOrErr
.takeError());
880 uint8_t Binding
= SymI
->getBinding();
881 if (Binding
== ELF::STB_GNU_UNIQUE
)
884 assert(Binding
!= ELF::STB_WEAK
&& "STB_WEAK not tested in calling function");
885 if (Binding
!= ELF::STB_GLOBAL
&& Binding
!= ELF::STB_LOCAL
)
888 elf_section_iterator SecI
= *SecIOrErr
;
889 if (SecI
!= Obj
.section_end()) {
890 uint32_t Type
= SecI
->getType();
891 uint64_t Flags
= SecI
->getFlags();
892 if (Flags
& ELF::SHF_EXECINSTR
)
894 if (Type
== ELF::SHT_NOBITS
)
896 if (Flags
& ELF::SHF_ALLOC
)
897 return Flags
& ELF::SHF_WRITE
? 'd' : 'r';
899 auto NameOrErr
= SecI
->getName();
901 consumeError(NameOrErr
.takeError());
904 if ((*NameOrErr
).starts_with(".debug"))
906 if (!(Flags
& ELF::SHF_WRITE
))
913 static char getSymbolNMTypeChar(COFFObjectFile
&Obj
, symbol_iterator I
) {
914 COFFSymbolRef Symb
= Obj
.getCOFFSymbol(*I
);
916 symbol_iterator
SymI(I
);
918 Expected
<StringRef
> Name
= SymI
->getName();
920 consumeError(Name
.takeError());
924 char Ret
= StringSwitch
<char>(*Name
)
925 .StartsWith(".debug", 'N')
926 .StartsWith(".sxdata", 'N')
932 uint32_t Characteristics
= 0;
933 if (!COFF::isReservedSectionNumber(Symb
.getSectionNumber())) {
934 Expected
<section_iterator
> SecIOrErr
= SymI
->getSection();
936 consumeError(SecIOrErr
.takeError());
939 section_iterator SecI
= *SecIOrErr
;
940 const coff_section
*Section
= Obj
.getCOFFSection(*SecI
);
941 Characteristics
= Section
->Characteristics
;
942 if (Expected
<StringRef
> NameOrErr
= Obj
.getSectionName(Section
))
943 if (NameOrErr
->starts_with(".idata"))
947 switch (Symb
.getSectionNumber()) {
948 case COFF::IMAGE_SYM_DEBUG
:
951 // Check section type.
952 if (Characteristics
& COFF::IMAGE_SCN_CNT_CODE
)
954 if (Characteristics
& COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
)
955 return Characteristics
& COFF::IMAGE_SCN_MEM_WRITE
? 'd' : 'r';
956 if (Characteristics
& COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
)
958 if (Characteristics
& COFF::IMAGE_SCN_LNK_INFO
)
960 // Check for section symbol.
961 if (Symb
.isSectionDefinition())
968 static char getSymbolNMTypeChar(XCOFFObjectFile
&Obj
, symbol_iterator I
) {
969 Expected
<uint32_t> TypeOrErr
= I
->getType();
971 warn(TypeOrErr
.takeError(), Obj
.getFileName(),
972 "for symbol with index " +
973 Twine(Obj
.getSymbolIndex(I
->getRawDataRefImpl().p
)));
977 uint32_t SymType
= *TypeOrErr
;
979 if (SymType
== SymbolRef::ST_File
)
982 // If the I->getSection() call would return an error, the earlier I->getType()
983 // call will already have returned the same error first.
984 section_iterator SecIter
= cantFail(I
->getSection());
986 if (SecIter
== Obj
.section_end())
989 if (Obj
.isDebugSection(SecIter
->getRawDataRefImpl()))
992 if (SecIter
->isText())
995 if (SecIter
->isData())
998 if (SecIter
->isBSS())
1004 static char getSymbolNMTypeChar(COFFImportFile
&Obj
) {
1005 switch (Obj
.getCOFFImportHeader()->getType()) {
1006 case COFF::IMPORT_CODE
:
1008 case COFF::IMPORT_DATA
:
1010 case COFF::IMPORT_CONST
:
1016 static char getSymbolNMTypeChar(MachOObjectFile
&Obj
, basic_symbol_iterator I
) {
1017 DataRefImpl Symb
= I
->getRawDataRefImpl();
1018 uint8_t NType
= Obj
.is64Bit() ? Obj
.getSymbol64TableEntry(Symb
).n_type
1019 : Obj
.getSymbolTableEntry(Symb
).n_type
;
1021 if (NType
& MachO::N_STAB
)
1024 switch (NType
& MachO::N_TYPE
) {
1029 case MachO::N_SECT
: {
1030 Expected
<section_iterator
> SecOrErr
= Obj
.getSymbolSection(Symb
);
1032 consumeError(SecOrErr
.takeError());
1035 section_iterator Sec
= *SecOrErr
;
1036 if (Sec
== Obj
.section_end())
1038 DataRefImpl Ref
= Sec
->getRawDataRefImpl();
1039 StringRef SectionName
;
1040 if (Expected
<StringRef
> NameOrErr
= Obj
.getSectionName(Ref
))
1041 SectionName
= *NameOrErr
;
1042 StringRef SegmentName
= Obj
.getSectionFinalSegmentName(Ref
);
1043 if (Obj
.is64Bit() && Obj
.getHeader64().filetype
== MachO::MH_KEXT_BUNDLE
&&
1044 SegmentName
== "__TEXT_EXEC" && SectionName
== "__text")
1046 if (SegmentName
== "__TEXT" && SectionName
== "__text")
1048 if (SegmentName
== "__DATA" && SectionName
== "__data")
1050 if (SegmentName
== "__DATA" && SectionName
== "__bss")
1059 static char getSymbolNMTypeChar(TapiFile
&Obj
, basic_symbol_iterator I
) {
1060 auto Type
= cantFail(Obj
.getSymbolType(I
->getRawDataRefImpl()));
1062 case SymbolRef::ST_Function
:
1064 case SymbolRef::ST_Data
:
1065 if (Obj
.hasSegmentInfo())
1073 static char getSymbolNMTypeChar(WasmObjectFile
&Obj
, basic_symbol_iterator I
) {
1074 uint32_t Flags
= cantFail(I
->getFlags());
1075 if (Flags
& SymbolRef::SF_Executable
)
1080 static char getSymbolNMTypeChar(IRObjectFile
&Obj
, basic_symbol_iterator I
) {
1081 uint32_t Flags
= cantFail(I
->getFlags());
1082 // FIXME: should we print 'b'? At the IR level we cannot be sure if this
1083 // will be in bss or not, but we could approximate.
1084 if (Flags
& SymbolRef::SF_Executable
)
1086 else if (Triple(Obj
.getTargetTriple()).isOSDarwin() &&
1087 (Flags
& SymbolRef::SF_Const
))
1093 static bool isObject(SymbolicFile
&Obj
, basic_symbol_iterator I
) {
1094 return isa
<ELFObjectFileBase
>(&Obj
) &&
1095 elf_symbol_iterator(I
)->getELFType() == ELF::STT_OBJECT
;
1098 // For ELF object files, Set TypeName to the symbol typename, to be printed
1099 // in the 'Type' column of the SYSV format output.
1100 static StringRef
getNMTypeName(SymbolicFile
&Obj
, basic_symbol_iterator I
) {
1101 if (isa
<ELFObjectFileBase
>(&Obj
)) {
1102 elf_symbol_iterator
SymI(I
);
1103 return SymI
->getELFTypeName();
1108 // Return Posix nm class type tag (single letter), but also set SecName and
1109 // section and name, to be used in format=sysv output.
1110 static char getNMSectionTagAndName(SymbolicFile
&Obj
, basic_symbol_iterator I
,
1111 StringRef
&SecName
) {
1112 // Symbol Flags have been checked in the caller.
1113 uint32_t Symflags
= cantFail(I
->getFlags());
1114 if (ELFObjectFileBase
*ELFObj
= dyn_cast
<ELFObjectFileBase
>(&Obj
)) {
1115 if (Symflags
& object::SymbolRef::SF_Absolute
)
1117 else if (Symflags
& object::SymbolRef::SF_Common
)
1119 else if (Symflags
& object::SymbolRef::SF_Undefined
)
1122 elf_symbol_iterator
SymI(I
);
1123 Expected
<elf_section_iterator
> SecIOrErr
= SymI
->getSection();
1125 consumeError(SecIOrErr
.takeError());
1129 if (*SecIOrErr
== ELFObj
->section_end())
1132 Expected
<StringRef
> NameOrErr
= (*SecIOrErr
)->getName();
1134 consumeError(NameOrErr
.takeError());
1137 SecName
= *NameOrErr
;
1141 if (Symflags
& object::SymbolRef::SF_Undefined
) {
1142 if (isa
<MachOObjectFile
>(Obj
) || !(Symflags
& object::SymbolRef::SF_Weak
))
1144 return isObject(Obj
, I
) ? 'v' : 'w';
1146 if (isa
<ELFObjectFileBase
>(&Obj
))
1147 if (ELFSymbolRef(*I
).getELFType() == ELF::STT_GNU_IFUNC
)
1149 if (!isa
<MachOObjectFile
>(Obj
) && (Symflags
& object::SymbolRef::SF_Weak
))
1150 return isObject(Obj
, I
) ? 'V' : 'W';
1152 if (Symflags
& object::SymbolRef::SF_Common
)
1156 if (Symflags
& object::SymbolRef::SF_Absolute
)
1158 else if (IRObjectFile
*IR
= dyn_cast
<IRObjectFile
>(&Obj
))
1159 Ret
= getSymbolNMTypeChar(*IR
, I
);
1160 else if (COFFObjectFile
*COFF
= dyn_cast
<COFFObjectFile
>(&Obj
))
1161 Ret
= getSymbolNMTypeChar(*COFF
, I
);
1162 else if (XCOFFObjectFile
*XCOFF
= dyn_cast
<XCOFFObjectFile
>(&Obj
))
1163 Ret
= getSymbolNMTypeChar(*XCOFF
, I
);
1164 else if (COFFImportFile
*COFFImport
= dyn_cast
<COFFImportFile
>(&Obj
))
1165 Ret
= getSymbolNMTypeChar(*COFFImport
);
1166 else if (MachOObjectFile
*MachO
= dyn_cast
<MachOObjectFile
>(&Obj
))
1167 Ret
= getSymbolNMTypeChar(*MachO
, I
);
1168 else if (WasmObjectFile
*Wasm
= dyn_cast
<WasmObjectFile
>(&Obj
))
1169 Ret
= getSymbolNMTypeChar(*Wasm
, I
);
1170 else if (TapiFile
*Tapi
= dyn_cast
<TapiFile
>(&Obj
))
1171 Ret
= getSymbolNMTypeChar(*Tapi
, I
);
1172 else if (ELFObjectFileBase
*ELF
= dyn_cast
<ELFObjectFileBase
>(&Obj
)) {
1173 Ret
= getSymbolNMTypeChar(*ELF
, I
);
1174 if (ELFSymbolRef(*I
).getBinding() == ELF::STB_GNU_UNIQUE
)
1177 llvm_unreachable("unknown binary format");
1179 if (!(Symflags
& object::SymbolRef::SF_Global
))
1182 return toupper(Ret
);
1185 // getNsectForSegSect() is used to implement the Mach-O "-s segname sectname"
1186 // option to dump only those symbols from that section in a Mach-O file.
1187 // It is called once for each Mach-O file from getSymbolNamesFromObject()
1188 // to get the section number for that named section from the command line
1189 // arguments. It returns the section number for that section in the Mach-O
1190 // file or zero it is not present.
1191 static unsigned getNsectForSegSect(MachOObjectFile
*Obj
) {
1193 for (auto &S
: Obj
->sections()) {
1194 DataRefImpl Ref
= S
.getRawDataRefImpl();
1195 StringRef SectionName
;
1196 if (Expected
<StringRef
> NameOrErr
= Obj
->getSectionName(Ref
))
1197 SectionName
= *NameOrErr
;
1198 StringRef SegmentName
= Obj
->getSectionFinalSegmentName(Ref
);
1199 if (SegmentName
== SegSect
[0] && SectionName
== SegSect
[1])
1206 // getNsectInMachO() is used to implement the Mach-O "-s segname sectname"
1207 // option to dump only those symbols from that section in a Mach-O file.
1208 // It is called once for each symbol in a Mach-O file from
1209 // getSymbolNamesFromObject() and returns the section number for that symbol
1210 // if it is in a section, else it returns 0.
1211 static unsigned getNsectInMachO(MachOObjectFile
&Obj
, BasicSymbolRef Sym
) {
1212 DataRefImpl Symb
= Sym
.getRawDataRefImpl();
1213 if (Obj
.is64Bit()) {
1214 MachO::nlist_64 STE
= Obj
.getSymbol64TableEntry(Symb
);
1215 return (STE
.n_type
& MachO::N_TYPE
) == MachO::N_SECT
? STE
.n_sect
: 0;
1217 MachO::nlist STE
= Obj
.getSymbolTableEntry(Symb
);
1218 return (STE
.n_type
& MachO::N_TYPE
) == MachO::N_SECT
? STE
.n_sect
: 0;
1221 static void dumpSymbolsFromDLInfoMachO(MachOObjectFile
&MachO
,
1222 std::vector
<NMSymbol
> &SymbolList
) {
1223 size_t I
= SymbolList
.size();
1224 std::string ExportsNameBuffer
;
1225 raw_string_ostream
EOS(ExportsNameBuffer
);
1226 std::string BindsNameBuffer
;
1227 raw_string_ostream
BOS(BindsNameBuffer
);
1228 std::string LazysNameBuffer
;
1229 raw_string_ostream
LOS(LazysNameBuffer
);
1230 std::string WeaksNameBuffer
;
1231 raw_string_ostream
WOS(WeaksNameBuffer
);
1232 std::string FunctionStartsNameBuffer
;
1233 raw_string_ostream
FOS(FunctionStartsNameBuffer
);
1235 MachO::mach_header H
;
1236 MachO::mach_header_64 H_64
;
1237 uint32_t HFlags
= 0;
1238 if (MachO
.is64Bit()) {
1239 H_64
= MachO
.MachOObjectFile::getHeader64();
1240 HFlags
= H_64
.flags
;
1242 H
= MachO
.MachOObjectFile::getHeader();
1245 uint64_t BaseSegmentAddress
= 0;
1246 for (const auto &Command
: MachO
.load_commands()) {
1247 if (Command
.C
.cmd
== MachO::LC_SEGMENT
) {
1248 MachO::segment_command Seg
= MachO
.getSegmentLoadCommand(Command
);
1249 if (Seg
.fileoff
== 0 && Seg
.filesize
!= 0) {
1250 BaseSegmentAddress
= Seg
.vmaddr
;
1253 } else if (Command
.C
.cmd
== MachO::LC_SEGMENT_64
) {
1254 MachO::segment_command_64 Seg
= MachO
.getSegment64LoadCommand(Command
);
1255 if (Seg
.fileoff
== 0 && Seg
.filesize
!= 0) {
1256 BaseSegmentAddress
= Seg
.vmaddr
;
1261 if (DyldInfoOnly
|| AddDyldInfo
||
1262 HFlags
& MachO::MH_NLIST_OUTOFSYNC_WITH_DYLDINFO
) {
1263 unsigned ExportsAdded
= 0;
1264 Error Err
= Error::success();
1265 for (const llvm::object::ExportEntry
&Entry
: MachO
.exports(Err
)) {
1267 bool ReExport
= false;
1268 if (!DyldInfoOnly
) {
1269 for (const NMSymbol
&S
: SymbolList
)
1270 if (S
.Address
== Entry
.address() + BaseSegmentAddress
&&
1271 S
.Name
== Entry
.name()) {
1278 S
.Address
= Entry
.address() + BaseSegmentAddress
;
1281 S
.Name
= Entry
.name().str();
1282 // There is no symbol in the nlist symbol table for this so we set
1283 // Sym effectivly to null and the rest of code in here must test for
1284 // it and not do things like Sym.getFlags() for it.
1285 S
.Sym
= BasicSymbolRef();
1286 S
.SymFlags
= SymbolRef::SF_Global
;
1287 S
.Section
= SectionRef();
1292 uint64_t EFlags
= Entry
.flags();
1293 bool Abs
= ((EFlags
& MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK
) ==
1294 MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE
);
1295 bool Resolver
= (EFlags
& MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER
);
1296 ReExport
= (EFlags
& MachO::EXPORT_SYMBOL_FLAGS_REEXPORT
);
1297 bool WeakDef
= (EFlags
& MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION
);
1299 S
.NDesc
|= MachO::N_WEAK_DEF
;
1301 S
.NType
= MachO::N_EXT
| MachO::N_ABS
;
1303 } else if (ReExport
) {
1304 S
.NType
= MachO::N_EXT
| MachO::N_INDR
;
1307 S
.NType
= MachO::N_EXT
| MachO::N_SECT
;
1309 S
.Address
= Entry
.other() + BaseSegmentAddress
;
1310 if ((S
.Address
& 1) != 0 && !MachO
.is64Bit() &&
1311 H
.cputype
== MachO::CPU_TYPE_ARM
) {
1313 S
.NDesc
|= MachO::N_ARM_THUMB_DEF
;
1316 S
.Address
= Entry
.address() + BaseSegmentAddress
;
1318 StringRef SegmentName
= StringRef();
1319 StringRef SectionName
= StringRef();
1320 for (const SectionRef
&Section
: MachO
.sections()) {
1323 if (Expected
<StringRef
> NameOrErr
= Section
.getName())
1324 SectionName
= *NameOrErr
;
1326 consumeError(NameOrErr
.takeError());
1329 MachO
.getSectionFinalSegmentName(Section
.getRawDataRefImpl());
1330 if (S
.Address
>= Section
.getAddress() &&
1331 S
.Address
< Section
.getAddress() + Section
.getSize()) {
1332 S
.Section
= Section
;
1334 } else if (Entry
.name() == "__mh_execute_header" &&
1335 SegmentName
== "__TEXT" && SectionName
== "__text") {
1336 S
.Section
= Section
;
1337 S
.NDesc
|= MachO::REFERENCED_DYNAMICALLY
;
1341 if (SegmentName
== "__TEXT" && SectionName
== "__text")
1343 else if (SegmentName
== "__DATA" && SectionName
== "__data")
1345 else if (SegmentName
== "__DATA" && SectionName
== "__bss")
1350 SymbolList
.push_back(S
);
1352 EOS
<< Entry
.name();
1356 // For ReExports there are a two more things to do, first add the
1357 // indirect name and second create the undefined symbol using the
1358 // referened dynamic library.
1361 // Add the indirect name.
1362 if (Entry
.otherName().empty())
1363 EOS
<< Entry
.name();
1365 EOS
<< Entry
.otherName();
1368 // Now create the undefined symbol using the referened dynamic
1374 if (Entry
.otherName().empty())
1375 U
.Name
= Entry
.name().str();
1377 U
.Name
= Entry
.otherName().str();
1378 // Again there is no symbol in the nlist symbol table for this so
1379 // we set Sym effectivly to null and the rest of code in here must
1380 // test for it and not do things like Sym.getFlags() for it.
1381 U
.Sym
= BasicSymbolRef();
1382 U
.SymFlags
= SymbolRef::SF_Global
| SymbolRef::SF_Undefined
;
1383 U
.Section
= SectionRef();
1384 U
.NType
= MachO::N_EXT
| MachO::N_UNDF
;
1387 // The library ordinal for this undefined symbol is in the export
1388 // trie Entry.other().
1389 MachO::SET_LIBRARY_ORDINAL(U
.NDesc
, Entry
.other());
1390 SymbolList
.push_back(U
);
1392 // Finally add the undefined symbol's name.
1393 if (Entry
.otherName().empty())
1394 EOS
<< Entry
.name();
1396 EOS
<< Entry
.otherName();
1403 error(std::move(Err
), MachO
.getFileName());
1404 // Set the symbol names and indirect names for the added symbols.
1407 const char *Q
= ExportsNameBuffer
.c_str();
1408 for (unsigned K
= 0; K
< ExportsAdded
; K
++) {
1409 SymbolList
[I
].Name
= Q
;
1411 if (SymbolList
[I
].TypeChar
== 'I') {
1412 SymbolList
[I
].IndirectName
= Q
;
1419 // Add the undefined symbols from the bind entries.
1420 unsigned BindsAdded
= 0;
1421 Error BErr
= Error::success();
1422 StringRef LastSymbolName
= StringRef();
1423 for (const llvm::object::MachOBindEntry
&Entry
: MachO
.bindTable(BErr
)) {
1425 if (LastSymbolName
== Entry
.symbolName())
1427 else if (!DyldInfoOnly
) {
1428 for (unsigned J
= 0; J
< SymbolList
.size() && !found
; ++J
) {
1429 if (SymbolList
[J
].Name
== Entry
.symbolName())
1434 LastSymbolName
= Entry
.symbolName();
1439 // There is no symbol in the nlist symbol table for this so we set
1440 // Sym effectivly to null and the rest of code in here must test for
1441 // it and not do things like Sym.getFlags() for it.
1442 B
.Sym
= BasicSymbolRef();
1443 B
.SymFlags
= SymbolRef::SF_Global
| SymbolRef::SF_Undefined
;
1444 B
.NType
= MachO::N_EXT
| MachO::N_UNDF
;
1447 MachO::SET_LIBRARY_ORDINAL(B
.NDesc
, Entry
.ordinal());
1448 B
.Name
= Entry
.symbolName().str();
1449 SymbolList
.push_back(B
);
1450 BOS
<< Entry
.symbolName();
1456 error(std::move(BErr
), MachO
.getFileName());
1457 // Set the symbol names and indirect names for the added symbols.
1460 const char *Q
= BindsNameBuffer
.c_str();
1461 for (unsigned K
= 0; K
< BindsAdded
; K
++) {
1462 SymbolList
[I
].Name
= Q
;
1464 if (SymbolList
[I
].TypeChar
== 'I') {
1465 SymbolList
[I
].IndirectName
= Q
;
1472 // Add the undefined symbols from the lazy bind entries.
1473 unsigned LazysAdded
= 0;
1474 Error LErr
= Error::success();
1475 LastSymbolName
= StringRef();
1476 for (const llvm::object::MachOBindEntry
&Entry
:
1477 MachO
.lazyBindTable(LErr
)) {
1479 if (LastSymbolName
== Entry
.symbolName())
1482 // Here we must check to see it this symbol is already in the
1483 // SymbolList as it might have already have been added above via a
1484 // non-lazy (bind) entry.
1485 for (unsigned J
= 0; J
< SymbolList
.size() && !found
; ++J
) {
1486 if (SymbolList
[J
].Name
== Entry
.symbolName())
1491 LastSymbolName
= Entry
.symbolName();
1493 L
.Name
= Entry
.symbolName().str();
1497 // There is no symbol in the nlist symbol table for this so we set
1498 // Sym effectivly to null and the rest of code in here must test for
1499 // it and not do things like Sym.getFlags() for it.
1500 L
.Sym
= BasicSymbolRef();
1501 L
.SymFlags
= SymbolRef::SF_Global
| SymbolRef::SF_Undefined
;
1502 L
.NType
= MachO::N_EXT
| MachO::N_UNDF
;
1504 // The REFERENCE_FLAG_UNDEFINED_LAZY is no longer used but here it
1505 // makes sence since we are creating this from a lazy bind entry.
1506 L
.NDesc
= MachO::REFERENCE_FLAG_UNDEFINED_LAZY
;
1507 MachO::SET_LIBRARY_ORDINAL(L
.NDesc
, Entry
.ordinal());
1508 SymbolList
.push_back(L
);
1509 LOS
<< Entry
.symbolName();
1515 error(std::move(LErr
), MachO
.getFileName());
1516 // Set the symbol names and indirect names for the added symbols.
1519 const char *Q
= LazysNameBuffer
.c_str();
1520 for (unsigned K
= 0; K
< LazysAdded
; K
++) {
1521 SymbolList
[I
].Name
= Q
;
1523 if (SymbolList
[I
].TypeChar
== 'I') {
1524 SymbolList
[I
].IndirectName
= Q
;
1531 // Add the undefineds symbol from the weak bind entries which are not
1533 unsigned WeaksAdded
= 0;
1534 Error WErr
= Error::success();
1535 LastSymbolName
= StringRef();
1536 for (const llvm::object::MachOBindEntry
&Entry
:
1537 MachO
.weakBindTable(WErr
)) {
1540 if (LastSymbolName
== Entry
.symbolName() ||
1541 Entry
.flags() & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION
) {
1544 for (J
= 0; J
< SymbolList
.size() && !found
; ++J
) {
1545 if (SymbolList
[J
].Name
== Entry
.symbolName()) {
1552 LastSymbolName
= Entry
.symbolName();
1554 W
.Name
= Entry
.symbolName().str();
1558 // There is no symbol in the nlist symbol table for this so we set
1559 // Sym effectivly to null and the rest of code in here must test for
1560 // it and not do things like Sym.getFlags() for it.
1561 W
.Sym
= BasicSymbolRef();
1562 W
.SymFlags
= SymbolRef::SF_Global
| SymbolRef::SF_Undefined
;
1563 W
.NType
= MachO::N_EXT
| MachO::N_UNDF
;
1565 // Odd that we are using N_WEAK_DEF on an undefined symbol but that is
1566 // what is created in this case by the linker when there are real
1567 // symbols in the nlist structs.
1568 W
.NDesc
= MachO::N_WEAK_DEF
;
1569 SymbolList
.push_back(W
);
1570 WOS
<< Entry
.symbolName();
1574 // This is the case the symbol was previously been found and it could
1575 // have been added from a bind or lazy bind symbol. If so and not
1576 // a definition also mark it as weak.
1577 if (SymbolList
[J
].TypeChar
== 'U')
1578 // See comment above about N_WEAK_DEF.
1579 SymbolList
[J
].NDesc
|= MachO::N_WEAK_DEF
;
1583 error(std::move(WErr
), MachO
.getFileName());
1584 // Set the symbol names and indirect names for the added symbols.
1587 const char *Q
= WeaksNameBuffer
.c_str();
1588 for (unsigned K
= 0; K
< WeaksAdded
; K
++) {
1589 SymbolList
[I
].Name
= Q
;
1591 if (SymbolList
[I
].TypeChar
== 'I') {
1592 SymbolList
[I
].IndirectName
= Q
;
1599 // Trying adding symbol from the function starts table and LC_MAIN entry
1601 SmallVector
<uint64_t, 8> FoundFns
;
1602 uint64_t lc_main_offset
= UINT64_MAX
;
1603 for (const auto &Command
: MachO
.load_commands()) {
1604 if (Command
.C
.cmd
== MachO::LC_FUNCTION_STARTS
) {
1605 // We found a function starts segment, parse the addresses for
1607 MachO::linkedit_data_command LLC
=
1608 MachO
.getLinkeditDataLoadCommand(Command
);
1610 MachO
.ReadULEB128s(LLC
.dataoff
, FoundFns
);
1611 } else if (Command
.C
.cmd
== MachO::LC_MAIN
) {
1612 MachO::entry_point_command LCmain
= MachO
.getEntryPointCommand(Command
);
1613 lc_main_offset
= LCmain
.entryoff
;
1616 // See if these addresses are already in the symbol table.
1617 unsigned FunctionStartsAdded
= 0;
1618 for (uint64_t f
= 0; f
< FoundFns
.size(); f
++) {
1620 for (unsigned J
= 0; J
< SymbolList
.size() && !found
; ++J
) {
1621 if (SymbolList
[J
].Address
== FoundFns
[f
] + BaseSegmentAddress
)
1624 // See this address is not already in the symbol table fake up an
1628 F
.Name
= "<redacted function X>";
1629 F
.Address
= FoundFns
[f
] + BaseSegmentAddress
;
1631 // There is no symbol in the nlist symbol table for this so we set
1632 // Sym effectivly to null and the rest of code in here must test for
1633 // it and not do things like Sym.getFlags() for it.
1634 F
.Sym
= BasicSymbolRef();
1636 F
.NType
= MachO::N_SECT
;
1638 StringRef SegmentName
= StringRef();
1639 StringRef SectionName
= StringRef();
1640 for (const SectionRef
&Section
: MachO
.sections()) {
1641 if (Expected
<StringRef
> NameOrErr
= Section
.getName())
1642 SectionName
= *NameOrErr
;
1644 consumeError(NameOrErr
.takeError());
1647 MachO
.getSectionFinalSegmentName(Section
.getRawDataRefImpl());
1649 if (F
.Address
>= Section
.getAddress() &&
1650 F
.Address
< Section
.getAddress() + Section
.getSize()) {
1651 F
.Section
= Section
;
1655 if (SegmentName
== "__TEXT" && SectionName
== "__text")
1657 else if (SegmentName
== "__DATA" && SectionName
== "__data")
1659 else if (SegmentName
== "__DATA" && SectionName
== "__bss")
1664 SymbolList
.push_back(F
);
1665 if (FoundFns
[f
] == lc_main_offset
)
1666 FOS
<< "<redacted LC_MAIN>";
1668 FOS
<< "<redacted function " << f
<< ">";
1670 FunctionStartsAdded
++;
1673 if (FunctionStartsAdded
) {
1675 const char *Q
= FunctionStartsNameBuffer
.c_str();
1676 for (unsigned K
= 0; K
< FunctionStartsAdded
; K
++) {
1677 SymbolList
[I
].Name
= Q
;
1679 if (SymbolList
[I
].TypeChar
== 'I') {
1680 SymbolList
[I
].IndirectName
= Q
;
1689 static bool shouldDump(SymbolicFile
&Obj
) {
1690 // The -X option is currently only implemented for XCOFF, ELF, and IR object
1691 // files. The option isn't fundamentally impossible with other formats, just
1692 // isn't implemented.
1693 if (!isa
<XCOFFObjectFile
>(Obj
) && !isa
<ELFObjectFileBase
>(Obj
) &&
1694 !isa
<IRObjectFile
>(Obj
))
1697 return Obj
.is64Bit() ? BitMode
!= BitModeTy::Bit32
1698 : BitMode
!= BitModeTy::Bit64
;
1701 static void getXCOFFExports(XCOFFObjectFile
*XCOFFObj
,
1702 std::vector
<NMSymbol
> &SymbolList
,
1703 StringRef ArchiveName
) {
1704 // Skip Shared object file.
1705 if (XCOFFObj
->getFlags() & XCOFF::F_SHROBJ
)
1708 for (SymbolRef Sym
: XCOFFObj
->symbols()) {
1709 // There is no visibility in old 32 bit XCOFF object file interpret.
1710 bool HasVisibilityAttr
=
1711 XCOFFObj
->is64Bit() || (XCOFFObj
->auxiliaryHeader32() &&
1712 (XCOFFObj
->auxiliaryHeader32()->getVersion() ==
1713 XCOFF::NEW_XCOFF_INTERPRET
));
1715 if (HasVisibilityAttr
) {
1716 XCOFFSymbolRef XCOFFSym
= XCOFFObj
->toSymbolRef(Sym
.getRawDataRefImpl());
1717 uint16_t SymType
= XCOFFSym
.getSymbolType();
1718 if ((SymType
& XCOFF::VISIBILITY_MASK
) == XCOFF::SYM_V_INTERNAL
)
1720 if ((SymType
& XCOFF::VISIBILITY_MASK
) == XCOFF::SYM_V_HIDDEN
)
1724 Expected
<section_iterator
> SymSecOrErr
= Sym
.getSection();
1726 warn(SymSecOrErr
.takeError(), XCOFFObj
->getFileName(),
1727 "for symbol with index " +
1728 Twine(XCOFFObj
->getSymbolIndex(Sym
.getRawDataRefImpl().p
)),
1732 section_iterator SecIter
= *SymSecOrErr
;
1733 // If the symbol is not in a text or data section, it is not exported.
1734 if (SecIter
== XCOFFObj
->section_end())
1736 if (!(SecIter
->isText() || SecIter
->isData() || SecIter
->isBSS()))
1739 StringRef SymName
= cantFail(Sym
.getName());
1740 if (SymName
.empty())
1742 if (SymName
.starts_with("__sinit") || SymName
.starts_with("__sterm") ||
1743 SymName
.front() == '.' || SymName
.front() == '(')
1746 // Check the SymName regex matching with "^__[0-9]+__".
1747 if (SymName
.size() > 4 && SymName
.starts_with("__") &&
1748 SymName
.ends_with("__")) {
1749 if (std::all_of(SymName
.begin() + 2, SymName
.end() - 2, isDigit
))
1753 if (SymName
== "__rsrc" && NoRsrc
)
1756 if (SymName
.starts_with("__tf1"))
1757 SymName
= SymName
.substr(6);
1758 else if (SymName
.starts_with("__tf9"))
1759 SymName
= SymName
.substr(14);
1762 S
.Name
= SymName
.str();
1765 if (HasVisibilityAttr
) {
1766 XCOFFSymbolRef XCOFFSym
= XCOFFObj
->toSymbolRef(Sym
.getRawDataRefImpl());
1767 uint16_t SymType
= XCOFFSym
.getSymbolType();
1768 if ((SymType
& XCOFF::VISIBILITY_MASK
) == XCOFF::SYM_V_PROTECTED
)
1769 S
.Visibility
= "protected";
1770 else if ((SymType
& XCOFF::VISIBILITY_MASK
) == XCOFF::SYM_V_EXPORTED
)
1771 S
.Visibility
= "export";
1773 if (S
.initializeFlags(*XCOFFObj
))
1774 SymbolList
.push_back(S
);
1778 static Expected
<SymbolicFile::basic_symbol_iterator_range
>
1779 getDynamicSyms(SymbolicFile
&Obj
) {
1780 const auto *E
= dyn_cast
<ELFObjectFileBase
>(&Obj
);
1782 return createError("File format has no dynamic symbol table");
1783 return E
->getDynamicSymbolIterators();
1786 // Returns false if there is error found or true otherwise.
1787 static bool getSymbolNamesFromObject(SymbolicFile
&Obj
,
1788 std::vector
<NMSymbol
> &SymbolList
) {
1789 auto Symbols
= Obj
.symbols();
1790 std::vector
<VersionEntry
> SymbolVersions
;
1793 Expected
<SymbolicFile::basic_symbol_iterator_range
> SymbolsOrErr
=
1794 getDynamicSyms(Obj
);
1795 if (!SymbolsOrErr
) {
1796 error(SymbolsOrErr
.takeError(), Obj
.getFileName());
1799 Symbols
= *SymbolsOrErr
;
1800 if (const auto *E
= dyn_cast
<ELFObjectFileBase
>(&Obj
)) {
1801 if (Expected
<std::vector
<VersionEntry
>> VersionsOrErr
=
1802 E
->readDynsymVersions())
1803 SymbolVersions
= std::move(*VersionsOrErr
);
1805 WithColor::warning(errs(), ToolName
)
1806 << "unable to read symbol versions: "
1807 << toString(VersionsOrErr
.takeError()) << "\n";
1810 // If a "-s segname sectname" option was specified and this is a Mach-O
1811 // file get the section number for that section in this object file.
1812 unsigned int Nsect
= 0;
1813 MachOObjectFile
*MachO
= dyn_cast
<MachOObjectFile
>(&Obj
);
1814 if (!SegSect
.empty() && MachO
) {
1815 Nsect
= getNsectForSegSect(MachO
);
1816 // If this section is not in the object file no symbols are printed.
1821 if (!(MachO
&& DyldInfoOnly
)) {
1823 for (BasicSymbolRef Sym
: Symbols
) {
1825 Expected
<uint32_t> SymFlagsOrErr
= Sym
.getFlags();
1826 if (!SymFlagsOrErr
) {
1827 error(SymFlagsOrErr
.takeError(), Obj
.getFileName());
1831 // Don't drop format specifc symbols for ARM and AArch64 ELF targets, they
1832 // are used to repesent mapping symbols and needed to honor the
1833 // --special-syms option.
1834 auto *ELFObj
= dyn_cast
<ELFObjectFileBase
>(&Obj
);
1835 bool HasMappingSymbol
=
1836 ELFObj
&& llvm::is_contained({ELF::EM_ARM
, ELF::EM_AARCH64
,
1837 ELF::EM_CSKY
, ELF::EM_RISCV
},
1838 ELFObj
->getEMachine());
1839 if (!HasMappingSymbol
&& !DebugSyms
&&
1840 (*SymFlagsOrErr
& SymbolRef::SF_FormatSpecific
))
1842 if (WithoutAliases
&& (*SymFlagsOrErr
& SymbolRef::SF_Indirect
))
1844 // If a "-s segname sectname" option was specified and this is a Mach-O
1845 // file and this section appears in this file, Nsect will be non-zero then
1846 // see if this symbol is a symbol from that section and if not skip it.
1847 if (Nsect
&& Nsect
!= getNsectInMachO(*MachO
, Sym
))
1852 if (isa
<ELFObjectFileBase
>(&Obj
))
1853 S
.Size
= ELFSymbolRef(Sym
).getSize();
1855 if (const XCOFFObjectFile
*XCOFFObj
=
1856 dyn_cast
<const XCOFFObjectFile
>(&Obj
))
1857 S
.Size
= XCOFFObj
->getSymbolSize(Sym
.getRawDataRefImpl());
1859 if (const WasmObjectFile
*WasmObj
= dyn_cast
<WasmObjectFile
>(&Obj
))
1860 S
.Size
= WasmObj
->getSymbolSize(Sym
);
1862 if (PrintAddress
&& isa
<ObjectFile
>(Obj
)) {
1863 SymbolRef
SymRef(Sym
);
1864 Expected
<uint64_t> AddressOrErr
= SymRef
.getAddress();
1865 if (!AddressOrErr
) {
1866 consumeError(AddressOrErr
.takeError());
1869 S
.Address
= *AddressOrErr
;
1871 S
.TypeName
= getNMTypeName(Obj
, Sym
);
1872 S
.TypeChar
= getNMSectionTagAndName(Obj
, Sym
, S
.SectionName
);
1874 raw_string_ostream
OS(S
.Name
);
1875 if (Error E
= Sym
.printName(OS
)) {
1877 OS
<< "bad string index";
1878 consumeError(std::move(E
));
1880 error(std::move(E
), Obj
.getFileName());
1882 if (!SymbolVersions
.empty() && !SymbolVersions
[I
].Name
.empty())
1884 (SymbolVersions
[I
].IsVerDef
? "@@" : "@") + SymbolVersions
[I
].Name
;
1887 if (S
.initializeFlags(Obj
))
1888 SymbolList
.push_back(S
);
1892 // If this is a Mach-O file where the nlist symbol table is out of sync
1893 // with the dyld export trie then look through exports and fake up symbols
1894 // for the ones that are missing (also done with the -add-dyldinfo flag).
1895 // This is needed if strip(1) -T is run on a binary containing swift
1896 // language symbols for example. The option -only-dyldinfo will fake up
1897 // all symbols from the dyld export trie as well as the bind info.
1898 if (MachO
&& !NoDyldInfo
)
1899 dumpSymbolsFromDLInfoMachO(*MachO
, SymbolList
);
1904 static void printObjectLabel(bool PrintArchiveName
, StringRef ArchiveName
,
1905 StringRef ArchitectureName
,
1906 StringRef ObjectFileName
) {
1908 if (ArchiveName
.empty() || !PrintArchiveName
)
1909 outs() << ObjectFileName
;
1911 outs() << ArchiveName
<< "(" << ObjectFileName
<< ")";
1912 if (!ArchitectureName
.empty())
1913 outs() << " (for architecture " << ArchitectureName
<< ")";
1917 static Expected
<bool> hasSymbols(SymbolicFile
&Obj
) {
1919 Expected
<SymbolicFile::basic_symbol_iterator_range
> DynamicSymsOrErr
=
1920 getDynamicSyms(Obj
);
1921 if (!DynamicSymsOrErr
)
1922 return DynamicSymsOrErr
.takeError();
1923 return !DynamicSymsOrErr
->empty();
1925 return !Obj
.symbols().empty();
1928 static void printSymbolNamesFromObject(
1929 SymbolicFile
&Obj
, std::vector
<NMSymbol
> &SymbolList
,
1930 bool PrintSymbolObject
, bool PrintObjectLabel
, StringRef ArchiveName
= {},
1931 StringRef ArchitectureName
= {}, StringRef ObjectName
= {},
1932 bool PrintArchiveName
= true) {
1934 if (PrintObjectLabel
&& !ExportSymbols
)
1935 printObjectLabel(PrintArchiveName
, ArchiveName
, ArchitectureName
,
1936 ObjectName
.empty() ? Obj
.getFileName() : ObjectName
);
1938 if (!getSymbolNamesFromObject(Obj
, SymbolList
) || ExportSymbols
)
1941 // If there is an error in hasSymbols(), the error should be encountered in
1942 // function getSymbolNamesFromObject first.
1943 if (!cantFail(hasSymbols(Obj
)) && SymbolList
.empty() && !Quiet
) {
1944 writeFileName(errs(), ArchiveName
, ArchitectureName
);
1945 errs() << "no symbols\n";
1948 sortSymbolList(SymbolList
);
1949 printSymbolList(Obj
, SymbolList
, PrintSymbolObject
, ArchiveName
,
1953 static void dumpSymbolsNameFromMachOFilesetEntry(
1954 MachOObjectFile
*Obj
, std::vector
<NMSymbol
> &SymbolList
,
1955 bool PrintSymbolObject
, bool PrintObjectLabel
) {
1956 auto Buf
= Obj
->getMemoryBufferRef();
1957 const auto *End
= Obj
->load_commands().end();
1958 for (const auto *It
= Obj
->load_commands().begin(); It
!= End
; ++It
) {
1959 const auto &Command
= *It
;
1960 if (Command
.C
.cmd
!= MachO::LC_FILESET_ENTRY
)
1963 MachO::fileset_entry_command Entry
=
1964 Obj
->getFilesetEntryLoadCommand(Command
);
1966 MachOObjectFile::createMachOObjectFile(Buf
, 0, 0, Entry
.fileoff
);
1968 if (Error Err
= MaybeMachO
.takeError())
1969 report_fatal_error(std::move(Err
));
1971 const char *EntryName
= Command
.Ptr
+ Entry
.entry_id
.offset
;
1973 outs() << "Symbols for " << EntryName
<< ": \n";
1975 std::unique_ptr
<MachOObjectFile
> EntryMachO
= std::move(MaybeMachO
.get());
1976 printSymbolNamesFromObject(*EntryMachO
, SymbolList
, PrintSymbolObject
,
1979 if (std::next(It
) != End
)
1984 static void dumpSymbolNamesFromObject(
1985 SymbolicFile
&Obj
, std::vector
<NMSymbol
> &SymbolList
,
1986 bool PrintSymbolObject
, bool PrintObjectLabel
, StringRef ArchiveName
= {},
1987 StringRef ArchitectureName
= {}, StringRef ObjectName
= {},
1988 bool PrintArchiveName
= true) {
1989 if (!shouldDump(Obj
))
1992 if (ExportSymbols
&& Obj
.isXCOFF()) {
1993 XCOFFObjectFile
*XCOFFObj
= cast
<XCOFFObjectFile
>(&Obj
);
1994 getXCOFFExports(XCOFFObj
, SymbolList
, ArchiveName
);
1998 CurrentFilename
= Obj
.getFileName();
2000 // Are we handling a MachO of type MH_FILESET?
2001 if (Obj
.isMachO() && Obj
.is64Bit() &&
2002 cast
<MachOObjectFile
>(&Obj
)->getHeader64().filetype
==
2003 MachO::MH_FILESET
) {
2004 dumpSymbolsNameFromMachOFilesetEntry(cast
<MachOObjectFile
>(&Obj
),
2005 SymbolList
, PrintSymbolObject
,
2010 printSymbolNamesFromObject(Obj
, SymbolList
, PrintSymbolObject
,
2011 PrintObjectLabel
, ArchiveName
, ArchitectureName
,
2012 ObjectName
, PrintArchiveName
);
2015 // checkMachOAndArchFlags() checks to see if the SymbolicFile is a Mach-O file
2016 // and if it is and there is a list of architecture flags is specified then
2017 // check to make sure this Mach-O file is one of those architectures or all
2018 // architectures was specificed. If not then an error is generated and this
2019 // routine returns false. Else it returns true.
2020 static bool checkMachOAndArchFlags(SymbolicFile
*O
, StringRef Filename
) {
2021 auto *MachO
= dyn_cast
<MachOObjectFile
>(O
);
2023 if (!MachO
|| ArchAll
|| ArchFlags
.empty())
2026 MachO::mach_header H
;
2027 MachO::mach_header_64 H_64
;
2029 const char *McpuDefault
, *ArchFlag
;
2030 if (MachO
->is64Bit()) {
2031 H_64
= MachO
->MachOObjectFile::getHeader64();
2032 T
= MachOObjectFile::getArchTriple(H_64
.cputype
, H_64
.cpusubtype
,
2033 &McpuDefault
, &ArchFlag
);
2035 H
= MachO
->MachOObjectFile::getHeader();
2036 T
= MachOObjectFile::getArchTriple(H
.cputype
, H
.cpusubtype
,
2037 &McpuDefault
, &ArchFlag
);
2039 const std::string
ArchFlagName(ArchFlag
);
2040 if (!llvm::is_contained(ArchFlags
, ArchFlagName
)) {
2041 error("No architecture specified", Filename
);
2047 static void printArchiveMap(iterator_range
<Archive::symbol_iterator
> &map
,
2048 StringRef Filename
) {
2049 for (auto I
: map
) {
2050 Expected
<Archive::Child
> C
= I
.getMember();
2052 error(C
.takeError(), Filename
);
2055 Expected
<StringRef
> FileNameOrErr
= C
->getName();
2056 if (!FileNameOrErr
) {
2057 error(FileNameOrErr
.takeError(), Filename
);
2060 StringRef SymName
= I
.getName();
2061 outs() << SymName
<< " in " << FileNameOrErr
.get() << "\n";
2067 static void dumpArchiveMap(Archive
*A
, StringRef Filename
) {
2068 auto Map
= A
->symbols();
2070 outs() << "Archive map\n";
2071 printArchiveMap(Map
, Filename
);
2074 auto ECMap
= A
->ec_symbols();
2076 warn(ECMap
.takeError(), Filename
);
2077 } else if (!ECMap
->empty()) {
2078 outs() << "Archive EC map\n";
2079 printArchiveMap(*ECMap
, Filename
);
2083 static void dumpArchive(Archive
*A
, std::vector
<NMSymbol
> &SymbolList
,
2084 StringRef Filename
, LLVMContext
*ContextPtr
) {
2086 dumpArchiveMap(A
, Filename
);
2088 Error Err
= Error::success();
2089 for (auto &C
: A
->children(Err
)) {
2090 Expected
<std::unique_ptr
<Binary
>> ChildOrErr
= C
.getAsBinary(ContextPtr
);
2092 if (auto E
= isNotObjectErrorInvalidFileType(ChildOrErr
.takeError()))
2093 error(std::move(E
), Filename
, C
);
2096 if (SymbolicFile
*O
= dyn_cast
<SymbolicFile
>(&*ChildOrErr
.get())) {
2097 if (!MachOPrintSizeWarning
&& PrintSize
&& isa
<MachOObjectFile
>(O
)) {
2098 WithColor::warning(errs(), ToolName
)
2099 << "sizes with -print-size for Mach-O files are always zero.\n";
2100 MachOPrintSizeWarning
= true;
2102 if (!checkMachOAndArchFlags(O
, Filename
))
2104 dumpSymbolNamesFromObject(*O
, SymbolList
, /*PrintSymbolObject=*/false,
2105 !PrintFileName
, Filename
,
2106 /*ArchitectureName=*/{}, O
->getFileName(),
2107 /*PrintArchiveName=*/false);
2111 error(std::move(Err
), A
->getFileName());
2114 static void dumpMachOUniversalBinaryMatchArchFlags(
2115 MachOUniversalBinary
*UB
, std::vector
<NMSymbol
> &SymbolList
,
2116 StringRef Filename
, LLVMContext
*ContextPtr
) {
2117 // Look for a slice in the universal binary that matches each ArchFlag.
2119 for (unsigned i
= 0; i
< ArchFlags
.size(); ++i
) {
2121 for (MachOUniversalBinary::object_iterator I
= UB
->begin_objects(),
2122 E
= UB
->end_objects();
2124 if (ArchFlags
[i
] == I
->getArchFlagName()) {
2126 Expected
<std::unique_ptr
<ObjectFile
>> ObjOrErr
= I
->getAsObjectFile();
2127 std::string ArchiveName
;
2128 std::string ArchitectureName
;
2129 ArchiveName
.clear();
2130 ArchitectureName
.clear();
2132 ObjectFile
&Obj
= *ObjOrErr
.get();
2133 if (ArchFlags
.size() > 1)
2134 ArchitectureName
= I
->getArchFlagName();
2135 dumpSymbolNamesFromObject(Obj
, SymbolList
,
2136 /*PrintSymbolObject=*/false,
2137 (ArchFlags
.size() > 1) && !PrintFileName
,
2138 ArchiveName
, ArchitectureName
);
2140 isNotObjectErrorInvalidFileType(ObjOrErr
.takeError())) {
2141 error(std::move(E
), Filename
,
2142 ArchFlags
.size() > 1 ? StringRef(I
->getArchFlagName())
2145 } else if (Expected
<std::unique_ptr
<Archive
>> AOrErr
=
2146 I
->getAsArchive()) {
2147 std::unique_ptr
<Archive
> &A
= *AOrErr
;
2148 Error Err
= Error::success();
2149 for (auto &C
: A
->children(Err
)) {
2150 Expected
<std::unique_ptr
<Binary
>> ChildOrErr
=
2151 C
.getAsBinary(ContextPtr
);
2154 isNotObjectErrorInvalidFileType(ChildOrErr
.takeError())) {
2155 error(std::move(E
), Filename
, C
,
2156 ArchFlags
.size() > 1 ? StringRef(I
->getArchFlagName())
2161 if (SymbolicFile
*O
= dyn_cast
<SymbolicFile
>(&*ChildOrErr
.get())) {
2162 ArchiveName
= std::string(A
->getFileName());
2163 if (ArchFlags
.size() > 1)
2164 ArchitectureName
= I
->getArchFlagName();
2165 dumpSymbolNamesFromObject(
2166 *O
, SymbolList
, /*PrintSymbolObject=*/false, !PrintFileName
,
2167 ArchiveName
, ArchitectureName
);
2171 error(std::move(Err
), A
->getFileName());
2173 consumeError(AOrErr
.takeError());
2174 error(Filename
+ " for architecture " +
2175 StringRef(I
->getArchFlagName()) +
2176 " is not a Mach-O file or an archive file",
2177 "Mach-O universal file");
2183 "file: " + Filename
+ " does not contain architecture");
2189 // Returns true If the binary contains a slice that matches the host
2190 // architecture, or false otherwise.
2191 static bool dumpMachOUniversalBinaryMatchHost(MachOUniversalBinary
*UB
,
2192 std::vector
<NMSymbol
> &SymbolList
,
2194 LLVMContext
*ContextPtr
) {
2195 Triple HostTriple
= MachOObjectFile::getHostArch();
2196 StringRef HostArchName
= HostTriple
.getArchName();
2197 for (MachOUniversalBinary::object_iterator I
= UB
->begin_objects(),
2198 E
= UB
->end_objects();
2200 if (HostArchName
== I
->getArchFlagName()) {
2201 Expected
<std::unique_ptr
<ObjectFile
>> ObjOrErr
= I
->getAsObjectFile();
2202 std::string ArchiveName
;
2204 ObjectFile
&Obj
= *ObjOrErr
.get();
2205 dumpSymbolNamesFromObject(Obj
, SymbolList
, /*PrintSymbolObject=*/false,
2206 /*PrintObjectLabel=*/false);
2207 } else if (auto E
= isNotObjectErrorInvalidFileType(ObjOrErr
.takeError()))
2208 error(std::move(E
), Filename
);
2209 else if (Expected
<std::unique_ptr
<Archive
>> AOrErr
= I
->getAsArchive()) {
2210 std::unique_ptr
<Archive
> &A
= *AOrErr
;
2211 Error Err
= Error::success();
2212 for (auto &C
: A
->children(Err
)) {
2213 Expected
<std::unique_ptr
<Binary
>> ChildOrErr
=
2214 C
.getAsBinary(ContextPtr
);
2217 isNotObjectErrorInvalidFileType(ChildOrErr
.takeError()))
2218 error(std::move(E
), Filename
, C
);
2221 if (SymbolicFile
*O
= dyn_cast
<SymbolicFile
>(&*ChildOrErr
.get())) {
2222 ArchiveName
= std::string(A
->getFileName());
2223 dumpSymbolNamesFromObject(*O
, SymbolList
,
2224 /*PrintSymbolObject=*/false,
2225 !PrintFileName
, ArchiveName
);
2229 error(std::move(Err
), A
->getFileName());
2231 consumeError(AOrErr
.takeError());
2232 error(Filename
+ " for architecture " +
2233 StringRef(I
->getArchFlagName()) +
2234 " is not a Mach-O file or an archive file",
2235 "Mach-O universal file");
2243 static void dumpMachOUniversalBinaryArchAll(MachOUniversalBinary
*UB
,
2244 std::vector
<NMSymbol
> &SymbolList
,
2246 LLVMContext
*ContextPtr
) {
2247 bool moreThanOneArch
= UB
->getNumberOfObjects() > 1;
2248 for (const MachOUniversalBinary::ObjectForArch
&O
: UB
->objects()) {
2249 Expected
<std::unique_ptr
<ObjectFile
>> ObjOrErr
= O
.getAsObjectFile();
2250 std::string ArchiveName
;
2251 std::string ArchitectureName
;
2252 ArchiveName
.clear();
2253 ArchitectureName
.clear();
2255 ObjectFile
&Obj
= *ObjOrErr
.get();
2256 if (isa
<MachOObjectFile
>(Obj
) && moreThanOneArch
)
2257 ArchitectureName
= O
.getArchFlagName();
2258 dumpSymbolNamesFromObject(Obj
, SymbolList
, /*PrintSymbolObject=*/false,
2259 !PrintFileName
, ArchiveName
, ArchitectureName
);
2260 } else if (auto E
= isNotObjectErrorInvalidFileType(ObjOrErr
.takeError())) {
2261 error(std::move(E
), Filename
,
2262 moreThanOneArch
? StringRef(O
.getArchFlagName()) : StringRef());
2264 } else if (Expected
<std::unique_ptr
<Archive
>> AOrErr
= O
.getAsArchive()) {
2265 std::unique_ptr
<Archive
> &A
= *AOrErr
;
2266 Error Err
= Error::success();
2267 for (auto &C
: A
->children(Err
)) {
2268 Expected
<std::unique_ptr
<Binary
>> ChildOrErr
=
2269 C
.getAsBinary(ContextPtr
);
2271 if (auto E
= isNotObjectErrorInvalidFileType(ChildOrErr
.takeError()))
2272 error(std::move(E
), Filename
, C
,
2273 moreThanOneArch
? StringRef(ArchitectureName
) : StringRef());
2276 if (SymbolicFile
*F
= dyn_cast
<SymbolicFile
>(&*ChildOrErr
.get())) {
2277 ArchiveName
= std::string(A
->getFileName());
2278 if (isa
<MachOObjectFile
>(F
) && moreThanOneArch
)
2279 ArchitectureName
= O
.getArchFlagName();
2280 dumpSymbolNamesFromObject(*F
, SymbolList
, /*PrintSymbolObject=*/false,
2281 !PrintFileName
, ArchiveName
,
2286 error(std::move(Err
), A
->getFileName());
2288 consumeError(AOrErr
.takeError());
2289 error(Filename
+ " for architecture " + StringRef(O
.getArchFlagName()) +
2290 " is not a Mach-O file or an archive file",
2291 "Mach-O universal file");
2296 static void dumpMachOUniversalBinary(MachOUniversalBinary
*UB
,
2297 std::vector
<NMSymbol
> &SymbolList
,
2299 LLVMContext
*ContextPtr
) {
2300 // If we have a list of architecture flags specified dump only those.
2301 if (!ArchAll
&& !ArchFlags
.empty()) {
2302 dumpMachOUniversalBinaryMatchArchFlags(UB
, SymbolList
, Filename
,
2307 // No architecture flags were specified so if this contains a slice that
2308 // matches the host architecture dump only that.
2310 dumpMachOUniversalBinaryMatchHost(UB
, SymbolList
, Filename
, ContextPtr
))
2313 // Either all architectures have been specified or none have been specified
2314 // and this does not contain the host architecture so dump all the slices.
2315 dumpMachOUniversalBinaryArchAll(UB
, SymbolList
, Filename
, ContextPtr
);
2318 static void dumpTapiUniversal(TapiUniversal
*TU
,
2319 std::vector
<NMSymbol
> &SymbolList
,
2320 StringRef Filename
) {
2321 for (const TapiUniversal::ObjectForArch
&I
: TU
->objects()) {
2322 StringRef ArchName
= I
.getArchFlagName();
2323 const bool ShowArch
=
2324 ArchFlags
.empty() || llvm::is_contained(ArchFlags
, ArchName
);
2327 if (!AddInlinedInfo
&& !I
.isTopLevelLib())
2329 if (auto ObjOrErr
= I
.getAsObjectFile())
2330 dumpSymbolNamesFromObject(
2331 *ObjOrErr
.get(), SymbolList
, /*PrintSymbolObject=*/false,
2332 /*PrintObjectLabel=*/true,
2333 /*ArchiveName=*/{}, ArchName
, I
.getInstallName());
2334 else if (Error E
= isNotObjectErrorInvalidFileType(ObjOrErr
.takeError())) {
2335 error(std::move(E
), Filename
, ArchName
);
2340 static void dumpSymbolicFile(SymbolicFile
*O
, std::vector
<NMSymbol
> &SymbolList
,
2341 StringRef Filename
) {
2342 if (!MachOPrintSizeWarning
&& PrintSize
&& isa
<MachOObjectFile
>(O
)) {
2343 WithColor::warning(errs(), ToolName
)
2344 << "sizes with --print-size for Mach-O files are always zero.\n";
2345 MachOPrintSizeWarning
= true;
2347 if (!checkMachOAndArchFlags(O
, Filename
))
2349 dumpSymbolNamesFromObject(*O
, SymbolList
, /*PrintSymbolObject=*/true,
2350 /*PrintObjectLabel=*/false);
2353 static std::vector
<NMSymbol
> dumpSymbolNamesFromFile(StringRef Filename
) {
2354 std::vector
<NMSymbol
> SymbolList
;
2355 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> BufferOrErr
=
2356 MemoryBuffer::getFileOrSTDIN(Filename
);
2357 if (error(BufferOrErr
.getError(), Filename
))
2360 // Ignore AIX linker import files (these files start with "#!"), when
2361 // exporting symbols.
2362 const char *BuffStart
= (*BufferOrErr
)->getBufferStart();
2363 size_t BufferSize
= (*BufferOrErr
)->getBufferSize();
2364 if (ExportSymbols
&& BufferSize
>= 2 && BuffStart
[0] == '#' &&
2365 BuffStart
[1] == '!')
2368 LLVMContext Context
;
2369 LLVMContext
*ContextPtr
= NoLLVMBitcode
? nullptr : &Context
;
2370 Expected
<std::unique_ptr
<Binary
>> BinaryOrErr
=
2371 createBinary(BufferOrErr
.get()->getMemBufferRef(), ContextPtr
);
2373 error(BinaryOrErr
.takeError(), Filename
);
2376 Binary
&Bin
= *BinaryOrErr
.get();
2377 if (Archive
*A
= dyn_cast
<Archive
>(&Bin
))
2378 dumpArchive(A
, SymbolList
, Filename
, ContextPtr
);
2379 else if (MachOUniversalBinary
*UB
= dyn_cast
<MachOUniversalBinary
>(&Bin
))
2380 dumpMachOUniversalBinary(UB
, SymbolList
, Filename
, ContextPtr
);
2381 else if (TapiUniversal
*TU
= dyn_cast
<TapiUniversal
>(&Bin
))
2382 dumpTapiUniversal(TU
, SymbolList
, Filename
);
2383 else if (SymbolicFile
*O
= dyn_cast
<SymbolicFile
>(&Bin
))
2384 dumpSymbolicFile(O
, SymbolList
, Filename
);
2389 exportSymbolNamesFromFiles(const std::vector
<std::string
> &InputFilenames
) {
2390 std::vector
<NMSymbol
> SymbolList
;
2391 for (const auto &FileName
: InputFilenames
) {
2392 std::vector
<NMSymbol
> FileSymList
= dumpSymbolNamesFromFile(FileName
);
2393 SymbolList
.insert(SymbolList
.end(), FileSymList
.begin(), FileSymList
.end());
2396 // Delete symbols which should not be printed from SymolList.
2397 llvm::erase_if(SymbolList
,
2398 [](const NMSymbol
&s
) { return !s
.shouldPrint(); });
2399 sortSymbolList(SymbolList
);
2400 SymbolList
.erase(llvm::unique(SymbolList
), SymbolList
.end());
2401 printExportSymbolList(SymbolList
);
2404 int llvm_nm_main(int argc
, char **argv
, const llvm::ToolContext
&) {
2406 StringSaver
Saver(A
);
2409 opt::InputArgList Args
=
2410 Tbl
.parseArgs(argc
, argv
, OPT_UNKNOWN
, Saver
, [&](StringRef Msg
) {
2414 if (Args
.hasArg(OPT_help
)) {
2417 (Twine(ToolName
) + " [options] <input object files>").str().c_str(),
2418 "LLVM symbol table dumper");
2419 // TODO Replace this with OptTable API once it adds extrahelp support.
2420 outs() << "\nPass @FILE as argument to read options from FILE.\n";
2423 if (Args
.hasArg(OPT_version
)) {
2424 // This needs to contain the word "GNU", libtool looks for that string.
2425 outs() << "llvm-nm, compatible with GNU nm" << '\n';
2426 cl::PrintVersionMessage();
2430 DebugSyms
= Args
.hasArg(OPT_debug_syms
);
2431 DefinedOnly
= Args
.hasArg(OPT_defined_only
);
2432 Demangle
= Args
.hasFlag(OPT_demangle
, OPT_no_demangle
, false);
2433 DynamicSyms
= Args
.hasArg(OPT_dynamic
);
2434 ExternalOnly
= Args
.hasArg(OPT_extern_only
);
2435 StringRef V
= Args
.getLastArgValue(OPT_format_EQ
, "bsd");
2438 else if (V
== "posix")
2439 OutputFormat
= posix
;
2440 else if (V
== "sysv")
2441 OutputFormat
= sysv
;
2442 else if (V
== "darwin")
2443 OutputFormat
= darwin
;
2444 else if (V
== "just-symbols")
2445 OutputFormat
= just_symbols
;
2447 error("--format value should be one of: bsd, posix, sysv, darwin, "
2449 LineNumbers
= Args
.hasArg(OPT_line_numbers
);
2450 NoLLVMBitcode
= Args
.hasArg(OPT_no_llvm_bc
);
2451 NoSort
= Args
.hasArg(OPT_no_sort
);
2452 NoWeakSymbols
= Args
.hasArg(OPT_no_weak
);
2453 NumericSort
= Args
.hasArg(OPT_numeric_sort
);
2454 ArchiveMap
= Args
.hasArg(OPT_print_armap
);
2455 PrintFileName
= Args
.hasArg(OPT_print_file_name
);
2456 PrintSize
= Args
.hasArg(OPT_print_size
);
2457 ReverseSort
= Args
.hasArg(OPT_reverse_sort
);
2458 ExportSymbols
= Args
.hasArg(OPT_export_symbols
);
2459 if (ExportSymbols
) {
2460 ExternalOnly
= true;
2464 Quiet
= Args
.hasArg(OPT_quiet
);
2465 V
= Args
.getLastArgValue(OPT_radix_EQ
, "x");
2467 AddressRadix
= Radix::o
;
2469 AddressRadix
= Radix::d
;
2471 AddressRadix
= Radix::x
;
2473 error("--radix value should be one of: 'o' (octal), 'd' (decimal), 'x' "
2475 SizeSort
= Args
.hasArg(OPT_size_sort
);
2476 SpecialSyms
= Args
.hasArg(OPT_special_syms
);
2477 UndefinedOnly
= Args
.hasArg(OPT_undefined_only
);
2478 WithoutAliases
= Args
.hasArg(OPT_without_aliases
);
2480 // Get BitMode from enviornment variable "OBJECT_MODE" for AIX OS, if
2482 Triple
HostTriple(sys::getProcessTriple());
2483 if (HostTriple
.isOSAIX()) {
2484 BitMode
= StringSwitch
<BitModeTy
>(getenv("OBJECT_MODE"))
2485 .Case("32", BitModeTy::Bit32
)
2486 .Case("64", BitModeTy::Bit64
)
2487 .Case("32_64", BitModeTy::Bit32_64
)
2488 .Case("any", BitModeTy::Any
)
2489 .Default(BitModeTy::Bit32
);
2491 BitMode
= BitModeTy::Any
;
2493 if (Arg
*A
= Args
.getLastArg(OPT_X
)) {
2494 StringRef Mode
= A
->getValue();
2496 BitMode
= BitModeTy::Bit32
;
2497 else if (Mode
== "64")
2498 BitMode
= BitModeTy::Bit64
;
2499 else if (Mode
== "32_64")
2500 BitMode
= BitModeTy::Bit32_64
;
2501 else if (Mode
== "any")
2502 BitMode
= BitModeTy::Any
;
2504 error("-X value should be one of: 32, 64, 32_64, (default) any");
2507 // Mach-O specific options.
2508 FormatMachOasHex
= Args
.hasArg(OPT_x
);
2509 AddDyldInfo
= Args
.hasArg(OPT_add_dyldinfo
);
2510 AddInlinedInfo
= Args
.hasArg(OPT_add_inlinedinfo
);
2511 DyldInfoOnly
= Args
.hasArg(OPT_dyldinfo_only
);
2512 NoDyldInfo
= Args
.hasArg(OPT_no_dyldinfo
);
2514 // XCOFF specific options.
2515 NoRsrc
= Args
.hasArg(OPT_no_rsrc
);
2517 // llvm-nm only reads binary files.
2518 if (error(sys::ChangeStdinToBinary()))
2521 // These calls are needed so that we can read bitcode correctly.
2522 llvm::InitializeAllTargetInfos();
2523 llvm::InitializeAllTargetMCs();
2524 llvm::InitializeAllAsmParsers();
2526 // The relative order of these is important. If you pass --size-sort it should
2527 // only print out the size. However, if you pass -S --size-sort, it should
2528 // print out both the size and address.
2529 if (SizeSort
&& !PrintSize
)
2530 PrintAddress
= false;
2531 if (OutputFormat
== sysv
|| SizeSort
)
2534 for (const auto *A
: Args
.filtered(OPT_arch_EQ
)) {
2535 SmallVector
<StringRef
, 2> Values
;
2536 llvm::SplitString(A
->getValue(), Values
, ",");
2537 for (StringRef V
: Values
) {
2540 else if (MachOObjectFile::isValidArch(V
))
2541 ArchFlags
.push_back(V
);
2543 error("Unknown architecture named '" + V
+ "'",
2544 "for the --arch option");
2548 // Mach-O takes -s to accept two arguments. We emulate this by iterating over
2549 // both OPT_s and OPT_INPUT.
2550 std::vector
<std::string
> InputFilenames
;
2551 int SegSectArgs
= 0;
2552 for (opt::Arg
*A
: Args
.filtered(OPT_s
, OPT_INPUT
)) {
2553 if (SegSectArgs
> 0) {
2555 SegSect
.push_back(A
->getValue());
2556 } else if (A
->getOption().matches(OPT_s
)) {
2559 InputFilenames
.push_back(A
->getValue());
2562 if (!SegSect
.empty() && SegSect
.size() != 2)
2563 error("bad number of arguments (must be two arguments)",
2564 "for the -s option");
2566 if (InputFilenames
.empty())
2567 InputFilenames
.push_back("a.out");
2568 if (InputFilenames
.size() > 1)
2569 MultipleFiles
= true;
2571 if (NoDyldInfo
&& (AddDyldInfo
|| DyldInfoOnly
))
2572 error("--no-dyldinfo can't be used with --add-dyldinfo or --dyldinfo-only");
2575 exportSymbolNamesFromFiles(InputFilenames
);
2577 llvm::for_each(InputFilenames
, dumpSymbolNamesFromFile
);