History log of /arch/sh/include/asm/dwarf.h
Revision Date Author Comments
858918b77b29d0e9ce7f524d1b57d602d85f5d64 07-Feb-2010 Matt Fleming <matt@console-pimps.org> sh: Optimise FDE/CIE lookup by using red-black trees

Now that the DWARF unwinder is being used to provide perf callstacks
unwinding speed is an issue. It is no longer being used in exceptional
circumstances where we don't care about runtime performance, e.g. when
panicing, so it makes sense improve performance is possible.

With this patch I saw a 42% improvement in unwind time when calling
return_address(1). Greater improvements will be seen as the number of
levels unwound increases as each unwind is now cheaper.

Note that insertion time has doubled but that's just the price we pay
for keeping the trees balanced. However, this is a one-time cost for
kernel boot/module load and so the improvements in lookup time dominate
the extra time we spend keeping the trees balanced.

Signed-off-by: Matt Fleming <matt@console-pimps.org>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
5a3abba77dc0eb0b00332c21899123cdfa3b19e5 13-Oct-2009 Paul Mundt <lethal@linux-sh.org> sh: Tidy up the dwarf module helpers.

This enables us to build the dwarf unwinder both with modules enabled and
disabled in addition to reducing code size in the latter case. The
helpers are also consolidated, and modified to resemble the BUG module
helpers.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
ac4fac8cb24ab209ae373a3e3e9995dff7d0c394 13-Oct-2009 Paul Mundt <lethal@linux-sh.org> sh: Generalize CALLER_ADDRx support.

This splits out the unwinder implementation and adds a new
return_address() abstraction modelled after the ARM code. The DWARF
unwinder is tied in to this, returning NULL otherwise in the case of
being unable to support arbitrary depths.

This enables us to get correct behaviour with the unwinder enabled,
as well as disabling the arbitrary depth support when frame pointers are
enabled, as arbitrary depths with __builtin_return_address() are not
supported regardless.

With this abstraction it's also possible to layer on a simplified
implementation with frame pointers in the event that the unwinder isn't
enabled, although this is left as a future exercise.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
ed4fe7f488008f38d5f423f0bcc736b1779d6ddc 10-Oct-2009 Matt Fleming <matt@console-pimps.org> sh: Fix memory leak in dwarf_unwind_stack()

If we broke out of the while (1) loop because the return address of
"frame" was zero, then "frame" needs to be free'd before we return.

Signed-off-by: Matt Fleming <matt@console-pimps.org>
a6a2f2ad67506090e332f440457553c0ec011d68 10-Oct-2009 Matt Fleming <matt@console-pimps.org> sh: Teach the DWARF unwinder about modules

Pass a module's .eh_frame section to the DWARF unwinder at module load
time so that the section's FDEs and CIEs can be registered with the
DWARF unwinder. This allows us to unwind the stack through module code
when generating backtraces.

Signed-off-by: Matt Fleming <matt@console-pimps.org>
2f6dafc5fcbf3fddce345c47da1f277a156fe22a 31-Aug-2009 Paul Mundt <lethal@linux-sh.org> sh: unwinder: Fix up uninitialized variable warnings on sh2a build.

A couple of these popped up on the sh2a build, causing build failures.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
5580e9044df9c0e87861739d8c527006ead92e52 20-Aug-2009 Matt Fleming <matt@console-pimps.org> sh: Handle the DWARF op, DW_CFA_undefined

Allow a DWARF register to have an undefined value. When applied to the
DWARF return address register this lets lets us label a function as
having no direct caller, e.g. kernel_thread_helper().

Signed-off-by: Matt Fleming <matt@console-pimps.org>
97efbbd5886e27b61c19c77d41f6491f5d96fbd0 16-Aug-2009 Matt Fleming <matt@console-pimps.org> sh: unwinder: Set the flags for DW_CFA_val_offset ops as DWARF_VAL_OFFSET

The handling of DW_CFA_val_offset ops was incorrectly using the
DWARF_REG_OFFSET flag but the register's value cannot be calculated
using the DWARF_REG_OFFSET method. Create a new flag to indicate that a
different method must be used to calculate the register's value even
though there is no implementation for DWARF_VAL_OFFSET yet; it's mainly
just a place holder.

Signed-off-by: Matt Fleming <matt@console-pimps.org>
fb3f3e7fc6d4afb32f9eba32124beaf40313de3c 16-Aug-2009 Matt Fleming <matt@console-pimps.org> sh: unwinder: Fix memory leak and create our own kmem cache

Plug a memory leak in dwarf_unwinder_dump() where we didn't free the
memory that we had previously allocated for the DWARF frames and DWARF
registers.

Now is also a opportune time to implement our own mempool and kmem
cache. It's a good idea to have a certain number of frame and register
objects in reserve at all times, so that we are guaranteed to have our
allocation satisfied even when memory is scarce. Since we have pools to
allocate from we can implement the registers for each frame as a linked
list as opposed to a sparsely populated array. Whilst it's true that the
lookup time for a linked list is larger than for arrays, there's only
usually a maximum of 8 registers per frame. So the overhead isn't that
much of a concern.

Signed-off-by: Matt Fleming <matt@console-pimps.org>
97f361e2498ada54b48a235619eaf5af8e46427e 16-Aug-2009 Paul Mundt <lethal@linux-sh.org> sh: unwinder: Move initialization to early_initcall() and tidy up locking.

This moves the initialization over to an early_initcall(). This fixes up
some lockdep interaction issues. At the same time, kill off some
superfluous locking in the init path.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
cd7246f0e2747bd2b43d25d0f63f05db182a62c0 16-Aug-2009 Matt Fleming <matt@console-pimps.org> sh: Add support for DWARF GNU extensions

Also, remove the "fix" to DW_CFA_def_cfa_register where we reset the
frame's cfa_offset to 0. This action is incorrect when handling
DW_CFA_def_cfa_register as the DWARF spec specifically states that the
previous contents of cfa_offset should be used with the new
register. The reason that I thought cfa_offset should be reset to 0 was
because it was being assigned a bogus value prior to executing the
DW_CFA_def_cfa_register op. It turns out that the bogus cfa_offset value
came from interpreting .cfi_escape pseudo-ops (those used by the GNU
extensions) as CFA_DW_def_cfa ops.

Signed-off-by: Matt Fleming <matt@console-pimps.org>
f826466772ae52f26152287fcb2259351de78f0f 13-Aug-2009 Matt Fleming <matt@console-pimps.org> sh: Delete DWARF_ARCH_UNWIND_OFFSET

Trying to figure out the best value for DWARF_ARCH_UNWIND_OFFSET is
tricky at best. Various things can change the size (and offset from the
beginning of the function) of the prologue. Notably, turning on ftrace
adds calls to mcount at the beginning of functions, thereby pushing the
prologue further into the function.

So replace DWARF_ARCH_UNWIND_OFFSET with some code that continues to
execute CFA instructions until the value of return address register is
defined. This is safe to do because we know that the return address must
have been pushed onto the frame before our first function call; we just
can't figure out where at compile-time.

Signed-off-by: Matt Fleming <matt@console-pimps.org>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
bd353861c735b2265c9d8b2559960c693e7c68ab 13-Aug-2009 Matt Fleming <matt@console-pimps.org> sh: dwarf unwinder support.

This is a first cut at a generic DWARF unwinder for the kernel. It's
still lacking DWARF64 support and the DWARF expression support hasn't
been tested very well but it is generating proper stacktraces on SH for
WARN_ON() and NULL dereferences.

Signed-off-by: Matt Fleming <matt@console-pimps.org>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>