]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
.
authorJan Kratochvil <jan.kratochvil@redhat.com>
Wed, 24 Oct 2012 18:49:14 +0000 (20:49 +0200)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Wed, 24 Oct 2012 18:49:14 +0000 (20:49 +0200)
backends/i386_frame_state.c
backends/ppc_frame_state.c
backends/s390_frame_state.c
backends/x86_64_frame_state.c
libdwfl/dwfl_frame_state.c
libdwfl/libdwfl.h
libdwfl/libdwflP.h

index c97a1124e2daa235c36d79323200fdfb4e778339..b5d543997241fbd5f90b5e55fe6606a90ad19c06 100644 (file)
 bool
 i386_frame_state (Dwfl_Frame_State *state)
 {
-  if (state->thread->process->core == NULL)
+  pid_t tid = state->thread->tid;
+  if (state->thread->process->core == NULL && tid)
     {
 #if !defined __i386__ && !defined __x86_64__
       return false;
 #else /* __i386__ || __x86_64__ */
-      pid_t tid = state->thread->tid;
       struct user_regs_struct user_regs;
       if (ptrace (PTRACE_GETREGS, tid, NULL, &user_regs) != 0)
        return false;
index f9c70429ca72b6742eb4f87fb9be2cb7d74e74d2..0965e23784264b5505e9fb6c4bf55bc2212341d0 100644 (file)
@@ -72,12 +72,12 @@ ppc_frame_state (Dwfl_Frame_State *state)
   Dwfl_Frame_State_Process *process = thread->process;
   Ebl *ebl = process->ebl;
   Elf *core = process->core;
-  if (core == NULL)
+  pid_t tid = thread->tid;
+  if (core == NULL && tid)
     {
 #ifndef __powerpc__
       return false;
 #else /* __powerpc__ */
-      pid_t tid = thread->tid;
       union
        {
          struct pt_regs r;
@@ -107,7 +107,7 @@ ppc_frame_state (Dwfl_Frame_State *state)
         for CFI.  */
 #endif /* __powerpc__ */
     }
-  else /* core */
+  else if (core)
     {
       if (! core_get_pc (core, &state->pc,
                         ebl->class == ELFCLASS64 ? 0x170 : 0xc8))
index 0c1beeb430278e8acd5d02d61538859ee2d03a8b..ddb15aaabe015cbf11c10d03ef6c32db6b115e17 100644 (file)
@@ -49,12 +49,12 @@ s390_frame_state (Dwfl_Frame_State *state)
   Dwfl_Frame_State_Process *process = thread->process;
   Ebl *ebl = process->ebl;
   Elf *core = process->core;
-  if (core == NULL)
+  pid_t tid = thread->tid;
+  if (core == NULL && tid)
     {
 #ifndef __s390__
       return false;
 #else /* __s390__ */
-      pid_t tid = thread->tid;
       struct user user_regs;
       ptrace_area parea;
       parea.process_addr = (uintptr_t) &user_regs;
@@ -78,7 +78,7 @@ s390_frame_state (Dwfl_Frame_State *state)
       state->pc_state = DWFL_FRAME_STATE_PC_SET;
 #endif /* __s390__ */
     }
-  else /* core */
+  else if (core)
     {
       /* Fetch PSWA.  */
       if (! core_get_pc (core, &state->pc,
index f40fe9aa1e629a13566cd931389c15d8175f5ec7..b3042502d837c8d006ff61f638c7e9ed60f47478 100644 (file)
 bool
 x86_64_frame_state (Dwfl_Frame_State *state)
 {
-  if (state->thread->process->core == NULL)
+  pid_t tid = state->thread->tid;
+  if (state->thread->process->core == NULL && tid)
     {
 #ifndef __x86_64__
       return false;
 #else /* __x86_64__ */
-      pid_t tid = state->thread->tid;
       struct user_regs_struct user_regs;
       if (ptrace (PTRACE_GETREGS, tid, NULL, &user_regs) != 0)
        return false;
index 1eab65bf1392ab3213432b15231e2f92b21117b6..d5eae72f8066733ae8cd174e5b990f7c7f18afe1 100644 (file)
@@ -312,8 +312,6 @@ dwfl_frame_state_pid (Dwfl *dwfl, pid_t pid)
 }
 INTDEF (dwfl_frame_state_pid)
 
-/* Fetch inferior registers from a core file.  */
-
 Dwfl_Frame_State *
 dwfl_frame_state_core (Dwfl *dwfl, const char *corefile)
 {
@@ -521,6 +519,60 @@ dwfl_frame_state_core (Dwfl *dwfl, const char *corefile)
 }
 INTDEF (dwfl_frame_state_core)
 
+Dwfl_Frame_State *
+dwfl_frame_state_data (Dwfl *dwfl, int pc_set, Dwarf_Addr pc, unsigned nregs,
+                      const uint64_t *regs_set, const Dwarf_Addr *regs)
+{
+  Ebl *ebl = NULL;
+  for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next)
+    {
+      Dwfl_Error error = __libdwfl_module_getebl (mod);
+      if (error != DWFL_E_NOERROR)
+       continue;
+      ebl = mod->ebl;
+    }
+  if (ebl == NULL || nregs > ebl_frame_state_nregs (ebl))
+    {
+      __libdwfl_seterrno (DWFL_E_UNKNOWN_ERROR);
+      return NULL;
+    }
+  Dwfl_Frame_State_Process *process = process_alloc (dwfl);
+  if (process == NULL)
+    return NULL;
+  process->ebl = ebl;
+  Dwfl_Frame_State_Thread *thread = thread_alloc (process, 0);
+  if (thread == NULL)
+    {
+      process_free (process);
+      __libdwfl_seterrno (DWFL_E_UNKNOWN_ERROR);
+      return NULL;
+    }
+  Dwfl_Frame_State *state = thread->unwound;
+  state->pc_state = DWFL_FRAME_STATE_ERROR;
+  if (pc_set)
+    {
+      state->pc = pc;
+      state->pc_state = DWFL_FRAME_STATE_PC_SET;
+    }
+  for (unsigned regno = 0; regno < nregs; regno++)
+    if ((regs_set[regno / sizeof (*regs_set) / 8]
+        & (1U << (regno % (sizeof (*regs_set) * 8)))) != 0
+        && ! dwfl_frame_state_reg_set (state, regno, regs[regno]))
+      {
+       process_free (process);
+       __libdwfl_seterrno (DWFL_E_UNKNOWN_ERROR);
+       return NULL;
+      }
+  if (! ebl_frame_state (state) || ! state_fetch_pc (state))
+    {
+      process_free (process);
+      __libdwfl_seterrno (DWFL_E_UNKNOWN_ERROR);
+      return NULL;
+    }
+  return process->thread->unwound;
+}
+INTDEF (dwfl_frame_state_data)
+
 Dwfl_Frame_State *
 dwfl_frame_thread_next (Dwfl_Frame_State *state)
 {
index 169661f2b7e94030cd514772f181e2fe1f292c5f..943dfb70b40e9ef2ab89909877b9dd33f5981382 100644 (file)
@@ -571,6 +571,12 @@ extern Dwfl_Frame_State *dwfl_frame_state_pid (Dwfl *dwfl, pid_t pid);
 extern Dwfl_Frame_State *dwfl_frame_state_core (Dwfl *dwfl,
                                                const char *corefile);
 
+/* Fetch inferior registers from a caller supplied storage.  */
+extern Dwfl_Frame_State *dwfl_frame_state_data (Dwfl *dwfl, int pc_set,
+                                               Dwarf_Addr pc, unsigned nregs,
+                                               const uint64_t *regs_set,
+                                               const Dwarf_Addr *regs);
+
 /* Return TRUE and update *STATEP for the unwound frame for successful unwind.
    Return TRUE and set *STATEP to NULL for the outermost frame.  Return FALSE
    (and call __libdwfl_seterrno) otherwise.  */
index ef9110cf533f405c63a8ace047dc1f941ae0ebcb..194beb64999a62c7301bdbf735a8c3bace684fe5 100644 (file)
@@ -240,9 +240,9 @@ struct Dwfl_Frame_State
   /* Either initialized from appropriate REGS element or on some archs
      initialized separately as the return address has no DWARF register.  */
   Dwarf_Addr pc;
-  /* (1 << X) bitmask where 0 <= X < NREGS.  */
+  /* (1 << X) bitmask where 0 <= X < ebl_frame_state_nregs.  */
   uint64_t regs_set[3];
-  /* REGS array size is ebl_frame_state_nregs (base->ebl).  */
+  /* REGS array size is ebl_frame_state_nregs.  */
   Dwarf_Addr regs[];
 };