ctkBinaryFileDescriptor.cpp 5.6 KB

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