reloc.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include "mm_aspace.h"
  2. #include <rtthread.h>
  3. #include <stdint.h>
  4. #include <string.h>
  5. #include <lwp_elf.h>
  6. #ifdef ARCH_MM_MMU
  7. #include <mmu.h>
  8. #include <page.h>
  9. #endif
  10. typedef struct
  11. {
  12. Elf32_Word st_name;
  13. Elf32_Addr st_value;
  14. Elf32_Word st_size;
  15. unsigned char st_info;
  16. unsigned char st_other;
  17. Elf32_Half st_shndx;
  18. } Elf32_sym;
  19. #ifdef ARCH_MM_MMU
  20. void arch_elf_reloc(rt_aspace_t aspace, void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, Elf32_sym *dynsym)
  21. {
  22. size_t rel_off;
  23. void* addr;
  24. if (rel_dyn_size && !dynsym)
  25. {
  26. return;
  27. }
  28. for (rel_off = 0; rel_off < rel_dyn_size; rel_off += 8)
  29. {
  30. uint32_t v1, v2;
  31. /*
  32. memcpy(&v1, rel_dyn_start + rel_off, 4);
  33. memcpy(&v2, rel_dyn_start + rel_off + 4, 4);
  34. */
  35. addr = rt_hw_mmu_v2p(aspace, (void*)((char*)rel_dyn_start + rel_off));
  36. addr = (void*)((char*)addr - PV_OFFSET);
  37. memcpy(&v1, addr, 4);
  38. addr = rt_hw_mmu_v2p(aspace, (void*)((char*)rel_dyn_start + rel_off + 4));
  39. addr = (void*)((char*)addr - PV_OFFSET);
  40. memcpy(&v2, addr, 4);
  41. addr = rt_hw_mmu_v2p(aspace, (void*)((char*)text_start + v1));
  42. addr = (void*)((char*)addr - PV_OFFSET);
  43. if ((v2 & 0xff) == R_ARM_RELATIVE)
  44. {
  45. // *(uint32_t*)(text_start + v1) += (uint32_t)text_start;
  46. *(uint32_t*)addr += (uint32_t)text_start;
  47. }
  48. else if ((v2 & 0xff) == R_ARM_ABS32)
  49. {
  50. uint32_t t;
  51. t = (v2 >> 8);
  52. if (t) /* 0 is UDF */
  53. {
  54. // *(uint32_t*)(text_start + v1) = (uint32_t)(text_start + dynsym[t].st_value);
  55. *(uint32_t*)addr = (uint32_t)((char*)text_start + dynsym[t].st_value);
  56. }
  57. }
  58. }
  59. /* modify got */
  60. if (got_size)
  61. {
  62. uint32_t *got_item = (uint32_t*)got_start;
  63. for (rel_off = 0; rel_off < got_size; rel_off += 4, got_item++)
  64. {
  65. //*got_item += (uint32_t)text_start;
  66. addr = rt_hw_mmu_v2p(aspace, got_item);
  67. addr = (void*)((char*)addr - PV_OFFSET);
  68. *(uint32_t *)addr += (uint32_t)text_start;
  69. }
  70. }
  71. }
  72. #else
  73. void arch_elf_reloc(void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, Elf32_sym *dynsym)
  74. {
  75. size_t rel_off;
  76. if (rel_dyn_size && !dynsym)
  77. {
  78. return;
  79. }
  80. for (rel_off = 0; rel_off < rel_dyn_size; rel_off += 8)
  81. {
  82. uint32_t v1, v2;
  83. memcpy(&v1, (void*)((char*)rel_dyn_start + rel_off), 4);
  84. memcpy(&v2, (void*)((char*)rel_dyn_start + rel_off + 4), 4);
  85. if ((v2 & 0xff) == R_ARM_RELATIVE)
  86. {
  87. *(uint32_t*)((char*)text_start + v1) += (uint32_t)text_start;
  88. }
  89. else if ((v2 & 0xff) == R_ARM_ABS32)
  90. {
  91. uint32_t t;
  92. t = (v2 >> 8);
  93. if (t) /* 0 is UDF */
  94. {
  95. *(uint32_t*)((char*)text_start + v1) = (uint32_t)((char*)text_start + dynsym[t].st_value);
  96. }
  97. }
  98. }
  99. /* modify got */
  100. if (got_size)
  101. {
  102. uint32_t *got_item = (uint32_t*)got_start;
  103. for (rel_off = 0; rel_off < got_size; rel_off += 4, got_item++)
  104. {
  105. *got_item += (uint32_t)text_start;
  106. }
  107. }
  108. }
  109. #endif