This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: ARM, stack unwinding, and Firefox OS
- From: Jed Davis <jld at mozilla dot com>
- To: gcc at gcc dot gnu dot org
- Date: Thu, 25 Apr 2013 20:12:09 -0700
- Subject: Re: ARM, stack unwinding, and Firefox OS
- References: <20130426022542 dot GB23798 at mozilla dot com>
On Thu, Apr 25, 2013 at 07:25:42PM -0700, Jed Davis wrote:
> I've attached a patch
Let's try that again....
--Jed
diff --git a/gcc-4.4.3/gcc/config/arm/arm.c b/gcc-4.4.3/gcc/config/arm/arm.c
index bef07e3..ce6acf1 100644
--- a/gcc-4.4.3/gcc/config/arm/arm.c
+++ b/gcc-4.4.3/gcc/config/arm/arm.c
@@ -1381,6 +1381,21 @@ arm_override_options (void)
target_flags &= ~MASK_APCS_FRAME;
}
+ if (TARGET_THUMB2_FAKE_APCS_FRAME && !(insn_flags & FL_THUMB2))
+ {
+ warning (0, "ignoring -mthumb2-fake-apcs-frame for non-Thumb2 target");
+ target_flags &= ~MASK_THUMB2_FAKE_APCS_FRAME;
+ }
+
+ if (TARGET_THUMB2_FAKE_APCS_FRAME && TARGET_ARM)
+ {
+ target_flags &= ~MASK_THUMB2_FAKE_APCS_FRAME;
+ if (!TARGET_APCS_FRAME)
+ {
+ warning (0, "-mthumb2-fake-apcs-frame but not -mapcs-frame specified when compiling for ARM");
+ }
+ }
+
/* Callee super interworking implies thumb interworking. Adding
this to the flags here simplifies the logic elsewhere. */
if (TARGET_THUMB && TARGET_CALLEE_INTERWORKING)
@@ -12696,6 +12711,11 @@ arm_compute_save_reg_mask (void)
if (cfun->machine->lr_save_eliminated)
save_reg_mask &= ~ (1 << LR_REGNUM);
+ if (TARGET_THUMB2_FAKE_APCS_FRAME && (save_reg_mask & (1 << LR_REGNUM)))
+ save_reg_mask |=
+ (1 << ARM_HARD_FRAME_POINTER_REGNUM)
+ | (1 << IP_REGNUM);
+
if (TARGET_REALLY_IWMMXT
&& ((bit_count (save_reg_mask)
+ ARM_NUM_INTS (crtl->args.pretend_args_size +
@@ -14506,6 +14526,15 @@ arm_expand_prologue (void)
RTX_FRAME_RELATED_P (insn) = 1;
}
}
+ else if (TARGET_THUMB2_FAKE_APCS_FRAME &&
+ (offsets->saved_regs_mask & (1 << ARM_HARD_FRAME_POINTER_REGNUM))) {
+ rtx arm_fp_rtx = gen_raw_REG (Pmode, ARM_HARD_FRAME_POINTER_REGNUM);
+
+ insn = GEN_INT (saved_regs);
+ insn = emit_insn (gen_addsi3 (arm_fp_rtx, stack_pointer_rtx, insn));
+ /* This is not "frame-related", because it doesn't set the frame
+ pointer that a debugger would use to find things. */
+ }
if (offsets->outgoing_args != offsets->saved_args + saved_regs)
{
diff --git a/gcc-4.4.3/gcc/config/arm/arm.h b/gcc-4.4.3/gcc/config/arm/arm.h
index 1189914..d50525e 100644
--- a/gcc-4.4.3/gcc/config/arm/arm.h
+++ b/gcc-4.4.3/gcc/config/arm/arm.h
@@ -837,11 +837,12 @@ extern int arm_structure_size_boundary;
is an easy way of ensuring that it remains valid for all \
calls. */ \
if (TARGET_APCS_FRAME || TARGET_CALLER_INTERWORKING \
- || TARGET_TPCS_FRAME || TARGET_TPCS_LEAF_FRAME) \
+ || TARGET_TPCS_FRAME || TARGET_TPCS_LEAF_FRAME \
+ || TARGET_THUMB2_FAKE_APCS_FRAME) \
{ \
fixed_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1; \
call_used_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1; \
- if (TARGET_CALLER_INTERWORKING) \
+ if (TARGET_CALLER_INTERWORKING || TARGET_THUMB2_FAKE_APCS_FRAME) \
global_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1; \
} \
SUBTARGET_CONDITIONAL_REGISTER_USAGE \
diff --git a/gcc-4.4.3/gcc/config/arm/arm.opt b/gcc-4.4.3/gcc/config/arm/arm.opt
index 6aca395..5c8c0c1 100644
--- a/gcc-4.4.3/gcc/config/arm/arm.opt
+++ b/gcc-4.4.3/gcc/config/arm/arm.opt
@@ -37,6 +37,10 @@ mapcs-frame
Target Report Mask(APCS_FRAME)
Generate APCS conformant stack frames
+mthumb2-fake-apcs-frame
+Target Report Mask(THUMB2_FAKE_APCS_FRAME)
+Emulate APCS conformant stack frames in Thumb2 code
+
mapcs-reentrant
Target Report Mask(APCS_REENT)
Generate re-entrant, PIC code