1 #include "mm_aspace.h"
2 #include <rtthread.h>
3 #include <stdint.h>
4 #include <string.h>
5 #include <elf.h>
6 #ifdef ARCH_MM_MMU
7 #include <mmu.h>
8 #include <page.h>
9 #endif
10
11 typedef struct
12 {
13 Elf64_Word st_name;
14 Elf64_Addr st_value;
15 Elf64_Word st_size;
16 unsigned char st_info;
17 unsigned char st_other;
18 Elf64_Half st_shndx;
19 } Elf64_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,Elf64_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, Elf64_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 addr = rt_hw_mmu_v2p(aspace, (void *)(((rt_size_t)rel_dyn_start) + rel_off));
36 memcpy(&v1, addr, 4);
37 addr = rt_hw_mmu_v2p(aspace, (void *)(((rt_size_t)rel_dyn_start) + rel_off + 4));
38 memcpy(&v2, addr, 4);
39
40 addr = rt_hw_mmu_v2p(aspace, (void *)((rt_size_t)text_start + v1));
41 if ((v2 & 0xff) == R_ARM_RELATIVE)
42 {
43 *(rt_size_t *)addr += (rt_size_t)text_start;
44 }
45 else if ((v2 & 0xff) == R_ARM_ABS32)
46 {
47 uint32_t t;
48 t = (v2 >> 8);
49 if (t) /* 0 is UDF */
50 {
51 *(rt_size_t *)addr = (((rt_size_t)text_start) + dynsym[t].st_value);
52 }
53 }
54 }
55 /* modify got */
56 if (got_size)
57 {
58 uint32_t *got_item = (uint32_t *)got_start;
59
60 for (rel_off = 0; rel_off < got_size; rel_off += 4, got_item++)
61 {
62 addr = rt_hw_mmu_v2p(aspace, got_item);
63 *(rt_size_t *)addr += (rt_size_t)text_start;
64 }
65 }
66 }
67 #else
68
arch_elf_reloc(void * text_start,void * rel_dyn_start,size_t rel_dyn_size,void * got_start,size_t got_size,Elf64_sym * dynsym)69 void arch_elf_reloc(void *text_start, void *rel_dyn_start, size_t rel_dyn_size, void *got_start, size_t got_size, Elf64_sym *dynsym)
70 {
71 size_t rel_off;
72
73 if (rel_dyn_size && !dynsym)
74 {
75 return;
76 }
77 for (rel_off = 0; rel_off < rel_dyn_size; rel_off += 8)
78 {
79 uint32_t v1, v2;
80
81 memcpy(&v1, ((rt_uint8_t *)rel_dyn_start) + rel_off, 4);
82 memcpy(&v2, ((rt_uint8_t *)rel_dyn_start) + rel_off + 4, 4);
83
84 if ((v2 & 0xff) == R_ARM_RELATIVE)
85 {
86 *(uint32_t *)(((rt_size_t)text_start) + v1) += (uint32_t)text_start;
87 }
88 else if ((v2 & 0xff) == R_ARM_ABS32)
89 {
90 uint32_t t;
91 t = (v2 >> 8);
92 if (t) /* 0 is UDF */
93 {
94 *(uint32_t *)(((rt_size_t)text_start) + v1) = (uint32_t)(((rt_size_t)text_start) + dynsym[t].st_value);
95 }
96 }
97 }
98 /* modify got */
99 if (got_size)
100 {
101 uint32_t *got_item = (uint32_t *)got_start;
102
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
110