summaryrefslogtreecommitdiff
path: root/gcc/config/arm/arm.c
diff options
context:
space:
mode:
authorChristophe Lyon <christophe.lyon@st.com>2019-09-10 09:50:43 +0200
committerChristophe Lyon <clyon@gcc.gnu.org>2019-09-10 09:50:43 +0200
commit96ef8d00f70f076933eea68124043e9ba675412d (patch)
tree356ea63ade0ad52bc4c1e95a658f580c818c706e /gcc/config/arm/arm.c
parent4997c9aed45b4439474005c4c71fac65151d1719 (diff)
downloadgcc-96ef8d00f70f076933eea68124043e9ba675412d.tar.gz
[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
Diffstat (limited to 'gcc/config/arm/arm.c')
-rw-r--r--gcc/config/arm/arm.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 6ff3001fd02..6b0c95f5752 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -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);