From: Richard Henderson Date: Mon, 29 Nov 2004 18:42:26 +0000 (-0800) Subject: re PR target/17224 (relocation truncated to fit: GPREL22) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b0c2dee9fbfb3ca4b768c17f14afcb89086c0eae;p=gcc.git re PR target/17224 (relocation truncated to fit: GPREL22) PR target/17224 * config/ia64/predicates.md (sdata_symbolic_operand): Deny offsets outside the referenced object. From-SVN: r91478 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c5801c2da63..ed8056abb4d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2004-11-29 Richard Henderson + + PR target/17224 + * config/ia64/predicates.md (sdata_symbolic_operand): Deny offsets + outside the referenced object. + 2004-11-29 Kazu Hirata * tree-if-conv.c (replace_phi_with_cond_modify_expr): Use diff --git a/gcc/config/ia64/predicates.md b/gcc/config/ia64/predicates.md index b66df845baa..6166612ecad 100644 --- a/gcc/config/ia64/predicates.md +++ b/gcc/config/ia64/predicates.md @@ -74,21 +74,55 @@ (define_predicate "sdata_symbolic_operand" (match_code "symbol_ref,const") { + HOST_WIDE_INT offset = 0, size = 0; + switch (GET_CODE (op)) { case CONST: op = XEXP (op, 0); if (GET_CODE (op) != PLUS - || GET_CODE (XEXP (op, 0)) != SYMBOL_REF) + || GET_CODE (XEXP (op, 0)) != SYMBOL_REF + || GET_CODE (XEXP (op, 1)) != CONST_INT) return false; + offset = INTVAL (XEXP (op, 1)); op = XEXP (op, 0); /* FALLTHRU */ case SYMBOL_REF: if (CONSTANT_POOL_ADDRESS_P (op)) - return GET_MODE_SIZE (get_pool_mode (op)) <= ia64_section_threshold; + { + size = GET_MODE_SIZE (get_pool_mode (op)); + if (size > ia64_section_threshold) + return false; + } else - return SYMBOL_REF_LOCAL_P (op) && SYMBOL_REF_SMALL_P (op); + { + tree t; + + if (!SYMBOL_REF_LOCAL_P (op) || !SYMBOL_REF_SMALL_P (op)) + return false; + + /* Note that in addition to DECLs, we can get various forms + of constants here. */ + t = SYMBOL_REF_DECL (op); + if (DECL_P (t)) + t = DECL_SIZE_UNIT (t); + else + t = TYPE_SIZE_UNIT (TREE_TYPE (t)); + if (t && host_integerp (t, 0)) + { + size = tree_low_cst (t, 0); + if (size < 0) + size = 0; + } + } + + /* Deny the stupid user trick of addressing outside the object. Such + things quickly result in GPREL22 relocation overflows. Of course, + they're also highly undefined. From a pure pedant's point of view + they deserve a slap on the wrist (such as provided by a relocation + overflow), but that just leads to bugzilla noise. */ + return (offset >= 0 && offset <= size); default: abort ();