[ARM/FDPIC v6 08/24] [ARM] FDPIC: Enforce local/global binding for function descriptors

Use local binding rules to decide whether we can use GOTOFFFUNCDESC to
compute the function address.

2019-09-10  Christophe Lyon  <christophe.lyon@st.com>
	Mickaël Guêné <mickael.guene@st.com>

	gcc/
	* config/arm/arm.c (arm_fdpic_local_funcdesc_p): New function.
	(legitimize_pic_address): Enforce binding rules on function
	pointers in FDPIC mode.
	(arm_assemble_integer): Likewise.


Co-Authored-By: Mickaël Guêné <mickael.guene@st.com>

From-SVN: r275570
This commit is contained in:
Christophe Lyon 2019-09-10 09:50:43 +02:00 committed by Christophe Lyon
parent 4997c9aed4
commit 96ef8d00f7
2 changed files with 50 additions and 2 deletions

View file

@ -1,3 +1,11 @@
2019-09-10 Christophe Lyon <christophe.lyon@st.com>
Mickaël Guêné <mickael.guene@st.com>
* config/arm/arm.c (arm_fdpic_local_funcdesc_p): New function.
(legitimize_pic_address): Enforce binding rules on function
pointers in FDPIC mode.
(arm_assemble_integer): Likewise.
2019-09-10 Christophe Lyon <christophe.lyon@st.com>
Mickaël Guêné <mickael.guene@st.com>

View file

@ -3754,6 +3754,42 @@ arm_options_perform_arch_sanity_checks (void)
}
}
/* Test whether a local function descriptor is canonical, i.e.,
whether we can use GOTOFFFUNCDESC to compute the address of the
function. */
static bool
arm_fdpic_local_funcdesc_p (rtx fnx)
{
tree fn;
enum symbol_visibility vis;
bool ret;
if (!TARGET_FDPIC)
return true;
if (! SYMBOL_REF_LOCAL_P (fnx))
return false;
fn = SYMBOL_REF_DECL (fnx);
if (! fn)
return false;
vis = DECL_VISIBILITY (fn);
if (vis == VISIBILITY_PROTECTED)
/* Private function descriptors for protected functions are not
canonical. Temporarily change the visibility to global so that
we can ensure uniqueness of funcdesc pointers. */
DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
ret = default_binds_local_p_1 (fn, flag_pic);
DECL_VISIBILITY (fn) = vis;
return ret;
}
static void
arm_add_gc_roots (void)
{
@ -7534,7 +7570,9 @@ legitimize_pic_address (rtx orig, machine_mode mode, rtx reg, rtx pic_reg,
|| (GET_CODE (orig) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (orig)
&& (SYMBOL_REF_DECL (orig)
? !DECL_WEAK (SYMBOL_REF_DECL (orig)) : 1)))
? !DECL_WEAK (SYMBOL_REF_DECL (orig)) : 1)
&& (!SYMBOL_REF_FUNCTION_P (orig)
|| arm_fdpic_local_funcdesc_p (orig))))
&& NEED_GOT_RELOC
&& arm_pic_data_is_text_relative)
insn = arm_pic_static_addr (orig, reg);
@ -23160,7 +23198,9 @@ arm_assemble_integer (rtx x, unsigned int size, int aligned_p)
|| (GET_CODE (x) == SYMBOL_REF
&& (!SYMBOL_REF_LOCAL_P (x)
|| (SYMBOL_REF_DECL (x)
? DECL_WEAK (SYMBOL_REF_DECL (x)) : 0))))
? DECL_WEAK (SYMBOL_REF_DECL (x)) : 0)
|| (SYMBOL_REF_FUNCTION_P (x)
&& !arm_fdpic_local_funcdesc_p (x)))))
{
if (TARGET_FDPIC && SYMBOL_REF_FUNCTION_P (x))
fputs ("(GOTFUNCDESC)", asm_out_file);