X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fllvm-nm%2Fllvm-nm.cpp;h=b812233034eee3a79312abffc932bd668917a7a7;hb=f75627aa1c8c16e91d97377a7f790e24c1da723e;hp=15dbc8c9beaee163a0c34221bd2b457907f0c31b;hpb=ca30411d989b7ceae3c3ea20cd31de7ec8bbf1fc;p=oota-llvm.git diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index 15dbc8c9bea..b812233034e 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -20,6 +20,7 @@ #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #include "llvm/Object/Archive.h" #include "llvm/Object/COFF.h" #include "llvm/Object/ELFObjectFile.h" @@ -44,6 +45,7 @@ #include #include #include + using namespace llvm; using namespace object; @@ -64,27 +66,30 @@ cl::list InputFilenames(cl::Positional, cl::desc(""), cl::opt UndefinedOnly("undefined-only", cl::desc("Show only undefined symbols")); cl::alias UndefinedOnly2("u", cl::desc("Alias for --undefined-only"), - cl::aliasopt(UndefinedOnly)); + cl::aliasopt(UndefinedOnly), cl::Grouping); cl::opt DynamicSyms("dynamic", cl::desc("Display the dynamic symbols instead " "of normal symbols.")); cl::alias DynamicSyms2("D", cl::desc("Alias for --dynamic"), - cl::aliasopt(DynamicSyms)); + cl::aliasopt(DynamicSyms), cl::Grouping); cl::opt DefinedOnly("defined-only", cl::desc("Show only defined symbols")); cl::alias DefinedOnly2("U", cl::desc("Alias for --defined-only"), - cl::aliasopt(DefinedOnly)); + cl::aliasopt(DefinedOnly), cl::Grouping); cl::opt ExternalOnly("extern-only", cl::desc("Show only external symbols")); cl::alias ExternalOnly2("g", cl::desc("Alias for --extern-only"), - cl::aliasopt(ExternalOnly)); + cl::aliasopt(ExternalOnly), cl::Grouping); -cl::opt BSDFormat("B", cl::desc("Alias for --format=bsd")); -cl::opt POSIXFormat("P", cl::desc("Alias for --format=posix")); -cl::opt DarwinFormat("m", cl::desc("Alias for --format=darwin")); +cl::opt BSDFormat("B", cl::desc("Alias for --format=bsd"), + cl::Grouping); +cl::opt POSIXFormat("P", cl::desc("Alias for --format=posix"), + cl::Grouping); +cl::opt DarwinFormat("m", cl::desc("Alias for --format=darwin"), + cl::Grouping); static cl::list ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"), @@ -96,32 +101,33 @@ cl::opt PrintFileName( cl::desc("Precede each symbol with the object file it came from")); cl::alias PrintFileNameA("A", cl::desc("Alias for --print-file-name"), - cl::aliasopt(PrintFileName)); + cl::aliasopt(PrintFileName), cl::Grouping); cl::alias PrintFileNameo("o", cl::desc("Alias for --print-file-name"), - cl::aliasopt(PrintFileName)); + cl::aliasopt(PrintFileName), cl::Grouping); cl::opt DebugSyms("debug-syms", cl::desc("Show all symbols, even debugger only")); cl::alias DebugSymsa("a", cl::desc("Alias for --debug-syms"), - cl::aliasopt(DebugSyms)); + cl::aliasopt(DebugSyms), cl::Grouping); cl::opt NumericSort("numeric-sort", cl::desc("Sort symbols by address")); cl::alias NumericSortn("n", cl::desc("Alias for --numeric-sort"), - cl::aliasopt(NumericSort)); + cl::aliasopt(NumericSort), cl::Grouping); cl::alias NumericSortv("v", cl::desc("Alias for --numeric-sort"), - cl::aliasopt(NumericSort)); + cl::aliasopt(NumericSort), cl::Grouping); cl::opt NoSort("no-sort", cl::desc("Show symbols in order encountered")); -cl::alias NoSortp("p", cl::desc("Alias for --no-sort"), cl::aliasopt(NoSort)); +cl::alias NoSortp("p", cl::desc("Alias for --no-sort"), cl::aliasopt(NoSort), + cl::Grouping); cl::opt ReverseSort("reverse-sort", cl::desc("Sort in reverse order")); cl::alias ReverseSortr("r", cl::desc("Alias for --reverse-sort"), - cl::aliasopt(ReverseSort)); + cl::aliasopt(ReverseSort), cl::Grouping); cl::opt PrintSize("print-size", cl::desc("Show symbol size instead of address")); cl::alias PrintSizeS("S", cl::desc("Alias for --print-size"), - cl::aliasopt(PrintSize)); + cl::aliasopt(PrintSize), cl::Grouping); cl::opt SizeSort("size-sort", cl::desc("Sort symbols by size")); @@ -130,12 +136,12 @@ cl::opt WithoutAliases("without-aliases", cl::Hidden, cl::opt ArchiveMap("print-armap", cl::desc("Print the archive map")); cl::alias ArchiveMaps("M", cl::desc("Alias for --print-armap"), - cl::aliasopt(ArchiveMap)); + cl::aliasopt(ArchiveMap), cl::Grouping); cl::opt JustSymbolName("just-symbol-name", cl::desc("Print just the symbol's name")); cl::alias JustSymbolNames("j", cl::desc("Alias for --just-symbol-name"), - cl::aliasopt(JustSymbolName)); + cl::aliasopt(JustSymbolName), cl::Grouping); // FIXME: 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. @@ -147,7 +153,7 @@ cl::list SegSect("s", cl::Positional, cl::ZeroOrMore, "and section name, Mach-O only")); cl::opt FormatMachOasHex("x", cl::desc("Print symbol entry in hex, " - "Mach-O only")); + "Mach-O only"), cl::Grouping); cl::opt NoLLVMBitcode("no-llvm-bc", cl::desc("Disable LLVM bitcode reader")); @@ -159,7 +165,7 @@ bool MultipleFiles = false; bool HadError = false; std::string ToolName; -} +} // anonymous namespace static void error(Twine Message, Twine Path = Twine()) { HadError = true; @@ -180,138 +186,121 @@ struct NMSymbol { uint64_t Size; char TypeChar; StringRef Name; - DataRefImpl Symb; + BasicSymbolRef Sym; }; -} +} // anonymous namespace static bool compareSymbolAddress(const NMSymbol &A, const NMSymbol &B) { - if (!ReverseSort) { - if (A.Address < B.Address) - return true; - if (A.Address == B.Address && A.Name < B.Name) - return true; - if (A.Address == B.Address && A.Name == B.Name && A.Size < B.Size) - return true; - return false; - } - - if (A.Address > B.Address) - return true; - if (A.Address == B.Address && A.Name > B.Name) - return true; - if (A.Address == B.Address && A.Name == B.Name && A.Size > B.Size) - return true; - return false; + bool ADefined = !(A.Sym.getFlags() & SymbolRef::SF_Undefined); + bool BDefined = !(B.Sym.getFlags() & SymbolRef::SF_Undefined); + return std::make_tuple(ADefined, A.Address, A.Name, A.Size) < + std::make_tuple(BDefined, B.Address, B.Name, B.Size); } static bool compareSymbolSize(const NMSymbol &A, const NMSymbol &B) { - if (!ReverseSort) { - if (A.Size < B.Size) - return true; - if (A.Size == B.Size && A.Name < B.Name) - return true; - if (A.Size == B.Size && A.Name == B.Name && A.Address < B.Address) - return true; - return false; - } - - if (A.Size > B.Size) - return true; - if (A.Size == B.Size && A.Name > B.Name) - return true; - if (A.Size == B.Size && A.Name == B.Name && A.Address > B.Address) - return true; - return false; + return std::make_tuple(A.Size, A.Name, A.Address) < + std::make_tuple(B.Size, B.Name, B.Address); } static bool compareSymbolName(const NMSymbol &A, const NMSymbol &B) { - if (!ReverseSort) { - if (A.Name < B.Name) - return true; - if (A.Name == B.Name && A.Size < B.Size) - return true; - if (A.Name == B.Name && A.Size == B.Size && A.Address < B.Address) - return true; - return false; - } - if (A.Name > B.Name) - return true; - if (A.Name == B.Name && A.Size > B.Size) - return true; - if (A.Name == B.Name && A.Size == B.Size && A.Address > B.Address) - return true; - return false; + return std::make_tuple(A.Name, A.Size, A.Address) < + std::make_tuple(B.Name, B.Size, B.Address); } static char isSymbolList64Bit(SymbolicFile &Obj) { - if (isa(Obj)) - return false; + if (isa(Obj)) { + IRObjectFile *IRobj = dyn_cast(&Obj); + Module &M = IRobj->getModule(); + if (M.getTargetTriple().empty()) + return false; + Triple T(M.getTargetTriple()); + return T.isArch64Bit(); + } if (isa(Obj)) return false; if (MachOObjectFile *MachO = dyn_cast(&Obj)) return MachO->is64Bit(); - if (isa(Obj)) - return false; - if (isa(Obj)) - return true; - if (isa(Obj)) - return false; - if (isa(Obj)) - return true; - return false; + return cast(Obj).getBytesInAddress() == 8; } static StringRef CurrentFilename; typedef std::vector SymbolListT; static SymbolListT SymbolList; +static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I); + // darwinPrintSymbol() is used to print a symbol from a Mach-O file when the // the OutputFormat is darwin or we are printing Mach-O symbols in hex. For // the darwin format it produces the same output as darwin's nm(1) -m output // and when printing Mach-O symbols in hex it produces the same output as // darwin's nm(1) -x format. -static void darwinPrintSymbol(MachOObjectFile *MachO, SymbolListT::iterator I, - char *SymbolAddrStr, const char *printBlanks) { +static void darwinPrintSymbol(SymbolicFile &Obj, SymbolListT::iterator I, + char *SymbolAddrStr, const char *printBlanks, + const char *printDashes, const char *printFormat) { MachO::mach_header H; MachO::mach_header_64 H_64; - uint32_t Filetype, Flags; - MachO::nlist_64 STE_64; - MachO::nlist STE; - uint8_t NType; - uint8_t NSect; - uint16_t NDesc; - uint32_t NStrx; - uint64_t NValue; - if (MachO->is64Bit()) { - H_64 = MachO->MachOObjectFile::getHeader64(); - Filetype = H_64.filetype; - Flags = H_64.flags; - STE_64 = MachO->getSymbol64TableEntry(I->Symb); - NType = STE_64.n_type; - NSect = STE_64.n_sect; - NDesc = STE_64.n_desc; - NStrx = STE_64.n_strx; - NValue = STE_64.n_value; + uint32_t Filetype = MachO::MH_OBJECT; + uint32_t Flags = 0; + uint8_t NType = 0; + uint8_t NSect = 0; + uint16_t NDesc = 0; + uint32_t NStrx = 0; + uint64_t NValue = 0; + MachOObjectFile *MachO = dyn_cast(&Obj); + if (Obj.isIR()) { + uint32_t SymFlags = I->Sym.getFlags(); + if (SymFlags & SymbolRef::SF_Global) + NType |= MachO::N_EXT; + if (SymFlags & SymbolRef::SF_Hidden) + NType |= MachO::N_PEXT; + if (SymFlags & SymbolRef::SF_Undefined) + NType |= MachO::N_EXT | MachO::N_UNDF; + else { + // Here we have a symbol definition. So to fake out a section name we + // use 1, 2 and 3 for section numbers. See below where they are used to + // print out fake section names. + NType |= MachO::N_SECT; + if(SymFlags & SymbolRef::SF_Const) + NSect = 3; + else { + IRObjectFile *IRobj = dyn_cast(&Obj); + char c = getSymbolNMTypeChar(*IRobj, I->Sym); + if (c == 't') + NSect = 1; + else + NSect = 2; + } + } + if (SymFlags & SymbolRef::SF_Weak) + NDesc |= MachO::N_WEAK_DEF; } else { - H = MachO->MachOObjectFile::getHeader(); - Filetype = H.filetype; - Flags = H.flags; - STE = MachO->getSymbolTableEntry(I->Symb); - NType = STE.n_type; - NSect = STE.n_sect; - NDesc = STE.n_desc; - NStrx = STE.n_strx; - NValue = STE.n_value; + DataRefImpl SymDRI = I->Sym.getRawDataRefImpl(); + if (MachO->is64Bit()) { + H_64 = MachO->MachOObjectFile::getHeader64(); + Filetype = H_64.filetype; + Flags = H_64.flags; + MachO::nlist_64 STE_64 = MachO->getSymbol64TableEntry(SymDRI); + NType = STE_64.n_type; + NSect = STE_64.n_sect; + NDesc = STE_64.n_desc; + NStrx = STE_64.n_strx; + NValue = STE_64.n_value; + } else { + H = MachO->MachOObjectFile::getHeader(); + Filetype = H.filetype; + Flags = H.flags; + MachO::nlist STE = MachO->getSymbolTableEntry(SymDRI); + NType = STE.n_type; + NSect = STE.n_sect; + NDesc = STE.n_desc; + NStrx = STE.n_strx; + NValue = STE.n_value; + } } // If we are printing Mach-O symbols in hex do that and return. if (FormatMachOasHex) { char Str[18] = ""; - const char *printFormat; - if (MachO->is64Bit()) - printFormat = "%016" PRIx64; - else - printFormat = "%08" PRIx64; format(printFormat, NValue).print(Str, sizeof(Str)); outs() << Str << ' '; format("%02x", NType).print(Str, sizeof(Str)); @@ -329,6 +318,8 @@ static void darwinPrintSymbol(MachOObjectFile *MachO, SymbolListT::iterator I, if (PrintAddress) { if ((NType & MachO::N_TYPE) == MachO::N_INDR) strcpy(SymbolAddrStr, printBlanks); + if (Obj.isIR() && (NType & MachO::N_TYPE) == MachO::N_TYPE) + strcpy(SymbolAddrStr, printDashes); outs() << SymbolAddrStr << ' '; } @@ -363,8 +354,20 @@ static void darwinPrintSymbol(MachOObjectFile *MachO, SymbolListT::iterator I, outs() << "(indirect) "; break; case MachO::N_SECT: { - section_iterator Sec = MachO->section_end(); - MachO->getSymbolSection(I->Symb, Sec); + if (Obj.isIR()) { + // For llvm bitcode files print out a fake section name using the values + // use 1, 2 and 3 for section numbers as set above. + if (NSect == 1) + outs() << "(LTO,CODE) "; + else if (NSect == 2) + outs() << "(LTO,DATA) "; + else if (NSect == 3) + outs() << "(LTO,RODATA) "; + else + outs() << "(?,?) "; + break; + } + section_iterator Sec = *MachO->getSymbolSection(I->Sym.getRawDataRefImpl()); DataRefImpl Ref = Sec->getRawDataRefImpl(); StringRef SectionName; MachO->getSectionName(Ref, SectionName); @@ -423,7 +426,8 @@ static void darwinPrintSymbol(MachOObjectFile *MachO, SymbolListT::iterator I, if ((NType & MachO::N_TYPE) == MachO::N_INDR) { outs() << I->Name << " (for "; StringRef IndirectName; - if (MachO->getIndirectName(I->Symb, IndirectName)) + if (!MachO || + MachO->getIndirectName(I->Sym.getRawDataRefImpl(), IndirectName)) outs() << "?)"; else outs() << IndirectName << ")"; @@ -441,7 +445,8 @@ static void darwinPrintSymbol(MachOObjectFile *MachO, SymbolListT::iterator I, outs() << " (dynamically looked up)"; else { StringRef LibraryName; - if (MachO->getLibraryShortNameByIndex(LibraryOrdinal - 1, LibraryName)) + if (!MachO || + MachO->getLibraryShortNameByIndex(LibraryOrdinal - 1, LibraryName)) outs() << " (from bad library ordinal " << LibraryOrdinal << ")"; else outs() << " (from " << LibraryName << ")"; @@ -489,13 +494,14 @@ static const struct DarwinStabName DarwinStabNames[] = { {MachO::N_ECOMM, "ECOMM"}, {MachO::N_ECOML, "ECOML"}, {MachO::N_LENG, "LENG"}, - {0, 0}}; + {0, nullptr}}; + static const char *getDarwinStabString(uint8_t NType) { for (unsigned i = 0; DarwinStabNames[i].Name; i++) { if (DarwinStabNames[i].NType == NType) return DarwinStabNames[i].Name; } - return 0; + return nullptr; } // darwinPrintStab() prints the n_sect, n_desc along with a symbolic name of @@ -506,13 +512,14 @@ static void darwinPrintStab(MachOObjectFile *MachO, SymbolListT::iterator I) { uint8_t NType; uint8_t NSect; uint16_t NDesc; + DataRefImpl SymDRI = I->Sym.getRawDataRefImpl(); if (MachO->is64Bit()) { - STE_64 = MachO->getSymbol64TableEntry(I->Symb); + STE_64 = MachO->getSymbol64TableEntry(SymDRI); NType = STE_64.n_type; NSect = STE_64.n_sect; NDesc = STE_64.n_desc; } else { - STE = MachO->getSymbolTableEntry(I->Symb); + STE = MachO->getSymbolTableEntry(SymDRI); NType = STE.n_type; NSect = STE.n_sect; NDesc = STE.n_desc; @@ -534,12 +541,17 @@ static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName, std::string ArchiveName, std::string ArchitectureName) { if (!NoSort) { + std::function Cmp; if (NumericSort) - std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolAddress); + Cmp = compareSymbolAddress; else if (SizeSort) - std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolSize); + Cmp = compareSymbolSize; else - std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolName); + Cmp = compareSymbolName; + + if (ReverseSort) + Cmp = [=](const NMSymbol &A, const NMSymbol &B) { return Cmp(B, A); }; + std::sort(SymbolList.begin(), SymbolList.end(), Cmp); } if (!PrintFileName) { @@ -554,20 +566,27 @@ static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName, } } - const char *printBlanks, *printFormat; + const char *printBlanks, *printDashes, *printFormat; if (isSymbolList64Bit(Obj)) { printBlanks = " "; + printDashes = "----------------"; printFormat = "%016" PRIx64; } else { printBlanks = " "; + printDashes = "--------"; printFormat = "%08" PRIx64; } for (SymbolListT::iterator I = SymbolList.begin(), E = SymbolList.end(); I != E; ++I) { - if ((I->TypeChar != 'U') && UndefinedOnly) + uint32_t SymFlags = I->Sym.getFlags(); + bool Undefined = SymFlags & SymbolRef::SF_Undefined; + if (!Undefined && UndefinedOnly) + continue; + if (Undefined && DefinedOnly) continue; - if ((I->TypeChar == 'U') && DefinedOnly) + bool Global = SymFlags & SymbolRef::SF_Global; + if (!Global && ExternalOnly) continue; if (SizeSort && !PrintAddress) continue; @@ -578,7 +597,8 @@ static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName, outs() << ArchiveName << ":"; outs() << CurrentFilename << ": "; } - if (JustSymbolName || (UndefinedOnly && isa(Obj))) { + if ((JustSymbolName || (UndefinedOnly && isa(Obj) && + OutputFormat != darwin)) && OutputFormat != posix) { outs() << I->Name << "\n"; continue; } @@ -586,14 +606,18 @@ static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName, char SymbolAddrStr[18] = ""; char SymbolSizeStr[18] = ""; - if (OutputFormat == sysv || I->Address == UnknownAddress) + if (OutputFormat == sysv || I->TypeChar == 'U') strcpy(SymbolAddrStr, printBlanks); if (OutputFormat == sysv) strcpy(SymbolSizeStr, printBlanks); - if (I->Address != UnknownAddress) - format(printFormat, I->Address) + if (I->TypeChar != 'U') { + if (Obj.isIR()) + strcpy(SymbolAddrStr, printDashes); + else + format(printFormat, I->Address) .print(SymbolAddrStr, sizeof(SymbolAddrStr)); + } format(printFormat, I->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr)); // If OutputFormat is darwin or we are printing Mach-O symbols in hex and @@ -602,11 +626,15 @@ static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName, // printing Mach-O symbols in hex and not a Mach-O object fall back to // OutputFormat bsd (see below). MachOObjectFile *MachO = dyn_cast(&Obj); - if ((OutputFormat == darwin || FormatMachOasHex) && MachO) { - darwinPrintSymbol(MachO, I, SymbolAddrStr, printBlanks); + if ((OutputFormat == darwin || FormatMachOasHex) && (MachO || Obj.isIR())) { + darwinPrintSymbol(Obj, I, SymbolAddrStr, printBlanks, printDashes, + printFormat); } else if (OutputFormat == posix) { - outs() << I->Name << " " << I->TypeChar << " " << SymbolAddrStr - << SymbolSizeStr << "\n"; + outs() << I->Name << " " << I->TypeChar << " "; + if (MachO) + outs() << I->Address << " " << "0" /* SymbolSizeStr */ << "\n"; + else + outs() << SymbolAddrStr << SymbolSizeStr << "\n"; } else if (OutputFormat == bsd || (OutputFormat == darwin && !MachO)) { if (PrintAddress) outs() << SymbolAddrStr << ' '; @@ -630,25 +658,21 @@ static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName, SymbolList.clear(); } -template -static char getSymbolNMTypeChar(ELFObjectFile &Obj, +static char getSymbolNMTypeChar(ELFObjectFileBase &Obj, basic_symbol_iterator I) { - typedef typename ELFObjectFile::Elf_Sym Elf_Sym; - typedef typename ELFObjectFile::Elf_Shdr Elf_Shdr; - // OK, this is ELF - symbol_iterator SymI(I); + elf_symbol_iterator SymI(I); - DataRefImpl Symb = I->getRawDataRefImpl(); - const Elf_Sym *ESym = Obj.getSymbol(Symb); - const ELFFile &EF = *Obj.getELFFile(); - const Elf_Shdr *ESec = EF.getSection(ESym); + ErrorOr SecIOrErr = SymI->getSection(); + if (error(SecIOrErr.getError())) + return '?'; - if (ESec) { - switch (ESec->sh_type) { + elf_section_iterator SecI = *SecIOrErr; + if (SecI != Obj.section_end()) { + switch (SecI->getType()) { case ELF::SHT_PROGBITS: case ELF::SHT_DYNAMIC: - switch (ESec->sh_flags) { + switch (SecI->getFlags()) { case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR): return 't'; case (ELF::SHF_TLS | ELF::SHF_ALLOC | ELF::SHF_WRITE): @@ -665,17 +689,17 @@ static char getSymbolNMTypeChar(ELFObjectFile &Obj, } } - if (ESym->getType() == ELF::STT_SECTION) { - StringRef Name; - if (error(SymI->getName(Name))) + if (SymI->getELFType() == ELF::STT_SECTION) { + ErrorOr Name = SymI->getName(); + if (error(Name.getError())) return '?'; - return StringSwitch(Name) + return StringSwitch(*Name) .StartsWith(".debug", 'N') .StartsWith(".note", 'n') .Default('?'); } - return '?'; + return 'n'; } static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { @@ -683,11 +707,11 @@ static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { // OK, this is COFF. symbol_iterator SymI(I); - StringRef Name; - if (error(SymI->getName(Name))) + ErrorOr Name = SymI->getName(); + if (error(Name.getError())) return '?'; - char Ret = StringSwitch(Name) + char Ret = StringSwitch(*Name) .StartsWith(".debug", 'N') .StartsWith(".sxdata", 'N') .Default('?'); @@ -697,9 +721,10 @@ static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { uint32_t Characteristics = 0; if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) { - section_iterator SecI = Obj.section_end(); - if (error(SymI->getSection(SecI))) + ErrorOr SecIOrErr = SymI->getSection(); + if (error(SecIOrErr.getError())) return '?'; + section_iterator SecI = *SecIOrErr; const coff_section *Section = Obj.getCOFFSection(*SecI); Characteristics = Section->Characteristics; } @@ -747,8 +772,7 @@ static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) { case MachO::N_INDR: return 'i'; case MachO::N_SECT: { - section_iterator Sec = Obj.section_end(); - Obj.getSymbolSection(Symb, Sec); + section_iterator Sec = *Obj.getSymbolSection(Symb); DataRefImpl Ref = Sec->getRawDataRefImpl(); StringRef SectionName; Obj.getSectionName(Ref, SectionName); @@ -782,26 +806,12 @@ static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) { return getSymbolNMTypeChar(*GV); } -template -static bool isELFObject(ELFObjectFile &Obj, symbol_iterator I) { - typedef typename ELFObjectFile::Elf_Sym Elf_Sym; - - DataRefImpl Symb = I->getRawDataRefImpl(); - const Elf_Sym *ESym = Obj.getSymbol(Symb); - - return ESym->getType() == ELF::STT_OBJECT; -} - static bool isObject(SymbolicFile &Obj, basic_symbol_iterator I) { - if (ELF32LEObjectFile *ELF = dyn_cast(&Obj)) - return isELFObject(*ELF, I); - if (ELF64LEObjectFile *ELF = dyn_cast(&Obj)) - return isELFObject(*ELF, I); - if (ELF32BEObjectFile *ELF = dyn_cast(&Obj)) - return isELFObject(*ELF, I); - if (ELF64BEObjectFile *ELF = dyn_cast(&Obj)) - return isELFObject(*ELF, I); - return false; + auto *ELF = dyn_cast(&Obj); + if (!ELF) + return false; + + return elf_symbol_iterator(I)->getELFType() == ELF::STT_OBJECT; } static char getNMTypeChar(SymbolicFile &Obj, basic_symbol_iterator I) { @@ -822,20 +832,20 @@ static char getNMTypeChar(SymbolicFile &Obj, basic_symbol_iterator I) { char Ret = '?'; if (Symflags & object::SymbolRef::SF_Absolute) Ret = 'a'; - else if (IRObjectFile *IR = dyn_cast(&Obj)) + else if (IRObjectFile *IR = dyn_cast(&Obj)) { Ret = getSymbolNMTypeChar(*IR, I); + Triple Host(sys::getDefaultTargetTriple()); + if (Ret == 'd' && Host.isOSDarwin()) { + if(Symflags & SymbolRef::SF_Const) + Ret = 's'; + } + } else if (COFFObjectFile *COFF = dyn_cast(&Obj)) Ret = getSymbolNMTypeChar(*COFF, I); else if (MachOObjectFile *MachO = dyn_cast(&Obj)) Ret = getSymbolNMTypeChar(*MachO, I); - else if (ELF32LEObjectFile *ELF = dyn_cast(&Obj)) - Ret = getSymbolNMTypeChar(*ELF, I); - else if (ELF64LEObjectFile *ELF = dyn_cast(&Obj)) - Ret = getSymbolNMTypeChar(*ELF, I); - else if (ELF32BEObjectFile *ELF = dyn_cast(&Obj)) - Ret = getSymbolNMTypeChar(*ELF, I); else - Ret = getSymbolNMTypeChar(cast(Obj), I); + Ret = getSymbolNMTypeChar(cast(Obj), I); if (Symflags & object::SymbolRef::SF_Global) Ret = toupper(Ret); @@ -869,8 +879,8 @@ static unsigned getNsectForSegSect(MachOObjectFile *Obj) { // It is called once for each symbol in a Mach-O file from // dumpSymbolNamesFromObject() and returns the section number for that symbol // if it is in a section, else it returns 0. -static unsigned getNsectInMachO(MachOObjectFile &Obj, basic_symbol_iterator I) { - DataRefImpl Symb = I->getRawDataRefImpl(); +static unsigned getNsectInMachO(MachOObjectFile &Obj, BasicSymbolRef Sym) { + DataRefImpl Symb = Sym.getRawDataRefImpl(); if (Obj.is64Bit()) { MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb); if ((STE.n_type & MachO::N_TYPE) == MachO::N_SECT) @@ -887,17 +897,16 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, std::string ArchiveName = std::string(), std::string ArchitectureName = std::string()) { - basic_symbol_iterator IBegin = Obj.symbol_begin(); - basic_symbol_iterator IEnd = Obj.symbol_end(); + auto Symbols = Obj.symbols(); if (DynamicSyms) { const auto *E = dyn_cast(&Obj); if (!E) { error("File format has no dynamic symbol table", Obj.getFileName()); return; } - auto IDyn = E->getDynamicSymbolIterators(); - IBegin = IDyn.begin(); - IEnd = IDyn.end(); + auto DynSymbols = E->getDynamicSymbolIterators(); + Symbols = + make_range(DynSymbols.begin(), DynSymbols.end()); } std::string NameBuffer; raw_string_ostream OS(NameBuffer); @@ -911,13 +920,13 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, if (Nsect == 0) return; } - for (basic_symbol_iterator I = IBegin; I != IEnd; ++I) { - uint32_t SymFlags = I->getFlags(); + for (BasicSymbolRef Sym : Symbols) { + uint32_t SymFlags = Sym.getFlags(); if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific)) continue; if (WithoutAliases) { if (IRObjectFile *IR = dyn_cast(&Obj)) { - const GlobalValue *GV = IR->getSymbolGV(I->getRawDataRefImpl()); + const GlobalValue *GV = IR->getSymbolGV(Sym.getRawDataRefImpl()); if (GV && isa(GV)) continue; } @@ -925,25 +934,27 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, // If a "-s segname sectname" option was specified and this is a Mach-O // file and this section appears in this file, Nsect will be non-zero then // see if this symbol is a symbol from that section and if not skip it. - if (Nsect && Nsect != getNsectInMachO(*MachO, I)) + if (Nsect && Nsect != getNsectInMachO(*MachO, Sym)) continue; NMSymbol S; S.Size = 0; - S.Address = UnknownAddress; + S.Address = 0; if (PrintSize) { - if (auto *E = dyn_cast(&Obj)) { - symbol_iterator SymI = I; - S.Size = E->getSymbolSize(*SymI); - } + if (isa(&Obj)) + S.Size = ELFSymbolRef(Sym).getSize(); } - if (PrintAddress && isa(Obj)) - if (error(symbol_iterator(I)->getAddress(S.Address))) + if (PrintAddress && isa(Obj)) { + SymbolRef SymRef(Sym); + ErrorOr AddressOrErr = SymRef.getAddress(); + if (error(AddressOrErr.getError())) break; - S.TypeChar = getNMTypeChar(Obj, I); - if (error(I->printName(OS))) + S.Address = *AddressOrErr; + } + S.TypeChar = getNMTypeChar(Obj, Sym); + if (error(Sym.printName(OS))) break; OS << '\0'; - S.Symb = I->getRawDataRefImpl(); + S.Sym = Sym; SymbolList.push_back(S); } @@ -1008,10 +1019,10 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { if (I != E) { outs() << "Archive map\n"; for (; I != E; ++I) { - ErrorOr C = I->getMember(); + ErrorOr C = I->getMember(); if (error(C.getError())) return; - ErrorOr FileNameOrErr = C.get()->getName(); + ErrorOr FileNameOrErr = C->getName(); if (error(FileNameOrErr.getError())) return; StringRef SymName = I->getName(); @@ -1023,7 +1034,10 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { for (Archive::child_iterator I = A->child_begin(), E = A->child_end(); I != E; ++I) { - ErrorOr> ChildOrErr = I->getAsBinary(&Context); + if (error(I->getError())) + return; + auto &C = I->get(); + ErrorOr> ChildOrErr = C.getAsBinary(&Context); if (ChildOrErr.getError()) continue; if (SymbolicFile *O = dyn_cast(&*ChildOrErr.get())) { @@ -1078,8 +1092,11 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); AI != AE; ++AI) { + if (error(AI->getError())) + return; + auto &C = AI->get(); ErrorOr> ChildOrErr = - AI->getAsBinary(&Context); + C.getAsBinary(&Context); if (ChildOrErr.getError()) continue; if (SymbolicFile *O = @@ -1132,8 +1149,11 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); AI != AE; ++AI) { + if (error(AI->getError())) + return; + auto &C = AI->get(); ErrorOr> ChildOrErr = - AI->getAsBinary(&Context); + C.getAsBinary(&Context); if (ChildOrErr.getError()) continue; if (SymbolicFile *O = @@ -1181,8 +1201,10 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { std::unique_ptr &A = *AOrErr; for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); AI != AE; ++AI) { - ErrorOr> ChildOrErr = - AI->getAsBinary(&Context); + if (error(AI->getError())) + return; + auto &C = AI->get(); + ErrorOr> ChildOrErr = C.getAsBinary(&Context); if (ChildOrErr.getError()) continue; if (SymbolicFile *O = dyn_cast(&*ChildOrErr.get())) { @@ -1215,7 +1237,6 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { return; } error("unrecognizable file type", Filename); - return; } int main(int argc, char **argv) {