From fcd8dad37efa05fd6090a68fe24b66a0ca7856ee Mon Sep 17 00:00:00 2001 From: "hp.com!davidm" Date: Fri, 30 Jan 2004 00:01:24 +0000 Subject: [PATCH] Update. (Logical change 1.162) --- TODO | 5 ++- src/x86/Ginit-x86.c | 37 +++++++++-------- src/x86/Ginit_local-x86.c | 6 ++- src/x86/Ginit_remote-x86.c | 6 ++- src/x86/offsets.h | 84 ++++++++++++++++++++++++++++++++++---- src/x86/unwind_i.h | 15 ++----- 6 files changed, 109 insertions(+), 44 deletions(-) diff --git a/TODO b/TODO index 785a8905..a4078cba 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 @@ Testing: === 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 fdb1936c..c13085c8 100644 --- a/src/x86/Ginit-x86.c +++ b/src/x86/Ginit-x86.c @@ -46,6 +46,10 @@ uc_addr (ucontext_t *uc, int reg) 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 @@ uc_addr (ucontext_t *uc, int reg) 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 @@ uc_addr (ucontext_t *uc, int reg) # 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 @@ access_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, 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 @@ static int 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 @@ access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, 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 @@ x86_local_addr_space_init (void) 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 36feebb7..76c297b3 100644 --- a/src/x86/Ginit_local-x86.c +++ b/src/x86/Ginit_local-x86.c @@ -41,8 +41,10 @@ unw_init_local (unw_cursor_t *cursor, ucontext_t *uc) { 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 f3d12829..1cd395b0 100644 --- a/src/x86/Ginit_remote-x86.c +++ b/src/x86/Ginit_remote-x86.c @@ -34,8 +34,10 @@ unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg) #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 b978d6cd..96f06d1f 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 9e0b024d..637e0eb6 100644 --- a/src/x86/unwind_i.h +++ b/src/x86/unwind_i.h @@ -48,23 +48,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #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 */