1 --- gcc/unwind-compat.c (revision 111580)
2 +++ gcc/unwind-compat.c (revision 111581)
5 symver (_Unwind_GetIP, GCC_3.0);
8 +_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
10 + *ip_before_insn = 0;
11 + return __libunwind_Unwind_GetIP (context);
14 extern void *__libunwind_Unwind_GetLanguageSpecificData
15 (struct _Unwind_Context *);
17 --- gcc/unwind-dw2.c (revision 111580)
18 +++ gcc/unwind-dw2.c (revision 111581)
21 struct dwarf_eh_bases bases;
22 _Unwind_Word args_size;
26 /* Byte size of every register managed by these routines. */
28 return (_Unwind_Ptr) context->ra;
31 +/* Retrieve the return address and flag whether that IP is before
32 + or after first not yet fully executed instruction. */
35 +_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
37 + *ip_before_insn = context->signal_frame != 0;
38 + return (_Unwind_Ptr) context->ra;
41 /* Overwrite the return address for CONTEXT with VAL. */
48 + /* "S" indicates a signal frame. */
49 + else if (aug[0] == 'S')
51 + fs->signal_frame = 1;
55 /* Otherwise we have an unknown augmentation string.
56 Bail unless we saw a 'z' prefix. */
59 a different stack configuration that we are not interested in. We
60 assume that the call itself is unwind info-neutral; if not, or if
61 there are delay instructions that adjust the stack, these must be
62 - reflected at the point immediately before the call insn. */
63 - while (insn_ptr < insn_end && fs->pc < context->ra)
64 + reflected at the point immediately before the call insn.
65 + In signal frames, return address is after last completed instruction,
66 + so we add 1 to return address to make the comparison <=. */
67 + while (insn_ptr < insn_end && fs->pc < context->ra + context->signal_frame)
69 unsigned char insn = *insn_ptr++;
70 _Unwind_Word reg, utmp;
73 return _URC_END_OF_STACK;
75 - fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
76 + fde = _Unwind_Find_FDE (context->ra + context->signal_frame - 1,
80 #ifdef MD_FALLBACK_FRAME_STATE_FOR
85 + context->signal_frame = fs->signal_frame;
87 #ifdef MD_FROB_UPDATE_CONTEXT
88 MD_FROB_UPDATE_CONTEXT (context, fs);
90 --- gcc/unwind-dw2.h (revision 111580)
91 +++ gcc/unwind-dw2.h (revision 111581)
93 unsigned char fde_encoding;
94 unsigned char lsda_encoding;
96 + unsigned char signal_frame;
100 --- gcc/unwind-c.c (revision 111580)
101 +++ gcc/unwind-c.c (revision 111581)
103 lsda_header_info info;
104 const unsigned char *language_specific_data, *p, *action_record;
105 _Unwind_Ptr landing_pad, ip;
106 + int ip_before_insn = 0;
108 #ifdef __ARM_EABI_UNWINDER__
109 if ((state & _US_ACTION_MASK) != _US_UNWIND_FRAME_STARTING)
112 /* Parse the LSDA header. */
113 p = parse_lsda_header (context, language_specific_data, &info);
114 - ip = _Unwind_GetIP (context) - 1;
115 + ip = _Unwind_GetIPInfo (context, &ip_before_insn);
116 + if (! ip_before_insn)
120 #ifdef __USING_SJLJ_EXCEPTIONS__
121 --- gcc/unwind-sjlj.c (revision 111580)
122 +++ gcc/unwind-sjlj.c (revision 111581)
124 return context->fc->call_site + 1;
128 +_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
130 + *ip_before_insn = 0;
131 + return context->fc->call_site + 1;
134 /* Set the return landing pad index in CONTEXT. */
137 --- gcc/unwind-generic.h (revision 111580)
138 +++ gcc/unwind-generic.h (revision 111581)
140 extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word);
142 extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *);
143 +extern _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *, int *);
144 extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr);
146 /* @@@ Retrieve the CFA of the given context. */
147 --- gcc/config/s390/linux-unwind.h (revision 111580)
148 +++ gcc/config/s390/linux-unwind.h (revision 111581)
149 @@ -113,27 +113,11 @@
150 fs->regs.reg[32].how = REG_SAVED_OFFSET;
151 fs->regs.reg[32].loc.offset = (long)®s->psw_addr - new_cfa;
152 fs->retaddr_column = 32;
153 + /* SIGILL, SIGFPE and SIGTRAP are delivered with psw_addr
154 + after the faulting instruction rather than before it.
155 + Don't set FS->signal_frame in that case. */
156 + if (!signo || (*signo != 4 && *signo != 5 && *signo != 8))
157 + fs->signal_frame = 1;
159 - /* If we got a SIGSEGV or a SIGBUS, the PSW address points *to*
160 - the faulting instruction, not after it. This causes the logic
161 - in unwind-dw2.c that decrements the RA to determine the correct
162 - CFI region to get confused. To fix that, we *increment* the RA
163 - here in that case. Note that we cannot modify the RA in place,
164 - and the frame state wants a *pointer*, not a value; thus we put
165 - the modified RA value into the unused register 33 slot of FS and
166 - have the register 32 save address point to that slot.
168 - Unfortunately, for regular signals on old kernels, we don't know
169 - the signal number. We default to not fiddling with the RA;
170 - that can fail in rare cases. Upgrade your kernel. */
172 - if (signo && (*signo == 11 || *signo == 7))
174 - fs->regs.reg[33].loc.exp =
175 - (unsigned char *)regs->psw_addr + 1;
176 - fs->regs.reg[32].loc.offset =
177 - (long)&fs->regs.reg[33].loc.exp - new_cfa;
180 return _URC_NO_REASON;
182 --- gcc/config/ia64/unwind-ia64.c (revision 111580)
183 +++ gcc/config/ia64/unwind-ia64.c (revision 111581)
184 @@ -1704,6 +1704,13 @@
189 +_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
191 + *ip_before_insn = 0;
192 + return context->rp;
195 /* Overwrite the return address for CONTEXT with VAL. */
198 --- gcc/config/i386/linux-unwind.h (revision 111580)
199 +++ gcc/config/i386/linux-unwind.h (revision 111581)
201 fs->regs.reg[16].how = REG_SAVED_OFFSET;
202 fs->regs.reg[16].loc.offset = (long)&sc->rip - new_cfa;
203 fs->retaddr_column = 16;
204 + fs->signal_frame = 1;
205 return _URC_NO_REASON;
209 fs->regs.reg[8].how = REG_SAVED_OFFSET;
210 fs->regs.reg[8].loc.offset = (long)&sc->REG_NAME(eip) - new_cfa;
211 fs->retaddr_column = 8;
212 + fs->signal_frame = 1;
213 return _URC_NO_REASON;
215 #endif /* not glibc 2.0 */
216 --- gcc/config/rs6000/linux-unwind.h (revision 111580)
217 +++ gcc/config/rs6000/linux-unwind.h (revision 111581)
220 enum { SIGNAL_FRAMESIZE = 128 };
222 -/* If the current unwind info (FS) does not contain explicit info
223 - saving R2, then we have to do a minor amount of code reading to
224 - figure out if it was saved. The big problem here is that the
225 - code that does the save/restore is generated by the linker, so
226 - we have no good way to determine at compile time what to do. */
228 -#define MD_FROB_UPDATE_CONTEXT frob_update_context
231 -frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
233 - if (fs->regs.reg[2].how == REG_UNSAVED)
236 - = (unsigned int *) _Unwind_GetGR (context, LINK_REGISTER_REGNUM);
237 - if (*insn == 0xE8410028)
238 - _Unwind_SetGRPtr (context, 2, context->cfa + 40);
242 /* If PC is at a sigreturn trampoline, return a pointer to the
243 regs. Otherwise return NULL. */
246 fs->regs.reg[ARG_POINTER_REGNUM].how = REG_SAVED_OFFSET;
247 fs->regs.reg[ARG_POINTER_REGNUM].loc.offset = (long) ®s->nip - new_cfa;
248 fs->retaddr_column = ARG_POINTER_REGNUM;
249 + fs->signal_frame = 1;
255 return _URC_NO_REASON;
258 +#define MD_FROB_UPDATE_CONTEXT frob_update_context
261 +frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
263 + const unsigned int *pc = (const unsigned int *) context->ra;
265 + /* Fix up for 2.6.12 - 2.6.16 Linux kernels that have vDSO, but don't
266 + have S flag in it. */
267 +#ifdef __powerpc64__
268 + /* addi r1, r1, 128; li r0, 0x0077; sc (sigreturn) */
269 + /* addi r1, r1, 128; li r0, 0x00AC; sc (rt_sigreturn) */
270 + if (pc[0] == 0x38210000 + SIGNAL_FRAMESIZE
271 + && (pc[1] == 0x38000077 || pc[1] == 0x380000AC)
272 + && pc[2] == 0x44000002)
273 + context->signal_frame = 1;
275 + /* li r0, 0x7777; sc (sigreturn old) */
276 + /* li r0, 0x0077; sc (sigreturn new) */
277 + /* li r0, 0x6666; sc (rt_sigreturn old) */
278 + /* li r0, 0x00AC; sc (rt_sigreturn new) */
279 + if ((pc[0] == 0x38007777 || pc[0] == 0x38000077
280 + || pc[0] == 0x38006666 || pc[0] == 0x380000AC)
281 + && pc[1] == 0x44000002)
282 + context->signal_frame = 1;
285 +#ifdef __powerpc64__
286 + if (fs->regs.reg[2].how == REG_UNSAVED)
288 + /* If the current unwind info (FS) does not contain explicit info
289 + saving R2, then we have to do a minor amount of code reading to
290 + figure out if it was saved. The big problem here is that the
291 + code that does the save/restore is generated by the linker, so
292 + we have no good way to determine at compile time what to do. */
294 + = (unsigned int *) _Unwind_GetGR (context, LINK_REGISTER_REGNUM);
295 + if (*insn == 0xE8410028)
296 + _Unwind_SetGRPtr (context, 2, context->cfa + 40);
300 --- gcc/config/arm/unwind-arm.h (revision 111580)
301 +++ gcc/config/arm/unwind-arm.h (revision 111581)
303 #define _Unwind_GetIP(context) \
304 (_Unwind_GetGR (context, 15) & ~(_Unwind_Word)1)
306 +#define _Unwind_GetIP(context, ip_before_insn) \
307 + (*ip_before_insn = 0, _Unwind_GetGR (context, 15) & ~(_Unwind_Word)1)
310 _Unwind_SetGR (_Unwind_Context *context, int regno, _Unwind_Word val)
312 --- gcc/libgcc-std.ver (revision 111580)
313 +++ gcc/libgcc-std.ver (revision 111581)
315 %inherit GCC_4.1.0 GCC_4.0.0
322 --- libstdc++-v3/libsupc++/eh_personality.cc (revision 111580)
323 +++ libstdc++-v3/libsupc++/eh_personality.cc (revision 111581)
325 int handler_switch_value;
326 void* thrown_ptr = ue_header + 1;
327 bool foreign_exception;
328 + int ip_before_insn = 0;
330 #ifdef __ARM_EABI_UNWINDER__
331 _Unwind_Action actions;
333 // Parse the LSDA header.
334 p = parse_lsda_header (context, language_specific_data, &info);
335 info.ttype_base = base_of_encoded_value (info.ttype_encoding, context);
336 - ip = _Unwind_GetIP (context) - 1;
337 + ip = _Unwind_GetIPInfo (context, &ip_before_insn);
338 + if (! ip_before_insn)
342 handler_switch_value = 0;
343 --- libjava/exception.cc (revision 111580)
344 +++ libjava/exception.cc (revision 111581)
346 int handler_switch_value;
349 + int ip_before_insn = 0;
352 // Interface version check.
353 @@ -212,10 +213,10 @@
354 goto install_context;
357 - // FIXME: In Phase 1, record _Unwind_GetIP in xh->obj as a part of
358 + // FIXME: In Phase 1, record _Unwind_GetIPInfo in xh->obj as a part of
359 // the stack trace for this exception. This will only collect Java
360 // frames, but perhaps that is acceptable.
361 - // FIXME2: _Unwind_GetIP is nonsensical for SJLJ, being a call-site
362 + // FIXME2: _Unwind_GetIPInfo is nonsensical for SJLJ, being a call-site
363 // index instead of a PC value. We could perhaps arrange for
364 // _Unwind_GetRegionStart to return context->fc->jbuf[1], which
365 // is the address of the handler label for __builtin_longjmp, but
368 // Parse the LSDA header.
369 p = parse_lsda_header (context, language_specific_data, &info);
370 - ip = _Unwind_GetIP (context) - 1;
371 + ip = _Unwind_GetIPInfo (context, &ip_before_insn);
372 + if (! ip_before_insn)
376 handler_switch_value = 0;
377 --- libjava/include/i386-signal.h (revision 111580)
378 +++ libjava/include/i386-signal.h (revision 111581)
380 #define SIGNAL_HANDLER(_name) \
381 static void _name (int _dummy __attribute__ ((__unused__)))
383 -#define MAKE_THROW_FRAME(_exception) \
386 - void **_p = (void **)&_dummy; \
387 - volatile struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p; \
389 - /* Advance the program counter so that it is after the start of the \
390 - instruction: the x86 exception handler expects \
391 - the PC to point to the instruction after a call. */ \
396 +#define MAKE_THROW_FRAME(_exception)
398 #define HANDLE_DIVIDE_OVERFLOW \
401 _regs->eip = (unsigned long)_eip; \
406 - /* Advance the program counter so that it is after the start \
407 - of the instruction: this is because the x86 exception \
408 - handler expects the PC to point to the instruction after a \
415 --- libjava/include/powerpc-signal.h (revision 111580)
416 +++ libjava/include/powerpc-signal.h (revision 111581)
418 #define SIGNAL_HANDLER(_name) \
419 static void _name (int /* _signal */, struct sigcontext *_sc)
421 -/* PPC either leaves PC pointing at a faulting instruction or the
422 - following instruction, depending on the signal. SEGV always does
423 - the former, so we adjust the saved PC to point to the following
424 - instruction. This is what the handler in libgcc expects. */
425 +/* MD_FALBACK_FRAME_STATE_FOR takes care of special casing PC
426 + before the faulting instruction, so we don't need to do anything
429 -#define MAKE_THROW_FRAME(_exception) \
432 - _sc->regs->nip += 4; \
436 +#define MAKE_THROW_FRAME(_exception)
438 /* For an explanation why we cannot simply use sigaction to
439 install the handlers, see i386-signal.h. */
441 --- libjava/include/x86_64-signal.h (revision 111580)
442 +++ libjava/include/x86_64-signal.h (revision 111581)
447 -#define MAKE_THROW_FRAME(_exception) \
450 - /* Advance the program counter so that it is after the start of the \
451 - instruction: the x86_64 exception handler expects \
452 - the PC to point to the instruction after a call. */ \
453 - struct ucontext *_uc = (struct ucontext *)_p; \
454 - volatile struct sigcontext *_sc = (struct sigcontext *) &_uc->uc_mcontext; \
458 +#define MAKE_THROW_FRAME(_exception)
460 #define RESTORE(name, syscall) RESTORE2 (name, syscall)
461 #define RESTORE2(name, syscall) \