• Uwe Kleine-König's avatar
    ARM: 7187/1: fix unwinding for XIP kernels · de66a979
    Uwe Kleine-König authored
    The linker places the unwind tables in readonly sections. So when using
    an XIP kernel these are located in ROM and cannot be modified.
    For that reason the current approach to convert the relative offsets in
    the unwind index to absolute addresses early in the boot process doesn't
    work with XIP.
    
    The offsets in the unwind index section are signed 31 bit numbers and
    the structs are sorted by this offset. So it first has offsets between
    0x40000000 and 0x7fffffff (i.e. the negative offsets) and then offsets
    between 0x00000000 and 0x3fffffff. When seperating these two blocks the
    numbers are sorted even when interpreting the offsets as unsigned longs.
    
    So determine the first non-negative entry once and track that using the
    new origin pointer. The actual bisection can then use a plain unsigned
    long comparison. The only thing that makes the new bisection more
    complicated is that the offsets are relative to their position in the
    index section, so the key to search needs to be adapted accordingly in
    each step.
    
    Moreover several consts are added to catch future writes and rename the
    member "addr" of struct unwind_idx to "addr_offset" to better match the
    new semantic. (This has the additional benefit of breaking eventual
    users at compile time to make them aware of the change.)
    
    In my tests the new algorithm was a tad faster than the original and has
    the additional upside of not needing the initial conversion and so saves
    some boot time and it's possible to unwind even earlier.
    Acked-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
    Acked-by: default avatarNicolas Pitre <nico@fluxnic.net>
    Signed-off-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
    Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
    de66a979
unwind.h 1.71 KB