re PR other/26208 (Serious problem with unwinding through signal frames)

PR other/26208
	* unwind-dw2.c (struct _Unwind_Context): Add signal_frame field.
	(extract_cie_info): Handle S flag in augmentation string.
	(execute_cfa_program): If context->signal_frame, execute also
	fs->pc == context->ra instructions.
	(uw_frame_state_for): If context->signal_frame, don't subtract one
	from context->ra to find FDE.
	(uw_update_context_1): Set context->signal_frame to
	fs->signal_frame.
	(_Unwind_GetIPInfo): New function.
	* unwind-dw2.h (_Unwind_FrameState): Add signal_frame field.
	* unwind-c.c (PERSONALITY_FUNCTION): Use _Unwind_GetIPInfo instead
	of _Unwind_GetIP.
	* unwind-sjlj.c (_Unwind_GetIPInfo): New function.
	* unwind-generic.h (_Unwind_GetIPInfo): New prototype.
	* unwind-compat.c (_Unwind_GetIPInfo): New function.
	* libgcc-std.ver (_Unwind_GetIPInfo): Export @@GCC_4.2.0.
	* config/ia64/unwind-ia64.c (_Unwind_GetIPInfo): New function.
	* config/arm/unwind-arm.h (_Unwind_GetIPInfo): Define.
	* config/i386/linux-unwind.h (x86_fallback_frame_state,
	x86_64_fallback_frame_state): Set fs->signal_frame.
	* config/rs6000/linux-unwind.h (ppc_fallback_frame_state): Likewise.
	(MD_FROB_UPDATE_CONTEXT): Define unconditionally.
	(frob_update_context): Likewise.  Workaround missing S flag in
	Linux 2.6.12 - 2.6.16 kernel vDSOs.
	* config/s390/linux-unwind.h (s390_fallback_frame_state): Likewise.
	Remove the psw_addr + 1 hack.
libjava/
	* exception.cc (PERSONALITY_FUNCTION): Use _Unwind_GetIPInfo instead
	of _Unwind_GetIP.
	* include/i386-signal.h (MAKE_THROW_FRAME): Change into empty macro.
	(HANDLE_DIVIDE_OVERFLOW): Don't adjust _res->eip if falling through
	to throw.
	* include/x86_64-signal.h (MAKE_THROW_FRAME): Change into empty
	macro.
	* include/powerpc-signal.h (MAKE_THROW_FRAME): Change into empty
	macro.
libstdc++-v3/
	* libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Use
	_Unwind_GetIPInfo instead of _Unwind_GetIP.

From-SVN: r111488
This commit is contained in:
Jakub Jelinek 2006-02-27 18:26:26 +01:00 committed by Jakub Jelinek
parent 6df11ca1be
commit 754e45a867
20 changed files with 185 additions and 102 deletions

View File

@ -1,3 +1,33 @@
2006-02-27 Jakub Jelinek <jakub@redhat.com>
PR other/26208
* unwind-dw2.c (struct _Unwind_Context): Add signal_frame field.
(extract_cie_info): Handle S flag in augmentation string.
(execute_cfa_program): If context->signal_frame, execute also
fs->pc == context->ra instructions.
(uw_frame_state_for): If context->signal_frame, don't subtract one
from context->ra to find FDE.
(uw_update_context_1): Set context->signal_frame to
fs->signal_frame.
(_Unwind_GetIPInfo): New function.
* unwind-dw2.h (_Unwind_FrameState): Add signal_frame field.
* unwind-c.c (PERSONALITY_FUNCTION): Use _Unwind_GetIPInfo instead
of _Unwind_GetIP.
* unwind-sjlj.c (_Unwind_GetIPInfo): New function.
* unwind-generic.h (_Unwind_GetIPInfo): New prototype.
* unwind-compat.c (_Unwind_GetIPInfo): New function.
* libgcc-std.ver (_Unwind_GetIPInfo): Export @@GCC_4.2.0.
* config/ia64/unwind-ia64.c (_Unwind_GetIPInfo): New function.
* config/arm/unwind-arm.h (_Unwind_GetIPInfo): Define.
* config/i386/linux-unwind.h (x86_fallback_frame_state,
x86_64_fallback_frame_state): Set fs->signal_frame.
* config/rs6000/linux-unwind.h (ppc_fallback_frame_state): Likewise.
(MD_FROB_UPDATE_CONTEXT): Define unconditionally.
(frob_update_context): Likewise. Workaround missing S flag in
Linux 2.6.12 - 2.6.16 kernel vDSOs.
* config/s390/linux-unwind.h (s390_fallback_frame_state): Likewise.
Remove the psw_addr + 1 hack.
2006-02-27 Daniel Berlin <dberlin@dberlin.org>
* tree-ssa-structalias.c (get_constraint_for): Move code to deal

View File

@ -1,5 +1,5 @@
/* Header file for the ARM EABI unwinder
Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
Contributed by Paul Brook
This file is free software; you can redistribute it and/or modify it
@ -250,6 +250,9 @@ extern "C" {
#define _Unwind_GetIP(context) \
(_Unwind_GetGR (context, 15) & ~(_Unwind_Word)1)
#define _Unwind_GetIP(context, ip_before_insn) \
(*ip_before_insn = 0, _Unwind_GetGR (context, 15) & ~(_Unwind_Word)1)
static inline void
_Unwind_SetGR (_Unwind_Context *context, int regno, _Unwind_Word val)
{

View File

@ -1,5 +1,5 @@
/* DWARF2 EH unwinding support for AMD x86-64 and x86.
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GCC.
@ -100,6 +100,7 @@ x86_64_fallback_frame_state (struct _Unwind_Context *context,
fs->regs.reg[16].how = REG_SAVED_OFFSET;
fs->regs.reg[16].loc.offset = (long)&sc->rip - new_cfa;
fs->retaddr_column = 16;
fs->signal_frame = 1;
return _URC_NO_REASON;
}
@ -172,6 +173,7 @@ x86_fallback_frame_state (struct _Unwind_Context *context,
fs->regs.reg[8].how = REG_SAVED_OFFSET;
fs->regs.reg[8].loc.offset = (long)&sc->REG_NAME(eip) - new_cfa;
fs->retaddr_column = 8;
fs->signal_frame = 1;
return _URC_NO_REASON;
}
#endif /* not glibc 2.0 */

View File

@ -1704,6 +1704,13 @@ _Unwind_GetIP (struct _Unwind_Context *context)
return context->rp;
}
inline _Unwind_Ptr
_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
{
*ip_before_insn = 0;
return context->rp;
}
/* Overwrite the return address for CONTEXT with VAL. */
inline void

View File

@ -1,5 +1,5 @@
/* DWARF2 EH unwinding support for PowerPC and PowerPC64 Linux.
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GCC.
@ -89,26 +89,6 @@ struct gcc_ucontext
enum { SIGNAL_FRAMESIZE = 128 };
/* If the current unwind info (FS) does not contain explicit info
saving R2, then we have to do a minor amount of code reading to
figure out if it was saved. The big problem here is that the
code that does the save/restore is generated by the linker, so
we have no good way to determine at compile time what to do. */
#define MD_FROB_UPDATE_CONTEXT frob_update_context
static void
frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
if (fs->regs.reg[2].how == REG_UNSAVED)
{
unsigned int *insn
= (unsigned int *) _Unwind_GetGR (context, LINK_REGISTER_REGNUM);
if (*insn == 0xE8410028)
_Unwind_SetGRPtr (context, 2, context->cfa + 40);
}
}
/* If PC is at a sigreturn trampoline, return a pointer to the
regs. Otherwise return NULL. */
@ -272,6 +252,7 @@ ppc_fallback_frame_state (struct _Unwind_Context *context,
fs->regs.reg[ARG_POINTER_REGNUM].how = REG_SAVED_OFFSET;
fs->regs.reg[ARG_POINTER_REGNUM].loc.offset = (long) &regs->nip - new_cfa;
fs->retaddr_column = ARG_POINTER_REGNUM;
fs->signal_frame = 1;
if (hwcap == 0)
{
@ -322,3 +303,46 @@ ppc_fallback_frame_state (struct _Unwind_Context *context,
return _URC_NO_REASON;
}
#define MD_FROB_UPDATE_CONTEXT frob_update_context
static void
frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
const unsigned int *pc = (const unsigned int *) context->ra;
/* Fix up for 2.6.12 - 2.6.16 Linux kernels that have vDSO, but don't
have S flag in it. */
#ifdef __powerpc64__
/* addi r1, r1, 128; li r0, 0x0077; sc (sigreturn) */
/* addi r1, r1, 128; li r0, 0x00AC; sc (rt_sigreturn) */
if (pc[0] == 0x38210000 + SIGNAL_FRAMESIZE
&& (pc[1] == 0x38000077 || pc[1] == 0x380000AC)
&& pc[2] == 0x44000002)
context->signal_frame = 1;
#else
/* li r0, 0x7777; sc (sigreturn old) */
/* li r0, 0x0077; sc (sigreturn new) */
/* li r0, 0x6666; sc (rt_sigreturn old) */
/* li r0, 0x00AC; sc (rt_sigreturn new) */
if ((pc[0] == 0x38007777 || pc[0] == 0x38000077
|| pc[0] == 0x38006666 || pc[0] == 0x380000AC)
&& pc[1] == 0x44000002)
context->signal_frame = 1;
#endif
#ifdef __powerpc64__
if (fs->regs.reg[2].how == REG_UNSAVED)
{
/* If the current unwind info (FS) does not contain explicit info
saving R2, then we have to do a minor amount of code reading to
figure out if it was saved. The big problem here is that the
code that does the save/restore is generated by the linker, so
we have no good way to determine at compile time what to do. */
unsigned int *insn
= (unsigned int *) _Unwind_GetGR (context, LINK_REGISTER_REGNUM);
if (*insn == 0xE8410028)
_Unwind_SetGRPtr (context, 2, context->cfa + 40);
}
#endif
}

View File

@ -1,5 +1,5 @@
/* DWARF2 EH unwinding support for S/390 Linux.
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GCC.
@ -113,27 +113,11 @@ s390_fallback_frame_state (struct _Unwind_Context *context,
fs->regs.reg[32].how = REG_SAVED_OFFSET;
fs->regs.reg[32].loc.offset = (long)&regs->psw_addr - new_cfa;
fs->retaddr_column = 32;
/* If we got a SIGSEGV or a SIGBUS, the PSW address points *to*
the faulting instruction, not after it. This causes the logic
in unwind-dw2.c that decrements the RA to determine the correct
CFI region to get confused. To fix that, we *increment* the RA
here in that case. Note that we cannot modify the RA in place,
and the frame state wants a *pointer*, not a value; thus we put
the modified RA value into the unused register 33 slot of FS and
have the register 32 save address point to that slot.
Unfortunately, for regular signals on old kernels, we don't know
the signal number. We default to not fiddling with the RA;
that can fail in rare cases. Upgrade your kernel. */
if (signo && (*signo == 11 || *signo == 7))
{
fs->regs.reg[33].loc.exp =
(unsigned char *)regs->psw_addr + 1;
fs->regs.reg[32].loc.offset =
(long)&fs->regs.reg[33].loc.exp - new_cfa;
}
/* SIGILL, SIGFPE and SIGTRAP are delivered with psw_addr
after the faulting instruction rather than before it.
Don't set FS->signal_frame in that case. */
if (!signo || (*signo != 4 && *signo != 5 && *signo != 8))
fs->signal_frame = 1;
return _URC_NO_REASON;
}

View File

@ -272,4 +272,5 @@ GCC_4.2.0 {
__floatuntisf
__floatuntixf
__floatuntitf
_Unwind_GetIPInfo
}

View File

@ -127,6 +127,7 @@ PERSONALITY_FUNCTION (int version,
lsda_header_info info;
const unsigned char *language_specific_data, *p, *action_record;
_Unwind_Ptr landing_pad, ip;
int ip_before_insn = 0;
#ifdef __ARM_EABI_UNWINDER__
if ((state & _US_ACTION_MASK) != _US_UNWIND_FRAME_STARTING)
@ -156,7 +157,9 @@ PERSONALITY_FUNCTION (int version,
/* Parse the LSDA header. */
p = parse_lsda_header (context, language_specific_data, &info);
ip = _Unwind_GetIP (context) - 1;
ip = _Unwind_GetIPInfo (context, &ip_before_insn);
if (! ip_before_insn)
--ip;
landing_pad = 0;
#ifdef __USING_SJLJ_EXCEPTIONS__

View File

@ -1,5 +1,5 @@
/* Backward compatibility unwind routines.
Copyright (C) 2004, 2005
Copyright (C) 2004, 2005, 2006
Free Software Foundation, Inc.
This file is part of GCC.
@ -136,6 +136,13 @@ _Unwind_GetIP (struct _Unwind_Context *context)
}
symver (_Unwind_GetIP, GCC_3.0);
_Unwind_Ptr
_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
{
*ip_before_insn = 0;
return __libunwind_Unwind_GetIP (context);
}
extern void *__libunwind_Unwind_GetLanguageSpecificData
(struct _Unwind_Context *);

View File

@ -1,5 +1,5 @@
/* DWARF2 exception handling and frame unwind runtime interface routines.
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This file is part of GCC.
@ -71,6 +71,7 @@ struct _Unwind_Context
void *lsda;
struct dwarf_eh_bases bases;
_Unwind_Word args_size;
char signal_frame;
};
/* Byte size of every register managed by these routines. */
@ -207,6 +208,16 @@ _Unwind_GetIP (struct _Unwind_Context *context)
return (_Unwind_Ptr) context->ra;
}
/* Retrieve the return address and flag whether that IP is before
or after first not yet fully executed instruction. */
inline _Unwind_Ptr
_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
{
*ip_before_insn = context->signal_frame != 0;
return (_Unwind_Ptr) context->ra;
}
/* Overwrite the return address for CONTEXT with VAL. */
inline void
@ -327,6 +338,13 @@ extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
aug += 1;
}
/* "S" indicates a signal frame. */
else if (aug[0] == 'S')
{
fs->signal_frame = 1;
aug += 1;
}
/* Otherwise we have an unknown augmentation string.
Bail unless we saw a 'z' prefix. */
else
@ -761,8 +779,10 @@ execute_cfa_program (const unsigned char *insn_ptr,
a different stack configuration that we are not interested in. We
assume that the call itself is unwind info-neutral; if not, or if
there are delay instructions that adjust the stack, these must be
reflected at the point immediately before the call insn. */
while (insn_ptr < insn_end && fs->pc < context->ra)
reflected at the point immediately before the call insn.
In signal frames, return address is after last completed instruction,
so we add 1 to return address to make the comparison <=. */
while (insn_ptr < insn_end && fs->pc < context->ra + context->signal_frame)
{
unsigned char insn = *insn_ptr++;
_Unwind_Word reg, utmp;
@ -974,7 +994,8 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
if (context->ra == 0)
return _URC_END_OF_STACK;
fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
fde = _Unwind_Find_FDE (context->ra + context->signal_frame - 1,
&context->bases);
if (fde == NULL)
{
#ifdef MD_FALLBACK_FRAME_STATE_FOR
@ -1192,6 +1213,8 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
break;
}
context->signal_frame = fs->signal_frame;
#ifdef MD_FROB_UPDATE_CONTEXT
MD_FROB_UPDATE_CONTEXT (context, fs);
#endif

View File

@ -83,6 +83,7 @@ typedef struct
unsigned char fde_encoding;
unsigned char lsda_encoding;
unsigned char saw_z;
unsigned char signal_frame;
void *eh_ptr;
} _Unwind_FrameState;

View File

@ -1,5 +1,5 @@
/* Exception handling and frame unwind runtime interface routines.
Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
Copyright (C) 2001, 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of GCC.
@ -155,6 +155,7 @@ extern _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *, int);
extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word);
extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *);
extern _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *, int *);
extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr);
/* @@@ Retrieve the CFA of the given context. */

View File

@ -214,6 +214,13 @@ _Unwind_GetIP (struct _Unwind_Context *context)
return context->fc->call_site + 1;
}
_Unwind_Ptr
_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
{
*ip_before_insn = 0;
return context->fc->call_site + 1;
}
/* Set the return landing pad index in CONTEXT. */
void

View File

@ -1,3 +1,16 @@
2006-02-27 Jakub Jelinek <jakub@redhat.com>
PR other/26208
* exception.cc (PERSONALITY_FUNCTION): Use _Unwind_GetIPInfo instead
of _Unwind_GetIP.
* include/i386-signal.h (MAKE_THROW_FRAME): Change into empty macro.
(HANDLE_DIVIDE_OVERFLOW): Don't adjust _res->eip if falling through
to throw.
* include/x86_64-signal.h (MAKE_THROW_FRAME): Change into empty
macro.
* include/powerpc-signal.h (MAKE_THROW_FRAME): Change into empty
macro.
2006-02-23 Scott Gilbertson <scottg@mantatest.com>
* gnu/awt/j2d/IntegerGraphicsState.java (getClip): Clone clip

View File

@ -1,6 +1,6 @@
// Functions for Exception Support for Java.
/* Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation
/* Copyright (C) 1998, 1999, 2001, 2002, 2006 Free Software Foundation
This file is part of libgcj.
@ -197,6 +197,7 @@ PERSONALITY_FUNCTION (int version,
int handler_switch_value;
bool saw_cleanup;
bool saw_handler;
int ip_before_insn = 0;
// Interface version check.
@ -212,10 +213,10 @@ PERSONALITY_FUNCTION (int version,
goto install_context;
}
// FIXME: In Phase 1, record _Unwind_GetIP in xh->obj as a part of
// FIXME: In Phase 1, record _Unwind_GetIPInfo in xh->obj as a part of
// the stack trace for this exception. This will only collect Java
// frames, but perhaps that is acceptable.
// FIXME2: _Unwind_GetIP is nonsensical for SJLJ, being a call-site
// FIXME2: _Unwind_GetIPInfo is nonsensical for SJLJ, being a call-site
// index instead of a PC value. We could perhaps arrange for
// _Unwind_GetRegionStart to return context->fc->jbuf[1], which
// is the address of the handler label for __builtin_longjmp, but
@ -230,7 +231,9 @@ PERSONALITY_FUNCTION (int version,
// Parse the LSDA header.
p = parse_lsda_header (context, language_specific_data, &info);
ip = _Unwind_GetIP (context) - 1;
ip = _Unwind_GetIPInfo (context, &ip_before_insn);
if (! ip_before_insn)
--ip;
landing_pad = 0;
action_record = 0;
handler_switch_value = 0;

View File

@ -1,7 +1,7 @@
// i386-signal.h - Catch runtime signals and turn them into exceptions
// on an i386 based Linux system.
/* Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation
/* Copyright (C) 1998, 1999, 2001, 2002, 2006 Free Software Foundation
This file is part of libgcj.
@ -22,19 +22,7 @@ details. */
#define SIGNAL_HANDLER(_name) \
static void _name (int _dummy __attribute__ ((__unused__)))
#define MAKE_THROW_FRAME(_exception) \
do \
{ \
void **_p = (void **)&_dummy; \
volatile struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p; \
\
/* Advance the program counter so that it is after the start of the \
instruction: the x86 exception handler expects \
the PC to point to the instruction after a call. */ \
_regs->eip += 2; \
\
} \
while (0)
#define MAKE_THROW_FRAME(_exception)
#define HANDLE_DIVIDE_OVERFLOW \
do \
@ -91,14 +79,6 @@ do \
_regs->eip = (unsigned long)_eip; \
return; \
} \
else \
{ \
/* Advance the program counter so that it is after the start \
of the instruction: this is because the x86 exception \
handler expects the PC to point to the instruction after a \
call. */ \
_regs->eip += 2; \
} \
} \
} \
while (0)

View File

@ -1,7 +1,7 @@
// powerpc-signal.h - Catch runtime signals and turn them into exceptions
// on a powerpc based Linux system.
/* Copyright (C) 2003 Free Software Foundation
/* Copyright (C) 2003, 2006 Free Software Foundation
This file is part of libgcj.
@ -22,18 +22,12 @@ details. */
#define SIGNAL_HANDLER(_name) \
static void _name (int /* _signal */, struct sigcontext *_sc)
/* PPC either leaves PC pointing at a faulting instruction or the
following instruction, depending on the signal. SEGV always does
the former, so we adjust the saved PC to point to the following
instruction. This is what the handler in libgcc expects. */
/* MD_FALBACK_FRAME_STATE_FOR takes care of special casing PC
before the faulting instruction, so we don't need to do anything
here. */
#define MAKE_THROW_FRAME(_exception)
#define MAKE_THROW_FRAME(_exception) \
do \
{ \
_sc->regs->nip += 4; \
} \
while (0)
/* For an explanation why we cannot simply use sigaction to
install the handlers, see i386-signal.h. */

View File

@ -1,7 +1,7 @@
// x86_64-signal.h - Catch runtime signals and turn them into exceptions
// on an x86_64 based GNU/Linux system.
/* Copyright (C) 2003 Free Software Foundation
/* Copyright (C) 2003, 2006 Free Software Foundation
This file is part of libgcj.
@ -34,16 +34,7 @@ extern "C"
};
}
#define MAKE_THROW_FRAME(_exception) \
do \
{ \
/* Advance the program counter so that it is after the start of the \
instruction: the x86_64 exception handler expects \
the PC to point to the instruction after a call. */ \
struct ucontext *_uc = (struct ucontext *)_p; \
_uc->uc_mcontext.gregs[REG_RIP] += 2; \
} \
while (0)
#define MAKE_THROW_FRAME(_exception)
#define RESTORE(name, syscall) RESTORE2 (name, syscall)
#define RESTORE2(name, syscall) \

View File

@ -1,3 +1,9 @@
2006-02-27 Jakub Jelinek <jakub@redhat.com>
PR other/26208
* libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Use
_Unwind_GetIPInfo instead of _Unwind_GetIP.
2006-02-27 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/14866

View File

@ -364,6 +364,7 @@ PERSONALITY_FUNCTION (int version,
int handler_switch_value;
void* thrown_ptr = ue_header + 1;
bool foreign_exception;
int ip_before_insn = 0;
#ifdef __ARM_EABI_UNWINDER__
_Unwind_Action actions;
@ -430,7 +431,9 @@ PERSONALITY_FUNCTION (int version,
// Parse the LSDA header.
p = parse_lsda_header (context, language_specific_data, &info);
info.ttype_base = base_of_encoded_value (info.ttype_encoding, context);
ip = _Unwind_GetIP (context) - 1;
ip = _Unwind_GetIPInfo (context, &ip_before_insn);
if (! ip_before_insn)
--ip;
landing_pad = 0;
action_record = 0;
handler_switch_value = 0;