From 09fa543f68b023479fb3705fe2544ec257368201 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Tue, 9 Sep 2008 21:11:21 +0200 Subject: Add new function _stp_mod_sec_lookup extracted from _stp_kallsyms_lookup. --- runtime/ChangeLog | 5 +++++ runtime/sym.c | 55 ++++++++++++++++++++++++++++++++----------------------- 2 files changed, 37 insertions(+), 23 deletions(-) (limited to 'runtime') diff --git a/runtime/ChangeLog b/runtime/ChangeLog index f7a844d8..b51a2c9b 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -13,6 +13,11 @@ * syscall.h: Added ia64 support. +2008-09-09 Mark Wielaard + + * sym.c (_stp_mod_sec_lookup): New function, extracted from + _stp_kallsyms_lookup. + 2008-09-09 Mark Wielaard * sym.c (_stp_kallsyms_lookup): Correct this_section_offset diff --git a/runtime/sym.c b/runtime/sym.c index b594d9c2..1a9e26b2 100644 --- a/runtime/sym.c +++ b/runtime/sym.c @@ -73,6 +73,37 @@ unsigned long _stp_module_relocate(const char *module, const char *section, unsi } +/* Return module owner and fills in closest section of the address + if found, return NULL otherwise. + XXX: needs to be address-space-specific. */ +static struct _stp_module *_stp_mod_sec_lookup(unsigned long addr, + struct _stp_section **sec) +{ + struct _stp_module *m = NULL; + unsigned midx = 0; + unsigned long closest_section_offset = ~0; + for (midx = 0; midx < _stp_num_modules; midx++) + { + unsigned secidx; + for (secidx = 0; secidx < _stp_modules[midx]->num_sections; secidx++) + { + unsigned long this_section_addr; + unsigned long this_section_offset; + this_section_addr = _stp_modules[midx]->sections[secidx].addr; + if (addr < this_section_addr) continue; + this_section_offset = addr - this_section_addr; + if (this_section_offset < closest_section_offset) + { + closest_section_offset = this_section_offset; + m = _stp_modules[midx]; + *sec = & m->sections[secidx]; + } + } + } + return m; +} + + /* XXX: needs to be address-space-specific. */ static const char *_stp_kallsyms_lookup(unsigned long addr, unsigned long *symbolsize, unsigned long *offset, @@ -86,29 +117,7 @@ static const char *_stp_kallsyms_lookup(unsigned long addr, unsigned long *symbo unsigned long flags; unsigned end, begin = 0; - /* Find the closest section (and its owner module); fill in m & sec. */ - { - unsigned midx = 0; - unsigned long closest_section_offset = ~0; - for (midx = 0; midx < _stp_num_modules; midx++) - { - unsigned secidx; - for (secidx = 0; secidx < _stp_modules[midx]->num_sections; secidx++) - { - unsigned long this_section_addr = _stp_modules[midx]->sections[secidx].addr; - unsigned long this_section_offset; - if (addr < this_section_addr) continue; - this_section_offset = addr - this_section_addr; - if (this_section_offset < closest_section_offset) - { - closest_section_offset = this_section_offset; - m = _stp_modules[midx]; - sec = & m->sections[secidx]; - } - } - } - } - + m = _stp_mod_sec_lookup(addr, &sec); if (unlikely (m == NULL || sec == NULL)) return NULL; -- cgit From f6f5a33817ac1d406c8c2687e32493cbc38ef4e7 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 10 Sep 2008 13:21:50 +0200 Subject: Feed dwarf unwinder data through _stp_mod_sec_lookup (), but disabled for now. --- runtime/ChangeLog | 8 ++++++++ runtime/runtime.h | 6 ++++-- runtime/stack-x86_64.c | 2 +- runtime/unwind.c | 3 ++- 4 files changed, 15 insertions(+), 4 deletions(-) (limited to 'runtime') diff --git a/runtime/ChangeLog b/runtime/ChangeLog index b51a2c9b..7502bf34 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,11 @@ +2008-09-10 Mark Wielaard + + * unwind.c (unwind): Use _stp_mod_sec_lookup to get module and + unwind tables. + * runtime.h (STP_USE_FRAME_BUFFER): Disable by default for now. + * stack-x86_64.c (__stp_stack_print): Add levels to + _stp_stack_print_fallback call. + 2008-09-09 Masami Hiramatsu * regs-ia64.c (__ia64_fetch_register): Return the address of the diff --git a/runtime/runtime.h b/runtime/runtime.h index fd0cac9e..52d689a3 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -73,8 +73,10 @@ static struct #endif #endif -/* dwarf unwinder only tested so far on i386 and x86_64 */ -#if !defined(STP_USE_FRAME_BUFFER) && (defined(__i386__) || defined(__x86_64__)) +/* dwarf unwinder only tested so far on i386 and x86_64, + but globally disabled for now */ +#if 0 +// !defined(STP_USE_FRAME_BUFFER) && (defined(__i386__) || defined(__x86_64__)) #define STP_USE_DWARF_UNWINDER #endif diff --git a/runtime/stack-x86_64.c b/runtime/stack-x86_64.c index 783e72bd..d3ec91cf 100644 --- a/runtime/stack-x86_64.c +++ b/runtime/stack-x86_64.c @@ -45,6 +45,6 @@ static void __stp_stack_print(struct pt_regs *regs, int verbose, int levels) break; } #else /* ! STP_USE_DWARF_UNWINDER */ - _stp_stack_print_fallback(REG_SP(regs), verbose); + _stp_stack_print_fallback(REG_SP(regs), verbose, levels); #endif } diff --git a/runtime/unwind.c b/runtime/unwind.c index 21ea4559..7b19573d 100644 --- a/runtime/unwind.c +++ b/runtime/unwind.c @@ -676,6 +676,7 @@ int unwind(struct unwind_frame_info *frame) signed ptrType = -1; uleb128_t retAddrReg = 0; struct _stp_module *m; + struct _stp_section *s = NULL; struct unwind_state state; dbug_unwind(1, "pc=%lx, %lx", pc, UNW_PC(frame)); @@ -683,7 +684,7 @@ int unwind(struct unwind_frame_info *frame) if (UNW_PC(frame) == 0) return -EINVAL; - m = NULL /*_stp_get_unwind_info(pc) */; + m = _stp_mod_sec_lookup (pc, &s); if (unlikely(m == NULL)) { dbug_unwind(1, "No module found for pc=%lx", pc); return -EINVAL; -- cgit From 6b2fda5424fb9aaeabe5056fc1e7286f6c8a034a Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 10 Sep 2008 13:51:30 +0200 Subject: Record module base and use it for adjusting start locations in dwarf unwinder. --- runtime/ChangeLog | 7 +++++++ runtime/sym.h | 2 ++ runtime/unwind.c | 27 ++++++++++++++++++++++++--- 3 files changed, 33 insertions(+), 3 deletions(-) (limited to 'runtime') diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 7502bf34..d794b4a1 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,10 @@ +2008-09-10 Mark Wielaard + + * sym.h (_stp_module): Add module_base field. + * unwind.c (adjustStartLoc): New function. + (_stp_search_unwind_hdr): Use adjustStartLoc. + (unwind): Likewise. + 2008-09-10 Mark Wielaard * unwind.c (unwind): Use _stp_mod_sec_lookup to get module and diff --git a/runtime/sym.h b/runtime/sym.h index b2fb8ee9..564f4eb2 100644 --- a/runtime/sym.h +++ b/runtime/sym.h @@ -34,6 +34,8 @@ struct _stp_module { /* is unloading. */ unsigned long module; /* XXX: why not struct module * ? */ + unsigned long module_base; + /* the stack unwind data for this module */ void *unwind_data; void *unwind_hdr; diff --git a/runtime/unwind.c b/runtime/unwind.c index 7b19573d..db8ae664 100644 --- a/runtime/unwind.c +++ b/runtime/unwind.c @@ -550,10 +550,27 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc, s return result && ptr.p8 == end && (targetLoc == 0 || state->label == NULL); } +// This is an address inside a module, adjust. +static unsigned long +adjustStartLoc (unsigned long startLoc, + struct _stp_module *m, + struct _stp_section *s) +{ + if (startLoc && (strcmp (m->name, "kernel") != 0)) + { + startLoc = _stp_module_relocate (m->name, s->name, + startLoc); + startLoc -= m->module_base; + } + return startLoc; +} + /* If we previously created an unwind header, then use it now to binary search */ /* for the FDE corresponding to pc. */ -static u32 *_stp_search_unwind_hdr(unsigned long pc, struct _stp_module *m) +static u32 *_stp_search_unwind_hdr(unsigned long pc, + struct _stp_module *m, + struct _stp_section *s) { const u8 *ptr, *end, *hdr = m->unwind_hdr; unsigned long startLoc; @@ -600,6 +617,7 @@ static u32 *_stp_search_unwind_hdr(unsigned long pc, struct _stp_module *m) do { const u8 *cur = ptr + (num / 2) * (2 * tableSize); startLoc = read_pointer(&cur, cur + tableSize, hdr[3]); + startLoc = adjustStartLoc(startLoc, m, s); if (pc < startLoc) num /= 2; else { @@ -608,7 +626,7 @@ static u32 *_stp_search_unwind_hdr(unsigned long pc, struct _stp_module *m) } } while (startLoc && num > 1); - if (num == 1 && (startLoc = read_pointer(&ptr, ptr + tableSize, hdr[3])) != 0 && pc >= startLoc) + if (num == 1 && (startLoc = adjustStartLoc(read_pointer(&ptr, ptr + tableSize, hdr[3]), m, s)) != 0 && pc >= startLoc) fde = (void *)read_pointer(&ptr, ptr + tableSize, hdr[3]); dbug_unwind(1, "returning fde=%lx startLoc=%lx", fde, startLoc); @@ -695,7 +713,7 @@ int unwind(struct unwind_frame_info *frame) goto err; } - fde = _stp_search_unwind_hdr(pc, m); + fde = _stp_search_unwind_hdr(pc, m, s); dbug_unwind(1, "%s: fde=%lx\n", m->name, fde); /* found the fde, now set startLoc and endLoc */ @@ -705,6 +723,8 @@ int unwind(struct unwind_frame_info *frame) ptr = (const u8 *)(fde + 2); ptrType = fde_pointer_type(cie); startLoc = read_pointer(&ptr, (const u8 *)(fde + 1) + *fde, ptrType); + startLoc = adjustStartLoc(startLoc, m, s); + dbug_unwind(2, "startLoc=%lx, ptrType=%s", startLoc, _stp_eh_enc_name(ptrType)); if (!(ptrType & DW_EH_PE_indirect)) ptrType &= DW_EH_PE_FORM | DW_EH_PE_signed; @@ -734,6 +754,7 @@ int unwind(struct unwind_frame_info *frame) ptr = (const u8 *)(fde + 2); startLoc = read_pointer(&ptr, (const u8 *)(fde + 1) + *fde, ptrType); + startLoc = adjustStartLoc(startLoc, m, s); dbug_unwind(2, "startLoc=%lx, ptrType=%s", startLoc, _stp_eh_enc_name(ptrType)); if (!startLoc) continue; -- cgit From e0c72583f8fb7a61d052c58b8e9c6df0925bc234 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 10 Sep 2008 15:17:52 +0200 Subject: Enable usage of STP_USE_DWARF_UNWINDER for i386 and arm for debugging purposes. --- runtime/ChangeLog | 5 +++++ runtime/runtime.h | 2 ++ 2 files changed, 7 insertions(+) (limited to 'runtime') diff --git a/runtime/ChangeLog b/runtime/ChangeLog index d794b4a1..6ff15b8a 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,8 @@ +2008-09-10 Mark Wielaard + + * runtime.h (CONFIG_FRAME_POINTER): Don't enable when + STP_USE_DWARF_UNWINDER is already defined. + 2008-09-10 Mark Wielaard * sym.h (_stp_module): Add module_base field. diff --git a/runtime/runtime.h b/runtime/runtime.h index 52d689a3..db793aa5 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -68,10 +68,12 @@ static struct #ifdef CONFIG_FRAME_POINTER /* Just because frame pointers are available does not mean we can trust them. */ +#ifndef STP_USE_DWARF_UNWINDER #if defined (__i386__) || defined (__arm__) #define STP_USE_FRAME_POINTER #endif #endif +#endif /* dwarf unwinder only tested so far on i386 and x86_64, but globally disabled for now */ -- cgit From 675fb1ddeec8cd22e17ab989f8a813a375ae6226 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 10 Sep 2008 17:43:42 +0200 Subject: Rename _stp_module module_base output to dwarf_module_base and document. --- runtime/ChangeLog | 5 +++++ runtime/sym.h | 7 +++++-- runtime/unwind.c | 6 ++++-- 3 files changed, 14 insertions(+), 4 deletions(-) (limited to 'runtime') diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 6ff15b8a..2438ee5e 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,8 @@ +2008-09-10 Mark Wielaard + + * sym.h (_stp_module): Rename module_base to dwarf_module_base. + * unwind.c (adjustStartLoc): Document and use dwarf_module_base. + 2008-09-10 Mark Wielaard * runtime.h (CONFIG_FRAME_POINTER): Don't enable when diff --git a/runtime/sym.h b/runtime/sym.h index 564f4eb2..5888d2c7 100644 --- a/runtime/sym.h +++ b/runtime/sym.h @@ -33,8 +33,11 @@ struct _stp_module { /* any notifier hooks that will tell us when a module */ /* is unloading. */ unsigned long module; /* XXX: why not struct module * ? */ - - unsigned long module_base; + + /* This is to undo .debug_frame relocation performed by elfutils, */ + /* which is done during the translate phase when we encode the */ + /* unwind data into the module. See adjustStartLoc() in unwind.c. */ + unsigned long dwarf_module_base; /* the stack unwind data for this module */ void *unwind_data; diff --git a/runtime/unwind.c b/runtime/unwind.c index db8ae664..bc8a93dc 100644 --- a/runtime/unwind.c +++ b/runtime/unwind.c @@ -550,7 +550,9 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc, s return result && ptr.p8 == end && (targetLoc == 0 || state->label == NULL); } -// This is an address inside a module, adjust. +// If this is an address inside a module, adjust for section relocation +// and the elfutils base relocation done during loading of the .dwarf_frame +// in translate.cxx. static unsigned long adjustStartLoc (unsigned long startLoc, struct _stp_module *m, @@ -560,7 +562,7 @@ adjustStartLoc (unsigned long startLoc, { startLoc = _stp_module_relocate (m->name, s->name, startLoc); - startLoc -= m->module_base; + startLoc -= m->dwarf_module_base; } return startLoc; } -- cgit From da4c496a55b73e2a768d3b1c6cee44b43144bcc8 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Wed, 10 Sep 2008 17:18:41 -0400 Subject: backtrace fix for i386 with neither frame pointers nor dwarf unwinding --- runtime/ChangeLog | 8 ++++++++ runtime/runtime.h | 4 +--- runtime/stack-i386.c | 6 +++++- 3 files changed, 14 insertions(+), 4 deletions(-) (limited to 'runtime') diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 2438ee5e..97b1a0c0 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,11 @@ +2008-09-10 Frank Ch. Eigler + + * runtime.h (STP_USE_FRAME_POINTER): Remove architecture #if's. + All will activate it if CONFIG_FRAME_POINTER unless + STP_USE_DWARF_UNWINDER. + * stack-i386.c: (__stp_stack_print): Handle !DWARF and !FRAME + configuration. + 2008-09-10 Mark Wielaard * sym.h (_stp_module): Rename module_base to dwarf_module_base. diff --git a/runtime/runtime.h b/runtime/runtime.h index db793aa5..cd3d0b11 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -69,15 +69,13 @@ static struct #ifdef CONFIG_FRAME_POINTER /* Just because frame pointers are available does not mean we can trust them. */ #ifndef STP_USE_DWARF_UNWINDER -#if defined (__i386__) || defined (__arm__) #define STP_USE_FRAME_POINTER #endif #endif -#endif /* dwarf unwinder only tested so far on i386 and x86_64, but globally disabled for now */ -#if 0 +#if 0 // !defined(STP_USE_FRAME_BUFFER) && (defined(__i386__) || defined(__x86_64__)) #define STP_USE_DWARF_UNWINDER #endif diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c index ad101889..ed7e2ce1 100644 --- a/runtime/stack-i386.c +++ b/runtime/stack-i386.c @@ -54,9 +54,10 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) fp = next_fp; } #else +#ifdef STP_USE_DWARF_UNWINDER struct unwind_frame_info info; arch_unw_init_frame_info(&info, regs); - + while (levels && !arch_unw_user_mode(&info)) { int ret = unwind(&info); dbug_unwind(1, "ret=%d PC=%lx SP=%lx\n", ret, UNW_PC(&info), UNW_SP(&info)); @@ -71,5 +72,8 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels) _stp_stack_print_fallback(context, UNW_SP(&info), verbose, levels); break; } +#else /* ! STP_USE_DWARF_UNWINDER */ + _stp_stack_print_fallback(context, (unsigned long)®_SP(regs), verbose, levels); #endif /* STP_USE_FRAME_POINTER */ +#endif } -- cgit