Ignore:
File:
1 edited

Legend:

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

    r76e1121f r63bdde6  
    3333 */
    3434
    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.
    61  */
    62 
    6335#include <stacktrace.h>
    6436#include <syscall/copy.h>
     
    12496extern char ktext_end;
    12597
    126 static bool bounds_check(uintptr_t pc)
    127 {
    128         return (pc >= (uintptr_t) &ktext_start) &&
    129             (pc < (uintptr_t) &ktext_end);
    130 }
    131 
    13298static bool
    13399scan(stack_trace_context_t *ctx, uintptr_t *prev_fp, uintptr_t *prev_ra)
     
    140106        do {
    141107                inst--;
    142                 if (!bounds_check((uintptr_t) inst))
    143                         return false;
    144108#if 0
    145109                /*
     
    216180                                        return false;
    217181                                /* too big offsets are suspicious */
    218                                 if ((size_t) offset > sizeof(istate_t))
     182                                if (offset > 32 * 4)
    219183                                        return false;
    220184
     
    243207{
    244208        return !((ctx->fp == 0) || ((ctx->fp % 8) != 0) ||
    245             (ctx->pc % 4 != 0) || !bounds_check(ctx->pc));
     209            (ctx->pc % 4 != 0) || (ctx->pc < (uintptr_t) &ktext_start) ||
     210            (ctx->pc >= (uintptr_t) &ktext_end));
    246211}
    247212
Note: See TracChangeset for help on using the changeset viewer.