Ejemplo n.º 1
0
static void dumpSymbolNamesFromObject(SymbolicFile *Obj, bool printName) {
  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);
  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;
      }
    }
    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);
}
Ejemplo n.º 2
0
static void sortAndPrintSymbolList(SymbolicFile *Obj, bool printName) {
  if (!NoSort) {
    if (NumericSort)
      std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolAddress);
    else if (SizeSort)
      std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolSize);
    else
      std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolName);
  }

  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, *printFormat;
  if (isSymbolList64Bit(Obj)) {
    printBlanks = "                ";
    printFormat = "%016" PRIx64;
  } else {
    printBlanks = "        ";
    printFormat = "%08" PRIx64;
  }

  for (SymbolListT::iterator I = SymbolList.begin(), E = SymbolList.end();
       I != E; ++I) {
    if ((I->TypeChar != 'U') && UndefinedOnly)
      continue;
    if ((I->TypeChar == 'U') && DefinedOnly)
      continue;
    if (SizeSort && !PrintAddress && I->Size == UnknownAddressOrSize)
      continue;
    if (JustSymbolName) {
      outs() << I->Name << "\n";
      continue;
    }

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

    if (OutputFormat == sysv || I->Address == UnknownAddressOrSize)
      strcpy(SymbolAddrStr, printBlanks);
    if (OutputFormat == sysv)
      strcpy(SymbolSizeStr, printBlanks);

    if (I->Address != UnknownAddressOrSize)
      format(printFormat, I->Address)
          .print(SymbolAddrStr, sizeof(SymbolAddrStr));
    if (I->Size != UnknownAddressOrSize)
      format(printFormat, I->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));

    // If OutputFormat is darwin and we have a MachOObjectFile print as darwin's
    // nm(1) -m output, else if OutputFormat is darwin and not a Mach-O object
    // fall back to OutputFormat bsd (see below).
    MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(Obj);
    if (OutputFormat == darwin && MachO) {
      darwinPrintSymbol(MachO, I, SymbolAddrStr, printBlanks);
    } else if (OutputFormat == posix) {
      outs() << I->Name << " " << I->TypeChar << " " << SymbolAddrStr
             << SymbolSizeStr << "\n";
    } else if (OutputFormat == bsd || (OutputFormat == darwin && !MachO)) {
      if (PrintAddress)
        outs() << SymbolAddrStr << ' ';
      if (PrintSize) {
        outs() << SymbolSizeStr;
        if (I->Size != UnknownAddressOrSize)
          outs() << ' ';
      }
      outs() << I->TypeChar << " " << 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();
}
Ejemplo n.º 3
0
static void sortAndPrintSymbolList() {
  if (!NoSort) {
    if (NumericSort)
      std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolAddress);
    else if (SizeSort)
      std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolSize);
    else
      std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolName);
  }

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

  for (SymbolListT::iterator I = SymbolList.begin(), E = SymbolList.end();
       I != E; ++I) {
    if ((I->TypeChar != 'U') && UndefinedOnly)
      continue;
    if ((I->TypeChar == 'U') && DefinedOnly)
      continue;
    if (SizeSort && !PrintAddress && I->Size == UnknownAddressOrSize)
      continue;

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

    if (OutputFormat == sysv || I->Address == UnknownAddressOrSize)
      strcpy(SymbolAddrStr, "        ");
    if (OutputFormat == sysv)
      strcpy(SymbolSizeStr, "        ");

    if (I->Address != UnknownAddressOrSize)
      format("%08" PRIx64, I->Address)
          .print(SymbolAddrStr, sizeof(SymbolAddrStr));
    if (I->Size != UnknownAddressOrSize)
      format("%08" PRIx64, I->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));

    if (OutputFormat == posix) {
      outs() << I->Name << " " << I->TypeChar << " " << SymbolAddrStr
             << SymbolSizeStr << "\n";
    } else if (OutputFormat == bsd) {
      if (PrintAddress)
        outs() << SymbolAddrStr << ' ';
      if (PrintSize) {
        outs() << SymbolSizeStr;
        if (I->Size != UnknownAddressOrSize)
          outs() << ' ';
      }
      outs() << I->TypeChar << " " << 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();
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
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();
}