public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r8-10736] [AArch64] Fix symbol offset limit (PR 98618)
@ 2021-01-21 17:55 Wilco Dijkstra
  0 siblings, 0 replies; only message in thread
From: Wilco Dijkstra @ 2021-01-21 17:55 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:c9569046bd8ba2671833d600b3bdbdb7de593873

commit r8-10736-gc9569046bd8ba2671833d600b3bdbdb7de593873
Author: Wilco Dijkstra <wdijkstr@arm.com>
Date:   Wed Oct 16 14:24:41 2019 +0000

    [AArch64] Fix symbol offset limit (PR 98618)
    
    In aarch64_classify_symbol symbols are allowed large offsets on relocations.
    This means the offset can use all of the +/-4GB offset, leaving no offset
    available for the symbol itself.  This results in relocation overflow and
    link-time errors for simple expressions like &global_array + 0xffffff00.
    
    To avoid this, unless the offset_within_block_p is true, limit the offset
    to +/-1MB so that the symbol needs to be within a 3.9GB offset from its
    references.  For the tiny code model use a 64KB offset, allowing most of
    the 1MB range for code/data between the symbol and its references.
    
            gcc/
            PR target/98618
            * config/aarch64/aarch64.c (aarch64_classify_symbol):
            Apply reasonable limit to symbol offsets.
    
            gcc/testsuite/
            PR target/98618
            * gcc.target/aarch64/symbol-range.c: Improve testcase.
            * gcc.target/aarch64/symbol-range-tiny.c: Likewise.
    
    (cherry picked from commit 7d3b27ff12610fde9d6c4b56abc70c6ee9b6b3db)

Diff:
---
 gcc/config/aarch64/aarch64.c                       | 33 +++++++++++++---------
 .../gcc.target/aarch64/symbol-range-tiny.c         |  8 +++---
 gcc/testsuite/gcc.target/aarch64/symbol-range.c    |  8 +++---
 3 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index e8e73b8ea92..7c4cf75b5a5 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -12011,26 +12011,31 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset)
 	     the offset does not cause overflow of the final address.  But
 	     we have no way of knowing the address of symbol at compile time
 	     so we can't accurately say if the distance between the PC and
-	     symbol + offset is outside the addressible range of +/-1M in the
-	     TINY code model.  So we rely on images not being greater than
-	     1M and cap the offset at 1M and anything beyond 1M will have to
-	     be loaded using an alternative mechanism.  Furthermore if the
-	     symbol is a weak reference to something that isn't known to
-	     resolve to a symbol in this module, then force to memory.  */
-	  if ((SYMBOL_REF_WEAK (x)
-	       && !aarch64_symbol_binds_local_p (x))
-	      || !IN_RANGE (offset, -1048575, 1048575))
+	     symbol + offset is outside the addressible range of +/-1MB in the
+	     TINY code model.  So we limit the maximum offset to +/-64KB and
+	     assume the offset to the symbol is not larger than +/-(1MB - 64KB).
+	     If offset_within_block_p is true we allow larger offsets.
+	     Furthermore force to memory if the symbol is a weak reference to
+	     something that doesn't resolve to a symbol in this module.  */
+
+	  if (SYMBOL_REF_WEAK (x) && !aarch64_symbol_binds_local_p (x))
 	    return SYMBOL_FORCE_TO_MEM;
+	  if (!(IN_RANGE (offset, -0x10000, 0x10000)
+		|| offset_within_block_p (x, offset)))
+	    return SYMBOL_FORCE_TO_MEM;
+
 	  return SYMBOL_TINY_ABSOLUTE;
 
 	case AARCH64_CMODEL_SMALL:
 	  /* Same reasoning as the tiny code model, but the offset cap here is
-	     4G.  */
-	  if ((SYMBOL_REF_WEAK (x)
-	       && !aarch64_symbol_binds_local_p (x))
-	      || !IN_RANGE (offset, HOST_WIDE_INT_C (-4294967263),
-			    HOST_WIDE_INT_C (4294967264)))
+	     1MB, allowing +/-3.9GB for the offset to the symbol.  */
+
+	  if (SYMBOL_REF_WEAK (x) && !aarch64_symbol_binds_local_p (x))
 	    return SYMBOL_FORCE_TO_MEM;
+	  if (!(IN_RANGE (offset, -0x100000, 0x100000)
+		|| offset_within_block_p (x, offset)))
+	    return SYMBOL_FORCE_TO_MEM;
+
 	  return SYMBOL_SMALL_ABSOLUTE;
 
 	case AARCH64_CMODEL_TINY_PIC:
diff --git a/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c b/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c
index d7e46b059e4..fc6a4f3ec78 100644
--- a/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c
+++ b/gcc/testsuite/gcc.target/aarch64/symbol-range-tiny.c
@@ -1,12 +1,12 @@
-/* { dg-do compile } */
+/* { dg-do link } */
 /* { dg-options "-O3 -save-temps -mcmodel=tiny" } */
 
-int fixed_regs[0x00200000];
+char fixed_regs[0x00080000];
 
 int
-foo()
+main ()
 {
-  return fixed_regs[0x00080000];
+  return fixed_regs[0x000ff000];
 }
 
 /* { dg-final { scan-assembler-not "adr\tx\[0-9\]+, fixed_regs\\\+" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/symbol-range.c b/gcc/testsuite/gcc.target/aarch64/symbol-range.c
index 6574cf43104..d8e82fa1b28 100644
--- a/gcc/testsuite/gcc.target/aarch64/symbol-range.c
+++ b/gcc/testsuite/gcc.target/aarch64/symbol-range.c
@@ -1,12 +1,12 @@
-/* { dg-do compile } */
+/* { dg-do link } */
 /* { dg-options "-O3 -save-temps -mcmodel=small" } */
 
-int fixed_regs[0x200000000ULL];
+char fixed_regs[0x80000000];
 
 int
-foo()
+main ()
 {
-  return fixed_regs[0x100000000ULL];
+  return fixed_regs[0xfffff000];
 }
 
 /* { dg-final { scan-assembler-not "adrp\tx\[0-9\]+, fixed_regs\\\+" } } */


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-01-21 17:55 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-21 17:55 [gcc r8-10736] [AArch64] Fix symbol offset limit (PR 98618) Wilco Dijkstra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).