# HG changeset patch # User ysuenaga # Date 1493171141 -3600 # Node ID ac0bfb91f920b7aa076a766cd92d7ed64f3c17db # Parent 0c96934993832078c71646ef2f703d62ee74c546 8173941, PR3330: SA does not work if executable is DSO Reviewed-by: aph, dsamersoff diff -r 0c9693499383 -r ac0bfb91f920 agent/src/os/linux/elfmacros.h --- a/agent/src/os/linux/elfmacros.h Thu Jun 23 17:58:59 2016 +0000 +++ b/agent/src/os/linux/elfmacros.h Wed Apr 26 02:45:41 2017 +0100 @@ -33,6 +33,7 @@ #define ELF_NHDR Elf64_Nhdr #define ELF_DYN Elf64_Dyn #define ELF_ADDR Elf64_Addr +#define ELF_AUXV Elf64_auxv_t #define ELF_ST_TYPE ELF64_ST_TYPE @@ -45,6 +46,7 @@ #define ELF_NHDR Elf32_Nhdr #define ELF_DYN Elf32_Dyn #define ELF_ADDR Elf32_Addr +#define ELF_AUXV Elf32_auxv_t #define ELF_ST_TYPE ELF32_ST_TYPE diff -r 0c9693499383 -r ac0bfb91f920 agent/src/os/linux/ps_core.c --- a/agent/src/os/linux/ps_core.c Thu Jun 23 17:58:59 2016 +0000 +++ b/agent/src/os/linux/ps_core.c Wed Apr 26 02:45:41 2017 +0100 @@ -629,6 +629,18 @@ if (notep->n_type == NT_PRSTATUS) { if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true) return false; + } else if (notep->n_type == NT_AUXV) { + // Get first segment from entry point + ELF_AUXV *auxv = (ELF_AUXV *)descdata; + while (auxv->a_type != AT_NULL) { + if (auxv->a_type == AT_ENTRY) { + // Set entry point address to address of dynamic section. + // We will adjust it in read_exec_segments(). + ph->core->dynamic_addr = auxv->a_un.a_val; + break; + } + auxv++; + } } p = descdata + ROUNDUP(notep->n_descsz, 4); } @@ -811,7 +823,13 @@ // from PT_DYNAMIC we want to read address of first link_map addr case PT_DYNAMIC: { - ph->core->dynamic_addr = exec_php->p_vaddr; + if (exec_ehdr->e_type == ET_EXEC) { + ph->core->dynamic_addr = exec_php->p_vaddr; + } else { // ET_DYN + // dynamic_addr has entry point of executable. + // Thus we should substract it. + ph->core->dynamic_addr += exec_php->p_vaddr - exec_ehdr->e_entry; + } print_debug("address of _DYNAMIC is 0x%lx\n", ph->core->dynamic_addr); break; } @@ -1007,8 +1025,9 @@ goto err; } - if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) { - print_debug("executable file is not a valid ELF ET_EXEC file\n"); + if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || + ((exec_ehdr.e_type != ET_EXEC) && (exec_ehdr.e_type != ET_DYN))) { + print_debug("executable file is not a valid ELF file\n"); goto err; }