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;
|
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)
|
void get_vdso_info(ihk_os_t os, long vdso_rpa)
|
||||||
{
|
{
|
||||||
ihk_device_t dev = ihk_os_to_dev(os);
|
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 */
|
/* offsets */
|
||||||
vdso->lbase = VDSO_LBASE;
|
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)*/
|
#endif /*LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0)*/
|
||||||
out:
|
out:
|
||||||
wmb();
|
wmb();
|
||||||
|
|||||||
Reference in New Issue
Block a user