Files
rt-thread/components/lwp/arch/risc-v/common/reloc.c
bernard 721dfbfe01 [smart] Add vDSO support for RISC-V architecture and refactor related components
- Implemented vDSO functionality for the RISC-V architecture, including the necessary source files and linker scripts.
- Introduced a new `vdso_sys.c` file for RISC-V, containing functions to handle time retrieval using the vDSO mechanism.
- Created architecture-specific linker scripts (`vdso.lds.S`) for both AArch64 and RISC-V.
- Updated the build system to support vDSO compilation for RISC-V, including necessary adjustments in `SConstruct` files.
- Refactored existing vDSO code to improve compatibility and maintainability across architectures.
- Adjusted the maximum number of PTY devices in the terminal configuration from 64 to 32 for better resource management.
- Fixed minor issues in existing code, including correcting the path for the vDSO shared library and ensuring proper function definitions.
2025-05-19 18:29:26 +08:00

110 lines
2.8 KiB
C

#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