示例#1
0
static void dumpSymbolNamesFromFile(std::string &Filename) {
  std::unique_ptr<MemoryBuffer> Buffer;
  if (error(MemoryBuffer::getFileOrSTDIN(Filename, Buffer), Filename))
    return;

  LLVMContext &Context = getGlobalContext();
  ErrorOr<Binary *> BinaryOrErr = createBinary(Buffer.release(), &Context);
  if (error(BinaryOrErr.getError(), Filename))
    return;
  std::unique_ptr<Binary> Bin(BinaryOrErr.get());

  if (Archive *A = dyn_cast<Archive>(Bin.get())) {
    if (ArchiveMap) {
      Archive::symbol_iterator I = A->symbol_begin();
      Archive::symbol_iterator E = A->symbol_end();
      if (I != E) {
        outs() << "Archive map\n";
        for (; I != E; ++I) {
          Archive::child_iterator C;
          StringRef SymName;
          StringRef FileName;
          if (error(I->getMember(C)))
            return;
          if (error(I->getName(SymName)))
            return;
          if (error(C->getName(FileName)))
            return;
          outs() << SymName << " in " << FileName << "\n";
        }
        outs() << "\n";
      }
    }

    for (Archive::child_iterator I = A->child_begin(), E = A->child_end();
         I != E; ++I) {
      std::unique_ptr<Binary> Child;
      if (I->getAsBinary(Child, &Context))
        continue;
      if (SymbolicFile *O = dyn_cast<SymbolicFile>(Child.get())) {
        outs() << O->getFileName() << ":\n";
        dumpSymbolNamesFromObject(O);
      }
    }
    return;
  }
  if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(Bin.get())) {
    for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
                                               E = UB->end_objects();
         I != E; ++I) {
      std::unique_ptr<ObjectFile> Obj;
      if (!I->getAsObjectFile(Obj)) {
        outs() << Obj->getFileName() << ":\n";
        dumpSymbolNamesFromObject(Obj.get());
      }
    }
    return;
  }
  if (SymbolicFile *O = dyn_cast<SymbolicFile>(Bin.get())) {
    dumpSymbolNamesFromObject(O);
    return;
  }
  error("unrecognizable file type", Filename);
  return;
}
示例#2
0
static void dumpSymbolNamesFromFile(std::string &Filename) {
  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
      MemoryBuffer::getFileOrSTDIN(Filename);
  if (error(BufferOrErr.getError(), Filename))
    return;
  std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get());

  LLVMContext &Context = getGlobalContext();
  ErrorOr<Binary *> BinaryOrErr = createBinary(Buffer, &Context);
  if (error(BinaryOrErr.getError(), Filename))
    return;
  Buffer.release();
  std::unique_ptr<Binary> Bin(BinaryOrErr.get());

  if (Archive *A = dyn_cast<Archive>(Bin.get())) {
    if (ArchiveMap) {
      Archive::symbol_iterator I = A->symbol_begin();
      Archive::symbol_iterator E = A->symbol_end();
      if (I != E) {
        outs() << "Archive map\n";
        for (; I != E; ++I) {
          ErrorOr<Archive::child_iterator> C = I->getMember();
          if (error(C.getError()))
            return;
          ErrorOr<StringRef> FileNameOrErr = C.get()->getName();
          if (error(FileNameOrErr.getError()))
            return;
          StringRef SymName = I->getName();
          outs() << SymName << " in " << FileNameOrErr.get() << "\n";
        }
        outs() << "\n";
      }
    }

    for (Archive::child_iterator I = A->child_begin(), E = A->child_end();
         I != E; ++I) {
      ErrorOr<std::unique_ptr<Binary>> ChildOrErr = I->getAsBinary(&Context);
      if (ChildOrErr.getError())
        continue;
      if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
        if (!checkMachOAndArchFlags(O, Filename))
          return;
        outs() << "\n";
        if (isa<MachOObjectFile>(O)) {
          outs() << Filename << "(" << O->getFileName() << ")";
        } else
          outs() << O->getFileName();
        outs() << ":\n";
        dumpSymbolNamesFromObject(O, false);
      }
    }
    return;
  }
  if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(Bin.get())) {
    // If we have a list of architecture flags specified dump only those.
    if (!ArchAll && ArchFlags.size() != 0) {
      // Look for a slice in the universal binary that matches each ArchFlag.
      bool ArchFound;
      for (unsigned i = 0; i < ArchFlags.size(); ++i) {
        ArchFound = false;
        for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
                                                   E = UB->end_objects();
             I != E; ++I) {
          if (ArchFlags[i] == I->getArchTypeName()) {
            ArchFound = true;
            ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr =
                I->getAsObjectFile();
            std::unique_ptr<Archive> A;
            if (ObjOrErr) {
              std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get());
              if (ArchFlags.size() > 1) {
                outs() << "\n" << Obj->getFileName() << " (for architecture "
                       << I->getArchTypeName() << ")"
                       << ":\n";
              }
              dumpSymbolNamesFromObject(Obj.get(), false);
            } else if (!I->getAsArchive(A)) {
              for (Archive::child_iterator AI = A->child_begin(),
                                           AE = A->child_end();
                   AI != AE; ++AI) {
                ErrorOr<std::unique_ptr<Binary>> ChildOrErr =
                    AI->getAsBinary(&Context);
                if (ChildOrErr.getError())
                  continue;
                if (SymbolicFile *O =
                        dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
                  outs() << "\n" << A->getFileName();
                  outs() << "(" << O->getFileName() << ")";
                  if (ArchFlags.size() > 1) {
                    outs() << " (for architecture " << I->getArchTypeName()
                           << ")";
                  }
                  outs() << ":\n";
                  dumpSymbolNamesFromObject(O, false);
                }
              }
            }
          }
        }
        if (!ArchFound) {
          error(ArchFlags[i],
                "file: " + Filename + " does not contain architecture");
          return;
        }
      }
      return;
    }
    // No architecture flags were specified so if this contains a slice that
    // matches the host architecture dump only that.
    if (!ArchAll) {
      StringRef HostArchName = MachOObjectFile::getHostArch().getArchName();
      for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
                                                 E = UB->end_objects();
           I != E; ++I) {
        if (HostArchName == I->getArchTypeName()) {
          ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
          std::unique_ptr<Archive> A;
          if (ObjOrErr) {
            std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get());
            dumpSymbolNamesFromObject(Obj.get(), false);
          } else if (!I->getAsArchive(A)) {
            for (Archive::child_iterator AI = A->child_begin(),
                                         AE = A->child_end();
                 AI != AE; ++AI) {
              ErrorOr<std::unique_ptr<Binary>> ChildOrErr =
                  AI->getAsBinary(&Context);
              if (ChildOrErr.getError())
                continue;
              if (SymbolicFile *O =
                      dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
                outs() << "\n" << A->getFileName() << "(" << O->getFileName()
                       << ")"
                       << ":\n";
                dumpSymbolNamesFromObject(O, false);
              }
            }
          }
          return;
        }
      }
    }
    // Either all architectures have been specified or none have been specified
    // and this does not contain the host architecture so dump all the slices.
    bool moreThanOneArch = UB->getNumberOfObjects() > 1;
    for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
                                               E = UB->end_objects();
         I != E; ++I) {
      ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
      std::unique_ptr<Archive> A;
      if (ObjOrErr) {
        std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get());
        if (moreThanOneArch)
          outs() << "\n";
        outs() << Obj->getFileName();
        if (isa<MachOObjectFile>(Obj.get()) && moreThanOneArch)
          outs() << " (for architecture " << I->getArchTypeName() << ")";
        outs() << ":\n";
        dumpSymbolNamesFromObject(Obj.get(), false);
      } else if (!I->getAsArchive(A)) {
        for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
             AI != AE; ++AI) {
          ErrorOr<std::unique_ptr<Binary>> ChildOrErr =
              AI->getAsBinary(&Context);
          if (ChildOrErr.getError())
            continue;
          if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
            outs() << "\n" << A->getFileName();
            if (isa<MachOObjectFile>(O)) {
              outs() << "(" << O->getFileName() << ")";
              if (moreThanOneArch)
                outs() << " (for architecture " << I->getArchTypeName() << ")";
            } else
              outs() << ":" << O->getFileName();
            outs() << ":\n";
            dumpSymbolNamesFromObject(O, false);
          }
        }
      }
    }
    return;
  }
  if (SymbolicFile *O = dyn_cast<SymbolicFile>(Bin.get())) {
    if (!checkMachOAndArchFlags(O, Filename))
      return;
    dumpSymbolNamesFromObject(O, true);
    return;
  }
  error("unrecognizable file type", Filename);
  return;
}
示例#3
0
文件: llvm-size.cpp 项目: SDkie/llvm
/// @brief Print the section sizes for @p file. If @p file is an archive, print
///        the section sizes for each archive member.
static void PrintFileSectionSizes(StringRef file) {
  // If file is not stdin, check that it exists.
  if (file != "-") {
    if (!sys::fs::exists(file)) {
      errs() << ToolName << ": '" << file << "': "
             << "No such file\n";
      return;
    }
  }

  // Attempt to open the binary.
  ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
  if (std::error_code EC = BinaryOrErr.getError()) {
    errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
    return;
  }
  Binary &Bin = *BinaryOrErr.get().getBinary();

  if (Archive *a = dyn_cast<Archive>(&Bin)) {
    // This is an archive. Iterate over each member and display its sizes.
    for (object::Archive::child_iterator i = a->child_begin(),
                                         e = a->child_end();
         i != e; ++i) {
      ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
      if (std::error_code EC = ChildOrErr.getError()) {
        errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
        continue;
      }
      if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
        MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
        if (!checkMachOAndArchFlags(o, file))
          return;
        if (OutputFormat == sysv)
          outs() << o->getFileName() << "   (ex " << a->getFileName() << "):\n";
        else if (MachO && OutputFormat == darwin)
          outs() << a->getFileName() << "(" << o->getFileName() << "):\n";
        PrintObjectSectionSizes(o);
        if (OutputFormat == berkeley) {
          if (MachO)
            outs() << a->getFileName() << "(" << o->getFileName() << ")\n";
          else
            outs() << o->getFileName() << " (ex " << a->getFileName() << ")\n";
        }
      }
    }
  } else if (MachOUniversalBinary *UB =
                 dyn_cast<MachOUniversalBinary>(&Bin)) {
    // If we have a list of architecture flags specified dump only those.
    if (!ArchAll && ArchFlags.size() != 0) {
      // Look for a slice in the universal binary that matches each ArchFlag.
      bool ArchFound;
      for (unsigned i = 0; i < ArchFlags.size(); ++i) {
        ArchFound = false;
        for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
                                                   E = UB->end_objects();
             I != E; ++I) {
          if (ArchFlags[i] == I->getArchTypeName()) {
            ArchFound = true;
            ErrorOr<std::unique_ptr<ObjectFile>> UO = I->getAsObjectFile();
            if (UO) {
              if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) {
                MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
                if (OutputFormat == sysv)
                  outs() << o->getFileName() << "  :\n";
                else if (MachO && OutputFormat == darwin) {
                  if (moreThanOneFile || ArchFlags.size() > 1)
                    outs() << o->getFileName() << " (for architecture "
                           << I->getArchTypeName() << "): \n";
                }
                PrintObjectSectionSizes(o);
                if (OutputFormat == berkeley) {
                  if (!MachO || moreThanOneFile || ArchFlags.size() > 1)
                    outs() << o->getFileName() << " (for architecture "
                           << I->getArchTypeName() << ")";
                  outs() << "\n";
                }
              }
            } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
                           I->getAsArchive()) {
              std::unique_ptr<Archive> &UA = *AOrErr;
              // This is an archive. Iterate over each member and display its
              // sizes.
              for (object::Archive::child_iterator i = UA->child_begin(),
                                                   e = UA->child_end();
                   i != e; ++i) {
                ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
                if (std::error_code EC = ChildOrErr.getError()) {
                  errs() << ToolName << ": " << file << ": " << EC.message()
                         << ".\n";
                  continue;
                }
                if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
                  MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
                  if (OutputFormat == sysv)
                    outs() << o->getFileName() << "   (ex " << UA->getFileName()
                           << "):\n";
                  else if (MachO && OutputFormat == darwin)
                    outs() << UA->getFileName() << "(" << o->getFileName()
                           << ")"
                           << " (for architecture " << I->getArchTypeName()
                           << "):\n";
                  PrintObjectSectionSizes(o);
                  if (OutputFormat == berkeley) {
                    if (MachO) {
                      outs() << UA->getFileName() << "(" << o->getFileName()
                             << ")";
                      if (ArchFlags.size() > 1)
                        outs() << " (for architecture " << I->getArchTypeName()
                               << ")";
                      outs() << "\n";
                    } else
                      outs() << o->getFileName() << " (ex " << UA->getFileName()
                             << ")\n";
                  }
                }
              }
            }
          }
        }
        if (!ArchFound) {
          errs() << ToolName << ": file: " << file
                 << " does not contain architecture" << ArchFlags[i] << ".\n";
          return;
        }
      }
      return;
    }
    // No architecture flags were specified so if this contains a slice that
    // matches the host architecture dump only that.
    if (!ArchAll) {
      StringRef HostArchName = MachOObjectFile::getHostArch().getArchName();
      for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
                                                 E = UB->end_objects();
           I != E; ++I) {
        if (HostArchName == I->getArchTypeName()) {
          ErrorOr<std::unique_ptr<ObjectFile>> UO = I->getAsObjectFile();
          if (UO) {
            if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) {
              MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
              if (OutputFormat == sysv)
                outs() << o->getFileName() << "  :\n";
              else if (MachO && OutputFormat == darwin) {
                if (moreThanOneFile)
                  outs() << o->getFileName() << " (for architecture "
                         << I->getArchTypeName() << "):\n";
              }
              PrintObjectSectionSizes(o);
              if (OutputFormat == berkeley) {
                if (!MachO || moreThanOneFile)
                  outs() << o->getFileName() << " (for architecture "
                         << I->getArchTypeName() << ")";
                outs() << "\n";
              }
            }
          } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
                         I->getAsArchive()) {
            std::unique_ptr<Archive> &UA = *AOrErr;
            // This is an archive. Iterate over each member and display its
            // sizes.
            for (object::Archive::child_iterator i = UA->child_begin(),
                                                 e = UA->child_end();
                 i != e; ++i) {
              ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
              if (std::error_code EC = ChildOrErr.getError()) {
                errs() << ToolName << ": " << file << ": " << EC.message()
                       << ".\n";
                continue;
              }
              if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
                MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
                if (OutputFormat == sysv)
                  outs() << o->getFileName() << "   (ex " << UA->getFileName()
                         << "):\n";
                else if (MachO && OutputFormat == darwin)
                  outs() << UA->getFileName() << "(" << o->getFileName() << ")"
                         << " (for architecture " << I->getArchTypeName()
                         << "):\n";
                PrintObjectSectionSizes(o);
                if (OutputFormat == berkeley) {
                  if (MachO)
                    outs() << UA->getFileName() << "(" << o->getFileName()
                           << ")\n";
                  else
                    outs() << o->getFileName() << " (ex " << UA->getFileName()
                           << ")\n";
                }
              }
            }
          }
          return;
        }
      }
    }
    // Either all architectures have been specified or none have been specified
    // and this does not contain the host architecture so dump all the slices.
    bool moreThanOneArch = UB->getNumberOfObjects() > 1;
    for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
                                               E = UB->end_objects();
         I != E; ++I) {
      ErrorOr<std::unique_ptr<ObjectFile>> UO = I->getAsObjectFile();
      if (UO) {
        if (ObjectFile *o = dyn_cast<ObjectFile>(&*UO.get())) {
          MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
          if (OutputFormat == sysv)
            outs() << o->getFileName() << "  :\n";
          else if (MachO && OutputFormat == darwin) {
            if (moreThanOneFile || moreThanOneArch)
              outs() << o->getFileName() << " (for architecture "
                     << I->getArchTypeName() << "):";
            outs() << "\n";
          }
          PrintObjectSectionSizes(o);
          if (OutputFormat == berkeley) {
            if (!MachO || moreThanOneFile || moreThanOneArch)
              outs() << o->getFileName() << " (for architecture "
                     << I->getArchTypeName() << ")";
            outs() << "\n";
          }
        }
      } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
                         I->getAsArchive()) {
        std::unique_ptr<Archive> &UA = *AOrErr;
        // This is an archive. Iterate over each member and display its sizes.
        for (object::Archive::child_iterator i = UA->child_begin(),
                                             e = UA->child_end();
             i != e; ++i) {
          ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
          if (std::error_code EC = ChildOrErr.getError()) {
            errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
            continue;
          }
          if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
            MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
            if (OutputFormat == sysv)
              outs() << o->getFileName() << "   (ex " << UA->getFileName()
                     << "):\n";
            else if (MachO && OutputFormat == darwin)
              outs() << UA->getFileName() << "(" << o->getFileName() << ")"
                     << " (for architecture " << I->getArchTypeName() << "):\n";
            PrintObjectSectionSizes(o);
            if (OutputFormat == berkeley) {
              if (MachO)
                outs() << UA->getFileName() << "(" << o->getFileName() << ")"
                       << " (for architecture " << I->getArchTypeName()
                       << ")\n";
              else
                outs() << o->getFileName() << " (ex " << UA->getFileName()
                       << ")\n";
            }
          }
        }
      }
    }
  } else if (ObjectFile *o = dyn_cast<ObjectFile>(&Bin)) {
    if (!checkMachOAndArchFlags(o, file))
      return;
    if (OutputFormat == sysv)
      outs() << o->getFileName() << "  :\n";
    PrintObjectSectionSizes(o);
    if (OutputFormat == berkeley) {
      MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o);
      if (!MachO || moreThanOneFile)
        outs() << o->getFileName();
      outs() << "\n";
    }
  } else {
    errs() << ToolName << ": " << file << ": "
           << "Unrecognized file type.\n";
  }
  // System V adds an extra newline at the end of each file.
  if (OutputFormat == sysv)
    outs() << "\n";
}