The attached patch fixes a problem with Xorg on MIPS64 n32 which is explained here:
https://bugs.freedesktop.org/show_bug.cgi?id=79939
Basically, libunwind is using a word size of 64-bit for all MIPS variants.
Then, Xorg does a casting to (void *) of a 64-bit variable provided by
libunwind. Given that the size of the pointers in MIPS64 n32 is 32-bit wide,
that casting causes an error like this one:
backtrace.c:90:20: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
libunwind already had support for local unwind on a MIPS. This patch makes
support for remote unwinding on a MIPS.
I should add a few words to the changes to _UPT_access_mem.c: On MIPS, an
unw_word_t is defined as a 64-bit integer whether it's compiled for a 32- or a
64-bit MIPS.
When doing remote unwinding using the default _UPT_accessors, dwarf_readu8()
therefore expects _UPT_access_mem() to return a 64-bit integer. However, if
compiled on a 32-bit MIPS, only 32 bits are valid upon return from
_UPT_access_mem(). The patch detects this and will in this case perform two
calls to ptrace(PTRACE_POKE/PEEK_DATA) and organize the return value according
to endianness.
Add MIPS support to the coredump library. Explicit support for the MIPS
program counter register is added so that we can start backtracing from
the program counter value we read from a core dump. The PC register
support was not strictly required for local backtracing, and we will in
fact just plug the return address to the PC register in getcontext().
I have only tested the 32bit "OABI" paths.
Dropping the extra frame for unw_backtrace itself using unw_step is
approximately 15% slower than skipping the frame in tdep_trace. So
drop the frame in the latter, and make the function a private
implementation detail for libunwind, not an exported interface.
Also moves unw_getcontext call back into unw_backtrace to avoid an
extra call frame in case slow_backtrace does not get inlined into
unw_backtrace.
Adds new function to perform a pure stack walk without unwinding,
functionally similar to backtrace() but accelerated by an address
attribute cache the caller maintains across calls.