PageRenderTime 25ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/src/system/boot/ppc/Elf32.cc

https://github.com/jmolloy/pedigree
C++ | 263 lines | 173 code | 28 blank | 62 comment | 41 complexity | e9a809568ac462fce65a7fb883abd9b0 MD5 | raw file
Possible License(s): 0BSD, LGPL-2.1, BSD-2-Clause
  1. /*
  2. * Copyright (c) 2008 James Molloy, Jörg Pfähler, Matthew Iselin
  3. *
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include "Elf32.h"
  17. #include "prom.h"
  18. //include <utilities/utility.h>
  19. extern void writeStr(const char *str);
  20. int strncpy(char *dest, const char *src, int len)
  21. {
  22. while (*src && len)
  23. {
  24. *dest++ = *src++;
  25. len--;
  26. }
  27. *dest = '\0';
  28. return 0;
  29. }
  30. int memset(void *buf, int c, size_t len)
  31. {
  32. unsigned char *tmp = reinterpret_cast<unsigned char *> (buf);
  33. while(len--)
  34. {
  35. *tmp++ = c;
  36. }
  37. return 0;
  38. }
  39. void memcpy(void *dest, const void *src, size_t len)
  40. {
  41. const unsigned char *sp = reinterpret_cast<const unsigned char *> (src);
  42. unsigned char *dp = reinterpret_cast<unsigned char *>(dest);
  43. for (; len != 0; len--) *dp++ = *sp++;
  44. }
  45. int strcmp(const char *p1, const char *p2)
  46. {
  47. int i = 0;
  48. int failed = 0;
  49. while(p1[i] != '\0' && p2[i] != '\0')
  50. {
  51. if(p1[i] != p2[i])
  52. {
  53. failed = 1;
  54. break;
  55. }
  56. i++;
  57. }
  58. // why did the loop exit?
  59. if( (p1[i] == '\0' && p2[i] != '\0') || (p1[i] != '\0' && p2[i] == '\0') )
  60. failed = 1;
  61. return failed;
  62. }
  63. Elf32::Elf32(const char *name) :
  64. m_pHeader(0),
  65. m_pSymbolTable(0),
  66. m_pStringTable(0),
  67. m_pShstrtab(0),
  68. m_pGotTable(0),
  69. m_pRelTable(0),
  70. m_pSectionHeaders(0),
  71. m_pBuffer(0)
  72. {
  73. strncpy(m_pId, name, 127);
  74. }
  75. Elf32::~Elf32()
  76. {
  77. }
  78. bool Elf32::load(uint8_t *pBuffer, unsigned int nBufferLength)
  79. {
  80. // The main header will be at pBuffer[0].
  81. m_pHeader = reinterpret_cast<Elf32Header_t *>(pBuffer);
  82. // Check the ident.
  83. if ( (m_pHeader->ident[1] != 'E') ||
  84. (m_pHeader->ident[2] != 'L') ||
  85. (m_pHeader->ident[3] != 'F') ||
  86. (m_pHeader->ident[0] != 127) )
  87. {
  88. m_pHeader = 0;
  89. return false;
  90. }
  91. // Load in the section headers.
  92. m_pSectionHeaders = reinterpret_cast<Elf32SectionHeader_t *>(&pBuffer[m_pHeader->shoff]);
  93. // Find the string tab&pBuffer[m_pStringTable->offset];le.
  94. m_pStringTable = &m_pSectionHeaders[m_pHeader->shstrndx];
  95. // Temporarily load the string table.
  96. const char *pStrtab = reinterpret_cast<const char *>(&pBuffer[m_pStringTable->offset]);
  97. // Go through each section header, trying to find .symtab.
  98. for (int i = 0; i < m_pHeader->shnum; i++)
  99. {
  100. const char *pStr = pStrtab + m_pSectionHeaders[i].name;
  101. if (!strcmp(pStr, ".symtab"))
  102. {
  103. m_pSymbolTable = &m_pSectionHeaders[i];
  104. }
  105. if (!strcmp(pStr, ".strtab"))
  106. m_pStringTable = &m_pSectionHeaders[i];
  107. }
  108. m_pBuffer = pBuffer;
  109. // Success.
  110. return true;
  111. }
  112. // bool Elf32::load(BootstrapInfo *pBootstrap)
  113. // {
  114. // // Firstly get the section header string table.
  115. // m_pShstrtab = reinterpret_cast<Elf32SectionHeader_t *>( pBootstrap->getSectionHeader(
  116. // pBootstrap->getStringTable() ));
  117. //
  118. // // Normally we will try to use the sectionHeader->offset member to access data, so an
  119. // // Elf section's data can be accessed without being mapped into virtual memory. However,
  120. // // when GRUB loads us, it doesn't tell us where exactly ->offset is with respect to, so here
  121. // // we fix offset = addr, then we work w.r.t 0x00.
  122. //
  123. // // Temporarily load the string table.
  124. // const char *pStrtab = reinterpret_cast<const char *>(m_pShstrtab->addr);
  125. //
  126. // // Now search for the symbol table.
  127. // for (int i = 0; i < pBootstrap->getSectionHeaderCount(); i++)
  128. // {
  129. // Elf32SectionHeader_t *pSh = reinterpret_cast<Elf32SectionHeader_t *>(pBootstrap->getSectionHeader(i));
  130. // const char *pStr = pStrtab + pSh->name;
  131. //
  132. // if (pSh->type == SHT_SYMTAB)
  133. // {
  134. // m_pSymbolTable = pSh;
  135. // m_pSymbolTable->offset = m_pSymbolTable->addr;
  136. // }
  137. // else if (!strcmp(pStr, ".strtab"))
  138. // {
  139. // m_pStringTable = pSh;
  140. // m_pStringTable->offset = m_pStringTable->addr;
  141. // }
  142. // }
  143. //
  144. // return true;
  145. // }
  146. bool Elf32::writeSections()
  147. {
  148. unsigned int physAddress = 0x1000000;
  149. for (int i = 0; i < m_pHeader->shnum; i++)
  150. {
  151. if (m_pSectionHeaders[i].flags & SHF_ALLOC)
  152. {
  153. if (m_pSectionHeaders[i].type != SHT_NOBITS)
  154. {
  155. prom_map(physAddress, m_pSectionHeaders[i].addr, m_pSectionHeaders[i].size+0x1000);
  156. physAddress += m_pSectionHeaders[i].size+0x1000;
  157. // Copy section data from the file.
  158. memcpy(reinterpret_cast<uint8_t*> (m_pSectionHeaders[i].addr),
  159. &m_pBuffer[m_pSectionHeaders[i].offset],
  160. m_pSectionHeaders[i].size);
  161. }
  162. else
  163. {
  164. prom_map(physAddress, m_pSectionHeaders[i].addr, m_pSectionHeaders[i].size+0x1000);
  165. physAddress += m_pSectionHeaders[i].size+0x1000;
  166. memset(reinterpret_cast<uint8_t*>(m_pSectionHeaders[i].addr),
  167. 0,
  168. m_pSectionHeaders[i].size);
  169. }
  170. for(unsigned int j = m_pSectionHeaders[i].addr; j < m_pSectionHeaders[i].addr+m_pSectionHeaders[i].size; j += 4)
  171. {
  172. asm volatile("dcbst 0, %0" :: "r" (j));
  173. }
  174. asm volatile("sync");
  175. for(unsigned int j = m_pSectionHeaders[i].addr; j < m_pSectionHeaders[i].addr+m_pSectionHeaders[i].size; j += 4)
  176. {
  177. asm volatile("icbi 0, %0" :: "r"(j));
  178. }
  179. asm volatile("sync;isync;");
  180. }
  181. }
  182. return true;
  183. }
  184. unsigned int Elf32::getLastAddress()
  185. {
  186. return 0;
  187. }
  188. const char *Elf32::lookupSymbol(unsigned int addr, unsigned int *startAddr)
  189. {
  190. if (!m_pSymbolTable || !m_pStringTable)
  191. return 0; // Just return null if we haven't got a symbol table.
  192. Elf32Symbol_t *pSymbol = reinterpret_cast<Elf32Symbol_t *>(&m_pBuffer[m_pSymbolTable->offset]);
  193. const char *pStrtab = reinterpret_cast<const char *>(&m_pBuffer[m_pStringTable->offset]);
  194. for (size_t i = 0; i < m_pSymbolTable->size / sizeof(Elf32Symbol_t); i++)
  195. {
  196. // Make sure we're looking at an object or function.
  197. if (ELF32_ST_TYPE(pSymbol->info) != 0x2 /* function */ &&
  198. ELF32_ST_TYPE(pSymbol->info) != 0x0 /* notype (asm functions) */)
  199. {
  200. pSymbol++;
  201. continue;
  202. }
  203. // If we're checking for a symbol that is apparently zero-sized, add one so we can actually
  204. // count it!
  205. uint32_t size = pSymbol->size;
  206. if (size == 0)
  207. size = 1;
  208. if ( (addr >= pSymbol->value) &&
  209. (addr < (pSymbol->value + size)) )
  210. {
  211. const char *pStr = pStrtab + pSymbol->name;
  212. if (startAddr)
  213. *startAddr = pSymbol->value;
  214. return pStr;
  215. }
  216. pSymbol ++;
  217. }
  218. return 0;
  219. }
  220. uint32_t Elf32::lookupDynamicSymbolAddress(uint32_t off)
  221. {
  222. return 0;
  223. }
  224. char *Elf32::lookupDynamicSymbolName(uint32_t off)
  225. {
  226. return 0;
  227. }
  228. uint32_t Elf32::getGlobalOffsetTable()
  229. {
  230. return 0;
  231. }
  232. uint32_t Elf32::getEntryPoint()
  233. {
  234. return m_pHeader->entry;
  235. }