[cmake-commits] king committed CMakeLists.txt 1.395 1.396 cmConfigure.cmake.h.in 1.13 1.14 cmELF.cxx NONE 1.1 cmELF.h NONE 1.1 cmSystemTools.cxx 1.362 1.363

cmake-commits at cmake.org cmake-commits at cmake.org
Wed Feb 27 16:26:37 EST 2008


Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv24940/Source

Modified Files:
	CMakeLists.txt cmConfigure.cmake.h.in cmSystemTools.cxx 
Added Files:
	cmELF.cxx cmELF.h 
Log Message:
ENH: Add ELF file parsing

  - Enabled when system provides elf.h
  - Introduce cmELF class to parse ELF files
  - Use in cmSystemTools::GuessLibrarySOName to really get soname


Index: CMakeLists.txt
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/CMakeLists.txt,v
retrieving revision 1.395
retrieving revision 1.396
diff -u -d -r1.395 -r1.396
--- CMakeLists.txt	21 Feb 2008 16:41:10 -0000	1.395
+++ CMakeLists.txt	27 Feb 2008 21:26:35 -0000	1.396
@@ -1,3 +1,11 @@
+# Check if we can build support for ELF parsing.
+CHECK_INCLUDE_FILE("elf.h" HAVE_ELF_H)
+IF(HAVE_ELF_H)
+  SET(CMAKE_USE_ELF_PARSER 1)
+ELSE(HAVE_ELF_H)
+  SET(CMAKE_USE_ELF_PARSER)
+ENDIF(HAVE_ELF_H)
+
 # configure the .h file
 CONFIGURE_FILE(
   "${CMake_SOURCE_DIR}/Source/cmConfigure.cmake.h.in"
@@ -75,6 +83,12 @@
   ENDIF(FLEX_EXECUTABLE)
 
 ENDIF(CMAKE_REGENERATE_YACCLEX)
+
+# Check if we can build the ELF parser.
+IF(CMAKE_USE_ELF_PARSER)
+  SET(ELF_SRCS cmELF.h cmELF.cxx)
+ENDIF(CMAKE_USE_ELF_PARSER)
+
 #
 # Sources for CMakeLib
 #
@@ -123,6 +137,7 @@
   cmDocumentVariables.cxx
   cmDynamicLoader.cxx
   cmDynamicLoader.h
+  ${ELF_SRCS}
   cmExprLexer.cxx
   cmExprParser.cxx
   cmExprParserHelper.cxx

--- NEW FILE: cmELF.h ---
/*=========================================================================

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmELF.h,v $
  Language:  C++
  Date:      $Date: 2008/02/27 21:26:35 $
  Version:   $Revision: 1.1 $

  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef cmELF_h
#define cmELF_h

#if !defined(CMAKE_USE_ELF_PARSER)
# error "This file may be included only if CMAKE_USE_ELF_PARSER is enabled."
#endif

class cmELFInternal;

/** \class cmELF
 * \brief Executable and Link Format (ELF) parser.
 */
class cmELF
{
public:
  /** Construct with the name of the ELF input file to parse.  */
  cmELF(const char* fname);

  /** Destruct.   */
  ~cmELF();

  /** Get the error message if any.  */
  std::string const& GetErrorMessage() const
    {
    return this->ErrorMessage;
    }

  /** Boolean conversion.  True if the ELF file is valid.  */
  operator bool() const { return this->Valid(); }

  /** Enumeration of ELF file types.  */
  enum FileType
  {
    FileTypeInvalid,
    FileTypeRelocatableObject,
    FileTypeExecutable,
    FileTypeSharedLibrary,
    FileTypeCore
  };

  /** Get the type of the file opened.  */
  FileType GetFileType() const;

  /** Get the number of ELF sections present.  */
  unsigned int GetNumberOfSections() const;

  /** Get the SONAME field if any.  */
  bool GetSOName(std::string& soname);

  /** Print human-readable information about the ELF file.  */
  void PrintInfo(std::ostream& os) const;

private:
  friend class cmELFInternal;
  bool Valid() const;
  cmELFInternal* Internal;
  std::string ErrorMessage;
};

#endif

Index: cmSystemTools.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmSystemTools.cxx,v
retrieving revision 1.362
retrieving revision 1.363
diff -u -d -r1.362 -r1.363
--- cmSystemTools.cxx	21 Feb 2008 18:58:40 -0000	1.362
+++ cmSystemTools.cxx	27 Feb 2008 21:26:35 -0000	1.363
@@ -52,6 +52,10 @@
 #  include <cmsys/MD5.h>
 #endif
 
+#if defined(CMAKE_USE_ELF_PARSER)
+# include "cmELF.h"
+#endif
+
 #if defined(__sgi) && !defined(__GNUC__)
 # pragma set woff 1375 /* base class destructor not virtual */
 #endif
@@ -2155,6 +2159,16 @@
 bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath,
                                        std::string& soname)
 {
+  // For ELF shared libraries use a real parser to get the correct
+  // soname.
+#if defined(CMAKE_USE_ELF_PARSER)
+  cmELF elf(fullPath.c_str());
+  if(elf)
+    {
+    return elf.GetSOName(soname);
+    }
+#endif
+
   // If the file is not a symlink we have no guess for its soname.
   if(!cmSystemTools::FileIsSymlink(fullPath.c_str()))
     {

Index: cmConfigure.cmake.h.in
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmConfigure.cmake.h.in,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- cmConfigure.cmake.h.in	18 Feb 2008 18:03:40 -0000	1.13
+++ cmConfigure.cmake.h.in	27 Feb 2008 21:26:35 -0000	1.14
@@ -20,6 +20,7 @@
 #cmakedefine CMAKE_NO_ANSI_FOR_SCOPE
 #cmakedefine HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE
 #cmakedefine HAVE_UNSETENV
+#cmakedefine CMAKE_USE_ELF_PARSER
 #cmakedefine CMAKE_STRICT
 #define  CMAKE_ROOT_DIR "${CMake_SOURCE_DIR}"
 #define  CMAKE_BUILD_DIR "${CMake_BINARY_DIR}"

--- NEW FILE: cmELF.cxx ---
/*=========================================================================

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmELF.cxx,v $
  Language:  C++
  Date:      $Date: 2008/02/27 21:26:35 $
  Version:   $Revision: 1.1 $

  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "cmStandardIncludes.h" // to get CMAKE_USE_ELF_PARSER first
#include "cmELF.h"

#include <cmsys/auto_ptr.hxx>

// Need the native byte order of the running CPU.
#include <cmsys/CPU.h>

// Include the ELF format information system header.
#include <elf.h>

//----------------------------------------------------------------------------
// Low-level byte swapping implementation.
template <size_t s> struct cmELFByteSwapSize {};
void cmELFByteSwap(char*, cmELFByteSwapSize<1> const&)
{
}
void cmELFByteSwap(char* data, cmELFByteSwapSize<2> const&)
{
  char one_byte;
  one_byte = data[0]; data[0] = data[1]; data[1] = one_byte;
}
void cmELFByteSwap(char* data, cmELFByteSwapSize<4> const&)
{
  char one_byte;
  one_byte = data[0]; data[0] = data[3]; data[3] = one_byte;
  one_byte = data[1]; data[1] = data[2]; data[2] = one_byte;
}
void cmELFByteSwap(char* data, cmELFByteSwapSize<8> const&)
{
  char one_byte;
  one_byte = data[0]; data[0] = data[7]; data[7] = one_byte;
  one_byte = data[1]; data[1] = data[6]; data[6] = one_byte;
  one_byte = data[2]; data[2] = data[5]; data[5] = one_byte;
  one_byte = data[3]; data[3] = data[4]; data[4] = one_byte;
}

// Low-level byte swapping interface.
template <typename T>
void cmELFByteSwap(T& x)
{
  cmELFByteSwap(reinterpret_cast<char*>(&x), cmELFByteSwapSize<sizeof(T)>());
}

//----------------------------------------------------------------------------
class cmELFInternal
{
public:
  enum ByteOrderType { ByteOrderMSB, ByteOrderLSB };

  // Construct and take ownership of the file stream object.
  cmELFInternal(cmELF* external,
                cmsys::auto_ptr<std::ifstream>& fin,
                ByteOrderType order):
    External(external),
    Stream(*fin.release()),
    ByteOrder(order),
    ELFType(cmELF::FileTypeInvalid)
    {
    // Decide whether we need to byte swap fields.
#if cmsys_CPU_ENDIAN_ID == cmsys_CPU_ENDIAN_ID_LITTLE
    this->NeedSwap = (this->ByteOrder == ByteOrderMSB);
#elif cmsys_CPU_ENDIAN_ID == cmsys_CPU_ENDIAN_ID_BIG
    this->NeedSwap = (this->ByteOrder == ByteOrderLSB);
#endif

    // We have not yet loaded the section info.
    this->DynamicSectionIndex = -1;
    }

  // Destruct and delete the file stream object.
  ~cmELFInternal()
    {
    delete &this->Stream;
    }

  // Forward to the per-class implementation.
  virtual unsigned int GetNumberOfSections() const = 0;
  virtual bool GetSOName(std::string& soname) = 0;
  virtual void PrintInfo(std::ostream& os) const = 0;

  // Return the recorded ELF type.
  cmELF::FileType GetFileType() const { return this->ELFType; }
protected:
  // Data common to all ELF class implementations.

  // The external cmELF object.
  cmELF* External;

  // The stream from which to read.
  std::istream& Stream;

  // The byte order of the ELF file.
  ByteOrderType ByteOrder;

  // The ELF file type.
  cmELF::FileType ELFType;

  // Whether we need to byte-swap structures read from the stream.
  bool NeedSwap;

  // The section header index of the DYNAMIC section (-1 if none).
  int DynamicSectionIndex;

  // Helper methods for subclasses.
  void SetErrorMessage(const char* msg)
    {
    this->External->ErrorMessage = msg;
    this->ELFType = cmELF::FileTypeInvalid;
    }
};

//----------------------------------------------------------------------------
// Configure the implementation template for 32-bit ELF files.
struct cmELFTypes32
{
  typedef Elf32_Ehdr ELF_Ehdr;
  typedef Elf32_Shdr ELF_Shdr;
  typedef Elf32_Dyn  ELF_Dyn;
  typedef Elf32_Half ELF_Half;
  static const char* GetName() { return "32-bit"; }
};

// Configure the implementation template for 32-bit ELF files.
struct cmELFTypes64
{
  typedef Elf64_Ehdr ELF_Ehdr;
  typedef Elf64_Shdr ELF_Shdr;
  typedef Elf64_Dyn  ELF_Dyn;
  typedef Elf64_Half ELF_Half;
  static const char* GetName() { return "64-bit"; }
};

//----------------------------------------------------------------------------
// Parser implementation template.
template <class Types>
class cmELFInternalImpl: public cmELFInternal
{
public:
  // Copy the ELF file format types from our configuration parameter.
  typedef typename Types::ELF_Ehdr ELF_Ehdr;
  typedef typename Types::ELF_Shdr ELF_Shdr;
  typedef typename Types::ELF_Dyn  ELF_Dyn;
  typedef typename Types::ELF_Half ELF_Half;

  // Construct with a stream and byte swap indicator.
  cmELFInternalImpl(cmELF* external,
                    cmsys::auto_ptr<std::ifstream>& fin,
                    ByteOrderType order);

  // Return the number of sections as specified by the ELF header.
  virtual unsigned int GetNumberOfSections() const
    {
    return static_cast<unsigned int>(this->ELFHeader.e_shnum);
    }

  // Lookup the SONAME in the DYNAMIC section.
  virtual bool GetSOName(std::string& soname);

  // Print information about the ELF file.
  virtual void PrintInfo(std::ostream& os) const
    {
    os << "ELF " << Types::GetName();
    if(this->ByteOrder == ByteOrderMSB)
      {
      os << " MSB";
      }
    else if(this->ByteOrder == ByteOrderLSB)
      {
      os << " LSB";
      }
    switch(this->ELFType)
      {
      case cmELF::FileTypeRelocatableObject:
        os << " relocatable object";
        break;
      case cmELF::FileTypeExecutable:
        os << " executable";
        break;
      case cmELF::FileTypeSharedLibrary:
        os << " shared library";
        break;
      case cmELF::FileTypeCore:
        os << " core file";
        break;
      }
    os << "\n";
    }

private:
  void ByteSwap(ELF_Ehdr& elf_header)
    {
    cmELFByteSwap(elf_header.e_type);
    cmELFByteSwap(elf_header.e_machine);
    cmELFByteSwap(elf_header.e_version);
    cmELFByteSwap(elf_header.e_entry);
    cmELFByteSwap(elf_header.e_phoff);
    cmELFByteSwap(elf_header.e_shoff);
    cmELFByteSwap(elf_header.e_flags);
    cmELFByteSwap(elf_header.e_ehsize);
    cmELFByteSwap(elf_header.e_phentsize);
    cmELFByteSwap(elf_header.e_phnum);
    cmELFByteSwap(elf_header.e_shentsize);
    cmELFByteSwap(elf_header.e_shnum);
    cmELFByteSwap(elf_header.e_shstrndx);
    }

  void ByteSwap(ELF_Shdr& sec_header)
    {
    cmELFByteSwap(sec_header.sh_name);
    cmELFByteSwap(sec_header.sh_type);
    cmELFByteSwap(sec_header.sh_flags);
    cmELFByteSwap(sec_header.sh_addr);
    cmELFByteSwap(sec_header.sh_offset);
    cmELFByteSwap(sec_header.sh_size);
    cmELFByteSwap(sec_header.sh_link);
    cmELFByteSwap(sec_header.sh_info);
    cmELFByteSwap(sec_header.sh_addralign);
    cmELFByteSwap(sec_header.sh_entsize);
    }

  void ByteSwap(ELF_Dyn& dyn)
    {
    cmELFByteSwap(dyn.d_tag);
    switch (dyn.d_tag)
      {
      case DT_NULL:     /* dyn.d_un ignored */         break;
      case DT_NEEDED:   cmELFByteSwap(dyn.d_un.d_val); break;
      case DT_PLTRELSZ: cmELFByteSwap(dyn.d_un.d_val); break;
      case DT_PLTGOT:   cmELFByteSwap(dyn.d_un.d_ptr); break;
      case DT_HASH:     cmELFByteSwap(dyn.d_un.d_ptr); break;
      case DT_STRTAB:   cmELFByteSwap(dyn.d_un.d_ptr); break;
      case DT_SYMTAB:   cmELFByteSwap(dyn.d_un.d_ptr); break;
      case DT_RELA:     cmELFByteSwap(dyn.d_un.d_ptr); break;
      case DT_RELASZ:   cmELFByteSwap(dyn.d_un.d_val); break;
      case DT_RELAENT:  cmELFByteSwap(dyn.d_un.d_val); break;
      case DT_STRSZ:    cmELFByteSwap(dyn.d_un.d_val); break;
      case DT_SYMENT:   cmELFByteSwap(dyn.d_un.d_val); break;
      case DT_INIT:     cmELFByteSwap(dyn.d_un.d_ptr); break;
      case DT_FINI:     cmELFByteSwap(dyn.d_un.d_ptr); break;
      case DT_SONAME:   cmELFByteSwap(dyn.d_un.d_val); break;
      case DT_RPATH:    cmELFByteSwap(dyn.d_un.d_val); break;
      case DT_SYMBOLIC: /* dyn.d_un ignored */         break;
      case DT_REL:      cmELFByteSwap(dyn.d_un.d_ptr); break;
      case DT_RELSZ:    cmELFByteSwap(dyn.d_un.d_val); break;
      case DT_RELENT:   cmELFByteSwap(dyn.d_un.d_val); break;
      case DT_PLTREL:   cmELFByteSwap(dyn.d_un.d_val); break;
      case DT_DEBUG:    cmELFByteSwap(dyn.d_un.d_ptr); break;
      case DT_TEXTREL:  /* dyn.d_un ignored */         break;
      case DT_JMPREL:   cmELFByteSwap(dyn.d_un.d_ptr); break;
      }
    }

  bool Read(ELF_Ehdr& x)
    {
    if(this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) &&
       this->NeedSwap)
      {
      ByteSwap(x);
      }
    return this->Stream? true:false;
    }
  bool Read(ELF_Shdr& x)
    {
    if(this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) &&
       this->NeedSwap)
      {
      ByteSwap(x);
      }
    return this->Stream? true:false;
    }
  bool Read(ELF_Dyn& x)
    {
    if(this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) &&
       this->NeedSwap)
      {
      ByteSwap(x);
      }
    return this->Stream? true:false;
    }

  bool LoadSectionHeader(ELF_Half i)
    {
    // Read the section header from the file.
    this->Stream.seekg(this->ELFHeader.e_shoff +
                       this->ELFHeader.e_shentsize * i);
    if(!this->Read(this->SectionHeaders[i]))
      {
      return false;
      }

    // Identify some important sections.
    if(this->SectionHeaders[i].sh_type == SHT_DYNAMIC)
      {
      this->DynamicSectionIndex = i;
      }
    return true;
    }

  bool LoadDynamicSection();

  // Store the main ELF header.
  ELF_Ehdr ELFHeader;

  // Store all the section headers.
  std::vector<ELF_Shdr> SectionHeaders;

  // Store all entries of the DYNAMIC section.
  std::vector<ELF_Dyn> DynamicSectionEntries;

  // Store the SOName if it has been loaded.
  std::string SOName;
  bool SONameChecked;
};

//----------------------------------------------------------------------------
template <class Types>
cmELFInternalImpl<Types>
::cmELFInternalImpl(cmELF* external,
                    cmsys::auto_ptr<std::ifstream>& fin,
                    ByteOrderType order):
  cmELFInternal(external, fin, order)
{
  // Initialize state.
  this->SONameChecked = false;

  // Read the main header.
  if(!this->Read(this->ELFHeader))
    {
    return;
    }

  // Determine the ELF file type.
  switch(this->ELFHeader.e_type)
    {
    case 1:
      this->ELFType = cmELF::FileTypeRelocatableObject;
      break;
    case 2:
      this->ELFType = cmELF::FileTypeExecutable;
      break;
    case 3:
      this->ELFType = cmELF::FileTypeSharedLibrary;
      break;
    case 4:
      this->ELFType = cmELF::FileTypeCore;
      break;
    default:
      return;
    }

  // Load the section headers.
  this->SectionHeaders.resize(this->ELFHeader.e_shnum);
  for(ELF_Half i=0; i < this->ELFHeader.e_shnum; ++i)
    {
    if(!this->LoadSectionHeader(i))
      {
      this->ELFType = cmELF::FileTypeInvalid;
      return;
      }
    }
}

//----------------------------------------------------------------------------
template <class Types>
bool cmELFInternalImpl<Types>::LoadDynamicSection()
{
  // If there is no dynamic section we are done.
  if(this->DynamicSectionIndex < 0)
    {
    return false;
    }

  // If the section was already loaded we are done.
  if(!this->DynamicSectionEntries.empty())
    {
    return true;
    }

  // Allocate the dynamic section entries.
  ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex];
  int n = sec.sh_size / sec.sh_entsize;
  this->DynamicSectionEntries.resize(n);

  // Read each entry.
  for(int j=0; j < n; ++j)
    {
    // Seek to the beginning of the section entry.
    this->Stream.seekg(sec.sh_offset + sec.sh_entsize*j);
    ELF_Dyn& dyn = this->DynamicSectionEntries[j];

    // Try reading the entry.
    if(!this->Read(dyn))
      {
      this->SetErrorMessage("Error reading entry from DYNAMIC section.");
      this->DynamicSectionIndex = -1;
      return false;
      }
    }
  return true;
}

//----------------------------------------------------------------------------
template <class Types>
bool cmELFInternalImpl<Types>::GetSOName(std::string& soname)
{
  // Short-circuit if already checked.
  if(this->SONameChecked)
    {
    soname = this->SOName;
    return !soname.empty();
    }
  this->SONameChecked = true;

  // Try reading the dynamic section.
  if(!this->LoadDynamicSection())
    {
    return false;
    }

  // Get the string table referenced by the DYNAMIC section.
  ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex];
  if(sec.sh_link >= this->SectionHeaders.size())
    {
    this->SetErrorMessage("Section DYNAMIC has invalid string table index.");
    return false;
    }
  ELF_Shdr const& strtab = this->SectionHeaders[sec.sh_link];

  // Look for the soname entry.
  for(typename std::vector<ELF_Dyn>::iterator
        di = this->DynamicSectionEntries.begin();
      di != this->DynamicSectionEntries.end(); ++di)
    {
    ELF_Dyn& dyn = *di;
    if(dyn.d_tag == DT_SONAME)
      {
      this->Stream.seekg(strtab.sh_offset + dyn.d_un.d_val);
      char c;
      while(this->Stream.get(c) && c != 0)
        {
        this->SOName += c;
        }
      if(!this->Stream)
        {
        this->SetErrorMessage("Dynamic section specifies unreadable SONAME.");
        this->SOName = "";
        return false;
        }
      soname = this->SOName;
      return true;
      }
    }
  return false;
}

//============================================================================
// External class implementation.

//----------------------------------------------------------------------------
cmELF::cmELF(const char* fname): Internal(0)
{
  // Try to open the file.
  cmsys::auto_ptr<std::ifstream> fin(new std::ifstream(fname));

  // Quit now if the file could not be opened.
  if(!fin.get() || !*fin)
    {
    this->ErrorMessage = "Error opening input file.";
    return;
    }

  // Read the ELF identification block.
  char ident[EI_NIDENT];
  if(!fin->read(ident, EI_NIDENT))
    {
    this->ErrorMessage = "Error reading ELF identification.";
    return;
    }
  if(!fin->seekg(0))
    {
    this->ErrorMessage = "Error seeking to beginning of file.";
    return;
    }

  // Verify the ELF identification.
  if(!(ident[EI_MAG0] == ELFMAG0 &&
       ident[EI_MAG1] == ELFMAG1 &&
       ident[EI_MAG2] == ELFMAG2 &&
       ident[EI_MAG3] == ELFMAG3))
    {
    this->ErrorMessage = "File does not have a valid ELF identification.";
    return;
    }

  // Check the byte order in which the rest of the file is encoded.
  cmELFInternal::ByteOrderType order;
  if(ident[EI_DATA] == ELFDATA2LSB)
    {
    // File is LSB.
    order =  cmELFInternal::ByteOrderLSB;
    }
  else if(ident[EI_DATA] == ELFDATA2MSB)
    {
    // File is MSB.
    order =  cmELFInternal::ByteOrderMSB;
    }
  else
    {
    this->ErrorMessage = "ELF file is not LSB or MSB encoded.";
    return;
    }

  // Check the class of the file and construct the corresponding
  // parser implementation.
  if(ident[EI_CLASS] == ELFCLASS32)
    {
    // 32-bit ELF
    this->Internal = new cmELFInternalImpl<cmELFTypes32>(this, fin, order);
    }
  else if(ident[EI_CLASS] == ELFCLASS64)
    {
    // 64-bit ELF
    this->Internal = new cmELFInternalImpl<cmELFTypes64>(this, fin, order);
    }
  else
    {
    this->ErrorMessage = "ELF file class is not 32-bit or 64-bit.";
    return;
    }
}

//----------------------------------------------------------------------------
cmELF::~cmELF()
{
  delete this->Internal;
}

//----------------------------------------------------------------------------
bool cmELF::Valid() const
{
  return this->Internal && this->Internal->GetFileType() != FileTypeInvalid;
}

//----------------------------------------------------------------------------
cmELF::FileType cmELF::GetFileType() const
{
  if(this->Valid())
    {
    return this->Internal->GetFileType();
    }
  else
    {
    return FileTypeInvalid;
    }
}

//----------------------------------------------------------------------------
unsigned int cmELF::GetNumberOfSections() const
{
  if(this->Valid())
    {
    return this->Internal->GetNumberOfSections();
    }
  else
    {
    return 0;
    }
}

//----------------------------------------------------------------------------
bool cmELF::GetSOName(std::string& soname)
{
  if(this->Valid() &&
     this->Internal->GetFileType() == cmELF::FileTypeSharedLibrary)
    {
    return this->Internal->GetSOName(soname);
    }
  else
    {
    return false;
    }
}

//----------------------------------------------------------------------------
void cmELF::PrintInfo(std::ostream& os) const
{
  if(this->Valid())
    {
    this->Internal->PrintInfo(os);
    }
  else
    {
    os << "Not a valid ELF file.\n";
    }
}



More information about the Cmake-commits mailing list