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