Changeset View
Changeset View
Standalone View
Standalone View
head/lib/libc/gen/elf_utils.c
Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
__elf_phdr_match_addr(struct dl_phdr_info *phdr_info, void *addr) | __elf_phdr_match_addr(struct dl_phdr_info *phdr_info, void *addr) | ||||
{ | { | ||||
const Elf_Phdr *ph; | const Elf_Phdr *ph; | ||||
int i; | int i; | ||||
for (i = 0; i < phdr_info->dlpi_phnum; i++) { | for (i = 0; i < phdr_info->dlpi_phnum; i++) { | ||||
ph = &phdr_info->dlpi_phdr[i]; | ph = &phdr_info->dlpi_phdr[i]; | ||||
if (ph->p_type != PT_LOAD || (ph->p_flags & PF_X) == 0) | if (ph->p_type != PT_LOAD) | ||||
continue; | continue; | ||||
/* ELFv1 ABI for powerpc64 passes function descriptor | |||||
* pointers around, not function pointers. The function | |||||
* descriptors live in .opd, which is a non-executable segment. | |||||
* The PF_X check would therefore make all address checks fail, | |||||
* causing a crash in some instances. Don't skip over | |||||
* non-executable segments in the ELFv1 powerpc64 case. | |||||
*/ | |||||
#if !defined(__powerpc64__) || (defined(_CALL_ELF) && _CALL_ELF == 2) | |||||
if ((ph->p_flags & PF_X) == 0) | |||||
continue; | |||||
#endif | |||||
if (phdr_info->dlpi_addr + ph->p_vaddr <= (uintptr_t)addr && | if (phdr_info->dlpi_addr + ph->p_vaddr <= (uintptr_t)addr && | ||||
(uintptr_t)addr + sizeof(addr) < phdr_info->dlpi_addr + | (uintptr_t)addr + sizeof(addr) < phdr_info->dlpi_addr + | ||||
ph->p_vaddr + ph->p_memsz) | ph->p_vaddr + ph->p_memsz) | ||||
break; | break; | ||||
} | } | ||||
return (i != phdr_info->dlpi_phnum); | return (i != phdr_info->dlpi_phnum); | ||||
} | } | ||||
Show All 27 Lines |