コード例 #1
0
ファイル: llvm-nm.cpp プロジェクト: NextGenIntelligence/llvm
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();
  if (DynamicSyms) {
    if (!Obj.isELF()) {
      error("File format has no dynamic symbol table", Obj.getFileName());
      return;
    }
    std::pair<symbol_iterator, symbol_iterator> IDyn =
        getELFDynamicSymbolIterators(&Obj);
    IBegin = IDyn.first;
    IEnd = IDyn.second;
  }
  std::string NameBuffer;
  raw_string_ostream OS(NameBuffer);
  // If a "-s segname sectname" option was specified and this is a Mach-O
  // file get the section number for that section in this object file.
  unsigned int Nsect = 0;
  MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
  if (SegSect.size() != 0 && MachO) {
    Nsect = getNsectForSegSect(MachO);
    // If this section is not in the object file no symbols are printed.
    if (Nsect == 0)
      return;
  }
  for (basic_symbol_iterator I = IBegin; I != IEnd; ++I) {
    uint32_t SymFlags = I->getFlags();
    if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific))
      continue;
    if (WithoutAliases) {
      if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj)) {
        const GlobalValue *GV = IR->getSymbolGV(I->getRawDataRefImpl());
        if (GV && isa<GlobalAlias>(GV))
          continue;
      }
    }
    // 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))
      continue;
    NMSymbol S;
    S.Size = UnknownAddressOrSize;
    S.Address = UnknownAddressOrSize;
    if ((PrintSize || SizeSort) && isa<ObjectFile>(Obj)) {
      symbol_iterator SymI = I;
      if (error(SymI->getSize(S.Size)))
        break;
    }
    if (PrintAddress && isa<ObjectFile>(Obj))
      if (error(symbol_iterator(I)->getAddress(S.Address)))
        break;
    S.TypeChar = getNMTypeChar(Obj, I);
    if (error(I->printName(OS)))
      break;
    OS << '\0';
    S.Symb = I->getRawDataRefImpl();
    SymbolList.push_back(S);
  }

  OS.flush();
  const char *P = NameBuffer.c_str();
  for (unsigned I = 0; I < SymbolList.size(); ++I) {
    SymbolList[I].Name = P;
    P += strlen(P) + 1;
  }

  CurrentFilename = Obj.getFileName();
  sortAndPrintSymbolList(Obj, printName, ArchiveName, ArchitectureName);
}
コード例 #2
0
ファイル: llvm-nm.cpp プロジェクト: swgillespie/llvm
static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName,
                                   std::string ArchiveName,
                                   std::string ArchitectureName) {
  if (!NoSort) {
    std::function<bool(const NMSymbol &, const NMSymbol &)> Cmp;
    if (NumericSort)
      Cmp = compareSymbolAddress;
    else if (SizeSort)
      Cmp = compareSymbolSize;
    else
      Cmp = compareSymbolName;

    if (ReverseSort)
      Cmp = [=](const NMSymbol &A, const NMSymbol &B) { return Cmp(B, A); };
    std::sort(SymbolList.begin(), SymbolList.end(), Cmp);
  }

  if (!PrintFileName) {
    if (OutputFormat == posix && MultipleFiles && printName) {
      outs() << '\n' << CurrentFilename << ":\n";
    } else if (OutputFormat == bsd && MultipleFiles && printName) {
      outs() << "\n" << CurrentFilename << ":\n";
    } else if (OutputFormat == sysv) {
      outs() << "\n\nSymbols from " << CurrentFilename << ":\n\n"
             << "Name                  Value   Class        Type"
             << "         Size   Line  Section\n";
    }
  }

  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) {
    uint32_t SymFlags = I->Sym.getFlags();
    bool Undefined = SymFlags & SymbolRef::SF_Undefined;
    bool Global = SymFlags & SymbolRef::SF_Global;
    if ((!Undefined && UndefinedOnly) || (Undefined && DefinedOnly) ||
        (!Global && ExternalOnly) || (SizeSort && !PrintAddress))
      continue;
    if (PrintFileName) {
      if (!ArchitectureName.empty())
        outs() << "(for architecture " << ArchitectureName << "):";
      if (!ArchiveName.empty())
        outs() << ArchiveName << ":";
      outs() << CurrentFilename << ": ";
    }
    if ((JustSymbolName || (UndefinedOnly && isa<MachOObjectFile>(Obj) &&
                            OutputFormat != darwin)) && OutputFormat != posix) {
      outs() << I->Name << "\n";
      continue;
    }

    char SymbolAddrStr[18] = "";
    char SymbolSizeStr[18] = "";

    if (OutputFormat == sysv || I->TypeChar == 'U')
      strcpy(SymbolAddrStr, printBlanks);
    if (OutputFormat == sysv)
      strcpy(SymbolSizeStr, printBlanks);

    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
    // we have a MachOObjectFile, call darwinPrintSymbol to print as darwin's
    // nm(1) -m output or hex, else if OutputFormat is darwin or we are
    // printing Mach-O symbols in hex and not a Mach-O object fall back to
    // OutputFormat bsd (see below).
    MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
    if ((OutputFormat == darwin || FormatMachOasHex) && (MachO || Obj.isIR())) {
      darwinPrintSymbol(Obj, I, SymbolAddrStr, printBlanks, printDashes,
                        printFormat);
    } else if (OutputFormat == posix) {
      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 << ' ';
      if (PrintSize) {
        outs() << SymbolSizeStr;
        outs() << ' ';
      }
      outs() << I->TypeChar;
      if (I->TypeChar == '-' && MachO)
        darwinPrintStab(MachO, I);
      outs() << " " << I->Name << "\n";
    } else if (OutputFormat == sysv) {
      std::string PaddedName(I->Name);
      while (PaddedName.length() < 20)
        PaddedName += " ";
      outs() << PaddedName << "|" << SymbolAddrStr << "|   " << I->TypeChar
             << "  |                  |" << SymbolSizeStr << "|     |\n";
    }
  }

  SymbolList.clear();
}
コード例 #3
0
ファイル: llvm-nm.cpp プロジェクト: swgillespie/llvm
static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
                                      std::string ArchiveName = std::string(),
                                      std::string ArchitectureName =
                                        std::string()) {
  auto Symbols = Obj.symbols();
  if (DynamicSyms) {
    const auto *E = dyn_cast<ELFObjectFileBase>(&Obj);
    if (!E) {
      error("File format has no dynamic symbol table", Obj.getFileName());
      return;
    }
    auto DynSymbols = E->getDynamicSymbolIterators();
    Symbols =
        make_range<basic_symbol_iterator>(DynSymbols.begin(), DynSymbols.end());
  }
  std::string NameBuffer;
  raw_string_ostream OS(NameBuffer);
  // If a "-s segname sectname" option was specified and this is a Mach-O
  // file get the section number for that section in this object file.
  unsigned int Nsect = 0;
  MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
  if (SegSect.size() != 0 && MachO) {
    Nsect = getNsectForSegSect(MachO);
    // If this section is not in the object file no symbols are printed.
    if (Nsect == 0)
      return;
  }
  for (BasicSymbolRef Sym : Symbols) {
    uint32_t SymFlags = Sym.getFlags();
    if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific))
      continue;
    if (WithoutAliases) {
      if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj)) {
        const GlobalValue *GV = IR->getSymbolGV(Sym.getRawDataRefImpl());
        if (GV && isa<GlobalAlias>(GV))
          continue;
      }
    }
    // 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, Sym))
      continue;
    NMSymbol S;
    S.Size = 0;
    S.Address = 0;
    if (PrintSize) {
      if (isa<ELFObjectFileBase>(&Obj))
        S.Size = ELFSymbolRef(Sym).getSize();
    }
    if (PrintAddress && isa<ObjectFile>(Obj)) {
      SymbolRef SymRef(Sym);
      ErrorOr<uint64_t> AddressOrErr = SymRef.getAddress();
      if (error(AddressOrErr.getError()))
        break;
      S.Address = *AddressOrErr;
    }
    S.TypeChar = getNMTypeChar(Obj, Sym);
    std::error_code EC = Sym.printName(OS);
    if (EC && MachO)
      OS << "bad string index";
    else 
      error(EC);
    OS << '\0';
    S.Sym = Sym;
    SymbolList.push_back(S);
  }

  OS.flush();
  const char *P = NameBuffer.c_str();
  for (unsigned I = 0; I < SymbolList.size(); ++I) {
    SymbolList[I].Name = P;
    P += strlen(P) + 1;
  }

  CurrentFilename = Obj.getFileName();
  sortAndPrintSymbolList(Obj, printName, ArchiveName, ArchitectureName);
}
コード例 #4
0
ファイル: llvm-nm.cpp プロジェクト: swgillespie/llvm
// 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(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 = 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<MachOObjectFile>(&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<IRObjectFile>(&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 {
    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] = "";
    format(printFormat, NValue).print(Str, sizeof(Str));
    outs() << Str << ' ';
    format("%02x", NType).print(Str, sizeof(Str));
    outs() << Str << ' ';
    format("%02x", NSect).print(Str, sizeof(Str));
    outs() << Str << ' ';
    format("%04x", NDesc).print(Str, sizeof(Str));
    outs() << Str << ' ';
    format("%08x", NStrx).print(Str, sizeof(Str));
    outs() << Str << ' ';
    outs() << I->Name << "\n";
    return;
  }

  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 << ' ';
  }

  switch (NType & MachO::N_TYPE) {
  case MachO::N_UNDF:
    if (NValue != 0) {
      outs() << "(common) ";
      if (MachO::GET_COMM_ALIGN(NDesc) != 0)
        outs() << "(alignment 2^" << (int)MachO::GET_COMM_ALIGN(NDesc) << ") ";
    } else {
      if ((NType & MachO::N_TYPE) == MachO::N_PBUD)
        outs() << "(prebound ";
      else
        outs() << "(";
      if ((NDesc & MachO::REFERENCE_TYPE) ==
          MachO::REFERENCE_FLAG_UNDEFINED_LAZY)
        outs() << "undefined [lazy bound]) ";
      else if ((NDesc & MachO::REFERENCE_TYPE) ==
               MachO::REFERENCE_FLAG_UNDEFINED_LAZY)
        outs() << "undefined [private lazy bound]) ";
      else if ((NDesc & MachO::REFERENCE_TYPE) ==
               MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY)
        outs() << "undefined [private]) ";
      else
        outs() << "undefined) ";
    }
    break;
  case MachO::N_ABS:
    outs() << "(absolute) ";
    break;
  case MachO::N_INDR:
    outs() << "(indirect) ";
    break;
  case MachO::N_SECT: {
    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;
    }
    ErrorOr<section_iterator> SecOrErr =
      MachO->getSymbolSection(I->Sym.getRawDataRefImpl());
    if (SecOrErr.getError()) {
      outs() << "(?,?) ";
      break;
    }
    section_iterator Sec = *SecOrErr;
    DataRefImpl Ref = Sec->getRawDataRefImpl();
    StringRef SectionName;
    MachO->getSectionName(Ref, SectionName);
    StringRef SegmentName = MachO->getSectionFinalSegmentName(Ref);
    outs() << "(" << SegmentName << "," << SectionName << ") ";
    break;
  }
  default:
    outs() << "(?) ";
    break;
  }

  if (NType & MachO::N_EXT) {
    if (NDesc & MachO::REFERENCED_DYNAMICALLY)
      outs() << "[referenced dynamically] ";
    if (NType & MachO::N_PEXT) {
      if ((NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF)
        outs() << "weak private external ";
      else
        outs() << "private external ";
    } else {
      if ((NDesc & MachO::N_WEAK_REF) == MachO::N_WEAK_REF ||
          (NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF) {
        if ((NDesc & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) ==
            (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
          outs() << "weak external automatically hidden ";
        else
          outs() << "weak external ";
      } else
        outs() << "external ";
    }
  } else {
    if (NType & MachO::N_PEXT)
      outs() << "non-external (was a private external) ";
    else
      outs() << "non-external ";
  }

  if (Filetype == MachO::MH_OBJECT &&
      (NDesc & MachO::N_NO_DEAD_STRIP) == MachO::N_NO_DEAD_STRIP)
    outs() << "[no dead strip] ";

  if (Filetype == MachO::MH_OBJECT &&
      ((NType & MachO::N_TYPE) != MachO::N_UNDF) &&
      (NDesc & MachO::N_SYMBOL_RESOLVER) == MachO::N_SYMBOL_RESOLVER)
    outs() << "[symbol resolver] ";

  if (Filetype == MachO::MH_OBJECT &&
      ((NType & MachO::N_TYPE) != MachO::N_UNDF) &&
      (NDesc & MachO::N_ALT_ENTRY) == MachO::N_ALT_ENTRY)
    outs() << "[alt entry] ";

  if ((NDesc & MachO::N_ARM_THUMB_DEF) == MachO::N_ARM_THUMB_DEF)
    outs() << "[Thumb] ";

  if ((NType & MachO::N_TYPE) == MachO::N_INDR) {
    outs() << I->Name << " (for ";
    StringRef IndirectName;
    if (!MachO ||
        MachO->getIndirectName(I->Sym.getRawDataRefImpl(), IndirectName))
      outs() << "?)";
    else
      outs() << IndirectName << ")";
  } else
    outs() << I->Name;

  if ((Flags & MachO::MH_TWOLEVEL) == MachO::MH_TWOLEVEL &&
      (((NType & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0) ||
       (NType & MachO::N_TYPE) == MachO::N_PBUD)) {
    uint32_t LibraryOrdinal = MachO::GET_LIBRARY_ORDINAL(NDesc);
    if (LibraryOrdinal != 0) {
      if (LibraryOrdinal == MachO::EXECUTABLE_ORDINAL)
        outs() << " (from executable)";
      else if (LibraryOrdinal == MachO::DYNAMIC_LOOKUP_ORDINAL)
        outs() << " (dynamically looked up)";
      else {
        StringRef LibraryName;
        if (!MachO ||
            MachO->getLibraryShortNameByIndex(LibraryOrdinal - 1, LibraryName))
          outs() << " (from bad library ordinal " << LibraryOrdinal << ")";
        else
          outs() << " (from " << LibraryName << ")";
      }
    }
  }

  outs() << "\n";
}