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 */