8173941: SA does not work if executable is DSO

Tue, 14 Feb 2017 20:51:31 -0500

author
ysuenaga
date
Tue, 14 Feb 2017 20:51:31 -0500
changeset 8719
f89cf87d867d
parent 8717
77d9c9da7188
child 8720
6bed084fd02f

8173941: SA does not work if executable is DSO
Reviewed-by: aph, dsamersoff

agent/src/os/linux/elfmacros.h file | annotate | diff | comparison | revisions
agent/src/os/linux/ps_core.c file | annotate | diff | comparison | revisions
     1.1 --- a/agent/src/os/linux/elfmacros.h	Mon Feb 06 23:36:58 2017 +0300
     1.2 +++ b/agent/src/os/linux/elfmacros.h	Tue Feb 14 20:51:31 2017 -0500
     1.3 @@ -33,6 +33,7 @@
     1.4  #define ELF_NHDR        Elf64_Nhdr
     1.5  #define ELF_DYN         Elf64_Dyn
     1.6  #define ELF_ADDR        Elf64_Addr
     1.7 +#define ELF_AUXV        Elf64_auxv_t
     1.8  
     1.9  #define ELF_ST_TYPE     ELF64_ST_TYPE
    1.10  
    1.11 @@ -45,6 +46,7 @@
    1.12  #define ELF_NHDR        Elf32_Nhdr
    1.13  #define ELF_DYN         Elf32_Dyn
    1.14  #define ELF_ADDR        Elf32_Addr
    1.15 +#define ELF_AUXV        Elf32_auxv_t
    1.16  
    1.17  #define ELF_ST_TYPE     ELF32_ST_TYPE
    1.18  
     2.1 --- a/agent/src/os/linux/ps_core.c	Mon Feb 06 23:36:58 2017 +0300
     2.2 +++ b/agent/src/os/linux/ps_core.c	Tue Feb 14 20:51:31 2017 -0500
     2.3 @@ -642,6 +642,18 @@
     2.4          if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true) {
     2.5            return false;
     2.6          }
     2.7 +      } else if (notep->n_type == NT_AUXV) {
     2.8 +        // Get first segment from entry point
     2.9 +        ELF_AUXV *auxv = (ELF_AUXV *)descdata;
    2.10 +        while (auxv->a_type != AT_NULL) {
    2.11 +          if (auxv->a_type == AT_ENTRY) {
    2.12 +            // Set entry point address to address of dynamic section.
    2.13 +            // We will adjust it in read_exec_segments().
    2.14 +            ph->core->dynamic_addr = auxv->a_un.a_val;
    2.15 +            break;
    2.16 +          }
    2.17 +          auxv++;
    2.18 +        }
    2.19        }
    2.20        p = descdata + ROUNDUP(notep->n_descsz, 4);
    2.21     }
    2.22 @@ -826,7 +838,13 @@
    2.23  
    2.24           // from PT_DYNAMIC we want to read address of first link_map addr
    2.25           case PT_DYNAMIC: {
    2.26 -            ph->core->dynamic_addr = exec_php->p_vaddr;
    2.27 +            if (exec_ehdr->e_type == ET_EXEC) {
    2.28 +                ph->core->dynamic_addr = exec_php->p_vaddr;
    2.29 +            } else { // ET_DYN
    2.30 +                // dynamic_addr has entry point of executable.
    2.31 +                // Thus we should substract it.
    2.32 +                ph->core->dynamic_addr += exec_php->p_vaddr - exec_ehdr->e_entry;
    2.33 +            }
    2.34              print_debug("address of _DYNAMIC is 0x%lx\n", ph->core->dynamic_addr);
    2.35              break;
    2.36           }
    2.37 @@ -1024,8 +1042,9 @@
    2.38      goto err;
    2.39    }
    2.40  
    2.41 -  if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
    2.42 -    print_debug("executable file is not a valid ELF ET_EXEC file\n");
    2.43 +  if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true ||
    2.44 +      ((exec_ehdr.e_type != ET_EXEC) && (exec_ehdr.e_type != ET_DYN))) {
    2.45 +    print_debug("executable file is not a valid ELF file\n");
    2.46      goto err;
    2.47    }
    2.48  

mercurial