Skip to content

Commit 859749d

Browse files
author
clyon
committed
[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 <[email protected]> Mickaël Guêné <[email protected]> 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@275571 138bc75d-0d04-0410-961f-82ee72b054a4
1 parent 2ec82e4 commit 859749d

File tree

3 files changed

+87
-9
lines changed

3 files changed

+87
-9
lines changed

gcc/ChangeLog

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
2019-09-10 Christophe Lyon <[email protected]>
2+
Mickaël Guêné <[email protected]>
3+
4+
gcc/
5+
* config/arm/arm.c (arm_asm_trampoline_template): Add FDPIC
6+
support.
7+
(arm_trampoline_init): Likewise.
8+
(arm_trampoline_adjust_address): Likewise.
9+
* config/arm/arm.h (TRAMPOLINE_SIZE): Likewise.
10+
111
2019-09-10 Christophe Lyon <[email protected]>
212
Mickaël Guêné <[email protected]>
313

gcc/config/arm/arm.c

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3939,14 +3939,52 @@ arm_warn_func_return (tree decl)
39393939
ldr pc, [pc]
39403940
.word static chain value
39413941
.word function's address
3942-
XXX FIXME: When the trampoline returns, r8 will be clobbered. */
3942+
XXX FIXME: When the trampoline returns, r8 will be clobbered.
3943+
3944+
In FDPIC mode, the trampoline looks like:
3945+
.word trampoline address
3946+
.word trampoline GOT address
3947+
ldr r12, [pc, #8] ; #4 for Arm mode
3948+
ldr r9, [pc, #8] ; #4 for Arm mode
3949+
ldr pc, [pc, #8] ; #4 for Arm mode
3950+
.word static chain value
3951+
.word GOT address
3952+
.word function's address
3953+
*/
39433954

39443955
static void
39453956
arm_asm_trampoline_template (FILE *f)
39463957
{
39473958
fprintf (f, "\t.syntax unified\n");
39483959

3949-
if (TARGET_ARM)
3960+
if (TARGET_FDPIC)
3961+
{
3962+
/* The first two words are a function descriptor pointing to the
3963+
trampoline code just below. */
3964+
if (TARGET_ARM)
3965+
fprintf (f, "\t.arm\n");
3966+
else if (TARGET_THUMB2)
3967+
fprintf (f, "\t.thumb\n");
3968+
else
3969+
/* Only ARM and Thumb-2 are supported. */
3970+
gcc_unreachable ();
3971+
3972+
assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
3973+
assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
3974+
/* Trampoline code which sets the static chain register but also
3975+
PIC register before jumping into real code. */
3976+
asm_fprintf (f, "\tldr\t%r, [%r, #%d]\n",
3977+
STATIC_CHAIN_REGNUM, PC_REGNUM,
3978+
TARGET_THUMB2 ? 8 : 4);
3979+
asm_fprintf (f, "\tldr\t%r, [%r, #%d]\n",
3980+
PIC_OFFSET_TABLE_REGNUM, PC_REGNUM,
3981+
TARGET_THUMB2 ? 8 : 4);
3982+
asm_fprintf (f, "\tldr\t%r, [%r, #%d]\n",
3983+
PC_REGNUM, PC_REGNUM,
3984+
TARGET_THUMB2 ? 8 : 4);
3985+
assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
3986+
}
3987+
else if (TARGET_ARM)
39503988
{
39513989
fprintf (f, "\t.arm\n");
39523990
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)
39874025
emit_block_move (m_tramp, assemble_trampoline_template (),
39884026
GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
39894027

3990-
mem = adjust_address (m_tramp, SImode, TARGET_32BIT ? 8 : 12);
3991-
emit_move_insn (mem, chain_value);
4028+
if (TARGET_FDPIC)
4029+
{
4030+
rtx funcdesc = XEXP (DECL_RTL (fndecl), 0);
4031+
rtx fnaddr = gen_rtx_MEM (Pmode, funcdesc);
4032+
rtx gotaddr = gen_rtx_MEM (Pmode, plus_constant (Pmode, funcdesc, 4));
4033+
/* The function start address is at offset 8, but in Thumb mode
4034+
we want bit 0 set to 1 to indicate Thumb-ness, hence 9
4035+
below. */
4036+
rtx trampoline_code_start
4037+
= plus_constant (Pmode, XEXP (m_tramp, 0), TARGET_THUMB2 ? 9 : 8);
4038+
4039+
/* Write initial funcdesc which points to the trampoline. */
4040+
mem = adjust_address (m_tramp, SImode, 0);
4041+
emit_move_insn (mem, trampoline_code_start);
4042+
mem = adjust_address (m_tramp, SImode, 4);
4043+
emit_move_insn (mem, gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM));
4044+
/* Setup static chain. */
4045+
mem = adjust_address (m_tramp, SImode, 20);
4046+
emit_move_insn (mem, chain_value);
4047+
/* GOT + real function entry point. */
4048+
mem = adjust_address (m_tramp, SImode, 24);
4049+
emit_move_insn (mem, gotaddr);
4050+
mem = adjust_address (m_tramp, SImode, 28);
4051+
emit_move_insn (mem, fnaddr);
4052+
}
4053+
else
4054+
{
4055+
mem = adjust_address (m_tramp, SImode, TARGET_32BIT ? 8 : 12);
4056+
emit_move_insn (mem, chain_value);
39924057

3993-
mem = adjust_address (m_tramp, SImode, TARGET_32BIT ? 12 : 16);
3994-
fnaddr = XEXP (DECL_RTL (fndecl), 0);
3995-
emit_move_insn (mem, fnaddr);
4058+
mem = adjust_address (m_tramp, SImode, TARGET_32BIT ? 12 : 16);
4059+
fnaddr = XEXP (DECL_RTL (fndecl), 0);
4060+
emit_move_insn (mem, fnaddr);
4061+
}
39964062

39974063
a_tramp = XEXP (m_tramp, 0);
39984064
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)
40064072
static rtx
40074073
arm_trampoline_adjust_address (rtx addr)
40084074
{
4009-
if (TARGET_THUMB)
4075+
/* For FDPIC don't fix trampoline address since it's a function
4076+
descriptor and not a function address. */
4077+
if (TARGET_THUMB && !TARGET_FDPIC)
40104078
addr = expand_simple_binop (Pmode, IOR, addr, const1_rtx,
40114079
NULL, 0, OPTAB_LIB_WIDEN);
40124080
return addr;

gcc/config/arm/arm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1595,7 +1595,7 @@ typedef struct
15951595
#define INIT_EXPANDERS arm_init_expanders ()
15961596

15971597
/* Length in units of the trampoline for entering a nested function. */
1598-
#define TRAMPOLINE_SIZE (TARGET_32BIT ? 16 : 20)
1598+
#define TRAMPOLINE_SIZE (TARGET_FDPIC ? 32 : (TARGET_32BIT ? 16 : 20))
15991599

16001600
/* Alignment required for a trampoline in bits. */
16011601
#define TRAMPOLINE_ALIGNMENT 32

0 commit comments

Comments
 (0)