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