diff options
author | Mark Wielaard <mwielaard@redhat.com> | 2008-09-10 13:51:30 +0200 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2008-09-10 14:01:32 +0200 |
commit | 6b2fda5424fb9aaeabe5056fc1e7286f6c8a034a (patch) | |
tree | 8dc8f120ebb03863298f8321e62b2251962c6ee7 | |
parent | f6f5a33817ac1d406c8c2687e32493cbc38ef4e7 (diff) | |
download | systemtap-steved-6b2fda5424fb9aaeabe5056fc1e7286f6c8a034a.tar.gz systemtap-steved-6b2fda5424fb9aaeabe5056fc1e7286f6c8a034a.tar.xz systemtap-steved-6b2fda5424fb9aaeabe5056fc1e7286f6c8a034a.zip |
Record module base and use it for adjusting start locations in dwarf unwinder.
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | runtime/ChangeLog | 7 | ||||
-rw-r--r-- | runtime/sym.h | 2 | ||||
-rw-r--r-- | runtime/unwind.c | 27 | ||||
-rw-r--r-- | translate.cxx | 1 |
5 files changed, 38 insertions, 3 deletions
@@ -1,5 +1,9 @@ 2008-09-10 Mark Wielaard <mjw@redhat.com> + * translate.cxx (dump_unwindsyms): Output module_base. + +2008-09-10 Mark Wielaard <mjw@redhat.com> + * translate.cxx (get_unwind_data): New function. (dump_unwindsyms): Output unwind data. diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 7502bf34..d794b4a1 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,5 +1,12 @@ 2008-09-10 Mark Wielaard <mjw@redhat.com> + * 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 <mjw@redhat.com> + * 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. 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; diff --git a/translate.cxx b/translate.cxx index d4507a1f..7c1469df 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4551,6 +4551,7 @@ dump_unwindsyms (Dwfl_Module *m, c->output << "struct _stp_module _stp_module_" << stpmod_idx << " = {" << endl; c->output << ".name = " << lex_cast_qstring (modname) << ", " << endl; + c->output << ".module_base = 0x" << hex << base << dec << ", " << endl; if (unwind != NULL) { |