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.apache.org/licenses/LICENSE-2.0.txt
  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. /*=========================================================================
  15. Portions (c) Copyright Brigham and Women's Hospital (BWH)
  16. All Rights Reserved.
  17. See http://www.slicer.org/copyright/copyright.txt for details.
  18. Program: Module Description Parser
  19. =========================================================================*/
  20. // CTK includes
  21. #include "ctkBinaryFileDescriptor.h"
  22. #include "ctkPimpl.h"
  23. // BinUtils includes
  24. #include <bfd.h>
  25. // STD includes
  26. #include <cstdlib>
  27. #include <utility>
  28. #include <vector>
  29. //-----------------------------------------------------------------------------
  30. class ctkBinaryFileDescriptorPrivate
  31. {
  32. public:
  33. // Convenient typedefs
  34. typedef std::pair<asection*, void* > MemorySectionType;
  35. typedef std::vector<MemorySectionType> MemorySectionContainer;
  36. ctkBinaryFileDescriptorPrivate();
  37. /// Resolves a symbol
  38. void* resolve(const char * symbol);
  39. MemorySectionContainer Sections;
  40. bfd * BFD;
  41. QString FileName;
  42. };
  43. // --------------------------------------------------------------------------
  44. // ctkBinaryFileDescriptorPrivate methods
  45. // --------------------------------------------------------------------------
  46. ctkBinaryFileDescriptorPrivate::ctkBinaryFileDescriptorPrivate()
  47. {
  48. this->BFD = 0;
  49. }
  50. // --------------------------------------------------------------------------
  51. void* ctkBinaryFileDescriptorPrivate::resolve(const char * symbol)
  52. {
  53. if (!this->BFD)
  54. {
  55. return 0;
  56. }
  57. void *addr = 0;
  58. // Get the symbol table
  59. long storageNeeded = bfd_get_symtab_upper_bound(this->BFD);
  60. asymbol ** symbolTable = reinterpret_cast<asymbol **>(malloc(storageNeeded));
  61. long numberOfSymbols = bfd_canonicalize_symtab(this->BFD, symbolTable);
  62. // Run through the symbol table, looking for the requested symbol
  63. for (int i = 0; i < numberOfSymbols; i++)
  64. {
  65. if (strcmp(symbol, symbolTable[i]->name) == 0)
  66. {
  67. // Found the symbol, get the section pointer
  68. asection *p = bfd_get_section(symbolTable[i]);
  69. // Do we have this section already?
  70. MemorySectionContainer::iterator sit;
  71. for (sit = this->Sections.begin(); sit != this->Sections.end(); ++sit)
  72. {
  73. if ((*sit).first == p)
  74. {
  75. break;
  76. }
  77. }
  78. PTR mem;
  79. if (sit == this->Sections.end())
  80. {
  81. // Get the contents of the section
  82. bfd_size_type sz = bfd_get_section_size (p);
  83. mem = malloc (sz);
  84. if (bfd_get_section_contents(this->BFD, p, mem, static_cast<file_ptr>(0), sz))
  85. {
  86. this->Sections.push_back( MemorySectionType(p, mem) );
  87. }
  88. else
  89. {
  90. // Error reading section
  91. free(mem);
  92. break;
  93. }
  94. }
  95. else
  96. {
  97. // pull the start of the section block from the cache
  98. mem = const_cast<void*>((*sit).second);
  99. }
  100. // determine the address of this section
  101. addr = reinterpret_cast<char *>(mem)
  102. + (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. }