ctkBinaryFileDescriptor.cpp

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Library:   CTK
00004  
00005   Copyright (c) 2010  Kitware Inc.
00006 
00007   Licensed under the Apache License, Version 2.0 (the "License");
00008   you may not use this file except in compliance with the License.
00009   You may obtain a copy of the License at
00010 
00011       http://www.commontk.org/LICENSE
00012 
00013   Unless required by applicable law or agreed to in writing, software
00014   distributed under the License is distributed on an "AS IS" BASIS,
00015   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016   See the License for the specific language governing permissions and
00017   limitations under the License.
00018  
00019 =========================================================================*/
00020 /*=auto=========================================================================
00021 
00022  Portions (c) Copyright 2005 Brigham and Women's Hospital (BWH) 
00023  All Rights Reserved.
00024 
00025  See Doc/copyright/copyright.txt
00026  or http://www.slicer.org/copyright/copyright.txt for details.
00027 
00028  Program:   Module Description Parser
00029 
00030 =========================================================================auto=*/
00031 
00032 // CTK includes
00033 #include "ctkBinaryFileDescriptor.h"
00034 
00035 // BinUtils includes
00036 #include <bfd.h>
00037 
00038 // STD includes
00039 #include <cstdlib>
00040 #include <utility>
00041 #include <vector>
00042 
00043 //-----------------------------------------------------------------------------
00044 class ctkBinaryFileDescriptorPrivate: public ctkPrivate<ctkBinaryFileDescriptor>
00045 {
00046 public:
00047   // Convenient typedefs
00048   typedef std::pair<asection*, void* > MemorySectionType;
00049   typedef std::vector<MemorySectionType> MemorySectionContainer;
00050   
00051   ctkBinaryFileDescriptorPrivate();
00052 
00054   void* resolve(const char * symbol);
00055 
00056   MemorySectionContainer Sections;
00057   bfd *                  BFD;
00058   
00059   QString FileName;
00060 };
00061 
00062 // --------------------------------------------------------------------------
00063 // ctkBinaryFileDescriptorPrivate methods
00064 
00065 // --------------------------------------------------------------------------
00066 ctkBinaryFileDescriptorPrivate::ctkBinaryFileDescriptorPrivate()
00067 {
00068   this->BFD = 0;
00069 }
00070 
00071 // --------------------------------------------------------------------------
00072 void* ctkBinaryFileDescriptorPrivate::resolve(const char * symbol)
00073 {
00074   if (!this->BFD)
00075     {
00076     return 0;
00077     }
00078 
00079   void *addr = 0;
00080   
00081   // Get the symbol table
00082   long storageNeeded = bfd_get_symtab_upper_bound(this->BFD);
00083   asymbol ** symbolTable = (asymbol **) malloc(storageNeeded);
00084   
00085   long numberOfSymbols = bfd_canonicalize_symtab(this->BFD, symbolTable);
00086     
00087   // Run through the symbol table, looking for the requested symbol
00088   for (int i = 0; i < numberOfSymbols; i++) 
00089     {
00090     if (strcmp(symbol, symbolTable[i]->name) == 0)
00091       { 
00092       // Found the symbol, get the section pointer
00093       asection *p = bfd_get_section(symbolTable[i]);
00094           
00095       // Do we have this section already?
00096       MemorySectionContainer::iterator sit;
00097       for (sit = this->Sections.begin(); sit != this->Sections.end(); ++sit)
00098         {
00099         if ((*sit).first == p)
00100           {
00101           break;
00102           }  
00103         }
00104             
00105       PTR mem;
00106       if (sit == this->Sections.end())
00107         {
00108         // Get the contents of the section
00109         bfd_size_type sz = bfd_get_section_size (p);
00110         mem = malloc (sz);
00111         if (bfd_get_section_contents(this->BFD, p, mem, (file_ptr) 0,sz))
00112           {
00113           this->Sections.push_back( MemorySectionType(p, mem) );
00114           }
00115         else
00116           {
00117           // Error reading section
00118           free(mem);
00119           break;
00120           }
00121         }
00122       else
00123         {
00124         // pull the start of the section block from the cache
00125         mem = const_cast<void*>((*sit).second);
00126         }
00127             
00128       // determine the address of this section
00129       addr = (char *)mem + (bfd_asymbol_value(symbolTable[i]) - bfd_asymbol_base(symbolTable[i]));
00130       break;
00131       }
00132     }
00133 
00134   // cleanup. just delete the outer vector for the symbol table
00135   free(symbolTable);
00136   
00137   return addr;
00138 }
00139 
00140 // --------------------------------------------------------------------------
00141 // ctkBinaryFileDescriptor methods
00142 
00143 // --------------------------------------------------------------------------
00144 ctkBinaryFileDescriptor::ctkBinaryFileDescriptor()
00145 {
00146   CTK_INIT_PRIVATE(ctkBinaryFileDescriptor);
00147 }
00148 
00149 // --------------------------------------------------------------------------
00150 ctkBinaryFileDescriptor::ctkBinaryFileDescriptor(const QString& _fileName)
00151 {
00152   CTK_INIT_PRIVATE(ctkBinaryFileDescriptor);
00153   CTK_D(ctkBinaryFileDescriptor);
00154   d->FileName = _fileName;
00155 }
00156 
00157 // --------------------------------------------------------------------------
00158 ctkBinaryFileDescriptor::~ctkBinaryFileDescriptor()
00159 {
00160 }
00161 
00162 // --------------------------------------------------------------------------
00163 CTK_GET_CXX(ctkBinaryFileDescriptor, QString, fileName, FileName);
00164 CTK_SET_CXX(ctkBinaryFileDescriptor, const QString&, setFileName, FileName);
00165 
00166 // --------------------------------------------------------------------------
00167 bool ctkBinaryFileDescriptor::isLoaded() const
00168 {
00169   CTK_D(const ctkBinaryFileDescriptor);
00170   return (d->BFD != 0);
00171 }
00172 
00173 // --------------------------------------------------------------------------
00174 bool ctkBinaryFileDescriptor::load()
00175 {
00176   CTK_D(ctkBinaryFileDescriptor);
00177   
00178   bfd_init();
00179   bfd * abfd = bfd_openr(d->FileName.toLatin1(), NULL);
00180   if (!abfd)
00181     {
00182     return false;
00183     }
00184   
00185   /* make sure it's an object file */
00186   if (!bfd_check_format (abfd, bfd_object)) 
00187     {
00188     bfd_close(abfd);
00189     return false;
00190     }
00191   
00192   d->BFD = abfd;
00193   return true;
00194 }
00195 
00196 // --------------------------------------------------------------------------
00197 bool ctkBinaryFileDescriptor::unload()
00198 {
00199   CTK_D(ctkBinaryFileDescriptor);
00200   
00201   if (d->BFD)
00202     {
00203     bfd_close(d->BFD);
00204     d->BFD = 0; 
00205     }
00206   return true;
00207 }
00208 
00209 // --------------------------------------------------------------------------
00210 void* ctkBinaryFileDescriptor::resolve(const char * symbol)
00211 {
00212   CTK_D(ctkBinaryFileDescriptor);
00213   return d->resolve(symbol);
00214 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated on 21 May 2010 for CTK by  doxygen 1.6.1