----- Original Message ----- > On Mon, Feb 13, 2012 at 11:59:04AM -0500, Dave Anderson wrote: > > > Maybe add some comment explaining why we do this check (a reference to the > > > kernel commit perhaps)? > > > > I agree about the comment -- and then some... > > > > This seems to be a fairly signficant piece of information to be hidden > > in a static variable: > > > > +static int index_in_prel31; > > > > Can you put it in the ARM machine_specific data structure? And then > > display it in arm_dump_machdep_table() for "help -m". > > Here's a v2 of the patch. > > Rabin Nice -- queued for crash-6.0.4. Thanks, Dave > diff --git a/arm.c b/arm.c > index 4ca2fcd..4be224e 100644 > --- a/arm.c > +++ b/arm.c > @@ -406,6 +406,7 @@ arm_dump_machdep_table(ulong arg) > fprintf(fp, "exception_text_start: %lx\n", > ms->exception_text_start); > fprintf(fp, " exception_text_end: %lx\n", ms->exception_text_end); > fprintf(fp, " crash_task_regs: %lx\n", > (ulong)ms->crash_task_regs); > + fprintf(fp, "unwind_index_prel31: %d\n", ms->unwind_index_prel31); > } > > /* > diff --git a/defs.h b/defs.h > index 82d51e5..2e7f6bd 100755 > --- a/defs.h > +++ b/defs.h > @@ -4241,6 +4241,7 @@ struct machine_specific { > ulong exception_text_start; > ulong exception_text_end; > struct arm_pt_regs *crash_task_regs; > + int unwind_index_prel31; > }; > > int init_unwind_tables(void); > diff --git a/unwind_arm.c b/unwind_arm.c > index d86ec63..640d6c9 100644 > --- a/unwind_arm.c > +++ b/unwind_arm.c > @@ -104,6 +104,7 @@ static int is_core_kernel_text(ulong); > static struct unwind_table *search_table(ulong); > static struct unwind_idx *search_index(const struct unwind_table *, > ulong); > static ulong prel31_to_addr(ulong, ulong); > +static void index_prel31_to_addr(struct unwind_table *); > static int unwind_frame(struct stackframe *, ulong); > > /* > @@ -187,6 +188,19 @@ init_kernel_unwind_table(void) > goto fail; > } > > + /* > + * Kernel versions before v3.2 (specifically, before commit > + * de66a979012db "ARM: 7187/1: fix unwinding for XIP kernels") > + * converted the prel31 offsets in the unwind index table to absolute > + * addresses on startup. Newer kernels don't perform this conversion, > + * and have a slightly more involved search algorithm. > + * > + * We always just use the older search method (a straightforward binary > + * search) and convert the index table offsets ourselves if we detect > + * that the kernel didn't do it. > + */ > + machdep->machspec->unwind_index_prel31 = !is_kernel_text(kernel_unwind_table->idx[0].addr); > + > kernel_unwind_table->start = kernel_unwind_table->idx; > kernel_unwind_table->end = (struct unwind_idx *) > ((char *)kernel_unwind_table->idx + idx_size); > @@ -194,6 +208,9 @@ init_kernel_unwind_table(void) > kernel_unwind_table->end_addr = (kernel_unwind_table->end - 1)->addr; > kernel_unwind_table->kv_base = idx_start; > > + if (machdep->machspec->unwind_index_prel31) > + index_prel31_to_addr(kernel_unwind_table); > + > if (CRASHDEBUG(1)) { > fprintf(fp, "UNWIND: master kernel table start\n"); > fprintf(fp, "UNWIND: size : %ld\n", idx_size); > @@ -260,6 +277,9 @@ read_module_unwind_table(struct unwind_table *tbl, ulong addr) > tbl->end_addr = TABLE_VALUE(buf, unwind_table_end_addr); > tbl->kv_base = idx_start; > > + if (machdep->machspec->unwind_index_prel31) > + index_prel31_to_addr(tbl); > + > if (CRASHDEBUG(1)) { > fprintf(fp, "UNWIND: module table start\n"); > fprintf(fp, "UNWIND: start : %p\n", tbl->start); > @@ -571,6 +591,16 @@ prel31_to_addr(ulong addr, ulong insn) > return addr + offset; > } > > +static void > +index_prel31_to_addr(struct unwind_table *tbl) > +{ > + struct unwind_idx *idx = tbl->start; > + ulong kvaddr = tbl->kv_base; > + > + for (; idx < tbl->end; idx++, kvaddr += sizeof(struct unwind_idx)) > + idx->addr = prel31_to_addr(kvaddr, idx->addr); > +} > + > static int > unwind_frame(struct stackframe *frame, ulong stacktop) > { -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility