changeset 8406:eed0eae93ee8

. Sync up with changes in the Linux versions.
author Greg Lewis <glewis@eyesbeyond.com>
date Sat, 18 Nov 2017 14:40:44 -0800
parents 498646acf462
children c156e56b2f1f
files agent/src/os/bsd/elfmacros.h agent/src/os/bsd/ps_core.c
diffstat 2 files changed, 24 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/os/bsd/elfmacros.h	Sat Nov 18 08:33:27 2017 -0800
+++ b/agent/src/os/bsd/elfmacros.h	Sat Nov 18 14:40:44 2017 -0800
@@ -34,6 +34,7 @@
 #define ELF_SYM         Elf64_Sym
 #define ELF_DYN         Elf64_Dyn
 #define ELF_ADDR        Elf64_Addr
+#define ELF_AUXV        Elf64_Auxinfo
 
 #ifndef ELF_ST_TYPE
 #define ELF_ST_TYPE     ELF64_ST_TYPE
@@ -47,6 +48,7 @@
 #define ELF_SYM         Elf32_Sym
 #define ELF_DYN         Elf32_Dyn
 #define ELF_ADDR        Elf32_Addr
+#define ELF_AUXV        Elf32_Auxinfo
 
 #ifndef ELF_ST_TYPE
 #define ELF_ST_TYPE     ELF32_ST_TYPE
--- a/agent/src/os/bsd/ps_core.c	Sat Nov 18 08:33:27 2017 -0800
+++ b/agent/src/os/bsd/ps_core.c	Sat Nov 18 14:40:44 2017 -0800
@@ -1091,6 +1091,18 @@
         if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true) {
           return false;
         }
+      } else if (notep->n_type == NT_PROCSTAT_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);
    }
@@ -1272,7 +1284,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;
          }
@@ -1472,8 +1490,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;
   }