arm64: mcctrl: Fixed to search vdso_offset_sigtramp dynamically.
Change-Id: Iab5459194ca5281a1680a7fc26ae8bfaf1945a13 Refs: #1341
This commit is contained in:
committed by
Masamichi Takagi
parent
9b3450ee7e
commit
12aef0b578
@ -98,6 +98,74 @@ reserve_user_space(struct mcctrl_usrdata *usrdata, unsigned long *startp, unsign
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if KERNEL_VERSION(4, 0, 0) <= LINUX_VERSION_CODE
|
||||
static long elf_search_vdso_sigtramp(void)
|
||||
{
|
||||
int i = 0;
|
||||
long ans = -1;
|
||||
char *shstr = NULL, *dynstr = NULL;
|
||||
Elf64_Ehdr *eh = NULL;
|
||||
Elf64_Shdr *tmp_sh = NULL, *sym_sh = NULL;
|
||||
Elf64_Sym *sym = NULL;
|
||||
|
||||
/* ELF header */
|
||||
eh = (Elf64_Ehdr *)vdso_start;
|
||||
if (eh == NULL) {
|
||||
D("vdso_start is NULL.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* ELF magic check */
|
||||
if (eh->e_ident[EI_MAG0] != ELFMAG0 &&
|
||||
eh->e_ident[EI_MAG1] != ELFMAG1 &&
|
||||
eh->e_ident[EI_MAG2] != ELFMAG2 &&
|
||||
eh->e_ident[EI_MAG3] != ELFMAG3) {
|
||||
D("vdso_start ELF MAGIC Mismatch.\n"
|
||||
"e_ident[EI_MAG0 - EI_MAG3]: %02x %02x %02x %02x\n",
|
||||
eh->e_ident[EI_MAG0], eh->e_ident[EI_MAG1],
|
||||
eh->e_ident[EI_MAG2], eh->e_ident[EI_MAG3]);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Search dynsym-table and dynstr-table offset
|
||||
* from section header table
|
||||
*/
|
||||
tmp_sh = (Elf64_Shdr *)(vdso_start + eh->e_shoff);
|
||||
shstr = vdso_start + (tmp_sh + eh->e_shstrndx)->sh_offset;
|
||||
for (i = 0; i < eh->e_shnum; i++, tmp_sh++) {
|
||||
if (tmp_sh->sh_type == SHT_DYNSYM) {
|
||||
sym_sh = tmp_sh;
|
||||
}
|
||||
|
||||
if (tmp_sh->sh_type == SHT_STRTAB &&
|
||||
!strcmp(&shstr[tmp_sh->sh_name], ".dynstr")) {
|
||||
dynstr = vdso_start + tmp_sh->sh_offset;
|
||||
}
|
||||
}
|
||||
|
||||
if (sym_sh == NULL) {
|
||||
D("dynsym-table not found.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dynstr == 0) {
|
||||
D("dynstr-table not found.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Search __kernel_rt_sigreturn offset from dynsym-table */
|
||||
sym = (Elf64_Sym *)(vdso_start + sym_sh->sh_offset);
|
||||
for (i = 0; (i * sym_sh->sh_entsize) < sym_sh->sh_size; i++, sym++) {
|
||||
if (!strcmp(dynstr + sym->st_name, "__kernel_rt_sigreturn")) {
|
||||
ans = sym->st_value;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return ans;
|
||||
}
|
||||
#endif /*LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0)*/
|
||||
|
||||
void get_vdso_info(ihk_os_t os, long vdso_rpa)
|
||||
{
|
||||
ihk_device_t dev = ihk_os_to_dev(os);
|
||||
@ -131,7 +199,12 @@ void get_vdso_info(ihk_os_t os, long vdso_rpa)
|
||||
|
||||
/* offsets */
|
||||
vdso->lbase = VDSO_LBASE;
|
||||
vdso->offset_sigtramp = vdso_offset_sigtramp;
|
||||
vdso->offset_sigtramp = elf_search_vdso_sigtramp();
|
||||
|
||||
if (unlikely(vdso->offset_sigtramp == -1)) {
|
||||
D("Use vdso_offset_sigtramp in header-file.\n");
|
||||
vdso->offset_sigtramp = vdso_offset_sigtramp;
|
||||
}
|
||||
#endif /*LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0)*/
|
||||
out:
|
||||
wmb();
|
||||
|
||||
Reference in New Issue
Block a user