ctkBinaryFileDescriptor.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) Kitware Inc.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.commontk.org/LICENSE
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. =========================================================================*/
  14. /*=auto=========================================================================
  15. Portions (c) Copyright 2005 Brigham and Women's Hospital (BWH)
  16. All Rights Reserved.
  17. See Doc/copyright/copyright.txt
  18. or http://www.slicer.org/copyright/copyright.txt for details.
  19. Program: Module Description Parser
  20. =========================================================================auto=*/
  21. // CTK includes
  22. #include "ctkBinaryFileDescriptor.h"
  23. #include "ctkPimpl.h"
  24. // BinUtils includes
  25. #include <bfd.h>
  26. // STD includes
  27. #include <cstdlib>
  28. #include <utility>
  29. #include <vector>
  30. //-----------------------------------------------------------------------------
  31. class ctkBinaryFileDescriptorPrivate
  32. {
  33. public:
  34. // Convenient typedefs
  35. typedef std::pair<asection*, void* > MemorySectionType;
  36. typedef std::vector<MemorySectionType> MemorySectionContainer;
  37. ctkBinaryFileDescriptorPrivate();
  38. /// Resolves a symbol
  39. void* resolve(const char * symbol);
  40. MemorySectionContainer Sections;
  41. bfd * BFD;
  42. QString FileName;
  43. };
  44. // --------------------------------------------------------------------------
  45. // ctkBinaryFileDescriptorPrivate methods
  46. // --------------------------------------------------------------------------
  47. ctkBinaryFileDescriptorPrivate::ctkBinaryFileDescriptorPrivate()
  48. {
  49. this->BFD = 0;
  50. }
  51. // --------------------------------------------------------------------------
  52. void* ctkBinaryFileDescriptorPrivate::resolve(const char * symbol)
  53. {
  54. if (!this->BFD)
  55. {
  56. return 0;
  57. }
  58. void *addr = 0;
  59. // Get the symbol table
  60. long storageNeeded = bfd_get_symtab_upper_bound(this->BFD);
  61. asymbol ** symbolTable = (asymbol **) malloc(storageNeeded);
  62. long numberOfSymbols = bfd_canonicalize_symtab(this->BFD, symbolTable);
  63. // Run through the symbol table, looking for the requested symbol
  64. for (int i = 0; i < numberOfSymbols; i++)
  65. {
  66. if (strcmp(symbol, symbolTable[i]->name) == 0)
  67. {
  68. // Found the symbol, get the section pointer
  69. asection *p = bfd_get_section(symbolTable[i]);
  70. // Do we have this section already?
  71. MemorySectionContainer::iterator sit;
  72. for (sit = this->Sections.begin(); sit != this->Sections.end(); ++sit)
  73. {
  74. if ((*sit).first == p)
  75. {
  76. break;
  77. }
  78. }
  79. PTR mem;
  80. if (sit == this->Sections.end())
  81. {
  82. // Get the contents of the section
  83. bfd_size_type sz = bfd_get_section_size (p);
  84. mem = malloc (sz);
  85. if (bfd_get_section_contents(this->BFD, p, mem, (file_ptr) 0,sz))
  86. {
  87. this->Sections.push_back( MemorySectionType(p, mem) );
  88. }
  89. else
  90. {
  91. // Error reading section
  92. free(mem);
  93. break;
  94. }
  95. }
  96. else
  97. {
  98. // pull the start of the section block from the cache
  99. mem = const_cast<void*>((*sit).second);
  100. }
  101. // determine the address of this section
  102. addr = (char *)mem + (bfd_asymbol_value(symbolTable[i]) - bfd_asymbol_base(symbolTable[i]));
  103. break;
  104. }
  105. }
  106. // cleanup. just delete the outer vector for the symbol table
  107. free(symbolTable);
  108. return addr;
  109. }
  110. // --------------------------------------------------------------------------
  111. // ctkBinaryFileDescriptor methods
  112. // --------------------------------------------------------------------------
  113. ctkBinaryFileDescriptor::ctkBinaryFileDescriptor(): d_ptr(new ctkBinaryFileDescriptorPrivate)
  114. {
  115. }
  116. // --------------------------------------------------------------------------
  117. ctkBinaryFileDescriptor::ctkBinaryFileDescriptor(const QString& _fileName):
  118. d_ptr(new ctkBinaryFileDescriptorPrivate)
  119. {
  120. Q_D(ctkBinaryFileDescriptor);
  121. d->FileName = _fileName;
  122. }
  123. // --------------------------------------------------------------------------
  124. ctkBinaryFileDescriptor::~ctkBinaryFileDescriptor()
  125. {
  126. }
  127. // --------------------------------------------------------------------------
  128. CTK_GET_CPP(ctkBinaryFileDescriptor, QString, fileName, FileName);
  129. CTK_SET_CPP(ctkBinaryFileDescriptor, const QString&, setFileName, FileName);
  130. // --------------------------------------------------------------------------
  131. bool ctkBinaryFileDescriptor::isLoaded() const
  132. {
  133. Q_D(const ctkBinaryFileDescriptor);
  134. return (d->BFD != 0);
  135. }
  136. // --------------------------------------------------------------------------
  137. bool ctkBinaryFileDescriptor::load()
  138. {
  139. Q_D(ctkBinaryFileDescriptor);
  140. bfd_init();
  141. bfd * abfd = bfd_openr(d->FileName.toLatin1(), NULL);
  142. if (!abfd)
  143. {
  144. return false;
  145. }
  146. /* make sure it's an object file */
  147. if (!bfd_check_format (abfd, bfd_object))
  148. {
  149. bfd_close(abfd);
  150. return false;
  151. }
  152. d->BFD = abfd;
  153. return true;
  154. }
  155. // --------------------------------------------------------------------------
  156. bool ctkBinaryFileDescriptor::unload()
  157. {
  158. Q_D(ctkBinaryFileDescriptor);
  159. if (d->BFD)
  160. {
  161. bfd_close(d->BFD);
  162. d->BFD = 0;
  163. }
  164. return true;
  165. }
  166. // --------------------------------------------------------------------------
  167. void* ctkBinaryFileDescriptor::resolve(const char * symbol)
  168. {
  169. Q_D(ctkBinaryFileDescriptor);
  170. return d->resolve(symbol);
  171. }