]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
.
authorJan Kratochvil <jan.kratochvil@redhat.com>
Mon, 15 Oct 2012 14:03:07 +0000 (16:03 +0200)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Mon, 15 Oct 2012 14:03:07 +0000 (16:03 +0200)
22 files changed:
backends/i386_frame_state.c
backends/ppc_frame_state.c
backends/s390_frame_state.c
backends/s390_frame_unwind.c
backends/s390_init.c
backends/x86_64_frame_state.c
libasm/libasm.h
libdw/cfi.h
libdw/libdw.h
libdwfl/dwfl_end.c
libdwfl/dwfl_frame_state.c
libdwfl/dwfl_frame_state_pc.c
libdwfl/dwfl_frame_unwind.c
libdwfl/libdwfl.h
libdwfl/libdwflP.h
libebl/Makefile.am
libebl/ebl-hooks.h
libebl/eblframestate.c
libebl/eblframeunwind.c
libebl/libebl.h
src/stack.c
tests/backtrace.c

index 0bf1f0e7a88e11455e8d701a8a470b30b9ea7056..c97a1124e2daa235c36d79323200fdfb4e778339 100644 (file)
 # include <sys/user.h>
 # include <sys/ptrace.h>
 #endif
-#include "../libdw/cfi.h"
+#include "libdwflP.h"
 
 #define BACKEND i386_
 #include "libebl_CPU.h"
 
 bool
-i386_frame_state (Dwarf_Frame_State *state)
+i386_frame_state (Dwfl_Frame_State *state)
 {
   if (state->thread->process->core == NULL)
     {
@@ -52,25 +52,25 @@ i386_frame_state (Dwarf_Frame_State *state)
       if (ptrace (PTRACE_GETREGS, tid, NULL, &user_regs) != 0)
        return false;
 # if defined __i386__
-      dwarf_frame_state_reg_set (state, 0, user_regs.eax);
-      dwarf_frame_state_reg_set (state, 1, user_regs.ecx);
-      dwarf_frame_state_reg_set (state, 2, user_regs.edx);
-      dwarf_frame_state_reg_set (state, 3, user_regs.ebx);
-      dwarf_frame_state_reg_set (state, 4, user_regs.esp);
-      dwarf_frame_state_reg_set (state, 5, user_regs.ebp);
-      dwarf_frame_state_reg_set (state, 6, user_regs.esi);
-      dwarf_frame_state_reg_set (state, 7, user_regs.edi);
-      dwarf_frame_state_reg_set (state, 8, user_regs.eip);
+      dwfl_frame_state_reg_set (state, 0, user_regs.eax);
+      dwfl_frame_state_reg_set (state, 1, user_regs.ecx);
+      dwfl_frame_state_reg_set (state, 2, user_regs.edx);
+      dwfl_frame_state_reg_set (state, 3, user_regs.ebx);
+      dwfl_frame_state_reg_set (state, 4, user_regs.esp);
+      dwfl_frame_state_reg_set (state, 5, user_regs.ebp);
+      dwfl_frame_state_reg_set (state, 6, user_regs.esi);
+      dwfl_frame_state_reg_set (state, 7, user_regs.edi);
+      dwfl_frame_state_reg_set (state, 8, user_regs.eip);
 # elif defined __x86_64__
-      dwarf_frame_state_reg_set (state, 0, user_regs.rax);
-      dwarf_frame_state_reg_set (state, 1, user_regs.rcx);
-      dwarf_frame_state_reg_set (state, 2, user_regs.rdx);
-      dwarf_frame_state_reg_set (state, 3, user_regs.rbx);
-      dwarf_frame_state_reg_set (state, 4, user_regs.rsp);
-      dwarf_frame_state_reg_set (state, 5, user_regs.rbp);
-      dwarf_frame_state_reg_set (state, 6, user_regs.rsi);
-      dwarf_frame_state_reg_set (state, 7, user_regs.rdi);
-      dwarf_frame_state_reg_set (state, 8, user_regs.rip);
+      dwfl_frame_state_reg_set (state, 0, user_regs.rax);
+      dwfl_frame_state_reg_set (state, 1, user_regs.rcx);
+      dwfl_frame_state_reg_set (state, 2, user_regs.rdx);
+      dwfl_frame_state_reg_set (state, 3, user_regs.rbx);
+      dwfl_frame_state_reg_set (state, 4, user_regs.rsp);
+      dwfl_frame_state_reg_set (state, 5, user_regs.rbp);
+      dwfl_frame_state_reg_set (state, 6, user_regs.rsi);
+      dwfl_frame_state_reg_set (state, 7, user_regs.rdi);
+      dwfl_frame_state_reg_set (state, 8, user_regs.rip);
 # else /* (__i386__ || __x86_64__) && (!__i386__ && !__x86_64__) */
 #  error
 # endif /* (__i386__ || __x86_64__) && (!__i386__ && !__x86_64__) */
index 4ad63cc8cd8db1550329bc5dbe5dad1178dd5388..f9c70429ca72b6742eb4f87fb9be2cb7d74e74d2 100644 (file)
@@ -1,4 +1,4 @@
-/* Fetch live process Dwarf_Frame_State from PID.
+/* Fetch live process Dwfl_Frame_State from PID.
    Copyright (C) 2012 Red Hat, Inc.
    This file is part of elfutils.
 
@@ -34,7 +34,7 @@
 # include <sys/user.h>
 # include <sys/ptrace.h>
 #endif
-#include "../libdw/cfi.h"
+#include "libdwflP.h"
 
 #define BACKEND ppc_
 #include "libebl_CPU.h"
@@ -66,10 +66,10 @@ __typeof (ppc_frame_dwarf_to_regno)
      __attribute__ ((alias ("ppc_frame_dwarf_to_regno")));
 
 bool
-ppc_frame_state (Dwarf_Frame_State *state)
+ppc_frame_state (Dwfl_Frame_State *state)
 {
-  Dwarf_Frame_State_Thread *thread = state->thread;
-  Dwarf_Frame_State_Process *process = thread->process;
+  Dwfl_Frame_State_Thread *thread = state->thread;
+  Dwfl_Frame_State_Process *process = thread->process;
   Ebl *ebl = process->ebl;
   Elf *core = process->core;
   if (core == NULL)
@@ -99,10 +99,10 @@ ppc_frame_state (Dwarf_Frame_State *state)
        }
       for (unsigned gpr = 0;
           gpr < sizeof (user_regs.r.gpr) / sizeof (*user_regs.r.gpr); gpr++)
-       dwarf_frame_state_reg_set (state, gpr, user_regs.r.gpr[gpr]);
+       dwfl_frame_state_reg_set (state, gpr, user_regs.r.gpr[gpr]);
       state->pc = user_regs.r.nip;
-      state->pc_state = DWARF_FRAME_STATE_PC_SET;
-      dwarf_frame_state_reg_set (state, 65, user_regs.r.link); // or 108
+      state->pc_state = DWFL_FRAME_STATE_PC_SET;
+      dwfl_frame_state_reg_set (state, 65, user_regs.r.link); // or 108
       /* Registers like msr, ctr, xer, dar, dsisr etc. are probably irrelevant
         for CFI.  */
 #endif /* __powerpc__ */
@@ -112,7 +112,7 @@ ppc_frame_state (Dwarf_Frame_State *state)
       if (! core_get_pc (core, &state->pc,
                         ebl->class == ELFCLASS64 ? 0x170 : 0xc8))
        return false;
-      state->pc_state = DWARF_FRAME_STATE_PC_SET;
+      state->pc_state = DWFL_FRAME_STATE_PC_SET;
     }
   return true;
 }
index 1f4917d6345773dfb226fe133917ab32376f4f21..0c1beeb430278e8acd5d02d61538859ee2d03a8b 100644 (file)
@@ -1,4 +1,4 @@
-/* Fetch live process Dwarf_Frame_State from PID.
+/* Fetch live process Dwfl_Frame_State from PID.
    Copyright (C) 2012 Red Hat, Inc.
    This file is part of elfutils.
 
@@ -35,7 +35,7 @@
 # include <asm/ptrace.h>
 # include <sys/ptrace.h>
 #endif
-#include "../libdw/cfi.h"
+#include "libdwflP.h"
 
 #define BACKEND s390_
 #include "libebl_CPU.h"
 #include "core-get-pc.c"
 
 bool
-s390_frame_state (Dwarf_Frame_State *state)
+s390_frame_state (Dwfl_Frame_State *state)
 {
-  Dwarf_Frame_State_Thread *thread = state->thread;
-  Dwarf_Frame_State_Process *process = thread->process;
+  Dwfl_Frame_State_Thread *thread = state->thread;
+  Dwfl_Frame_State_Process *process = thread->process;
   Ebl *ebl = process->ebl;
   Elf *core = process->core;
   if (core == NULL)
@@ -75,7 +75,7 @@ s390_frame_state (Dwarf_Frame_State *state)
                                   *((const __typeof (*state->regs) *)
                                     &user_regs.regs.fp_regs.fprs[u]));
       state->pc = user_regs.regs.psw.addr;
-      state->pc_state = DWARF_FRAME_STATE_PC_SET;
+      state->pc_state = DWFL_FRAME_STATE_PC_SET;
 #endif /* __s390__ */
     }
   else /* core */
@@ -84,7 +84,7 @@ s390_frame_state (Dwarf_Frame_State *state)
       if (! core_get_pc (core, &state->pc,
                         ebl->class == ELFCLASS32 ? 0x4c : 0x78))
        return false;
-      state->pc_state = DWARF_FRAME_STATE_PC_SET;
+      state->pc_state = DWFL_FRAME_STATE_PC_SET;
     }
   return true;
 }
@@ -92,8 +92,8 @@ s390_frame_state (Dwarf_Frame_State *state)
 void
 s390_normalize_pc (Ebl *ebl __attribute__ ((unused)), Dwarf_Addr *pc)
 {
-  if (ebl->class != ELFCLASS32)
-    return;
+  assert (ebl->class == ELFCLASS32);
+
   /* Clear S390 bit 31.  */
   *pc &= (1U << 31) - 1;
 }
index 41eae49b70960c6db3d79c61292668a0b7b17938..f285d68462586727702750fba179f572d2b7d808 100644 (file)
 #endif
 
 #include <stdlib.h>
-#include "../libdwfl/libdwfl.h"
 #include <assert.h>
-#include "../libdw/cfi.h"
+#include "libdwflP.h"
 
 #define BACKEND s390_
 #include "libebl_CPU.h"
 
 bool
-s390_frame_unwind (Ebl *ebl, Dwarf_Frame_State **statep, Dwarf_Addr pc,
-                  bool (*memory_read) (Dwarf_Frame_State_Process *process,
+s390_frame_unwind (Ebl *ebl, Dwfl_Frame_State **statep, Dwarf_Addr pc,
+                  bool (*memory_read) (Dwfl_Frame_State_Process *process,
                                        Dwarf_Addr addr, Dwarf_Addr *result))
 {
-  Dwarf_Frame_State *state = *statep;
-  Dwarf_Frame_State_Process *process = state->thread->process;
+  Dwfl_Frame_State *state = *statep;
+  Dwfl_Frame_State_Process *process = state->thread->process;
   assert (state->unwound == NULL);
   /* Caller already assumed caller adjustment but S390 instructions are 4 bytes
      long.  Undo it.  */
@@ -67,7 +66,7 @@ s390_frame_unwind (Ebl *ebl, Dwarf_Frame_State **statep, Dwarf_Addr pc,
   /* See GDB s390_sigtramp_frame_unwind_cache.  */
 # define S390_SP_REGNUM (0 + 15) /* S390_R15_REGNUM */
   Dwarf_Addr this_sp;
-  if (! dwarf_frame_state_reg_get (state, S390_SP_REGNUM, &this_sp))
+  if (! dwfl_frame_state_reg_get (state, S390_SP_REGNUM, &this_sp))
     return false;
   unsigned word_size = ebl->class == ELFCLASS64 ? 8 : 4;
   Dwarf_Addr next_cfa = this_sp + 16 * word_size + 32;
@@ -84,13 +83,13 @@ s390_frame_unwind (Ebl *ebl, Dwarf_Frame_State **statep, Dwarf_Addr pc,
     return false;
   sigreg_ptr += word_size;
   size_t nregs = ebl->frame_state_nregs;
-  Dwarf_Frame_State *unwound;
+  Dwfl_Frame_State *unwound;
   unwound = malloc (sizeof (*unwound) + sizeof (*unwound->regs) * nregs);
   state->unwound = unwound;
   unwound->thread = state->thread;
   unwound->unwound = NULL;
   unwound->pc = val;
-  unwound->pc_state = DWARF_FRAME_STATE_ERROR;
+  unwound->pc_state = DWFL_FRAME_STATE_ERROR;
   memset (unwound->regs_set, 0, sizeof (unwound->regs_set));
   unwound->signal_frame = true;
   /* Then the GPRs.  */
@@ -98,7 +97,7 @@ s390_frame_unwind (Ebl *ebl, Dwarf_Frame_State **statep, Dwarf_Addr pc,
     {
       if (! memory_read (process, sigreg_ptr, &val))
        return false;
-      if (! dwarf_frame_state_reg_set (unwound, 0 + i, val))
+      if (! dwfl_frame_state_reg_set (unwound, 0 + i, val))
        return false;
       sigreg_ptr += word_size;
     }
@@ -119,7 +118,7 @@ s390_frame_unwind (Ebl *ebl, Dwarf_Frame_State **statep, Dwarf_Addr pc,
            return false;
          val = (val << 32) | val_low;
        }
-      if (! dwarf_frame_state_reg_set (unwound, 16 + i, val))
+      if (! dwfl_frame_state_reg_set (unwound, 16 + i, val))
        return false;
       sigreg_ptr += 8;
     }
@@ -133,15 +132,15 @@ s390_frame_unwind (Ebl *ebl, Dwarf_Frame_State **statep, Dwarf_Addr pc,
          if (! memory_read (process, sigreg_ptr, &val))
            return false;
          Dwarf_Addr val_low;
-         if (! dwarf_frame_state_reg_get (unwound, 0 + i, &val_low))
+         if (! dwfl_frame_state_reg_get (unwound, 0 + i, &val_low))
            return false;
          val = (val << 32) | val_low;
-         if (! dwarf_frame_state_reg_set (unwound, 0 + i, val))
+         if (! dwfl_frame_state_reg_set (unwound, 0 + i, val))
            return false;
          sigreg_ptr += 4;
        }
     }
-  unwound->pc_state = DWARF_FRAME_STATE_PC_SET;
+  unwound->pc_state = DWFL_FRAME_STATE_PC_SET;
   *statep = unwound;
   return true;
 }
index 5c9c092b25851992c4a9d4eaa3dd9d09e6eed3af..9770cf7a6d00789384d2cbb92c388cb122d11623 100644 (file)
@@ -68,7 +68,8 @@ s390_init (elf, machine, eh, ehlen)
      unwinding.  */
   eh->frame_state_nregs = 32;
   HOOK (eh, frame_state);
-  HOOK (eh, normalize_pc);
+  if (eh->class == ELFCLASS32)
+    HOOK (eh, normalize_pc);
   HOOK (eh, frame_unwind);
 
   /* Only the 64-bit format uses the incorrect hash table entry size.  */
index c828af407f90a2c6cde077bad7a6228f78f267eb..f40fe9aa1e629a13566cd931389c15d8175f5ec7 100644 (file)
@@ -1,4 +1,4 @@
-/* Fetch live process Dwarf_Frame_State from PID.
+/* Fetch live process Dwfl_Frame_State from PID.
    Copyright (C) 2012 Red Hat, Inc.
    This file is part of elfutils.
 
 # include <sys/user.h>
 # include <sys/ptrace.h>
 #endif
-#include "../libdw/cfi.h"
+#include "libdwflP.h"
 
 #define BACKEND x86_64_
 #include "libebl_CPU.h"
 
 bool
-x86_64_frame_state (Dwarf_Frame_State *state)
+x86_64_frame_state (Dwfl_Frame_State *state)
 {
   if (state->thread->process->core == NULL)
     {
@@ -52,23 +52,23 @@ x86_64_frame_state (Dwarf_Frame_State *state)
       struct user_regs_struct user_regs;
       if (ptrace (PTRACE_GETREGS, tid, NULL, &user_regs) != 0)
        return false;
-      dwarf_frame_state_reg_set (state, 0, user_regs.rax);
-      dwarf_frame_state_reg_set (state, 1, user_regs.rdx);
-      dwarf_frame_state_reg_set (state, 2, user_regs.rcx);
-      dwarf_frame_state_reg_set (state, 3, user_regs.rbx);
-      dwarf_frame_state_reg_set (state, 4, user_regs.rsi);
-      dwarf_frame_state_reg_set (state, 5, user_regs.rdi);
-      dwarf_frame_state_reg_set (state, 6, user_regs.rbp);
-      dwarf_frame_state_reg_set (state, 7, user_regs.rsp);
-      dwarf_frame_state_reg_set (state, 8, user_regs.r8);
-      dwarf_frame_state_reg_set (state, 9, user_regs.r9);
-      dwarf_frame_state_reg_set (state, 10, user_regs.r10);
-      dwarf_frame_state_reg_set (state, 11, user_regs.r11);
-      dwarf_frame_state_reg_set (state, 12, user_regs.r12);
-      dwarf_frame_state_reg_set (state, 13, user_regs.r13);
-      dwarf_frame_state_reg_set (state, 14, user_regs.r14);
-      dwarf_frame_state_reg_set (state, 15, user_regs.r15);
-      dwarf_frame_state_reg_set (state, 16, user_regs.rip);
+      dwfl_frame_state_reg_set (state, 0, user_regs.rax);
+      dwfl_frame_state_reg_set (state, 1, user_regs.rdx);
+      dwfl_frame_state_reg_set (state, 2, user_regs.rcx);
+      dwfl_frame_state_reg_set (state, 3, user_regs.rbx);
+      dwfl_frame_state_reg_set (state, 4, user_regs.rsi);
+      dwfl_frame_state_reg_set (state, 5, user_regs.rdi);
+      dwfl_frame_state_reg_set (state, 6, user_regs.rbp);
+      dwfl_frame_state_reg_set (state, 7, user_regs.rsp);
+      dwfl_frame_state_reg_set (state, 8, user_regs.r8);
+      dwfl_frame_state_reg_set (state, 9, user_regs.r9);
+      dwfl_frame_state_reg_set (state, 10, user_regs.r10);
+      dwfl_frame_state_reg_set (state, 11, user_regs.r11);
+      dwfl_frame_state_reg_set (state, 12, user_regs.r12);
+      dwfl_frame_state_reg_set (state, 13, user_regs.r13);
+      dwfl_frame_state_reg_set (state, 14, user_regs.r14);
+      dwfl_frame_state_reg_set (state, 15, user_regs.r15);
+      dwfl_frame_state_reg_set (state, 16, user_regs.rip);
 #endif /* __x86_64__ */
     }
   return true;
index 00ce56f9e1daa9a07a3c4c574c35ea90b9dcd607..5c6122436c3364e396a1525964d19165688608ae 100644 (file)
@@ -32,7 +32,7 @@
 #include <stdbool.h>
 #include <stdint.h>
 
-#include "../libebl/libebl.h"
+#include <libebl.h>
 
 
 /* Opaque type for the assembler context descriptor.  */
index 5cdc21a4086e735fd1f72c47112f11b8205f64fc..44a84d4e0db11da8ac0acd32e3ab3bd0a6c41cfa 100644 (file)
@@ -31,9 +31,7 @@
 
 #include "libdwP.h"
 #include "libelfP.h"
-#include "../libebl/libeblP.h"
 struct ebl;
-#include <assert.h>
 
 /* Cached CIE representation.  */
 struct dwarf_cie
@@ -188,100 +186,6 @@ struct Dwarf_Frame_s
   struct dwarf_frame_register regs[];
 };
 
-/* This holds information common for all the frames of one backtrace.  */
-struct Dwarf_Frame_State_Process
-{
-  Dwarf_Frame_State_Process *next;
-  struct Dwfl *dwfl;
-  struct ebl *ebl;
-  /* If it is false we share EBL with one of DWFL's Dwfl_Module->ebl.  */
-  bool ebl_close : 1;
-  /* If there is no core file both CORE is NULL and CORE_FD is -1.  */
-  Elf *core;
-  int core_fd;
-  Dwarf_Frame_State_Thread *thread;
-};
-
-struct Dwarf_Frame_State_Thread
-{
-  Dwarf_Frame_State_Process *process;
-  Dwarf_Frame_State_Thread *next;
-  /* If there is no TID it is 0.  */
-  pid_t tid;
-  bool tid_attached : 1;
-  /* Bottom frame.  */
-  Dwarf_Frame_State *unwound;
-};
-
-/* This holds everything we know about the state of the frame at a particular
-   PC location described by an FDE.  */
-struct Dwarf_Frame_State
-{
-  Dwarf_Frame_State_Thread *thread;
-  /* Previous (outer) frame.  */
-  Dwarf_Frame_State *unwound;
-  bool signal_frame : 1;
-  enum
-  {
-    /* This structure is still being initialized or there was an error
-       initializing it.  */
-    DWARF_FRAME_STATE_ERROR,
-    /* PC field is valid.  */
-    DWARF_FRAME_STATE_PC_SET,
-    /* PC field is undefined, this means the next (inner) frame was the
-       outermost frame.  */
-    DWARF_FRAME_STATE_PC_UNDEFINED
-  } pc_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.  */
-  uint64_t regs_set[3];
-  /* REGS array size is ebl_frame_state_nregs (base->ebl).  */
-  Dwarf_Addr regs[];
-};
-
-/* Fetch value from Dwarf_Frame_State->regs indexed by DWARF REGNO.
-   No error code is set if the function returns FALSE.  */
-static inline bool
-dwarf_frame_state_reg_get (Dwarf_Frame_State *state, unsigned regno,
-                           Dwarf_Addr *val)
-{
-  Ebl *ebl = state->thread->process->ebl;
-  if (ebl->frame_dwarf_to_regno != NULL
-      && ! ebl->frame_dwarf_to_regno (ebl, &regno))
-    return false;
-  if (regno >= ebl->frame_state_nregs)
-    return false;
-  if ((state->regs_set[regno / sizeof (*state->regs_set) / 8]
-       & (1U << (regno % (sizeof (*state->regs_set) * 8)))) == 0)
-    return false;
-  if (val)
-    *val = state->regs[regno];
-  return true;
-}
-
-/* Store value to Dwarf_Frame_State->regs indexed by DWARF REGNO.
-   No error code is set if the function returns FALSE.  */
-static inline bool
-dwarf_frame_state_reg_set (Dwarf_Frame_State *state, unsigned regno,
-                          Dwarf_Addr val)
-{
-  Ebl *ebl = state->thread->process->ebl;
-  if (ebl->frame_dwarf_to_regno != NULL
-      && ! ebl->frame_dwarf_to_regno (ebl, &regno))
-    return false;
-  if (regno >= ebl->frame_state_nregs)
-    return false;
-  /* For example i386 user_regs_struct has signed fields.  */
-  if (ebl->class == ELFCLASS32)
-    val &= 0xffffffff;
-  state->regs_set[regno / sizeof (*state->regs_set) / 8] |=
-                             (1U << (regno % (sizeof (*state->regs_set) * 8)));
-  state->regs[regno] = val;
-  return true;
-}
-
 
 /* Clean up the data structure and all it points to.  */
 extern void __libdw_destroy_frame_cache (Dwarf_CFI *cache)
index 6bd063bd4b4b13c984d7ca65616d795f41005918..f5fc4e2389b44c7673032b8bb4b90800b7141a16 100644 (file)
@@ -231,10 +231,6 @@ typedef union
 /* Opaque type representing a frame state described by CFI.  */
 typedef struct Dwarf_Frame_s Dwarf_Frame;
 
-typedef struct Dwarf_Frame_State_Process Dwarf_Frame_State_Process;
-typedef struct Dwarf_Frame_State_Thread Dwarf_Frame_State_Thread;
-typedef struct Dwarf_Frame_State Dwarf_Frame_State;
-
 /* Opaque type representing a CFI section found in a DWARF or ELF file.  */
 typedef struct Dwarf_CFI_s Dwarf_CFI;
 
index 40c8fb58832e926e3a92585010e3e58b0a8e41bd..ae0ce402855897f0dfa8077c6102298eda3e58b7 100644 (file)
@@ -27,7 +27,6 @@
    not, see <http://www.gnu.org/licenses/>.  */
 
 #include "libdwflP.h"
-#include "../libdw/cfi.h"
 #include <unistd.h>
 #include <sys/ptrace.h>
 
@@ -38,22 +37,22 @@ dwfl_end (Dwfl *dwfl)
     return;
 
   /* FIXME: Unify with dwfl_frame_state.c.  */
-  Dwarf_Frame_State_Process *process = dwfl->framestatelist;
+  Dwfl_Frame_State_Process *process = dwfl->framestatelist;
   while (process != NULL)
     {
-      Dwarf_Frame_State_Thread *thread = process->thread;
+      Dwfl_Frame_State_Thread *thread = process->thread;
       while (thread != NULL)
        {
          if (thread->tid_attached)
            ptrace (PTRACE_DETACH, thread->tid, NULL, NULL);
-         Dwarf_Frame_State *state = thread->unwound;
+         Dwfl_Frame_State *state = thread->unwound;
          while (state != NULL)
            {
-             Dwarf_Frame_State *dead = state;
+             Dwfl_Frame_State *dead = state;
              state = state->unwound;
              free (dead);
            }
-         Dwarf_Frame_State_Thread *dead = thread;
+         Dwfl_Frame_State_Thread *dead = thread;
          thread = thread->next;
          free (dead);
        }
@@ -62,7 +61,7 @@ dwfl_end (Dwfl *dwfl)
       elf_end (process->core);
       if (process->core_fd != -1)
        close (process->core_fd);
-      Dwarf_Frame_State_Process *dead = process;
+      Dwfl_Frame_State_Process *dead = process;
       process = process->next;
       free (dead);
     }
index 6f8737580c45dc5f5b283833df2b33a699978924..1eab65bf1392ab3213432b15231e2f92b21117b6 100644 (file)
@@ -27,7 +27,6 @@
    not, see <http://www.gnu.org/licenses/>.  */
 
 #include "libdwflP.h"
-#include "../libdw/cfi.h"
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/ptrace.h>
@@ -43,9 +42,9 @@
 static bool
 tid_is_attached (Dwfl *dwfl, pid_t tid)
 {
-  for (Dwarf_Frame_State_Process *process = dwfl->framestatelist; process;
+  for (Dwfl_Frame_State_Process *process = dwfl->framestatelist; process;
        process = process->next)
-    for (Dwarf_Frame_State_Thread *thread = process->thread; thread;
+    for (Dwfl_Frame_State_Thread *thread = process->thread; thread;
          thread = thread->next)
       if (thread->tid_attached && thread->tid == tid)
        return true;
@@ -53,15 +52,15 @@ tid_is_attached (Dwfl *dwfl, pid_t tid)
 }
 
 static bool
-state_fetch_pc (Dwarf_Frame_State *state)
+state_fetch_pc (Dwfl_Frame_State *state)
 {
   switch (state->pc_state)
   {
-    case DWARF_FRAME_STATE_PC_SET:
+    case DWFL_FRAME_STATE_PC_SET:
       return true;
-    case DWARF_FRAME_STATE_PC_UNDEFINED:
+    case DWFL_FRAME_STATE_PC_UNDEFINED:
       abort ();
-    case DWARF_FRAME_STATE_ERROR:;
+    case DWFL_FRAME_STATE_ERROR:;
       Ebl *ebl = state->thread->process->ebl;
       Dwarf_CIE abi_info;
       if (ebl_abi_cfi (ebl, &abi_info) != 0)
@@ -77,7 +76,7 @@ state_fetch_pc (Dwarf_Frame_State *state)
          return false;
        }
       state->pc = state->regs[ra];
-      state->pc_state = DWARF_FRAME_STATE_PC_SET;
+      state->pc_state = DWFL_FRAME_STATE_PC_SET;
       return true;
     }
   abort ();
@@ -86,9 +85,9 @@ state_fetch_pc (Dwarf_Frame_State *state)
 /* Do not call it on your own, to be used by thread_* functions only.  */
 
 static void
-state_free (Dwarf_Frame_State *state)
+state_free (Dwfl_Frame_State *state)
 {
-  Dwarf_Frame_State_Thread *thread = state->thread;
+  Dwfl_Frame_State_Thread *thread = state->thread;
   assert (thread->unwound == state);
   thread->unwound = state->unwound;
   free (state);
@@ -96,22 +95,22 @@ state_free (Dwarf_Frame_State *state)
 
 /* Do not call it on your own, to be used by thread_* functions only.  */
 
-static Dwarf_Frame_State *
-state_alloc (Dwarf_Frame_State_Thread *thread)
+static Dwfl_Frame_State *
+state_alloc (Dwfl_Frame_State_Thread *thread)
 {
   assert (thread->unwound == NULL);
   Ebl *ebl = thread->process->ebl;
   size_t nregs = ebl_frame_state_nregs (ebl);
   if (nregs == 0)
     return NULL;
-  assert (nregs < sizeof (((Dwarf_Frame_State *) NULL)->regs_set) * 8);
-  Dwarf_Frame_State *state = malloc (sizeof (*state)
+  assert (nregs < sizeof (((Dwfl_Frame_State *) NULL)->regs_set) * 8);
+  Dwfl_Frame_State *state = malloc (sizeof (*state)
                                     + sizeof (*state->regs) * nregs);
   if (state == NULL)
     return NULL;
   state->thread = thread;
   state->signal_frame = false;
-  state->pc_state = DWARF_FRAME_STATE_ERROR;
+  state->pc_state = DWFL_FRAME_STATE_ERROR;
   memset (state->regs_set, 0, sizeof (state->regs_set));
   thread->unwound = state;
   state->unwound = NULL;
@@ -119,13 +118,13 @@ state_alloc (Dwarf_Frame_State_Thread *thread)
 }
 
 static void
-thread_free (Dwarf_Frame_State_Thread *thread)
+thread_free (Dwfl_Frame_State_Thread *thread)
 {
   while (thread->unwound)
     state_free (thread->unwound);
   if (thread->tid_attached)
     ptrace (PTRACE_DETACH, thread->tid, NULL, NULL);
-  Dwarf_Frame_State_Process *process = thread->process;
+  Dwfl_Frame_State_Process *process = thread->process;
   assert (process->thread == thread);
   process->thread = thread->next;
   free (thread);
@@ -133,10 +132,10 @@ thread_free (Dwarf_Frame_State_Thread *thread)
 
 /* One state_alloc is called automatically.  */
 
-static Dwarf_Frame_State_Thread *
-thread_alloc (Dwarf_Frame_State_Process *process, pid_t tid)
+static Dwfl_Frame_State_Thread *
+thread_alloc (Dwfl_Frame_State_Process *process, pid_t tid)
 {
-  Dwarf_Frame_State_Thread *thread = malloc (sizeof (*thread));
+  Dwfl_Frame_State_Thread *thread = malloc (sizeof (*thread));
   if (thread == NULL)
     return NULL;
   thread->process = process;
@@ -154,7 +153,7 @@ thread_alloc (Dwarf_Frame_State_Process *process, pid_t tid)
 }
 
 static void
-process_free (Dwarf_Frame_State_Process *process)
+process_free (Dwfl_Frame_State_Process *process)
 {
   while (process->thread)
     thread_free (process->thread);
@@ -169,10 +168,10 @@ process_free (Dwarf_Frame_State_Process *process)
   free (process);
 }
 
-static Dwarf_Frame_State_Process *
+static Dwfl_Frame_State_Process *
 process_alloc (Dwfl *dwfl)
 {
-  Dwarf_Frame_State_Process *process = malloc (sizeof (*process));
+  Dwfl_Frame_State_Process *process = malloc (sizeof (*process));
   if (process == NULL)
     return NULL;
   process->dwfl = dwfl;
@@ -212,13 +211,13 @@ ptrace_attach (pid_t tid)
   return true;
 }
 
-Dwarf_Frame_State *
+Dwfl_Frame_State *
 dwfl_frame_state_pid (Dwfl *dwfl, pid_t pid)
 {
   char dirname[64];
   int i = snprintf (dirname, sizeof (dirname), "/proc/%ld/task", (long) pid);
   assert (i > 0 && i < (ssize_t) sizeof (dirname) - 1);
-  Dwarf_Frame_State_Process *process = process_alloc (dwfl);
+  Dwfl_Frame_State_Process *process = process_alloc (dwfl);
   if (process == NULL)
     return NULL;
   for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next)
@@ -273,7 +272,7 @@ dwfl_frame_state_pid (Dwfl *dwfl, pid_t pid)
          __libdwfl_seterrno (DWFL_E_UNKNOWN_ERROR);
          return NULL;
        }
-      Dwarf_Frame_State_Thread *thread = thread_alloc (process, tid);
+      Dwfl_Frame_State_Thread *thread = thread_alloc (process, tid);
       if (thread == NULL)
        {
          process_free (process);
@@ -289,7 +288,7 @@ dwfl_frame_state_pid (Dwfl *dwfl, pid_t pid)
            }
          thread->tid_attached = true;
        }
-      Dwarf_Frame_State *state = thread->unwound;
+      Dwfl_Frame_State *state = thread->unwound;
       if (! ebl_frame_state (state) || ! state_fetch_pc (state))
        {
          thread_free (thread);
@@ -315,10 +314,10 @@ INTDEF (dwfl_frame_state_pid)
 
 /* Fetch inferior registers from a core file.  */
 
-Dwarf_Frame_State *
+Dwfl_Frame_State *
 dwfl_frame_state_core (Dwfl *dwfl, const char *corefile)
 {
-  Dwarf_Frame_State_Process *process = process_alloc (dwfl);
+  Dwfl_Frame_State_Process *process = process_alloc (dwfl);
   if (process == NULL)
     return NULL;
   int core_fd = open64 (corefile, O_RDONLY);
@@ -370,7 +369,7 @@ dwfl_frame_state_core (Dwfl *dwfl, const char *corefile)
       __libdwfl_seterrno (DWFL_E_LIBELF);
       return NULL;
     }
-  Dwarf_Frame_State_Thread *thread = NULL;
+  Dwfl_Frame_State_Thread *thread = NULL;
   for (size_t cnt = 0; cnt < phnum; ++cnt)
     {
       GElf_Phdr phdr_mem, *phdr = gelf_getphdr (core, cnt, &phdr_mem);
@@ -428,7 +427,7 @@ dwfl_frame_state_core (Dwfl *dwfl, const char *corefile)
                {
                  /* Delay initialization of THREAD till all notes for it have
                     been read in.  */
-                 Dwarf_Frame_State *state = thread->unwound;
+                 Dwfl_Frame_State *state = thread->unwound;
                  if (! ebl_frame_state (state) || ! state_fetch_pc (state))
                    {
                      thread_free (thread);
@@ -449,7 +448,7 @@ dwfl_frame_state_core (Dwfl *dwfl, const char *corefile)
              /* Ignore notes before first PR_NTSTATUS.  */
              continue;
            }
-         Dwarf_Frame_State *state = thread->unwound;
+         Dwfl_Frame_State *state = thread->unwound;
          desc += regs_offset;
          for (size_t regloci = 0; regloci < nregloc; regloci++)
            {
@@ -466,7 +465,7 @@ dwfl_frame_state_core (Dwfl *dwfl, const char *corefile)
                     CFI which clashes with register 108 (LR) we need.
                     LR (108) is provided earlier (in NT_PRSTATUS) than the # 65.
                     FIXME: It depends now on their order in core notes.  */
-                 if (dwarf_frame_state_reg_get (state, regno, NULL))
+                 if (dwfl_frame_state_reg_get (state, regno, NULL))
                    continue;
                  Dwarf_Addr val;
                  switch (regloc->bits)
@@ -497,7 +496,7 @@ dwfl_frame_state_core (Dwfl *dwfl, const char *corefile)
                      return NULL;
                    }
                  /* Registers not valid for CFI are just ignored.  */
-                 dwarf_frame_state_reg_set (state, regno, val);
+                 dwfl_frame_state_reg_set (state, regno, val);
                  reg_desc += regloc->pad;
                }
            }
@@ -507,7 +506,7 @@ dwfl_frame_state_core (Dwfl *dwfl, const char *corefile)
     {
       /* Delay initialization of THREAD till all notes for it have been read
         in.  */
-      Dwarf_Frame_State *state = thread->unwound;
+      Dwfl_Frame_State *state = thread->unwound;
       if (! ebl_frame_state (state) || ! state_fetch_pc (state))
        thread_free (thread);
     }
@@ -522,16 +521,16 @@ dwfl_frame_state_core (Dwfl *dwfl, const char *corefile)
 }
 INTDEF (dwfl_frame_state_core)
 
-Dwarf_Frame_State *
-dwfl_frame_thread_next (Dwarf_Frame_State *state)
+Dwfl_Frame_State *
+dwfl_frame_thread_next (Dwfl_Frame_State *state)
 {
-  Dwarf_Frame_State_Thread *thread_next = state->thread->next;
+  Dwfl_Frame_State_Thread *thread_next = state->thread->next;
   return thread_next ? thread_next->unwound : NULL;
 }
 INTDEF (dwfl_frame_thread_next)
 
 pid_t
-dwfl_frame_tid_get (Dwarf_Frame_State *state)
+dwfl_frame_tid_get (Dwfl_Frame_State *state)
 {
   return state->thread->tid;
 }
index a8d190613e8863473aef50b1ebb49f71872b3e73..4d6fc8bd3b1830cc5290d76fdec5835f5291d6d7 100644 (file)
 # include <config.h>
 #endif
 
-#include "../libdw/cfi.h"
-#include "../libebl/libebl.h"
 #include "libdwflP.h"
 
 bool
-dwfl_frame_state_pc (Dwarf_Frame_State *state, Dwarf_Addr *pc, bool *minusone)
+dwfl_frame_state_pc (Dwfl_Frame_State *state, Dwarf_Addr *pc, bool *minusone)
 {
-  assert (state->pc_state == DWARF_FRAME_STATE_PC_SET);
+  assert (state->pc_state == DWFL_FRAME_STATE_PC_SET);
   *pc = state->pc;
   ebl_normalize_pc (state->thread->process->ebl, pc);
   if (minusone)
index 2e28bd983eee60a9d70ecfe2c38645eede78bc89..90dbabf07693b9a7aaa90c2d0f387f6935b36677 100644 (file)
@@ -61,9 +61,9 @@ segment_end (Dwfl *dwfl, GElf_Addr end)
 }
 
 static bool
-state_get_reg (Dwarf_Frame_State *state, unsigned regno, Dwarf_Addr *val)
+state_get_reg (Dwfl_Frame_State *state, unsigned regno, Dwarf_Addr *val)
 {
-  if (! dwarf_frame_state_reg_get (state, regno, val))
+  if (! dwfl_frame_state_reg_get (state, regno, val))
     {
       __libdwfl_seterrno (DWFL_E_UNKNOWN_ERROR);
       return false;
@@ -72,7 +72,7 @@ state_get_reg (Dwarf_Frame_State *state, unsigned regno, Dwarf_Addr *val)
 }
 
 static bool
-memory_read (Dwarf_Frame_State_Process *process, Dwarf_Addr addr,
+memory_read (Dwfl_Frame_State_Process *process, Dwarf_Addr addr,
             Dwarf_Addr *result)
 {
   if (process->core == NULL)
@@ -171,7 +171,7 @@ bra_compar (const void *key_voidp, const void *elem_voidp)
 /* FIXME: Handle bytecode deadlocks and overflows.  */
 
 static bool
-expr_eval (Dwarf_Frame_State *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
+expr_eval (Dwfl_Frame_State *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
           size_t nops, Dwarf_Addr *result)
 {
   if (nops == 0)
@@ -398,19 +398,19 @@ expr_eval (Dwarf_Frame_State *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
    (and call __libdwfl_seterrno) otherwise.  */
 
 static bool
-have_unwound (Dwarf_Frame_State **statep)
+have_unwound (Dwfl_Frame_State **statep)
 {
-  Dwarf_Frame_State *state = *statep, *unwound = state->unwound;
+  Dwfl_Frame_State *state = *statep, *unwound = state->unwound;
   switch (unwound->pc_state)
   {
-    case DWARF_FRAME_STATE_ERROR:
+    case DWFL_FRAME_STATE_ERROR:
       __libdwfl_seterrno (DWFL_E_UNKNOWN_ERROR);
       *statep = NULL;
       return false;
-    case DWARF_FRAME_STATE_PC_SET:
+    case DWFL_FRAME_STATE_PC_SET:
       *statep = unwound;
       return true;
-    case DWARF_FRAME_STATE_PC_UNDEFINED:
+    case DWFL_FRAME_STATE_PC_UNDEFINED:
       *statep = NULL;
       return true;
   }
@@ -467,15 +467,15 @@ no_fde (Dwarf_Addr pc, Dwfl_Module *mod, Dwarf_Addr bias)
    an undefined PC register (due to an error unwinding it).  */
 
 static bool
-handle_cfi (Dwarf_Frame_State **statep, Dwarf_Addr pc, Dwfl_Module *mod,
+handle_cfi (Dwfl_Frame_State **statep, Dwarf_Addr pc, Dwfl_Module *mod,
            Dwarf_CFI *cfi, Dwarf_Addr bias)
 {
-  Dwarf_Frame_State *state = *statep;
+  Dwfl_Frame_State *state = *statep;
   Dwarf_Frame *frame;
   if (INTUSE(dwarf_cfi_addrframe) (cfi, pc - bias, &frame) != 0)
     {
       int dw_errno = dwarf_errno ();
-      if (dw_errno == DWARF_E_NO_MATCH)
+      if (dw_errno == DWFL_E_NO_MATCH)
        {
          if (! no_fde (pc, mod, bias))
            return false;
@@ -486,17 +486,17 @@ handle_cfi (Dwarf_Frame_State **statep, Dwarf_Addr pc, Dwfl_Module *mod,
       __libdwfl_seterrno (DWFL_E_LIBDW);
       return false;
     }
-  Dwarf_Frame_State_Thread *thread = state->thread;
-  Dwarf_Frame_State_Process *process = thread->process;
+  Dwfl_Frame_State_Thread *thread = state->thread;
+  Dwfl_Frame_State_Process *process = thread->process;
   Ebl *ebl = process->ebl;
   size_t nregs = ebl_frame_state_nregs (ebl);
-  Dwarf_Frame_State *unwound;
+  Dwfl_Frame_State *unwound;
   unwound = malloc (sizeof (*unwound) + sizeof (*unwound->regs) * nregs);
   state->unwound = unwound;
   unwound->thread = thread;
   unwound->unwound = NULL;
   unwound->signal_frame = frame->fde->cie->signal_frame;
-  unwound->pc_state = DWARF_FRAME_STATE_ERROR;
+  unwound->pc_state = DWFL_FRAME_STATE_ERROR;
   memset (unwound->regs_set, 0, sizeof (unwound->regs_set));
   for (unsigned regno = 0; regno < nregs; regno++)
     {
@@ -516,7 +516,7 @@ handle_cfi (Dwarf_Frame_State **statep, Dwarf_Addr pc, Dwfl_Module *mod,
              /* REGNO is undefined.  */
              unsigned ra = frame->fde->cie->return_address_register;
              if (ebl_frame_dwarf_to_regno (ebl, &ra) && regno == ra)
-               unwound->pc_state = DWARF_FRAME_STATE_PC_UNDEFINED;
+               unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
              continue;
            }
          else if (reg_ops == NULL)
@@ -538,31 +538,31 @@ handle_cfi (Dwarf_Frame_State **statep, Dwarf_Addr pc, Dwfl_Module *mod,
             But PPC32 does not use such registers.  */
          continue;
        }
-      if (! dwarf_frame_state_reg_set (unwound, regno, regval))
+      if (! dwfl_frame_state_reg_set (unwound, regno, regval))
        {
          __libdwfl_seterrno (DWFL_E_UNKNOWN_ERROR);
          continue;
        }
     }
-  if (unwound->pc_state == DWARF_FRAME_STATE_ERROR
-      && dwarf_frame_state_reg_get (unwound,
-                                   frame->fde->cie->return_address_register,
-                                   &unwound->pc))
+  if (unwound->pc_state == DWFL_FRAME_STATE_ERROR
+      && dwfl_frame_state_reg_get (unwound,
+                                  frame->fde->cie->return_address_register,
+                                  &unwound->pc))
     {
       /* PPC32 __libc_start_main properly CFI-unwinds PC as zero.  Currently
         none of the archs supported for unwinding have zero as a valid PC.  */
       if (unwound->pc == 0)
-       unwound->pc_state = DWARF_FRAME_STATE_PC_UNDEFINED;
+       unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
       else
-       unwound->pc_state = DWARF_FRAME_STATE_PC_SET;
+       unwound->pc_state = DWFL_FRAME_STATE_PC_SET;
     }
   return have_unwound (statep);
 }
 
 bool
-dwfl_frame_unwind (Dwarf_Frame_State **statep)
+dwfl_frame_unwind (Dwfl_Frame_State **statep)
 {
-  Dwarf_Frame_State *state = *statep;
+  Dwfl_Frame_State *state = *statep;
   if (state->unwound)
     return have_unwound (statep);
   Dwarf_Addr pc;
@@ -583,7 +583,7 @@ dwfl_frame_unwind (Dwarf_Frame_State **statep)
            return true;
          if (state->unwound)
            {
-             assert (state->unwound->pc_state == DWARF_FRAME_STATE_ERROR);
+             assert (state->unwound->pc_state == DWFL_FRAME_STATE_ERROR);
              return false;
            }
        }
@@ -594,7 +594,7 @@ dwfl_frame_unwind (Dwarf_Frame_State **statep)
            return true;
          if (state->unwound)
            {
-             assert (state->unwound->pc_state == DWARF_FRAME_STATE_ERROR);
+             assert (state->unwound->pc_state == DWFL_FRAME_STATE_ERROR);
              return false;
            }
        }
@@ -604,7 +604,7 @@ dwfl_frame_unwind (Dwarf_Frame_State **statep)
     return true;
   if (state->unwound)
     {
-      assert (state->unwound->pc_state == DWARF_FRAME_STATE_ERROR);
+      assert (state->unwound->pc_state == DWFL_FRAME_STATE_ERROR);
       return false;
     }
   __libdwfl_seterrno (DWFL_E_NO_DWARF);
index 7706f530b4aa6f4674b0bcc6b535cfb8022caa90..6204e3ffa66342d808a2d216fc7f0d1d7ec2ba32 100644 (file)
@@ -41,6 +41,10 @@ typedef struct Dwfl_Module Dwfl_Module;
 /* Handle describing a line record.  */
 typedef struct Dwfl_Line Dwfl_Line;
 
+/* This holds everything we know about the state of the frame at a particular
+   PC location described by an FDE.  */
+typedef struct Dwfl_Frame_State Dwfl_Frame_State;
+
 /* Callbacks.  */
 typedef struct
 {
@@ -558,33 +562,33 @@ extern Dwarf_CFI *dwfl_module_eh_cfi (Dwfl_Module *mod, Dwarf_Addr *bias);
 
 /* Get innermost frame of first thread of live process PID.  Returns NULL on
    failure.  */
-extern Dwarf_Frame_State *dwfl_frame_state_pid (Dwfl *dwfl, pid_t pid);
+extern Dwfl_Frame_State *dwfl_frame_state_pid (Dwfl *dwfl, pid_t pid);
 
 /* Get innermost frame of first thread of core file COREFILE.  Returns NULL on
    failure.  */
-extern Dwarf_Frame_State *dwfl_frame_state_core (Dwfl *dwfl,
-                                                const char *corefile);
+extern Dwfl_Frame_State *dwfl_frame_state_core (Dwfl *dwfl,
+                                               const char *corefile);
 
 /* 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.  */
-extern bool dwfl_frame_unwind (Dwarf_Frame_State **statep);
+extern bool dwfl_frame_unwind (Dwfl_Frame_State **statep);
 
 /* Get return address register value for frame.  Return TRUE if *PC set and
    optionally *MINUSONE is also set, if MINUSONE is not NULL.  Return FALSE
    (and call __libdw_seterrno) otherwise.  *MINUSONE is TRUE for normal calls
    where *PC should be decremented by one to get the call instruction, it is
    FALSE if this frame was interrupted by a signal handler.  */
-extern bool dwfl_frame_state_pc (Dwarf_Frame_State *state, Dwarf_Addr *pc,
+extern bool dwfl_frame_state_pc (Dwfl_Frame_State *state, Dwarf_Addr *pc,
                                 bool *minusone);
 
 /* Get innermost frame of the next thread from STATE.  STATE can be any frame
    of (the previous) thread.  */
-extern Dwarf_Frame_State *dwfl_frame_thread_next (Dwarf_Frame_State *state);
+extern Dwfl_Frame_State *dwfl_frame_thread_next (Dwfl_Frame_State *state);
 
 /* Get Task ID of the thread of STATE.  This is PID for the thread started by
    function main and gettid () for the other threads.  */
-extern pid_t dwfl_frame_tid_get (Dwarf_Frame_State *state);
+extern pid_t dwfl_frame_tid_get (Dwfl_Frame_State *state);
 
 #ifdef __cplusplus
 }
index db0ba31fd131c65e32d6270e6003e89949d517b4..ad6a6d118ef17cb132afa92a3cad8a351aff608c 100644 (file)
 #include <string.h>
 
 #include "../libdw/libdwP.h"   /* We need its INTDECLs.  */
+#include "../libebl/libeblP.h"
+
+typedef struct Dwfl_Frame_State_Process Dwfl_Frame_State_Process;
+typedef struct Dwfl_Frame_State_Thread Dwfl_Frame_State_Thread;
 
 /* gettext helper macros.  */
 #define _(Str) dgettext ("elfutils", Str)
@@ -92,7 +96,7 @@ struct Dwfl
 
   Dwfl_Module *modulelist;    /* List in order used by full traversals.  */
 
-  Dwarf_Frame_State_Process *framestatelist;
+  Dwfl_Frame_State_Process *framestatelist;
 
   GElf_Addr offline_next_address;
 
@@ -184,7 +188,106 @@ struct Dwfl_Module
   bool gc;                     /* Mark/sweep flag.  */
 };
 
+/* This holds information common for all the threads/tasks/TIDs of one process
+   for backtraces.  */
+
+struct Dwfl_Frame_State_Process
+{
+  Dwfl_Frame_State_Process *next;
+  struct Dwfl *dwfl;
+  struct ebl *ebl;
+  /* If it is false we share EBL with one of DWFL's Dwfl_Module->ebl.  */
+  bool ebl_close : 1;
+  /* If there is no core file both CORE is NULL and CORE_FD is -1.  */
+  Elf *core;
+  int core_fd;
+  Dwfl_Frame_State_Thread *thread;
+};
+
+/* This holds information common for all the frames of one backtrace for
+   a partical thread/task/TID.  */
+
+struct Dwfl_Frame_State_Thread
+{
+  Dwfl_Frame_State_Process *process;
+  Dwfl_Frame_State_Thread *next;
+  /* If there is no TID it is 0.  */
+  pid_t tid;
+  bool tid_attached : 1;
+  /* Bottom frame.  */
+  Dwfl_Frame_State *unwound;
+};
+
+/* See its typedef in libdwfl.h.  */
+
+struct Dwfl_Frame_State
+{
+  Dwfl_Frame_State_Thread *thread;
+  /* Previous (outer) frame.  */
+  Dwfl_Frame_State *unwound;
+  bool signal_frame : 1;
+  enum
+  {
+    /* This structure is still being initialized or there was an error
+       initializing it.  */
+    DWFL_FRAME_STATE_ERROR,
+    /* PC field is valid.  */
+    DWFL_FRAME_STATE_PC_SET,
+    /* PC field is undefined, this means the next (inner) frame was the
+       outermost frame.  */
+    DWFL_FRAME_STATE_PC_UNDEFINED
+  } pc_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.  */
+  uint64_t regs_set[3];
+  /* REGS array size is ebl_frame_state_nregs (base->ebl).  */
+  Dwarf_Addr regs[];
+};
+
+/* Fetch value from Dwfl_Frame_State->regs indexed by DWARF REGNO.
+   No error code is set if the function returns FALSE.  */
+
+static inline bool
+dwfl_frame_state_reg_get (Dwfl_Frame_State *state, unsigned regno,
+                         Dwarf_Addr *val)
+{
+  Ebl *ebl = state->thread->process->ebl;
+  if (ebl->frame_dwarf_to_regno != NULL
+      && ! ebl->frame_dwarf_to_regno (ebl, &regno))
+    return false;
+  if (regno >= ebl->frame_state_nregs)
+    return false;
+  if ((state->regs_set[regno / sizeof (*state->regs_set) / 8]
+       & (1U << (regno % (sizeof (*state->regs_set) * 8)))) == 0)
+    return false;
+  if (val)
+    *val = state->regs[regno];
+  return true;
+}
+
+/* Store value to Dwfl_Frame_State->regs indexed by DWARF REGNO.
+   No error code is set if the function returns FALSE.  */
 
+static inline bool
+dwfl_frame_state_reg_set (Dwfl_Frame_State *state, unsigned regno,
+                         Dwarf_Addr val)
+{
+  Ebl *ebl = state->thread->process->ebl;
+  if (ebl->frame_dwarf_to_regno != NULL
+      && ! ebl->frame_dwarf_to_regno (ebl, &regno))
+    return false;
+  if (regno >= ebl->frame_state_nregs)
+    return false;
+  /* For example i386 user_regs_struct has signed fields.  */
+  if (ebl->class == ELFCLASS32)
+    val &= 0xffffffff;
+  state->regs_set[regno / sizeof (*state->regs_set) / 8] |=
+                             (1U << (regno % (sizeof (*state->regs_set) * 8)));
+  state->regs[regno] = val;
+  return true;
+}
 
 /* Information cached about each CU in Dwfl_Module.dw.  */
 struct dwfl_cu
index 580d213e8dec704a9922922d5047a4cafaa7d82a..92497c3d8ae0652b984267260c5db52f45f37f93 100644 (file)
@@ -29,7 +29,8 @@
 ##
 include $(top_srcdir)/config/eu.am
 AM_CFLAGS += -fpic
-INCLUDES += -I$(srcdir)/../libelf -I$(srcdir)/../libdw -I$(srcdir)/../libasm
+INCLUDES += -I$(srcdir)/../libelf -I$(srcdir)/../libdw -I$(srcdir)/../libasm \
+           -I$(srcdir)/../libdwfl
 VERSION = 1
 LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
 
index a8908657a55e70288745e59e852d489f33572d9c..9372c8facf4fa4e26ae038921fa74feff8d07713 100644 (file)
@@ -167,7 +167,7 @@ const char *EBLHOOK(get_func_pc) (Ebl *ebl, struct Dwfl_Module *mod,
                                  GElf_Sym *sym);
 
 /* Fetch process data from STATE->base->pid or STATE->base->core.  */
-bool EBLHOOK(frame_state) (Dwarf_Frame_State *state);
+bool EBLHOOK(frame_state) (struct Dwfl_Frame_State *state);
 
 /* Number of Dwarf_Frame_State->regs entries to allocate for frame_state
    above.  */
@@ -184,11 +184,12 @@ void EBLHOOK(normalize_pc) (Ebl *ebl, Dwarf_Addr *pc);
 
 /* See dwfl_frame_unwind.  */
 bool
-  EBLHOOK(frame_unwind) (Ebl *ebl, Dwarf_Frame_State **statep, Dwarf_Addr pc,
-                        bool
-                          (*memory_read) (Dwarf_Frame_State_Process *process,
-                                          Dwarf_Addr addr,
-                                          Dwarf_Addr *result));
+  EBLHOOK(frame_unwind) (Ebl *ebl, struct Dwfl_Frame_State **statep,
+                        Dwarf_Addr pc,
+                        bool (*memory_read) (
+                                      struct Dwfl_Frame_State_Process *process,
+                                             Dwarf_Addr addr,
+                                             Dwarf_Addr *result));
 
 /* Destructor for ELF backend handle.  */
 void EBLHOOK(destr) (struct ebl *);
index cce8397fb7b42aa08b679b22495bade12f4c0b8e..a7cc13c52bade1319c7cb1515faa818e7ba842c5 100644 (file)
@@ -1,4 +1,4 @@
-/* Fetch live process Dwarf_Frame_State from PID.
+/* Fetch live process Dwfl_Frame_State from PID.
    Copyright (C) 2012 Red Hat, Inc.
    This file is part of elfutils.
 
 #endif
 
 #include <libeblP.h>
-#include "../libdw/cfi.h"
 #include <assert.h>
+#include "libdwflP.h"
 
 bool
-ebl_frame_state (Dwarf_Frame_State *state)
+ebl_frame_state (Dwfl_Frame_State *state)
 {
-  Dwarf_Frame_State_Process *process = state->thread->process;
+  Dwfl_Frame_State_Process *process = state->thread->process;
   Ebl *ebl = process->ebl;
   /* Otherwise caller could not allocate STATE of proper size.  If FRAME_STATE
      is unsupported then FRAME_STATE_NREGS is zero.  */
index 7981df484ad9b11623bf67183147eda8a75ca1ce..7fe0eb0bad32015be32c406229ff21ea4234a8f1 100644 (file)
@@ -33,8 +33,8 @@
 #include <libeblP.h>
 
 bool
-ebl_frame_unwind (Ebl *ebl, Dwarf_Frame_State **statep, Dwarf_Addr pc,
-                 bool (*memory_read) (Dwarf_Frame_State_Process *process,
+ebl_frame_unwind (Ebl *ebl, Dwfl_Frame_State **statep, Dwarf_Addr pc,
+                 bool (*memory_read) (struct Dwfl_Frame_State_Process *process,
                                       Dwarf_Addr addr, Dwarf_Addr *result))
 {
   if (ebl == NULL || ebl->frame_unwind == NULL)
index ac52bf457e1d295448e80a5af194bcac40f0fec7..8d70c39934cb4757eedbf4cfcade22e90ad350f3 100644 (file)
@@ -386,7 +386,8 @@ extern const char *ebl_get_func_pc (Ebl *ebl, struct Dwfl_Module *mod,
   __nonnull_attribute__ (1, 2, 3);
 
 /* Fetch process data from STATE->base->pid or STATE->base->core.  */
-extern bool ebl_frame_state (Dwarf_Frame_State *state)
+struct Dwfl_Frame_State;
+extern bool ebl_frame_state (struct Dwfl_Frame_State *state)
   __nonnull_attribute__ (1);
 
 /* Number of registers to allocate for STATE of ebl_frame_state.  */
@@ -398,10 +399,12 @@ extern void ebl_normalize_pc (Ebl *ebl, Dwarf_Addr *pc)
   __nonnull_attribute__ (1, 2);
 
 /* Get previous frame state for an existing frame state.  */
+struct Dwfl_Frame_State_Process;
 extern bool
-  ebl_frame_unwind (Ebl *ebl, Dwarf_Frame_State **statep, Dwarf_Addr pc,
-                   bool (*memory_read) (Dwarf_Frame_State_Process *process,
-                                        Dwarf_Addr addr, Dwarf_Addr *result))
+  ebl_frame_unwind (Ebl *ebl, struct Dwfl_Frame_State **statep, Dwarf_Addr pc,
+                   bool
+                     (*memory_read) (struct Dwfl_Frame_State_Process *process,
+                                     Dwarf_Addr addr, Dwarf_Addr *result))
   __nonnull_attribute__ (1, 2, 4);
 
 /* Convert *REGNO as is in DWARF to a lower range.  */
index 5994ef52766fa4c129781ad1733b1a40dbe57b90..dd7be049dc7ea59377591972058537ca36751d75 100644 (file)
@@ -47,7 +47,7 @@ dump (Dwfl *dwfl, pid_t pid, const char *corefile)
 {
   if (pid)
     report_pid (dwfl, pid);
-  Dwarf_Frame_State *state;
+  Dwfl_Frame_State *state;
   if (pid)
     state = dwfl_frame_state_pid (dwfl, pid);
   else if (corefile)
@@ -58,7 +58,7 @@ dump (Dwfl *dwfl, pid_t pid, const char *corefile)
     error (2, 0, "dwfl_frame_state: %s", dwfl_errmsg (-1));
   do
     {
-      Dwarf_Frame_State *thread = state;
+      Dwfl_Frame_State *thread = state;
       pid_t tid = dwfl_frame_tid_get (thread);
       printf ("TID %ld:\n", (long) tid);
       unsigned frameno;
index 5a20f88ec816c517c3f57339404e56908236f138..6fab87d6cb18892744b665f3d6a16093b1722553 100644 (file)
@@ -179,7 +179,7 @@ dump (pid_t pid, const char *corefile,
       void *data)
 {
   Dwfl *dwfl;
-  Dwarf_Frame_State *state;
+  Dwfl_Frame_State *state;
   if (pid && !corefile)
     {
       dwfl = dwfl_pid (pid);
@@ -199,7 +199,7 @@ dump (pid_t pid, const char *corefile,
   int err = 0;
   do
     {
-      Dwarf_Frame_State *thread = state;
+      Dwfl_Frame_State *thread = state;
       pid_t tid = dwfl_frame_tid_get (thread);
       printf ("TID %ld:\n", (long) tid);
       unsigned frameno;