[ARM/FDPIC v6 09/24] [ARM] FDPIC: Add support for taking address of nested function
In FDPIC mode, the trampoline generated to support pointers to nested functions looks like: .word trampoline address .word trampoline GOT address ldr r12, [pc, #8] ldr r9, [pc, #8] ldr pc, [pc, #8] .word static chain value .word GOT address .word function's address because in FDPIC function pointers are actually pointers to function descriptors, we have to actually generate a function descriptor for the trampoline. 2019--09-10 Christophe Lyon <christophe.lyon@st.com> Mickaël Guêné <mickael.guene@st.com> gcc/ * config/arm/arm.c (arm_asm_trampoline_template): Add FDPIC support. (arm_trampoline_init): Likewise. (arm_trampoline_adjust_address): Likewise. * config/arm/arm.h (TRAMPOLINE_SIZE): Likewise. Co-Authored-By: Mickaël Guêné <mickael.guene@st.com> From-SVN: r275571
This commit is contained in:
parent
96ef8d00f7
commit
bc87cffb13
|
@ -1,3 +1,13 @@
|
|||
2019-09-10 Christophe Lyon <christophe.lyon@st.com>
|
||||
Mickaël Guêné <mickael.guene@st.com>
|
||||
|
||||
gcc/
|
||||
* config/arm/arm.c (arm_asm_trampoline_template): Add FDPIC
|
||||
support.
|
||||
(arm_trampoline_init): Likewise.
|
||||
(arm_trampoline_adjust_address): Likewise.
|
||||
* config/arm/arm.h (TRAMPOLINE_SIZE): Likewise.
|
||||
|
||||
2019-09-10 Christophe Lyon <christophe.lyon@st.com>
|
||||
Mickaël Guêné <mickael.guene@st.com>
|
||||
|
||||
|
|
|
@ -3939,14 +3939,52 @@ arm_warn_func_return (tree decl)
|
|||
ldr pc, [pc]
|
||||
.word static chain value
|
||||
.word function's address
|
||||
XXX FIXME: When the trampoline returns, r8 will be clobbered. */
|
||||
XXX FIXME: When the trampoline returns, r8 will be clobbered.
|
||||
|
||||
In FDPIC mode, the trampoline looks like:
|
||||
.word trampoline address
|
||||
.word trampoline GOT address
|
||||
ldr r12, [pc, #8] ; #4 for Arm mode
|
||||
ldr r9, [pc, #8] ; #4 for Arm mode
|
||||
ldr pc, [pc, #8] ; #4 for Arm mode
|
||||
.word static chain value
|
||||
.word GOT address
|
||||
.word function's address
|
||||
*/
|
||||
|
||||
static void
|
||||
arm_asm_trampoline_template (FILE *f)
|
||||
{
|
||||
fprintf (f, "\t.syntax unified\n");
|
||||
|
||||
if (TARGET_ARM)
|
||||
if (TARGET_FDPIC)
|
||||
{
|
||||
/* The first two words are a function descriptor pointing to the
|
||||
trampoline code just below. */
|
||||
if (TARGET_ARM)
|
||||
fprintf (f, "\t.arm\n");
|
||||
else if (TARGET_THUMB2)
|
||||
fprintf (f, "\t.thumb\n");
|
||||
else
|
||||
/* Only ARM and Thumb-2 are supported. */
|
||||
gcc_unreachable ();
|
||||
|
||||
assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
|
||||
assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
|
||||
/* Trampoline code which sets the static chain register but also
|
||||
PIC register before jumping into real code. */
|
||||
asm_fprintf (f, "\tldr\t%r, [%r, #%d]\n",
|
||||
STATIC_CHAIN_REGNUM, PC_REGNUM,
|
||||
TARGET_THUMB2 ? 8 : 4);
|
||||
asm_fprintf (f, "\tldr\t%r, [%r, #%d]\n",
|
||||
PIC_OFFSET_TABLE_REGNUM, PC_REGNUM,
|
||||
TARGET_THUMB2 ? 8 : 4);
|
||||
asm_fprintf (f, "\tldr\t%r, [%r, #%d]\n",
|
||||
PC_REGNUM, PC_REGNUM,
|
||||
TARGET_THUMB2 ? 8 : 4);
|
||||
assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
|
||||
}
|
||||
else if (TARGET_ARM)
|
||||
{
|
||||
fprintf (f, "\t.arm\n");
|
||||
asm_fprintf (f, "\tldr\t%r, [%r, #0]\n", STATIC_CHAIN_REGNUM, PC_REGNUM);
|
||||
|
@ -3987,12 +4025,40 @@ arm_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
|
|||
emit_block_move (m_tramp, assemble_trampoline_template (),
|
||||
GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
|
||||
|
||||
mem = adjust_address (m_tramp, SImode, TARGET_32BIT ? 8 : 12);
|
||||
emit_move_insn (mem, chain_value);
|
||||
if (TARGET_FDPIC)
|
||||
{
|
||||
rtx funcdesc = XEXP (DECL_RTL (fndecl), 0);
|
||||
rtx fnaddr = gen_rtx_MEM (Pmode, funcdesc);
|
||||
rtx gotaddr = gen_rtx_MEM (Pmode, plus_constant (Pmode, funcdesc, 4));
|
||||
/* The function start address is at offset 8, but in Thumb mode
|
||||
we want bit 0 set to 1 to indicate Thumb-ness, hence 9
|
||||
below. */
|
||||
rtx trampoline_code_start
|
||||
= plus_constant (Pmode, XEXP (m_tramp, 0), TARGET_THUMB2 ? 9 : 8);
|
||||
|
||||
mem = adjust_address (m_tramp, SImode, TARGET_32BIT ? 12 : 16);
|
||||
fnaddr = XEXP (DECL_RTL (fndecl), 0);
|
||||
emit_move_insn (mem, fnaddr);
|
||||
/* Write initial funcdesc which points to the trampoline. */
|
||||
mem = adjust_address (m_tramp, SImode, 0);
|
||||
emit_move_insn (mem, trampoline_code_start);
|
||||
mem = adjust_address (m_tramp, SImode, 4);
|
||||
emit_move_insn (mem, gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM));
|
||||
/* Setup static chain. */
|
||||
mem = adjust_address (m_tramp, SImode, 20);
|
||||
emit_move_insn (mem, chain_value);
|
||||
/* GOT + real function entry point. */
|
||||
mem = adjust_address (m_tramp, SImode, 24);
|
||||
emit_move_insn (mem, gotaddr);
|
||||
mem = adjust_address (m_tramp, SImode, 28);
|
||||
emit_move_insn (mem, fnaddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
mem = adjust_address (m_tramp, SImode, TARGET_32BIT ? 8 : 12);
|
||||
emit_move_insn (mem, chain_value);
|
||||
|
||||
mem = adjust_address (m_tramp, SImode, TARGET_32BIT ? 12 : 16);
|
||||
fnaddr = XEXP (DECL_RTL (fndecl), 0);
|
||||
emit_move_insn (mem, fnaddr);
|
||||
}
|
||||
|
||||
a_tramp = XEXP (m_tramp, 0);
|
||||
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"),
|
||||
|
@ -4006,7 +4072,9 @@ arm_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
|
|||
static rtx
|
||||
arm_trampoline_adjust_address (rtx addr)
|
||||
{
|
||||
if (TARGET_THUMB)
|
||||
/* For FDPIC don't fix trampoline address since it's a function
|
||||
descriptor and not a function address. */
|
||||
if (TARGET_THUMB && !TARGET_FDPIC)
|
||||
addr = expand_simple_binop (Pmode, IOR, addr, const1_rtx,
|
||||
NULL, 0, OPTAB_LIB_WIDEN);
|
||||
return addr;
|
||||
|
|
|
@ -1595,7 +1595,7 @@ typedef struct
|
|||
#define INIT_EXPANDERS arm_init_expanders ()
|
||||
|
||||
/* Length in units of the trampoline for entering a nested function. */
|
||||
#define TRAMPOLINE_SIZE (TARGET_32BIT ? 16 : 20)
|
||||
#define TRAMPOLINE_SIZE (TARGET_FDPIC ? 32 : (TARGET_32BIT ? 16 : 20))
|
||||
|
||||
/* Alignment required for a trampoline in bits. */
|
||||
#define TRAMPOLINE_ALIGNMENT 32
|
||||
|
|
Loading…
Reference in New Issue