PageRenderTime 335ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/src/system/boot/mips/Elf32.cc

https://github.com/jmolloy/pedigree
C++ | 239 lines | 150 code | 27 blank | 62 comment | 39 complexity | b5a2c20406fa826d67c6935565ff69f5 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 <utilities/utility.h>
  18. extern void writeStr(const char *str);
  19. int strncpy(char *dest, const char *src, int len)
  20. {
  21. while (*src && len)
  22. {
  23. *dest++ = *src++;
  24. len--;
  25. }
  26. *dest = '\0';
  27. }
  28. int memset(void *buf, int c, size_t len)
  29. {
  30. unsigned char *tmp = (unsigned char *)buf;
  31. while(len--)
  32. {
  33. *tmp++ = c;
  34. }
  35. }
  36. void memcpy(void *dest, const void *src, size_t len)
  37. {
  38. const unsigned char *sp = (const unsigned char *)src;
  39. unsigned char *dp = (unsigned char *)dest;
  40. for (; len != 0; len--) *dp++ = *sp++;
  41. }
  42. int strcmp(const char *p1, const char *p2)
  43. {
  44. int i = 0;
  45. int failed = 0;
  46. while(p1[i] != '\0' && p2[i] != '\0')
  47. {
  48. if(p1[i] != p2[i])
  49. {
  50. failed = 1;
  51. break;
  52. }
  53. i++;
  54. }
  55. // why did the loop exit?
  56. if( (p1[i] == '\0' && p2[i] != '\0') || (p1[i] != '\0' && p2[i] == '\0') )
  57. failed = 1;
  58. return failed;
  59. }
  60. Elf32::Elf32(const char *name) :
  61. m_pHeader(0),
  62. m_pSymbolTable(0),
  63. m_pStringTable(0),
  64. m_pShstrtab(0),
  65. m_pGotTable(0),
  66. m_pRelTable(0),
  67. m_pSectionHeaders(0),
  68. m_pBuffer(0)
  69. {
  70. strncpy(m_pId, name, 127);
  71. }
  72. Elf32::~Elf32()
  73. {
  74. }
  75. bool Elf32::load(uint8_t *pBuffer, unsigned int nBufferLength)
  76. {
  77. // The main header will be at pBuffer[0].
  78. m_pHeader = reinterpret_cast<Elf32Header_t *>(pBuffer);
  79. // Check the ident.
  80. if ( (m_pHeader->ident[1] != 'E') ||
  81. (m_pHeader->ident[2] != 'L') ||
  82. (m_pHeader->ident[3] != 'F') ||
  83. (m_pHeader->ident[0] != 127) )
  84. {
  85. m_pHeader = (Elf32Header_t*)0;
  86. return false;
  87. }
  88. // Load in the section headers.
  89. m_pSectionHeaders = reinterpret_cast<Elf32SectionHeader_t *>(&pBuffer[m_pHeader->shoff]);
  90. // Find the string tab&pBuffer[m_pStringTable->offset];le.
  91. m_pStringTable = &m_pSectionHeaders[m_pHeader->shstrndx];
  92. // Temporarily load the string table.
  93. const char *pStrtab = reinterpret_cast<const char *>(&pBuffer[m_pStringTable->offset]);
  94. // Go through each section header, trying to find .symtab.
  95. for (int i = 0; i < m_pHeader->shnum; i++)
  96. {
  97. const char *pStr = pStrtab + m_pSectionHeaders[i].name;
  98. if (!strcmp(pStr, ".symtab"))
  99. {
  100. m_pSymbolTable = &m_pSectionHeaders[i];
  101. }
  102. if (!strcmp(pStr, ".strtab"))
  103. m_pStringTable = &m_pSectionHeaders[i];
  104. }
  105. m_pBuffer = pBuffer;
  106. // Success.
  107. return true;
  108. }
  109. // bool Elf32::load(BootstrapInfo *pBootstrap)
  110. // {
  111. // // Firstly get the section header string table.
  112. // m_pShstrtab = reinterpret_cast<Elf32SectionHeader_t *>( pBootstrap->getSectionHeader(
  113. // pBootstrap->getStringTable() ));
  114. //
  115. // // Normally we will try to use the sectionHeader->offset member to access data, so an
  116. // // Elf section's data can be accessed without being mapped into virtual memory. However,
  117. // // when GRUB loads us, it doesn't tell us where exactly ->offset is with respect to, so here
  118. // // we fix offset = addr, then we work w.r.t 0x00.
  119. //
  120. // // Temporarily load the string table.
  121. // const char *pStrtab = reinterpret_cast<const char *>(m_pShstrtab->addr);
  122. //
  123. // // Now search for the symbol table.
  124. // for (int i = 0; i < pBootstrap->getSectionHeaderCount(); i++)
  125. // {
  126. // Elf32SectionHeader_t *pSh = reinterpret_cast<Elf32SectionHeader_t *>(pBootstrap->getSectionHeader(i));
  127. // const char *pStr = pStrtab + pSh->name;
  128. //
  129. // if (pSh->type == SHT_SYMTAB)
  130. // {
  131. // m_pSymbolTable = pSh;
  132. // m_pSymbolTable->offset = m_pSymbolTable->addr;
  133. // }
  134. // else if (!strcmp(pStr, ".strtab"))
  135. // {
  136. // m_pStringTable = pSh;
  137. // m_pStringTable->offset = m_pStringTable->addr;
  138. // }
  139. // }
  140. //
  141. // return true;
  142. // }
  143. bool Elf32::writeSections()
  144. {
  145. for (int i = 0; i < m_pHeader->shnum; i++)
  146. {
  147. if (m_pSectionHeaders[i].flags & SHF_ALLOC)
  148. {
  149. if (m_pSectionHeaders[i].type != SHT_NOBITS)
  150. {
  151. // Copy section data from the file.
  152. memcpy((uint8_t*)m_pSectionHeaders[i].addr,
  153. &m_pBuffer[m_pSectionHeaders[i].offset],
  154. m_pSectionHeaders[i].size);
  155. }
  156. else
  157. {
  158. memset((uint8_t*)m_pSectionHeaders[i].addr,
  159. 0,
  160. m_pSectionHeaders[i].size);
  161. }
  162. }
  163. }
  164. }
  165. unsigned int Elf32::getLastAddress()
  166. {
  167. }
  168. const char *Elf32::lookupSymbol(unsigned int addr, unsigned int *startAddr)
  169. {
  170. if (!m_pSymbolTable || !m_pStringTable)
  171. return (const char*)2; // Just return null if we haven't got a symbol table.
  172. Elf32Symbol_t *pSymbol = reinterpret_cast<Elf32Symbol_t *>(&m_pBuffer[m_pSymbolTable->offset]);
  173. const char *pStrtab = reinterpret_cast<const char *>(&m_pBuffer[m_pStringTable->offset]);
  174. for (size_t i = 0; i < m_pSymbolTable->size / sizeof(Elf32Symbol_t); i++)
  175. {
  176. // Make sure we're looking at an object or function.
  177. if (ELF32_ST_TYPE(pSymbol->info) != 0x2 /* function */ &&
  178. ELF32_ST_TYPE(pSymbol->info) != 0x0 /* notype (asm functions) */)
  179. {
  180. pSymbol++;
  181. continue;
  182. }
  183. // If we're checking for a symbol that is apparently zero-sized, add one so we can actually
  184. // count it!
  185. uint32_t size = pSymbol->size;
  186. if (size == 0)
  187. size = 1;
  188. if ( (addr >= pSymbol->value) &&
  189. (addr < (pSymbol->value + size)) )
  190. {
  191. const char *pStr = pStrtab + pSymbol->name;
  192. if (startAddr)
  193. *startAddr = pSymbol->value;
  194. return pStr;
  195. }
  196. pSymbol ++;
  197. }
  198. return (const char*)3;
  199. }
  200. uint32_t Elf32::lookupDynamicSymbolAddress(uint32_t off)
  201. {
  202. }
  203. char *Elf32::lookupDynamicSymbolName(uint32_t off)
  204. {
  205. }
  206. uint32_t Elf32::getGlobalOffsetTable()
  207. {
  208. }
  209. uint32_t Elf32::getEntryPoint()
  210. {
  211. return m_pHeader->entry;
  212. }