mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-05 14:59:45 +08:00
i386.c (general_no_elim_operand): Disallow virtual regs.
* config/i386/i386.c (general_no_elim_operand): Disallow virtual regs. (ix86_save_reg): If maybe_eh_return, true for EH_RETURN_DATA_REGNOs. True for pic register if current_function_calls_eh_return. (ix86_expand_epilogue): Change "emit_return" argument into "style". Handle eh_return requirements. * config/i386/i386.h (EH_RETURN_DATA_REGNO): New. (EH_RETURN_STACKADJ_RTX): New. * config/i386/i386.md (exception_receiver): Remove. (eh_return, eh_return_1): New. * config/i386/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New. From-SVN: r40926
This commit is contained in:
parent
4573b4de23
commit
1020a5ab7e
@ -1,13 +1,24 @@
|
|||||||
2001-03-28 Richard Henderson <rth@redhat.com>
|
2001-03-28 Richard Henderson <rth@redhat.com>
|
||||||
|
|
||||||
* config/alpha/alpha.c (alpha_sa_mask): Add EH_RETURN_DATA_REGNOs.
|
* config/i386/i386.c (general_no_elim_operand): Disallow virtual regs.
|
||||||
(alpha_mark_machine_status): No eh_epilogue_sp_ofs ...
|
(ix86_save_reg): If maybe_eh_return, true for EH_RETURN_DATA_REGNOs.
|
||||||
(alpha_expand_epilogue): ... use EH_RETURN_STACKADJ_RTX instead.
|
True for pic register if current_function_calls_eh_return.
|
||||||
* config/alpha/alpha.h (machine_function): Remove eh_epilogue_sp_ofs.
|
(ix86_expand_epilogue): Change "emit_return" argument into "style".
|
||||||
(EH_RETURN_DATA_REGNO): New.
|
Handle eh_return requirements.
|
||||||
(EH_RETURN_STACKADJ_RTX, EH_RETURN_HANDLER_RTX): New.
|
* config/i386/i386.h (EH_RETURN_DATA_REGNO): New.
|
||||||
* config/alpha/alpha.md (eh_epilogue): Remove.
|
(EH_RETURN_STACKADJ_RTX): New.
|
||||||
(exception_receiver): Use $26 for ldgp input.
|
* config/i386/i386.md (exception_receiver): Remove.
|
||||||
|
(eh_return, eh_return_1): New.
|
||||||
|
* config/i386/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New.
|
||||||
|
|
||||||
|
* config/alpha/alpha.c (alpha_sa_mask): Add EH_RETURN_DATA_REGNOs.
|
||||||
|
(alpha_mark_machine_status): No eh_epilogue_sp_ofs ...
|
||||||
|
(alpha_expand_epilogue): ... use EH_RETURN_STACKADJ_RTX instead.
|
||||||
|
* config/alpha/alpha.h (machine_function): Remove eh_epilogue_sp_ofs.
|
||||||
|
(EH_RETURN_DATA_REGNO): New.
|
||||||
|
(EH_RETURN_STACKADJ_RTX, EH_RETURN_HANDLER_RTX): New.
|
||||||
|
* config/alpha/alpha.md (eh_epilogue): Remove.
|
||||||
|
(exception_receiver): Use $26 for ldgp input.
|
||||||
* config/alpha/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New.
|
* config/alpha/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New.
|
||||||
|
|
||||||
2001-03-28 Richard Henderson <rth@redhat.com>
|
2001-03-28 Richard Henderson <rth@redhat.com>
|
||||||
|
@ -566,7 +566,7 @@ static int ix86_split_to_parts PARAMS ((rtx, rtx *, enum machine_mode));
|
|||||||
static int ix86_safe_length_prefix PARAMS ((rtx));
|
static int ix86_safe_length_prefix PARAMS ((rtx));
|
||||||
static int ix86_nsaved_regs PARAMS((void));
|
static int ix86_nsaved_regs PARAMS((void));
|
||||||
static void ix86_emit_save_regs PARAMS((void));
|
static void ix86_emit_save_regs PARAMS((void));
|
||||||
static void ix86_emit_restore_regs_using_mov PARAMS ((rtx, int));
|
static void ix86_emit_restore_regs_using_mov PARAMS ((rtx, int, bool));
|
||||||
static void ix86_emit_epilogue_esp_adjustment PARAMS((int));
|
static void ix86_emit_epilogue_esp_adjustment PARAMS((int));
|
||||||
static void ix86_set_move_mem_attrs_1 PARAMS ((rtx, rtx, rtx, rtx, rtx));
|
static void ix86_set_move_mem_attrs_1 PARAMS ((rtx, rtx, rtx, rtx, rtx));
|
||||||
static void ix86_sched_reorder_pentium PARAMS((rtx *, rtx *));
|
static void ix86_sched_reorder_pentium PARAMS((rtx *, rtx *));
|
||||||
@ -606,7 +606,7 @@ static int ix86_fp_comparison_arithmetics_cost PARAMS ((enum rtx_code code));
|
|||||||
static int ix86_fp_comparison_fcomi_cost PARAMS ((enum rtx_code code));
|
static int ix86_fp_comparison_fcomi_cost PARAMS ((enum rtx_code code));
|
||||||
static int ix86_fp_comparison_sahf_cost PARAMS ((enum rtx_code code));
|
static int ix86_fp_comparison_sahf_cost PARAMS ((enum rtx_code code));
|
||||||
static int ix86_fp_comparison_cost PARAMS ((enum rtx_code code));
|
static int ix86_fp_comparison_cost PARAMS ((enum rtx_code code));
|
||||||
static int ix86_save_reg PARAMS ((int));
|
static int ix86_save_reg PARAMS ((int, bool));
|
||||||
static void ix86_compute_frame_layout PARAMS ((struct ix86_frame *));
|
static void ix86_compute_frame_layout PARAMS ((struct ix86_frame *));
|
||||||
|
|
||||||
/* Sometimes certain combinations of command options do not make
|
/* Sometimes certain combinations of command options do not make
|
||||||
@ -1475,6 +1475,10 @@ general_no_elim_operand (op, mode)
|
|||||||
|| t == virtual_incoming_args_rtx || t == virtual_stack_vars_rtx
|
|| t == virtual_incoming_args_rtx || t == virtual_stack_vars_rtx
|
||||||
|| t == virtual_stack_dynamic_rtx)
|
|| t == virtual_stack_dynamic_rtx)
|
||||||
return 0;
|
return 0;
|
||||||
|
if (REG_P (t)
|
||||||
|
&& REGNO (t) >= FIRST_VIRTUAL_REGISTER
|
||||||
|
&& REGNO (t) <= LAST_VIRTUAL_REGISTER)
|
||||||
|
return 0;
|
||||||
|
|
||||||
return general_operand (op, mode);
|
return general_operand (op, mode);
|
||||||
}
|
}
|
||||||
@ -2249,17 +2253,35 @@ gen_push (arg)
|
|||||||
|
|
||||||
/* Return 1 if we need to save REGNO. */
|
/* Return 1 if we need to save REGNO. */
|
||||||
static int
|
static int
|
||||||
ix86_save_reg (regno)
|
ix86_save_reg (regno, maybe_eh_return)
|
||||||
int regno;
|
int regno;
|
||||||
|
bool maybe_eh_return;
|
||||||
{
|
{
|
||||||
int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
|
if (flag_pic
|
||||||
|| current_function_uses_const_pool)
|
&& ! TARGET_64BIT
|
||||||
&& !TARGET_64BIT;
|
&& regno == PIC_OFFSET_TABLE_REGNUM
|
||||||
return ((regs_ever_live[regno] && !call_used_regs[regno]
|
&& (current_function_uses_pic_offset_table
|
||||||
&& !fixed_regs[regno]
|
|| current_function_uses_const_pool
|
||||||
&& (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
|
|| current_function_calls_eh_return))
|
||||||
|| (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used));
|
return 1;
|
||||||
|
|
||||||
|
if (current_function_calls_eh_return && maybe_eh_return)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; ; i++)
|
||||||
|
{
|
||||||
|
unsigned test = EH_RETURN_DATA_REGNO(i);
|
||||||
|
if (test == INVALID_REGNUM)
|
||||||
|
break;
|
||||||
|
if (test == (unsigned) regno)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (regs_ever_live[regno]
|
||||||
|
&& !call_used_regs[regno]
|
||||||
|
&& !fixed_regs[regno]
|
||||||
|
&& (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return number of registers to be saved on the stack. */
|
/* Return number of registers to be saved on the stack. */
|
||||||
@ -2271,7 +2293,7 @@ ix86_nsaved_regs ()
|
|||||||
int regno;
|
int regno;
|
||||||
|
|
||||||
for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
|
for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
|
||||||
if (ix86_save_reg (regno))
|
if (ix86_save_reg (regno, true))
|
||||||
nregs++;
|
nregs++;
|
||||||
return nregs;
|
return nregs;
|
||||||
}
|
}
|
||||||
@ -2423,7 +2445,7 @@ ix86_emit_save_regs ()
|
|||||||
rtx insn;
|
rtx insn;
|
||||||
|
|
||||||
for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
|
for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
|
||||||
if (ix86_save_reg (regno))
|
if (ix86_save_reg (regno, true))
|
||||||
{
|
{
|
||||||
insn = emit_insn (gen_push (gen_rtx_REG (Pmode, regno)));
|
insn = emit_insn (gen_push (gen_rtx_REG (Pmode, regno)));
|
||||||
RTX_FRAME_RELATED_P (insn) = 1;
|
RTX_FRAME_RELATED_P (insn) = 1;
|
||||||
@ -2535,14 +2557,15 @@ ix86_emit_epilogue_esp_adjustment (tsize)
|
|||||||
/* Emit code to restore saved registers using MOV insns. First register
|
/* Emit code to restore saved registers using MOV insns. First register
|
||||||
is restored from POINTER + OFFSET. */
|
is restored from POINTER + OFFSET. */
|
||||||
static void
|
static void
|
||||||
ix86_emit_restore_regs_using_mov (pointer, offset)
|
ix86_emit_restore_regs_using_mov (pointer, offset, maybe_eh_return)
|
||||||
rtx pointer;
|
rtx pointer;
|
||||||
int offset;
|
int offset;
|
||||||
|
bool maybe_eh_return;
|
||||||
{
|
{
|
||||||
int regno;
|
int regno;
|
||||||
|
|
||||||
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
||||||
if (ix86_save_reg (regno))
|
if (ix86_save_reg (regno, maybe_eh_return))
|
||||||
{
|
{
|
||||||
emit_move_insn (gen_rtx_REG (Pmode, regno),
|
emit_move_insn (gen_rtx_REG (Pmode, regno),
|
||||||
adj_offsettable_operand (gen_rtx_MEM (Pmode,
|
adj_offsettable_operand (gen_rtx_MEM (Pmode,
|
||||||
@ -2555,8 +2578,8 @@ ix86_emit_restore_regs_using_mov (pointer, offset)
|
|||||||
/* Restore function stack, frame, and registers. */
|
/* Restore function stack, frame, and registers. */
|
||||||
|
|
||||||
void
|
void
|
||||||
ix86_expand_epilogue (emit_return)
|
ix86_expand_epilogue (style)
|
||||||
int emit_return;
|
int style;
|
||||||
{
|
{
|
||||||
int regno;
|
int regno;
|
||||||
int sp_valid = !frame_pointer_needed || current_function_sp_is_unchanging;
|
int sp_valid = !frame_pointer_needed || current_function_sp_is_unchanging;
|
||||||
@ -2588,7 +2611,8 @@ ix86_expand_epilogue (emit_return)
|
|||||||
if ((!sp_valid && frame.nregs <= 1)
|
if ((!sp_valid && frame.nregs <= 1)
|
||||||
|| (frame_pointer_needed && !frame.nregs && frame.to_allocate)
|
|| (frame_pointer_needed && !frame.nregs && frame.to_allocate)
|
||||||
|| (frame_pointer_needed && TARGET_USE_LEAVE && !optimize_size
|
|| (frame_pointer_needed && TARGET_USE_LEAVE && !optimize_size
|
||||||
&& frame.nregs == 1))
|
&& frame.nregs == 1)
|
||||||
|
|| style == 2)
|
||||||
{
|
{
|
||||||
/* Restore registers. We can use ebp or esp to address the memory
|
/* Restore registers. We can use ebp or esp to address the memory
|
||||||
locations. If both are available, default to ebp, since offsets
|
locations. If both are available, default to ebp, since offsets
|
||||||
@ -2597,12 +2621,41 @@ ix86_expand_epilogue (emit_return)
|
|||||||
mode. */
|
mode. */
|
||||||
|
|
||||||
if (!frame_pointer_needed || (sp_valid && !frame.to_allocate))
|
if (!frame_pointer_needed || (sp_valid && !frame.to_allocate))
|
||||||
ix86_emit_restore_regs_using_mov (stack_pointer_rtx, frame.to_allocate);
|
ix86_emit_restore_regs_using_mov (stack_pointer_rtx,
|
||||||
|
frame.to_allocate, style == 2);
|
||||||
else
|
else
|
||||||
ix86_emit_restore_regs_using_mov (hard_frame_pointer_rtx, offset);
|
ix86_emit_restore_regs_using_mov (hard_frame_pointer_rtx,
|
||||||
|
offset, style == 2);
|
||||||
|
|
||||||
if (!frame_pointer_needed)
|
/* eh_return epilogues need %ecx added to the stack pointer. */
|
||||||
ix86_emit_epilogue_esp_adjustment (frame.to_allocate + frame.nregs * UNITS_PER_WORD);
|
if (style == 2)
|
||||||
|
{
|
||||||
|
rtx tmp, sa = EH_RETURN_STACKADJ_RTX;
|
||||||
|
|
||||||
|
if (frame_pointer_needed)
|
||||||
|
{
|
||||||
|
tmp = gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, sa);
|
||||||
|
tmp = plus_constant (tmp, UNITS_PER_WORD);
|
||||||
|
emit_insn (gen_rtx_SET (VOIDmode, sa, tmp));
|
||||||
|
|
||||||
|
tmp = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
|
||||||
|
emit_move_insn (hard_frame_pointer_rtx, tmp);
|
||||||
|
|
||||||
|
emit_insn (gen_pro_epilogue_adjust_stack
|
||||||
|
(stack_pointer_rtx, sa, const0_rtx,
|
||||||
|
hard_frame_pointer_rtx));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tmp = gen_rtx_PLUS (Pmode, stack_pointer_rtx, sa);
|
||||||
|
tmp = plus_constant (tmp, (frame.to_allocate
|
||||||
|
+ frame.nregs * UNITS_PER_WORD));
|
||||||
|
emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx, tmp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!frame_pointer_needed)
|
||||||
|
ix86_emit_epilogue_esp_adjustment (frame.to_allocate
|
||||||
|
+ frame.nregs * UNITS_PER_WORD);
|
||||||
/* If not an i386, mov & pop is faster than "leave". */
|
/* If not an i386, mov & pop is faster than "leave". */
|
||||||
else if (TARGET_USE_LEAVE || optimize_size)
|
else if (TARGET_USE_LEAVE || optimize_size)
|
||||||
emit_insn (TARGET_64BIT ? gen_leave_rex64 () : gen_leave ());
|
emit_insn (TARGET_64BIT ? gen_leave_rex64 () : gen_leave ());
|
||||||
@ -2635,7 +2688,7 @@ ix86_expand_epilogue (emit_return)
|
|||||||
ix86_emit_epilogue_esp_adjustment (frame.to_allocate);
|
ix86_emit_epilogue_esp_adjustment (frame.to_allocate);
|
||||||
|
|
||||||
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
||||||
if (ix86_save_reg (regno))
|
if (ix86_save_reg (regno, false))
|
||||||
{
|
{
|
||||||
if (TARGET_64BIT)
|
if (TARGET_64BIT)
|
||||||
emit_insn (gen_popdi1 (gen_rtx_REG (Pmode, regno)));
|
emit_insn (gen_popdi1 (gen_rtx_REG (Pmode, regno)));
|
||||||
@ -2652,7 +2705,7 @@ ix86_expand_epilogue (emit_return)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Sibcall epilogues don't want a return instruction. */
|
/* Sibcall epilogues don't want a return instruction. */
|
||||||
if (! emit_return)
|
if (style == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (current_function_pops_args && current_function_args_size)
|
if (current_function_pops_args && current_function_args_size)
|
||||||
|
@ -2779,10 +2779,10 @@ extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
|
|||||||
gen_rtx_MEM (VOIDmode, gen_rtx_REG (VOIDmode, STACK_POINTER_REGNUM))
|
gen_rtx_MEM (VOIDmode, gen_rtx_REG (VOIDmode, STACK_POINTER_REGNUM))
|
||||||
|
|
||||||
/* After the prologue, RA is at -4(AP) in the current frame. */
|
/* After the prologue, RA is at -4(AP) in the current frame. */
|
||||||
#define RETURN_ADDR_RTX(COUNT, FRAME) \
|
#define RETURN_ADDR_RTX(COUNT, FRAME) \
|
||||||
((COUNT) == 0 \
|
((COUNT) == 0 \
|
||||||
? gen_rtx_MEM (Pmode, plus_constant (arg_pointer_rtx, TARGET_64BIT ? -8 : -4))\
|
? gen_rtx_MEM (Pmode, plus_constant (arg_pointer_rtx, -UNITS_PER_WORD)) \
|
||||||
: gen_rtx_MEM (Pmode, plus_constant (FRAME, TARGET_64BIT ? 8 : 4)))
|
: gen_rtx_MEM (Pmode, plus_constant (FRAME, UNITS_PER_WORD)))
|
||||||
|
|
||||||
/* PC is dbx register 8; let's use that column for RA. */
|
/* PC is dbx register 8; let's use that column for RA. */
|
||||||
#define DWARF_FRAME_RETURN_COLUMN (TARGET_64BIT ? 16 : 8)
|
#define DWARF_FRAME_RETURN_COLUMN (TARGET_64BIT ? 16 : 8)
|
||||||
@ -2790,6 +2790,10 @@ extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
|
|||||||
/* Before the prologue, the top of the frame is at 4(%esp). */
|
/* Before the prologue, the top of the frame is at 4(%esp). */
|
||||||
#define INCOMING_FRAME_SP_OFFSET UNITS_PER_WORD
|
#define INCOMING_FRAME_SP_OFFSET UNITS_PER_WORD
|
||||||
|
|
||||||
|
/* Describe how we implement __builtin_eh_return. */
|
||||||
|
#define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? (N) : INVALID_REGNUM)
|
||||||
|
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 2)
|
||||||
|
|
||||||
/* This is how to output the definition of a user-level label named NAME,
|
/* This is how to output the definition of a user-level label named NAME,
|
||||||
such as the label on a static function or variable NAME. */
|
such as the label on a static function or variable NAME. */
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@
|
|||||||
;; 10 This is a `sahf' operation.
|
;; 10 This is a `sahf' operation.
|
||||||
;; 11 This is a `fstcw' operation
|
;; 11 This is a `fstcw' operation
|
||||||
;; 12 This is behaviour of add when setting carry flag.
|
;; 12 This is behaviour of add when setting carry flag.
|
||||||
|
;; 13 This is a `eh_return' placeholder.
|
||||||
|
|
||||||
;; For SSE/MMX support:
|
;; For SSE/MMX support:
|
||||||
;; 30 This is `fix', guaranteed to be truncating.
|
;; 30 This is `fix', guaranteed to be truncating.
|
||||||
@ -13017,6 +13018,35 @@
|
|||||||
""
|
""
|
||||||
"ix86_expand_epilogue (0); DONE;")
|
"ix86_expand_epilogue (0); DONE;")
|
||||||
|
|
||||||
|
(define_expand "eh_return"
|
||||||
|
[(use (match_operand 0 "register_operand" ""))
|
||||||
|
(use (match_operand 1 "register_operand" ""))]
|
||||||
|
""
|
||||||
|
"
|
||||||
|
{
|
||||||
|
rtx tmp, sa = operands[0], ra = operands[1];
|
||||||
|
|
||||||
|
/* Tricky bit: we write the address of the handler to which we will
|
||||||
|
be returning into someone else's stack frame, one word below the
|
||||||
|
stack address we wish to restore. */
|
||||||
|
tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
|
||||||
|
tmp = plus_constant (tmp, -UNITS_PER_WORD);
|
||||||
|
tmp = gen_rtx_MEM (Pmode, tmp);
|
||||||
|
emit_move_insn (tmp, ra);
|
||||||
|
|
||||||
|
emit_insn (gen_eh_return_1 (sa));
|
||||||
|
emit_barrier ();
|
||||||
|
DONE;
|
||||||
|
}")
|
||||||
|
|
||||||
|
(define_insn_and_split "eh_return_1"
|
||||||
|
[(unspec_volatile [(match_operand 0 "register_operand" "c")] 13)]
|
||||||
|
""
|
||||||
|
"#"
|
||||||
|
"reload_completed"
|
||||||
|
[(const_int 1)]
|
||||||
|
"ix86_expand_epilogue (2); DONE;")
|
||||||
|
|
||||||
(define_insn "leave"
|
(define_insn "leave"
|
||||||
[(set (reg:SI 7) (reg:SI 6))
|
[(set (reg:SI 7) (reg:SI 6))
|
||||||
(set (reg:SI 6) (mem:SI (pre_dec:SI (reg:SI 7))))]
|
(set (reg:SI 6) (mem:SI (pre_dec:SI (reg:SI 7))))]
|
||||||
@ -15754,15 +15784,6 @@
|
|||||||
DONE;
|
DONE;
|
||||||
}")
|
}")
|
||||||
|
|
||||||
(define_expand "exception_receiver"
|
|
||||||
[(const_int 0)]
|
|
||||||
"flag_pic"
|
|
||||||
"
|
|
||||||
{
|
|
||||||
load_pic_register ();
|
|
||||||
DONE;
|
|
||||||
}")
|
|
||||||
|
|
||||||
(define_expand "builtin_setjmp_receiver"
|
(define_expand "builtin_setjmp_receiver"
|
||||||
[(label_ref (match_operand 0 "" ""))]
|
[(label_ref (match_operand 0 "" ""))]
|
||||||
"flag_pic"
|
"flag_pic"
|
||||||
|
@ -188,3 +188,65 @@ Boston, MA 02111-1307, USA. */
|
|||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Do code reading to identify a signal frame, and set the frame
|
||||||
|
state data appropriately. See unwind-dw2.c for the structs. */
|
||||||
|
|
||||||
|
#ifdef IN_LIBGCC2
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/ucontext.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
|
||||||
|
do { \
|
||||||
|
unsigned char *pc_ = (CONTEXT)->ra; \
|
||||||
|
struct sigcontext *sc_; \
|
||||||
|
long new_cfa_; \
|
||||||
|
\
|
||||||
|
/* popl %eax ; movl $__NR_sigreturn,%eax ; int $0x80 */ \
|
||||||
|
if (*(unsigned short *)(pc_+0) == 0xb858 \
|
||||||
|
&& *(unsigned int *)(pc_+2) == 119 \
|
||||||
|
&& *(unsigned short *)(pc_+6) == 0x80cd) \
|
||||||
|
sc_ = (CONTEXT)->cfa + 4; \
|
||||||
|
/* movl $__NR_rt_sigreturn,%eax ; int $0x80 */ \
|
||||||
|
else if (*(unsigned char *)(pc_+0) == 0xb8 \
|
||||||
|
&& *(unsigned int *)(pc_+1) == 173 \
|
||||||
|
&& *(unsigned short *)(pc_+5) == 0x80cd) \
|
||||||
|
{ \
|
||||||
|
struct rt_sigframe { \
|
||||||
|
int sig; \
|
||||||
|
struct siginfo *pinfo; \
|
||||||
|
void *puc; \
|
||||||
|
struct siginfo info; \
|
||||||
|
struct ucontext uc; \
|
||||||
|
} *rt_ = (CONTEXT)->cfa; \
|
||||||
|
sc_ = (struct sigcontext *) &rt_->uc.uc_mcontext; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
new_cfa_ = sc_->esp; \
|
||||||
|
(FS)->cfa_how = CFA_REG_OFFSET; \
|
||||||
|
(FS)->cfa_reg = 4; \
|
||||||
|
(FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
|
||||||
|
\
|
||||||
|
/* The SVR4 register numbering macros aren't usable in libgcc. */ \
|
||||||
|
(FS)->regs.reg[0].how = REG_SAVED_OFFSET; \
|
||||||
|
(FS)->regs.reg[0].loc.offset = (long)&sc_->eax - new_cfa_; \
|
||||||
|
(FS)->regs.reg[3].how = REG_SAVED_OFFSET; \
|
||||||
|
(FS)->regs.reg[3].loc.offset = (long)&sc_->ebx - new_cfa_; \
|
||||||
|
(FS)->regs.reg[1].how = REG_SAVED_OFFSET; \
|
||||||
|
(FS)->regs.reg[1].loc.offset = (long)&sc_->ecx - new_cfa_; \
|
||||||
|
(FS)->regs.reg[2].how = REG_SAVED_OFFSET; \
|
||||||
|
(FS)->regs.reg[2].loc.offset = (long)&sc_->edx - new_cfa_; \
|
||||||
|
(FS)->regs.reg[6].how = REG_SAVED_OFFSET; \
|
||||||
|
(FS)->regs.reg[6].loc.offset = (long)&sc_->esi - new_cfa_; \
|
||||||
|
(FS)->regs.reg[7].how = REG_SAVED_OFFSET; \
|
||||||
|
(FS)->regs.reg[7].loc.offset = (long)&sc_->edi - new_cfa_; \
|
||||||
|
(FS)->regs.reg[5].how = REG_SAVED_OFFSET; \
|
||||||
|
(FS)->regs.reg[5].loc.offset = (long)&sc_->ebp - new_cfa_; \
|
||||||
|
(FS)->regs.reg[8].how = REG_SAVED_OFFSET; \
|
||||||
|
(FS)->regs.reg[8].loc.offset = (long)&sc_->eip - new_cfa_; \
|
||||||
|
(FS)->retaddr_column = 8; \
|
||||||
|
goto SUCCESS; \
|
||||||
|
} while (0)
|
||||||
|
Loading…
Reference in New Issue
Block a user