Message ID | 20180525080354.13295-10-christophe.lyon@st.com |
---|---|
State | New |
Headers | show |
Series | FDPIC ARM for ARM | expand |
Hi Chrishophe, Could you please provide a description of what this patch does and how it achieves that? On 25/05/18 09:03, Christophe Lyon wrote: > 2018-XX-XX 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_init): Likewise. > * config/arm/arm.h (TRAMPOLINE_SIZE): Likewise. > > Change-Id: I4b5127261a9aefa0f0318f110574ec07a856aeb1 > > diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c > index 025485d..2434602 100644 > --- a/gcc/config/arm/arm.c > +++ b/gcc/config/arm/arm.c > @@ -3967,7 +3967,27 @@ 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 to jump into > + the trampoline code just below. */ > + if (TARGET_ARM) fprintf (f, "\t.arm\n"); > + else if (TARGET_THUMB2) fprintf (f, "\t.thumb\n"); > + else fprintf (f, "\t.code\t16\n"); > + Please format this in GNU style. > + 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); Likewise. Also, this will use offset 4 for TARGET_THUMB1. Given that you handle TARGET_THUMB1 in the if statement above you expect this code can be entered for TARGET_THUMB1? Thanks, Kyrill > + 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); > @@ -4008,12 +4028,37 @@ 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)); > + rtx trampolineCodeStart > + = plus_constant (Pmode, XEXP (m_tramp, 0), TARGET_THUMB2 ? 9 : 8); > + > + /* Write initial funcdesc which will jump into trampoline. */ > + mem = adjust_address (m_tramp, SImode, 0); > + emit_move_insn (mem, trampolineCodeStart); > + 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); > + 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"), > @@ -4027,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; > diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h > index e8ef439..db17ef2 100644 > --- a/gcc/config/arm/arm.h > +++ b/gcc/config/arm/arm.h > @@ -1578,7 +1578,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 > -- > 2.6.3 >
On 8 June 2018 at 12:33, Kyrill Tkachov <kyrylo.tkachov@foss.arm.com> wrote: > Hi Chrishophe, > > Could you please provide a description of what this patch does and how it > achieves that? > OK, I'l try to do some archaeology and formulate a description. > > On 25/05/18 09:03, Christophe Lyon wrote: >> >> 2018-XX-XX 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_init): Likewise. >> * config/arm/arm.h (TRAMPOLINE_SIZE): Likewise. >> >> Change-Id: I4b5127261a9aefa0f0318f110574ec07a856aeb1 >> >> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c >> index 025485d..2434602 100644 >> --- a/gcc/config/arm/arm.c >> +++ b/gcc/config/arm/arm.c >> @@ -3967,7 +3967,27 @@ 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 to jump into >> + the trampoline code just below. */ >> + if (TARGET_ARM) fprintf (f, "\t.arm\n"); >> + else if (TARGET_THUMB2) fprintf (f, "\t.thumb\n"); >> + else fprintf (f, "\t.code\t16\n"); >> + > > > Please format this in GNU style. Sorry for missing that. I did visually inspect all the patches and ran check_GNU_style (both .sh and .py, none complained). > >> + 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); > > > Likewise. > Also, this will use offset 4 for TARGET_THUMB1. Given that you handle > TARGET_THUMB1 > in the if statement above you expect this code can be entered for > TARGET_THUMB1? > I'll check that, Thanks > Thanks, > Kyrill > > >> + 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); >> @@ -4008,12 +4028,37 @@ 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)); >> + rtx trampolineCodeStart >> + = plus_constant (Pmode, XEXP (m_tramp, 0), TARGET_THUMB2 ? 9 : 8); >> + >> + /* Write initial funcdesc which will jump into trampoline. */ >> + mem = adjust_address (m_tramp, SImode, 0); >> + emit_move_insn (mem, trampolineCodeStart); >> + 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); >> + 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"), >> @@ -4027,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; >> diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h >> index e8ef439..db17ef2 100644 >> --- a/gcc/config/arm/arm.h >> +++ b/gcc/config/arm/arm.h >> @@ -1578,7 +1578,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 >> -- >> 2.6.3 >> >
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 025485d..2434602 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -3967,7 +3967,27 @@ 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 to jump into + the trampoline code just below. */ + if (TARGET_ARM) fprintf (f, "\t.arm\n"); + else if (TARGET_THUMB2) fprintf (f, "\t.thumb\n"); + else fprintf (f, "\t.code\t16\n"); + + 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); @@ -4008,12 +4028,37 @@ 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)); + rtx trampolineCodeStart + = plus_constant (Pmode, XEXP (m_tramp, 0), TARGET_THUMB2 ? 9 : 8); + + /* Write initial funcdesc which will jump into trampoline. */ + mem = adjust_address (m_tramp, SImode, 0); + emit_move_insn (mem, trampolineCodeStart); + 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); + 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"), @@ -4027,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; diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index e8ef439..db17ef2 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1578,7 +1578,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