Ignore:
Timestamp:
2010-10-19T20:55:53Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a93d79a
Parents:
1882525 (diff), a7a85d16 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/mips32/src/debug/stacktrace.c

    r1882525 rf14291b  
    3131 */
    3232/** @file
     33 */
     34
     35/*
     36 * This stack tracing code is based on the suggested algorithm described on page
     37 * 3-27 and 3-28 of:
     38 *
     39 * SYSTEM V
     40 * APPLICATION BINARY INTERFACE
     41 *
     42 * MIPS RISC Processor
     43 * Supplement
     44 * 3rd Edition
     45 *
     46 * Unfortunately, GCC generates code which is not entirely compliant with this
     47 * method. For example, it places the "jr ra" instruction quite arbitrarily in
     48 * the middle of the function which makes the original algorithm unapplicable.
     49 *
     50 * We deal with this problem by simply not using those parts of the algorithm
     51 * that rely on the "jr ra" instruction occurring in the last basic block of a
     52 * function, which gives us still usable, but less reliable stack tracer. The
     53 * unreliability stems from the fact that under some circumstances it can become
     54 * confused and produce incorrect or incomplete stack trace. We apply extra
     55 * sanity checks so that the algorithm is still safe and should not crash the
     56 * system.
     57 *
     58 * Even though not perfect, our solution is pretty lightweight, especially when
     59 * compared with a prospective alternative solution based on additional
     60 * debugging information stored directly in the kernel image.
    3361 */
    3462
     
    96124extern char ktext_end;
    97125
     126static bool bounds_check(uintptr_t pc)
     127{
     128        return (pc >= (uintptr_t) &ktext_start) &&
     129            (pc < (uintptr_t) &ktext_end);
     130}
     131
    98132static bool
    99133scan(stack_trace_context_t *ctx, uintptr_t *prev_fp, uintptr_t *prev_ra)
     
    106140        do {
    107141                inst--;
     142                if (!bounds_check((uintptr_t) inst))
     143                        return false;
    108144#if 0
    109145                /*
     
    180216                                        return false;
    181217                                /* too big offsets are suspicious */
    182                                 if (offset > 32 * 4)
     218                                if ((size_t) offset > sizeof(istate_t))
    183219                                        return false;
    184220
     
    207243{
    208244        return !((ctx->fp == 0) || ((ctx->fp % 8) != 0) ||
    209             (ctx->pc % 4 != 0) || (ctx->pc < (uintptr_t) &ktext_start) ||
    210             (ctx->pc >= (uintptr_t) &ktext_end));
     245            (ctx->pc % 4 != 0) || !bounds_check(ctx->pc));
    211246}
    212247
Note: See TracChangeset for help on using the changeset viewer.