123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- /*=========================================================================
- Library: CTK
- Copyright (c) Kitware Inc.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0.txt
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- =========================================================================*/
- /*=========================================================================
- Portions (c) Copyright Brigham and Women's Hospital (BWH)
- All Rights Reserved.
- See http://www.slicer.org/copyright/copyright.txt for details.
- Program: Module Description Parser
- =========================================================================*/
- // CTK includes
- #include "ctkBinaryFileDescriptor.h"
- #include "ctkPimpl.h"
- // BinUtils includes
- #include <bfd.h>
- // STD includes
- #include <cstdlib>
- #include <utility>
- #include <vector>
- //-----------------------------------------------------------------------------
- class ctkBinaryFileDescriptorPrivate
- {
- 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 = reinterpret_cast<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, static_cast<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 = reinterpret_cast<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(): d_ptr(new ctkBinaryFileDescriptorPrivate)
- {
- }
- // --------------------------------------------------------------------------
- ctkBinaryFileDescriptor::ctkBinaryFileDescriptor(const QString& _fileName):
- d_ptr(new ctkBinaryFileDescriptorPrivate)
- {
- Q_D(ctkBinaryFileDescriptor);
- d->FileName = _fileName;
- }
- // --------------------------------------------------------------------------
- ctkBinaryFileDescriptor::~ctkBinaryFileDescriptor()
- {
- }
- // --------------------------------------------------------------------------
- CTK_GET_CPP(ctkBinaryFileDescriptor, QString, fileName, FileName);
- CTK_SET_CPP(ctkBinaryFileDescriptor, const QString&, setFileName, FileName);
- // --------------------------------------------------------------------------
- bool ctkBinaryFileDescriptor::isLoaded() const
- {
- Q_D(const ctkBinaryFileDescriptor);
- return (d->BFD != 0);
- }
- // --------------------------------------------------------------------------
- bool ctkBinaryFileDescriptor::load()
- {
- Q_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()
- {
- Q_D(ctkBinaryFileDescriptor);
-
- if (d->BFD)
- {
- bfd_close(d->BFD);
- d->BFD = 0;
- }
- return true;
- }
- // --------------------------------------------------------------------------
- void* ctkBinaryFileDescriptor::resolve(const char * symbol)
- {
- Q_D(ctkBinaryFileDescriptor);
- return d->resolve(symbol);
- }
|