This doesn't yet implement inspecting the .pdata/.xdata to find the
LSDA pointer (in UnwindCursor::getInfoFromSEH), but normal C++
exception handling seems to run just fine without it. (The only
place I can see where it's even referenced is in
unwind_phase2_forced, and I can't find a codepath where libcxxabi
would end up calling that.)
Differential Revision: https://reviews.llvm.org/D55674
llvm-svn: 349532
- Follow up to revision r342895
- gcc would not build libunwind with the earlier patch as the autia1716
instruction wasn't allowed to be assembled for pre armv8.3a targets
- The autia1716 instruction lives in the hint space encodings so is a valid
instruction for all armv8a targets
- To work around this I have swapped out the autia1716 instruction for the hint
instruction
Differential Revision: https://reviews.llvm.org/D55700
llvm-svn: 349140
- When return address signing is enabled, the LR may be signed on function entry
- When an exception is thrown the return address is inspected used to unwind the call stack
- Before this happens, the return address must be correctly authenticated to avoid causing an abort by dereferencing the signed pointer
Differential Revision: https://reviews.llvm.org/D51432
llvm-svn: 342895
Even though SEH for ARM is incomplete, make what code already exists
at least compile correctly.
The _LIBUNWIND_CURSOR_SIZE wasn't correct.
ARM (and AArch64) have a DISPATCHER_CONTEXT field named TargetPc
instead of TargetIp.
For the libunwind.h UNW_* constants, there is no UNW_ARM_PC, only
UNW_ARM_IP.
Don't use 'r' as loop variable when 'r' already is a Registers_arm
member.
Differential Revision: https://reviews.llvm.org/D51530
llvm-svn: 341217
Summary:
I've tested this implementation on x86-64 to ensure that it works. All
`libc++abi` tests pass, as do all `libc++` exception-related tests. ARM
still remains to be implemented (@compnerd?).
Special thanks to KJK::Hyperion for his excellent series of articles on
how EH works on x86-64 Windows. (Seriously, check it out. It's awesome.)
I'm actually not sure if this should go in as is. I particularly don't
like that I duplicated the UnwindCursor class for this special case.
Reviewers: mstorsjo, rnk, compnerd, smeenai, javed.absar
Subscribers: mgorny, kristof.beyls, christof, chrib, cfe-commits, compnerd, llvm-commits
Differential Revision: https://reviews.llvm.org/D50564
llvm-svn: 341125
Summary:
Make the `_Unwind_Exception` struct correct under SEH. Add a
declaration of `_GCC_specific_handler()`, which is used by SEH versions
of Itanium personality handlers to do common setup. Roughly corresponds
to Clang's D50380.
Reviewers: mstorsjo, rnk, compnerd, smeenai
Subscribers: christof, chrib, cfe-commits, llvm-commits
Differential Revision: https://reviews.llvm.org/D50414
llvm-svn: 339258
This makes it possible to unwind hardware exception stack frames,
which necessarily save every register and so need an extra column
for storing the return address. CFI for the exception handler could
then look as follows:
.globl exception_vector
exception_vector:
.cfi_startproc
.cfi_signal_frame
.cfi_return_column 32
l.addi r1, r1, -0x100
.cfi_def_cfa_offset 0x100
l.sw 0x00(r1), r2
.cfi_offset 2, 0x00-0x100
l.sw 0x04(r1), r3
.cfi_offset 3, 0x04-0x100
l.sw 0x08(r1), r4
.cfi_offset 4, 0x08-0x100
l.mfspr r3, r0, SPR_EPCR_BASE
l.sw 0x78(r1), r3
.cfi_offset 32, 0x78-0x100
l.jal exception_handler
l.nop
l.lwz r2, 0x00(r1)
l.lwz r3, 0x04(r1)
l.lwz r4, 0x08(r1)
l.jr r9
l.nop
.cfi_endproc
This register could, of course, also be accessed by the trace
callback or personality function, if so desired.
llvm-svn: 332513
Summary:
For MIPS ABIs with 64-bit floating point registers including newabi
and O32 with 64-bit floating point registers, just save and restore the
32 floating-point registers as doubles.
For O32 MIPS with 32-bit floating-point registers, save and restore the
individual floating-point registers as "plain" registers. These registers
are encoded as floats rather than doubles, but the DWARF unwinder
assumes that floating-point registers are stored as doubles when reading
them from memory (via AddressSpace::getDouble()). Treating the
registers as "normal" registers instead causes the DWARF unwinder to
fetch them from memory as a 32-bit register. This does mean that for
O32 with 32-bit floating-point registers unw_get_fpreg() and
unw_set_fpreg() do not work. One would have to use unw_get_reg()
and unw_set_reg() instead. However, DWARF unwinding works
correctly as the DWARF CFI emits records for individual 32-bit
floating-point registers even when they are treated as doubles stored
in paired registers. If the lack of unw_get/set_fpreg() becomes a pressing
need in the future for O32 MIPS we could add in special handling to
make it work.
Reviewers: sdardis, compnerd
Reviewed By: sdardis
Differential Revision: https://reviews.llvm.org/D41968
llvm-svn: 332414
Summary:
N32 uses the same register context as N64. However, N32 requires one
change to properly fetch addresses from registers stored in memory.
Since N32 is an ILP32 platform, getP() only fetches the first 32-bits
of a stored register. For a big-endian platform this fetches the
upper 32-bits which will be zero. To fix this, add a new
getRegister() method to AddressSpace which is responsible for
extracting the address stored in a register in memory. This matches
getP() for all current ABIs except for N32 where it reads the 64-bit
register and returns the low 32-bits as an address. The
DwarfInstructions::getSavedRegister() method uses
AddressSpace::getRegister() instead of AddressSpace::getP().
Reviewers: sdardis, compnerd
Reviewed By: sdardis
Differential Revision: https://reviews.llvm.org/D39074
llvm-svn: 326250
The Registers_ppc64 class needed a couple of changes, both to accommodate the
new registers as well as to handle the overlaps of VS register set
without wasting space.
The save/restore code of V and VS registers was added.
As VS registers depend on the VMX extension, they are processed only if
VMX support is detected (_ARCH_PWR8 for now).
Patch by Leandro Lupori!
Differential Revision: https://reviews.llvm.org/D41906
llvm-svn: 322596
This is in preparation for adding support for N32 unwinding which reuses
the newabi register class.
Reviewed By: compnerd
Differential Revision: https://reviews.llvm.org/D41842
llvm-svn: 322093
Initial working version of libunwind for PowerPC 64. Tested on
little-endian ppc64 host only.
Based on the existing PowerPC 32 code.
It supports:
- context save/restore (unw_getcontext, unw_init_local, unw_resume)
- read/write from/to saved registers
- backtrace (unw_step)
Patch by Leandro Lupori!
Differential Revision: https://reviews.llvm.org/D41386
Now builds with LIBUNWIND_ENABLE_CROSS_UNWINDING=ON should
work.
llvm-svn: 321680
Initial working version of libunwind for PowerPC 64. Tested on
little-endian ppc64 host only.
Based on the existing PowerPC 32 code.
It supports:
- context save/restore (unw_getcontext, unw_init_local, unw_resume)
- read/write from/to saved registers
- backtrace (unw_step)
Patch by Leandro Lupori!
Differential Revision: https://reviews.llvm.org/D41386
llvm-svn: 321667
This supports the soft-float ABI only and has been tested with both clang
and gcc on FreeBSD.
Reviewed By: sdardis, compnerd
Differential Revision: https://reviews.llvm.org/D38110
llvm-svn: 320528
The previous definition of _LIBUNWIND_HIGHEST_DWARF_REGISTER seems
to be a copy of the ARM64 value (introduced in SVN r276128); since
the code actually hasn't compiled properly for arm in dwarf mode
before, this hasn't actually been used. Set it to the correct value
based on the UNW_ARM_* enum values.
The iwmmx control variables have to be made mutable, since they are
touched from within getRegister (which previously wasn't const), and
getRegister is used on a const Registers object in DwarfInstructions.hpp.
Differential Revision: https://reviews.llvm.org/D39251
llvm-svn: 317192
This matches the original libunwind API. This also unifies the
type between ARM EHABI and the other configurations, and allows
getting rid of a number of casts in log messages.
The cursor size updates for ppc and or1k are untested, but
unw_proc_info_t shrinks by 4 uint64_t units on i386 at least.
Differential Revision: https://reviews.llvm.org/D39365
llvm-svn: 316942
This restores the previous behaviour of the Registers_* classes
after SVN r316745.
Differential Revision: https://reviews.llvm.org/D39382
llvm-svn: 316843
Clang doesn't currently support building for windows/x86_64 with
dwarf by setting command line parameters, but if manually modified
to use dwarf, we can make libunwind work in this configuration
as well.
Also include i386 in the docs when adding this as a supported
configuration; libunwind already works for i386 windows, but
can fail due to an issue unrelated to windows itself.
Differential Revision: https://reviews.llvm.org/D38819
llvm-svn: 316747
This avoids having to keep the same information duplicated in multiple
places.
Adjust _LIBUNWIND_HIGHEST_DWARF_REGISTER to actually have the value
of the highest used register and only use the value
_LIBUNWIND_HIGHEST_DWARF_REGISTER + 1 (kMaxRegisterNumber + 1) for
allocating the savedRegisters array.
Differential Revision: https://reviews.llvm.org/D39281
llvm-svn: 316745
This was missed in SVN r274744 when the WMMX part was made optional;
when made optional, some struct fields were reordered, which caused
the total struct size to grow due to padding/alignment.
llvm-svn: 316559
It seems that GCC interprets `__attribute__((__aligned__))` as 8-byte
alignment on ARM, but clang does not. Explicitly specify the
double-word alignment value to ensure that the structure is properly
aligned.
llvm-svn: 311574
The C++ ABI requires that the exception object is double-word aligned.
The alignment attribute was applied to the `_Unwind_Exception` type
which is used on non-EHABI targets. On EHABI, the exception object type
is `_Unwind_Control_Block`. Apply the explicit maximal alignment on the
type to ensure that the allocation has the correct alignment.
Resolves PR33858!
llvm-svn: 311562
Restore the `libunwind.h` enumeration values back to the inverted
values. This diverges from the DWARF definition of the register values.
However, this allows our header to be compatible with other unwind
implementations (e.g. HP, GNU Savannah, GCC).
The register IDs are only swapped in the header and need to be unswapped
when accessing the unwind register file. The flipped EBP and ESP only
applies on non-Apple x86 targets.
When optimizations were enabled, EBP and ESP would no longer be
equivalent. As a result, the incorrect access on Linux would manifest
as a failure to unwind the stack. We can now unwind the stack with and
without FPO on Linux x86.
Resolves PR30879!
llvm-svn: 292723
Summary:
During building of recent compiler-rt sources on FreeBSD for arm, I
noticed that our unwind.h (which originates in libunwind) was missing
the `_US_ACTION_MASK` constant:
compiler-rt/lib/builtins/gcc_personality_v0.c:187:18: error: use of undeclared identifier '_US_ACTION_MASK'
if ((state & _US_ACTION_MASK) != _US_UNWIND_FRAME_STARTING)
^
It appears that both clang's internal unwind.h, and libgcc's unwind.h
define this constant as 3, so let's add this to libunwind's version too.
Reviewers: logan, kledzik, davide, emaste
Subscribers: joerg, davide, aemerson, emaste, llvm-commits
Differential Revision: https://reviews.llvm.org/D24222
llvm-svn: 280669
For historical reasons i386 has ebp and esp swapped in the eh_frame
register numbering on at least Darwin. That is:
Darwin FreeBSD
Reg # eh_frame eh_frame DWARF
===== ======== ======== =====
4 ebp esp esp
5 esp ebp ebp
Although the UNW_X86_* constants are not intended to be coupled with
DWARF / eh_frame numbering they are currently conflated in libunwind.
Differential Revision: https://reviews.llvm.org/D22508
llvm-svn: 280099
Summary: _Unwind_Exception is required to be double word aligned. Currently the struct is under aligned.
Reviewers: mclow.lists, compnerd, kledzik, emaste
Subscribers: emaste, cfe-commits
Differential Revision: https://reviews.llvm.org/D22543
llvm-svn: 276215
These registers are only available on a limited set of ARM targets (those
based on XScale). Other targets should not have to pay the cost of these.
This patch shaves off about ~300 bytes of stack usage and ~1KB of code-size.
Differential revision: http://reviews.llvm.org/D21991
Reviewers: bcraig, compnerd
Change-Id: I2d7a1911a193bd70b123e78747e1a7d1482463c7
llvm-svn: 274744
Currently libunwind is built to support cross-unwinding [1] by default, which
requires the buffers unw_context_t and unw_cursor_t to be large enough to hold
the vritual register set (VRS) of any supported architecture. This is not
desirable for some platforms where the stack usage of the unwinder needs
to be kept to a minimum (e.g. bare-metal targets). The current patch introduces
a native-only (-DLIBUNWIND_ENABLE_CROSS_UNWINDING=OFF) unwinder variant that
adopts strict sizes for the buffers unw_context_t and unw_cursor_t depending
on the target architecture.
[1] http://www.nongnu.org/libunwind/man/libunwind(3).html#section_4
Change-Id: I380fff9a56c16a0fc520e3b1d8454a34b4a48373
llvm-svn: 270692
This patch makes no assumptions on ABI past the ABI defined in
the OpenRISC 1000 spec except that the DWARF register numbers will
be 0-31 for registers r0-r31, which is true for both gcc and
clang at the moment.
llvm-svn: 246413
To build libc++abi without libunwind, we should make sure that all
function calls to _Unwind_{Get,Set}{GR,IP}() are inlined as function
calls to _Unwind_VRS_{Get,Set}(). Otherwise, libc++abi.so will fail to
link since libgcc does not provide these symbol at all.
This commit fixes the problem by providing both the inlined version and
exported version.
llvm-svn: 243073
This moves the majority of the unwind sources into the new project layout for
libunwind. This was previously discussed on llvmdev at [1]. This is a
purely movement related change, with the build infrastructure currently still
residing in the libc++abi repository.
[1] http://lists.cs.uiuc.edu/pipermail/llvmdev/2015-January/081507.html
llvm-svn: 235758