Pārlūkot izejas kodu

ENH: Add ctkBinaryFileDescriptor class

Jean-Christophe Fillion-Robin 15 gadi atpakaļ
vecāks
revīzija
ad3e3078d6

+ 8 - 0
Libs/Core/CMake/TestBFD/CMakeLists.txt

@@ -0,0 +1,8 @@
+PROJECT(TestBFD)
+
+IF(BUILD_SHARED_LIBS)
+  ADD_LIBRARY(TestBFD SHARED TestBFD.cpp)
+ELSE(BUILD_SHARED_LIBS)
+  ADD_LIBRARY(TestBFD TestBFD.cpp)
+ENDIF(BUILD_SHARED_LIBS)
+TARGET_LINK_LIBRARIES(TestBFD bfd iberty)

+ 10 - 0
Libs/Core/CMake/TestBFD/TestBFD.cpp

@@ -0,0 +1,10 @@
+#include <bfd.h>
+
+void TestBFD()
+{
+  bfd *abfd = 0;
+  asymbol *symbol = 0;
+  asection *p = 0;
+
+  bfd_init();
+}

+ 34 - 0
Libs/Core/CMake/ctkMacroBFDCheck.cmake

@@ -0,0 +1,34 @@
+#
+# ctkMacroBFDCheck.cmake - After this file is included into your main CMake script,
+#                          HAVE_BFD will be defined if libbfd is available.
+#
+
+SET(BFD_LIBRARIES)
+UNSET(HAVE_BFD)
+
+IF(NOT WIN32)
+  INCLUDE(CheckIncludeFile)
+  CHECK_INCLUDE_FILE(bfd.h HAVE_BFD_HEADER)
+
+  IF(HAVE_BFD_HEADER)
+    # make sure we can build with libbfd
+    #MESSAGE(STATUS "Checking libbfd")
+    TRY_COMPILE(HAVE_BFD
+      ${CMAKE_CURRENT_BINARY_DIR}/CMake/TestBFD
+      ${CMAKE_CURRENT_SOURCE_DIR}/CMake/TestBFD
+      TestBFD
+      CMAKE_FLAGS
+      -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}
+      -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
+      OUTPUT_VARIABLE OUTPUT)
+    #MESSAGE(${OUTPUT})
+
+    IF(HAVE_BFD)
+      SET(BFD_LIBRARIES bfd iberty)
+      MESSAGE(STATUS "CTKCore: libbfd is available")
+    ELSE()
+      MESSAGE(STATUS "CTKCore: libbfd is *NOT* available")
+    ENDIF()
+
+  ENDIF()
+ENDIF()

+ 14 - 1
Libs/Core/CMakeLists.txt

@@ -1,5 +1,11 @@
 PROJECT(CTKCore)
 PROJECT(CTKCore)
 
 
+# CMake modules
+SET(CMAKE_MODULE_PATH ${CTKCore_SOURCE_DIR}/CMake ${CMAKE_MODULE_PATH})
+
+# CMake Macros
+INCLUDE(CMake/ctkMacroBFDCheck.cmake)
+
 #
 #
 # 3rd party dependencies
 # 3rd party dependencies
 #
 #
@@ -25,7 +31,7 @@ ENDIF()
 IF(QTMOBILITY_QTSERVICEFW_LIBRARY_DEBUG)
 IF(QTMOBILITY_QTSERVICEFW_LIBRARY_DEBUG)
   LIST(APPEND QTMOBILITY_QTSERVICEFW_LIBRARIES debug ${QTMOBILITY_QTSERVICEFW_LIBRARY_DEBUG})
   LIST(APPEND QTMOBILITY_QTSERVICEFW_LIBRARIES debug ${QTMOBILITY_QTSERVICEFW_LIBRARY_DEBUG})
 ENDIF()
 ENDIF()
-             
+
 #
 #
 # See CTK/CMake/ctkMacroBuildQtLib.cmake for details
 # See CTK/CMake/ctkMacroBuildQtLib.cmake for details
 #
 #
@@ -58,6 +64,13 @@ SET(KIT_SRCS
   ctkUtils.h
   ctkUtils.h
   )
   )
 
 
+IF(CTK_HAVE_BFD)
+  LIST(APPEND KIT_SRCS
+    ctkBinaryFileDescriptor.cpp
+    ctkBinaryFileDescriptor.h
+    )
+ENDIF()
+
 # Headers that should run through moc
 # Headers that should run through moc
 SET(KIT_MOC_SRCS
 SET(KIT_MOC_SRCS
   ctkModelTester.h
   ctkModelTester.h

+ 208 - 0
Libs/Core/ctkBinaryFileDescriptor.cpp

@@ -0,0 +1,208 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+/*=auto=========================================================================
+
+ Portions (c) Copyright 2005 Brigham and Women's Hospital (BWH) 
+ All Rights Reserved.
+
+ See Doc/copyright/copyright.txt
+ or http://www.slicer.org/copyright/copyright.txt for details.
+
+ Program:   Module Description Parser
+
+=========================================================================auto=*/
+
+// CTK includes
+#include "ctkBinaryFileDescriptor.h"
+
+// BinUtils includes
+#include <bfd.h>
+
+// STD includes
+#include <cstdlib>
+#include <utility>
+#include <vector>
+
+//-----------------------------------------------------------------------------
+class ctkBinaryFileDescriptorPrivate: public ctkPrivate<ctkBinaryFileDescriptor>
+{
+public:
+  // Convenient typedefs
+  typedef std::pair<asection*, void* > MemorySectionType;
+  typedef std::vector<MemorySectionType> MemorySectionContainer;
+  
+  ctkBinaryFileDescriptorPrivate();
+
+  /// Resolves a symbol
+  void* resolve(const char * symbol);
+
+  MemorySectionContainer Sections;
+  bfd *                  BFD;
+  
+  QString FileName;
+};
+
+// --------------------------------------------------------------------------
+// ctkBinaryFileDescriptorPrivate methods
+
+// --------------------------------------------------------------------------
+ctkBinaryFileDescriptorPrivate::ctkBinaryFileDescriptorPrivate()
+{
+  this->BFD = 0;
+}
+
+// --------------------------------------------------------------------------
+void* ctkBinaryFileDescriptorPrivate::resolve(const char * symbol)
+{
+  if (!this->BFD)
+    {
+    return 0;
+    }
+
+  void *addr = 0;
+  
+  // Get the symbol table
+  long storageNeeded = bfd_get_symtab_upper_bound(this->BFD);
+  asymbol ** symbolTable = (asymbol **) malloc(storageNeeded);
+  
+  long numberOfSymbols = bfd_canonicalize_symtab(this->BFD, symbolTable);
+    
+  // Run through the symbol table, looking for the requested symbol
+  for (int i = 0; i < numberOfSymbols; i++) 
+    {
+    if (strcmp(symbol, symbolTable[i]->name) == 0)
+      { 
+      // Found the symbol, get the section pointer
+      asection *p = bfd_get_section(symbolTable[i]);
+          
+      // Do we have this section already?
+      MemorySectionContainer::iterator sit;
+      for (sit = this->Sections.begin(); sit != this->Sections.end(); ++sit)
+        {
+        if ((*sit).first == p)
+          {
+          break;
+          }  
+        }
+            
+      PTR mem;
+      if (sit == this->Sections.end())
+        {
+        // Get the contents of the section
+        bfd_size_type sz = bfd_get_section_size (p);
+        mem = malloc (sz);
+        if (bfd_get_section_contents(this->BFD, p, mem, (file_ptr) 0,sz))
+          {
+          this->Sections.push_back( MemorySectionType(p, mem) );
+          }
+        else
+          {
+          // Error reading section
+          free(mem);
+          break;
+          }
+        }
+      else
+        {
+        // pull the start of the section block from the cache
+        mem = const_cast<void*>((*sit).second);
+        }
+            
+      // determine the address of this section
+      addr = (char *)mem + (bfd_asymbol_value(symbolTable[i]) - bfd_asymbol_base(symbolTable[i]));
+      break;
+      }
+    }
+
+  // cleanup. just delete the outer vector for the symbol table
+  free(symbolTable);
+  
+  return addr;
+}
+
+// --------------------------------------------------------------------------
+// ctkBinaryFileDescriptor methods
+
+// --------------------------------------------------------------------------
+ctkBinaryFileDescriptor::ctkBinaryFileDescriptor()
+{
+  CTK_INIT_PRIVATE(ctkBinaryFileDescriptor);
+}
+
+// --------------------------------------------------------------------------
+ctkBinaryFileDescriptor::ctkBinaryFileDescriptor(const QString& _fileName)
+{
+  CTK_INIT_PRIVATE(ctkBinaryFileDescriptor);
+  CTK_D(ctkBinaryFileDescriptor);
+  d->FileName = _fileName;
+}
+
+// --------------------------------------------------------------------------
+ctkBinaryFileDescriptor::~ctkBinaryFileDescriptor()
+{
+}
+
+// --------------------------------------------------------------------------
+CTK_GET_CXX(ctkBinaryFileDescriptor, QString, fileName, FileName);
+CTK_SET_CXX(ctkBinaryFileDescriptor, const QString&, setFileName, FileName);
+
+// --------------------------------------------------------------------------
+bool ctkBinaryFileDescriptor::isLoaded() const
+{
+  CTK_D(const ctkBinaryFileDescriptor);
+  return (d->BFD != 0);
+}
+
+// --------------------------------------------------------------------------
+bool ctkBinaryFileDescriptor::load()
+{
+  CTK_D(ctkBinaryFileDescriptor);
+  
+  bfd_init();
+  bfd * abfd = bfd_openr(d->FileName.toLatin1(), NULL);
+  if (!abfd)
+    {
+    return false;
+    }
+  
+  /* make sure it's an object file */
+  if (!bfd_check_format (abfd, bfd_object)) 
+    {
+    bfd_close(abfd);
+    return false;
+    }
+  
+  d->BFD = abfd;
+  return true;
+}
+
+// --------------------------------------------------------------------------
+bool ctkBinaryFileDescriptor::unload()
+{
+  CTK_D(ctkBinaryFileDescriptor);
+  
+  if (d->BFD)
+    {
+    bfd_close(d->BFD);
+    d->BFD = 0; 
+    }
+  return true;
+}
+
+// --------------------------------------------------------------------------
+void* ctkBinaryFileDescriptor::resolve(const char * symbol)
+{
+  CTK_D(ctkBinaryFileDescriptor);
+  return d->resolve(symbol);
+}

+ 68 - 0
Libs/Core/ctkBinaryFileDescriptor.h

@@ -0,0 +1,68 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc. 
+  All rights reserved.
+  Distributed under a BSD License. See LICENSE.txt file.
+
+  This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the above copyright notice for more information.
+
+=========================================================================*/
+/*=auto=========================================================================
+
+ Portions (c) Copyright 2005 Brigham and Women's Hospital (BWH) 
+ All Rights Reserved.
+
+ See Doc/copyright/copyright.txt
+ or http://www.slicer.org/copyright/copyright.txt for details.
+
+ Program:   Module Description Parser
+
+=========================================================================auto=*/
+
+#ifndef __ctkBinaryFileDescriptor_h
+#define __ctkBinaryFileDescriptor_h
+
+// Qt includes
+#include <QString>
+
+// CTK includes
+#include "ctkPimpl.h"
+
+#include "CTKWidgetsExport.h"
+
+/// Allows to resolve global symbols contained into an executable.
+/// Implementation valid only for unix-like systems (Linux, Mac, ...)
+
+class ctkBinaryFileDescriptorPrivate;
+
+class CTK_WIDGETS_EXPORT ctkBinaryFileDescriptor
+{
+public:
+  ctkBinaryFileDescriptor();
+  ctkBinaryFileDescriptor(const QString& _fileName);
+  virtual ~ctkBinaryFileDescriptor();
+
+  QString fileName()const;
+  void setFileName(const QString& _fileName);
+
+  /// Load the object file containing the symbols
+  bool load();
+
+  /// Unload / close the object file
+  bool unload();
+
+  bool isLoaded() const;
+
+  /// Get the address of a symbol in memory
+  void* resolve(const char * symbol);
+
+private:
+  CTK_DECLARE_PRIVATE(ctkBinaryFileDescriptor);
+
+};
+
+#endif

+ 1 - 0
Libs/Core/target_libraries.cmake

@@ -7,4 +7,5 @@
 SET(target_libraries
 SET(target_libraries
   QT_LIBRARIES
   QT_LIBRARIES
   QTMOBILITY_QTSERVICEFW_LIBRARIES
   QTMOBILITY_QTSERVICEFW_LIBRARIES
+  BFD_LIBRARIES
   )
   )