123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- #include "mm_aspace.h"
- #include <rtthread.h>
- #include <stdint.h>
- #include <string.h>
- #include <elf.h>
- #ifdef ARCH_MM_MMU
- #include <mmu.h>
- #include <page.h>
- #endif
- typedef struct
- {
- Elf64_Word st_name;
- Elf64_Addr st_value;
- Elf64_Word st_size;
- unsigned char st_info;
- unsigned char st_other;
- Elf64_Half st_shndx;
- } Elf64_sym;
- #ifdef ARCH_MM_MMU
- 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)
- {
- size_t rel_off;
- void* addr;
- if (rel_dyn_size && !dynsym)
- {
- return;
- }
- for (rel_off = 0; rel_off < rel_dyn_size; rel_off += 8)
- {
- uint32_t v1, v2;
- addr = rt_hw_mmu_v2p(aspace, (void *)(((rt_size_t)rel_dyn_start) + rel_off));
- memcpy(&v1, addr, 4);
- addr = rt_hw_mmu_v2p(aspace, (void *)(((rt_size_t)rel_dyn_start) + rel_off + 4));
- memcpy(&v2, addr, 4);
- addr = rt_hw_mmu_v2p(aspace, (void *)((rt_size_t)text_start + v1));
- if ((v2 & 0xff) == R_ARM_RELATIVE)
- {
- *(rt_size_t*)addr += (rt_size_t)text_start;
- }
- else if ((v2 & 0xff) == R_ARM_ABS32)
- {
- uint32_t t;
- t = (v2 >> 8);
- if (t) /* 0 is UDF */
- {
- *(rt_size_t*)addr = (((rt_size_t)text_start) + dynsym[t].st_value);
- }
- }
- }
- /* modify got */
- if (got_size)
- {
- uint32_t *got_item = (uint32_t*)got_start;
- for (rel_off = 0; rel_off < got_size; rel_off += 4, got_item++)
- {
- addr = rt_hw_mmu_v2p(aspace, got_item);
- *(rt_size_t *)addr += (rt_size_t)text_start;
- }
- }
- }
- #else
- 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)
- {
- size_t rel_off;
- if (rel_dyn_size && !dynsym)
- {
- return;
- }
- for (rel_off = 0; rel_off < rel_dyn_size; rel_off += 8)
- {
- uint32_t v1, v2;
- memcpy(&v1, ((rt_uint8_t *)rel_dyn_start) + rel_off, 4);
- memcpy(&v2, ((rt_uint8_t *)rel_dyn_start) + rel_off + 4, 4);
- if ((v2 & 0xff) == R_ARM_RELATIVE)
- {
- *(uint32_t*)(((rt_size_t)text_start) + v1) += (uint32_t)text_start;
- }
- else if ((v2 & 0xff) == R_ARM_ABS32)
- {
- uint32_t t;
- t = (v2 >> 8);
- if (t) /* 0 is UDF */
- {
- *(uint32_t*)(((rt_size_t)text_start) + v1) = (uint32_t)(((rt_size_t)text_start) + dynsym[t].st_value);
- }
- }
- }
- /* modify got */
- if (got_size)
- {
- uint32_t *got_item = (uint32_t*)got_start;
- for (rel_off = 0; rel_off < got_size; rel_off += 4, got_item++)
- {
- *got_item += (uint32_t)text_start;
- }
- }
- }
- #endif
|