Update.
(Logical change 1.162)
diff --git a/TODO b/TODO
index 785a890..a4078cb 100644
--- a/TODO
+++ b/TODO
@@ -4,7 +4,6 @@
implements its own runtime loader).
- document split local-only/generic libraries and separate libunwind-ptrace.a
convenience-library
-- implement non-local versions of dwarf_readXX()
- document new "tdep" member in unw_proc_info_t structure
- for DWARF 2, use a dummy CIE entry with an augmentation that
provides the dyn-info-list-address
@@ -19,6 +18,10 @@
=== taken care of:
++ Switch ia64 (and rest over) to using Debug() instead of debug()
++ implement non-local versions of dwarf_readXX()
++ consolidate mostly architecture-independent code such as
+ unw_get_accessors() into shared files
+ caching is pretty fundamentally broken, what should happen is this:
o On unw_init_local()/unw_init_remote(), libunwind should validate
that the cached information is still valid and, if not, flush the
diff --git a/src/x86/Ginit-x86.c b/src/x86/Ginit-x86.c
index fdb1936..c13085c 100644
--- a/src/x86/Ginit-x86.c
+++ b/src/x86/Ginit-x86.c
@@ -46,6 +46,10 @@
switch (reg)
{
+ case UNW_X86_GS: addr = &uc->uc_mcontext.gregs[REG_GS]; break;
+ case UNW_X86_FS: addr = &uc->uc_mcontext.gregs[REG_FS]; break;
+ case UNW_X86_ES: addr = &uc->uc_mcontext.gregs[REG_ES]; break;
+ case UNW_X86_DS: addr = &uc->uc_mcontext.gregs[REG_DS]; break;
case UNW_X86_EAX: addr = &uc->uc_mcontext.gregs[REG_EAX]; break;
case UNW_X86_EBX: addr = &uc->uc_mcontext.gregs[REG_EBX]; break;
case UNW_X86_ECX: addr = &uc->uc_mcontext.gregs[REG_ECX]; break;
@@ -55,6 +59,10 @@
case UNW_X86_EBP: addr = &uc->uc_mcontext.gregs[REG_EBP]; break;
case UNW_X86_EIP: addr = &uc->uc_mcontext.gregs[REG_EIP]; break;
case UNW_X86_ESP: addr = &uc->uc_mcontext.gregs[REG_ESP]; break;
+ case UNW_X86_TRAPNO: addr = &uc->uc_mcontext.gregs[REG_TRAPNO]; break;
+ case UNW_X86_CS: addr = &uc->uc_mcontext.gregs[REG_CS]; break;
+ case UNW_X86_EFLAGS: addr = &uc->uc_mcontext.gregs[REG_EFL]; break;
+ case UNW_X86_SS: addr = &uc->uc_mcontext.gregs[REG_SS]; break;
default:
addr = NULL;
@@ -65,7 +73,7 @@
# ifdef UNW_LOCAL_ONLY
void *
-_Ux86_uc_addr (ucontext_t *uc, int reg)
+tdep_uc_addr (ucontext_t *uc, int reg)
{
return uc_addr (uc, reg);
}
@@ -117,13 +125,11 @@
unw_word_t *addr;
ucontext_t *uc = arg;
-#if 0
- if (reg >= UNW_IA64_FR && reg < UNW_IA64_FR + 128)
+ if (unw_is_fpreg (reg))
goto badreg;
-#endif
- addr = uc_addr (uc, reg);
- if (!addr)
+Debug (16, "reg = %s\n", unw_regname (reg));
+ if (!(addr = uc_addr (uc, reg)))
goto badreg;
if (write)
@@ -147,31 +153,26 @@
access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
int write, void *arg)
{
-#if 1
- printf ("access_fpreg: screams to get implemented, doesn't it?\n");
- return 0;
-#else
ucontext_t *uc = arg;
unw_fpreg_t *addr;
- if (reg < UNW_IA64_FR || reg >= UNW_IA64_FR + 128)
+ if (!unw_is_fpreg (reg))
goto badreg;
- addr = uc_addr (uc, reg);
- if (!addr)
+ if (!(addr = uc_addr (uc, reg)))
goto badreg;
if (write)
{
- Debug (12, "%s <- %016lx.%016lx\n",
- unw_regname (reg), val->raw.bits[1], val->raw.bits[0]);
+ Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg),
+ ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]);
*(unw_fpreg_t *) addr = *val;
}
else
{
*val = *(unw_fpreg_t *) addr;
- Debug (12, "%s -> %016lx.%016lx\n",
- unw_regname (reg), val->raw.bits[1], val->raw.bits[0]);
+ Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg),
+ ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]);
}
return 0;
@@ -179,7 +180,6 @@
Debug (1, "bad register number %u\n", reg);
/* attempt to access a non-preserved register */
return -UNW_EBADREG;
-#endif
}
static int
@@ -203,6 +203,7 @@
local_addr_space.acc.access_fpreg = access_fpreg;
local_addr_space.acc.resume = x86_local_resume;
local_addr_space.acc.get_proc_name = get_static_proc_name;
+ unw_flush_cache (&local_addr_space, 0, 0);
}
#endif /* !UNW_REMOTE_ONLY */
diff --git a/src/x86/Ginit_local-x86.c b/src/x86/Ginit_local-x86.c
index 36feebb..76c297b 100644
--- a/src/x86/Ginit_local-x86.c
+++ b/src/x86/Ginit_local-x86.c
@@ -41,8 +41,10 @@
{
struct cursor *c = (struct cursor *) cursor;
- if (x86_needs_initialization)
- x86_init ();
+ if (tdep_needs_initialization)
+ tdep_init ();
+
+ Debug (2, "(cursor=%p)\n", c);
c->dwarf.as = unw_local_addr_space;
c->dwarf.as_arg = uc;
diff --git a/src/x86/Ginit_remote-x86.c b/src/x86/Ginit_remote-x86.c
index f3d1282..1cd395b 100644
--- a/src/x86/Ginit_remote-x86.c
+++ b/src/x86/Ginit_remote-x86.c
@@ -34,8 +34,10 @@
#else /* !UNW_LOCAL_ONLY */
struct cursor *c = (struct cursor *) cursor;
- if (x86_needs_initialization)
- x86_init ();
+ if (tdep_needs_initialization)
+ tdep_init ();
+
+ Debug (2, "(cursor=%p)\n", c);
c->dwarf.as = as;
c->dwarf.as_arg = as_arg;
diff --git a/src/x86/offsets.h b/src/x86/offsets.h
index b978d6c..96f06d1 100644
--- a/src/x86/offsets.h
+++ b/src/x86/offsets.h
@@ -2,16 +2,82 @@
/* Define various structure offsets to simplify cross-compilation. */
+/* Offsets for x86 Linux "ucontext_t": */
+
+#define LINUX_UC_FLAGS_OFF 0x00
+#define LINUX_UC_LINK_OFF 0x04
+#define LINUX_UC_STACK_OFF 0x08
+#define LINUX_UC_MCONTEXT_OFF 0x14
+#define LINUX_UC_SIGMASK_OFF 0x6c
+
/* The struct sigcontext is located at an offset of 4
from the stack pointer in the signal frame. */
-#define LINUX_SC_ESP_OFF 0x1c
-#define LINUX_SC_EBP_OFF 0x18
-#define LINUX_SC_EIP_OFF 0x38
+/* Offsets for x86 Linux "struct sigcontext": */
-/* With SA_SIGINFO set, we believe that basically the same
- layout is used for ucontext_t, except that 20 bytes are added
- at the beginning. */
-#define LINUX_UC_ESP_OFF (LINUX_SC_ESP_OFF+20)
-#define LINUX_UC_EBP_OFF (LINUX_SC_EBP_OFF+20)
-#define LINUX_UC_EIP_OFF (LINUX_SC_EIP_OFF+20)
+#define LINUX_SC_GS_OFF 0x00
+#define LINUX_SC_GSH_OFF 0x02
+#define LINUX_SC_FS_OFF 0x04
+#define LINUX_SC_FSH_OFF 0x06
+#define LINUX_SC_ES_OFF 0x08
+#define LINUX_SC_ESH_OFF 0x0a
+#define LINUX_SC_DS_OFF 0x0c
+#define LINUX_SC_DSH_OFF 0x0e
+#define LINUX_SC_EDI_OFF 0x10
+#define LINUX_SC_ESI_OFF 0x14
+#define LINUX_SC_EBP_OFF 0x18
+#define LINUX_SC_ESP_OFF 0x1c
+#define LINUX_SC_EBX_OFF 0x20
+#define LINUX_SC_EDX_OFF 0x24
+#define LINUX_SC_ECX_OFF 0x28
+#define LINUX_SC_EAX_OFF 0x2c
+#define LINUX_SC_TRAPNO_OFF 0x30
+#define LINUX_SC_ERR_OFF 0x34
+#define LINUX_SC_EIP_OFF 0x38
+#define LINUX_SC_CS_OFF 0x3c
+#define LINUX_SC_CSH_OFF 0x3e
+#define LINUX_SC_EFLAGS_OFF 0x40
+#define LINUX_SC_ESP_AT_SIGNAL_OFF 0x44
+#define LINUX_SC_SS_OFF 0x48
+#define LINUX_SC_SSH_OFF 0x4a
+#define LINUX_SC_FPSTATE_OFF 0x4c
+#define LINUX_SC_OLDMASK_OFF 0x50
+#define LINUX_SC_CR2_OFF 0x54
+
+/* Offsets for x86 Linux "struct _fpstate": */
+
+#define LINUX_FPSTATE_CW_OFF 0x000
+#define LINUX_FPSTATE_SW_OFF 0x004
+#define LINUX_FPSTATE_TAG_OFF 0x008
+#define LINUX_FPSTATE_IPOFF_OFF 0x00c
+#define LINUX_FPSTATE_CSSEL_OFF 0x010
+#define LINUX_FPSTATE_DATAOFF_OFF 0x014
+#define LINUX_FPSTATE_DATASEL_OFF 0x018
+#define LINUX_FPSTATE_ST0_OFF 0x01c
+#define LINUX_FPSTATE_ST1_OFF 0x026
+#define LINUX_FPSTATE_ST2_OFF 0x030
+#define LINUX_FPSTATE_ST3_OFF 0x03a
+#define LINUX_FPSTATE_ST4_OFF 0x044
+#define LINUX_FPSTATE_ST5_OFF 0x04e
+#define LINUX_FPSTATE_ST6_OFF 0x058
+#define LINUX_FPSTATE_ST7_OFF 0x062
+#define LINUX_FPSTATE_STATUS_OFF 0x06c
+#define LINUX_FPSTATE_MAGIC_OFF 0x06e
+#define LINUX_FPSTATE_FXSR_ENV_OFF 0x070
+#define LINUX_FPSTATE_MXCSR_OFF 0x088
+#define LINUX_FPSTATE_FXSR_ST0_OFF 0x090
+#define LINUX_FPSTATE_FXSR_ST1_OFF 0x0a0
+#define LINUX_FPSTATE_FXSR_ST2_OFF 0x0b0
+#define LINUX_FPSTATE_FXSR_ST3_OFF 0x0c0
+#define LINUX_FPSTATE_FXSR_ST4_OFF 0x0d0
+#define LINUX_FPSTATE_FXSR_ST5_OFF 0x0e0
+#define LINUX_FPSTATE_FXSR_ST6_OFF 0x0f0
+#define LINUX_FPSTATE_FXSR_ST7_OFF 0x100
+#define LINUX_FPSTATE_XMM0_OFF 0x110
+#define LINUX_FPSTATE_XMM1_OFF 0x120
+#define LINUX_FPSTATE_XMM2_OFF 0x130
+#define LINUX_FPSTATE_XMM3_OFF 0x140
+#define LINUX_FPSTATE_XMM4_OFF 0x150
+#define LINUX_FPSTATE_XMM5_OFF 0x160
+#define LINUX_FPSTATE_XMM6_OFF 0x170
+#define LINUX_FPSTATE_XMM7_OFF 0x180
diff --git a/src/x86/unwind_i.h b/src/x86/unwind_i.h
index 9e0b024..637e0eb 100644
--- a/src/x86/unwind_i.h
+++ b/src/x86/unwind_i.h
@@ -48,23 +48,14 @@
#define TRAPNO 10
#define ST0 11
-#define x86_lock UNW_ARCH_OBJ(lock)
-#define x86_needs_initialization UNW_ARCH_OBJ(needs_initialization)
-#define x86_init UNW_ARCH_OBJ(init)
-#define x86_access_reg UNW_OBJ(access_reg)
-#define x86_access_fpreg UNW_OBJ(access_fpreg)
+#define x86_lock UNW_OBJ(lock)
#define x86_local_resume UNW_OBJ(local_resume)
#define x86_local_addr_space_init UNW_OBJ(local_addr_space_init)
+#define x86_scratch_loc UNW_OBJ(scratch_loc)
-extern int x86_needs_initialization;
-
-extern void x86_init (void);
-extern int x86_access_reg (struct cursor *c, unw_regnum_t reg,
- unw_word_t *valp, int write);
-extern int x86_access_fpreg (struct cursor *c, unw_regnum_t reg,
- unw_fpreg_t *valp, int write);
extern void x86_local_addr_space_init (void);
extern int x86_local_resume (unw_addr_space_t as, unw_cursor_t *cursor,
void *arg);
+extern dwarf_loc_t x86_scratch_loc (struct cursor *c, unw_regnum_t reg);
#endif /* unwind_i_h */