public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug target/98618] New: aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21
@ 2021-01-11 10:37 nsz at gcc dot gnu.org
  2021-01-11 10:51 ` [Bug target/98618] " fw at gcc dot gnu.org
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: nsz at gcc dot gnu.org @ 2021-01-11 10:37 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98618

            Bug ID: 98618
           Summary: aarch64: oob adrp offset causes relocation truncated
                    to fit: R_AARCH64_ADR_PREL_PG_HI21
           Product: gcc
           Version: 8.4.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: nsz at gcc dot gnu.org
  Target Milestone: ---

gcc-8 and earlier can generate adrp with out of bounds offset
for hidden and local symbols.

i haven't yet found the change that fixed this in gcc-9.

this affects glibc since
https://sourceware.org/git/?p=glibc.git;a=commit;h=2f056e8a5dd4dc0f075413f931e82cede37d1057

$ cat bug.c
long n;
struct s { long a[100]; };
extern struct s obj __attribute__((visibility("hidden")));
void foo()
{
  long *a = obj.a;
  a[n - 0x70000000 + 35] = n;
  a[0x6ffffdff - n + 35 + 6 + 16 + 3] = n;
}

$ gcc -fPIC -O2 -c bug.c
$ objdump -rd bug.o

bug.o:     file format elf64-littleaarch64


Disassembly of section .text:

0000000000000000 <foo>:
   0:   90000000        adrp    x0, 8 <foo+0x8>
                        0: R_AARCH64_ADR_GOT_PAGE       n
   4:   90000002        adrp    x2, 0 <obj>
                        4: R_AARCH64_ADR_PREL_PG_HI21   obj-0x37ffffee8
   8:   91000042        add     x2, x2, #0x0
                        8: R_AARCH64_ADD_ABS_LO12_NC    obj-0x37ffffee8
   c:   90000001        adrp    x1, 0 <obj>
                        c: R_AARCH64_ADR_PREL_PG_HI21   obj+0x37ffff1d8
  10:   f9400000        ldr     x0, [x0]
                        10: R_AARCH64_LD64_GOT_LO12_NC  n
  14:   91000021        add     x1, x1, #0x0
                        14: R_AARCH64_ADD_ABS_LO12_NC   obj+0x37ffff1d8
  18:   f9400000        ldr     x0, [x0]
  1c:   cb000fe3        neg     x3, x0, lsl #3
  20:   f8207840        str     x0, [x2, x0, lsl #3]
  24:   f8216860        str     x0, [x3, x1]
  28:   d65f03c0        ret
$ gcc -shared bug.o obj.o
bug.o: In function `foo':
bug.c:(.text+0x4): relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21
against symbol `obj' defined in .data section in obj.o
bug.c:(.text+0xc): relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21
against symbol `obj' defined in .data section in obj.o
collect2: error: ld returned 1 exit status

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug target/98618] aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21
  2021-01-11 10:37 [Bug target/98618] New: aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 nsz at gcc dot gnu.org
@ 2021-01-11 10:51 ` fw at gcc dot gnu.org
  2021-01-11 10:59 ` nsz at gcc dot gnu.org
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: fw at gcc dot gnu.org @ 2021-01-11 10:51 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98618

--- Comment #1 from Florian Weimer <fw at gcc dot gnu.org> ---
Is the test case really valid? It involves an out-of-bounds array access, after
all.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug target/98618] aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21
  2021-01-11 10:37 [Bug target/98618] New: aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 nsz at gcc dot gnu.org
  2021-01-11 10:51 ` [Bug target/98618] " fw at gcc dot gnu.org
@ 2021-01-11 10:59 ` nsz at gcc dot gnu.org
  2021-01-11 11:48 ` wilco at gcc dot gnu.org
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: nsz at gcc dot gnu.org @ 2021-01-11 10:59 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98618

--- Comment #2 from nsz at gcc dot gnu.org ---
(In reply to Florian Weimer from comment #1)
> Is the test case really valid? It involves an out-of-bounds array access,
> after all.

no it doesn't, n is signed long and its value can be such that the access is in
bounds (and that's what the compiler must assume, so adrp must be anchored
accordingly).

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug target/98618] aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21
  2021-01-11 10:37 [Bug target/98618] New: aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 nsz at gcc dot gnu.org
  2021-01-11 10:51 ` [Bug target/98618] " fw at gcc dot gnu.org
  2021-01-11 10:59 ` nsz at gcc dot gnu.org
@ 2021-01-11 11:48 ` wilco at gcc dot gnu.org
  2021-01-11 12:15 ` nsz at gcc dot gnu.org
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: wilco at gcc dot gnu.org @ 2021-01-11 11:48 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98618

Wilco <wilco at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
                 CC|                            |wilco at gcc dot gnu.org
   Last reconfirmed|                            |2021-01-11
             Status|UNCONFIRMED                 |NEW

--- Comment #3 from Wilco <wilco at gcc dot gnu.org> ---
I fixed this in GCC10:
https://gcc.gnu.org/git/?p=gcc.git&a=commit;h=7d3b27ff12610fde9d6c4b56abc70c6ee9b6b3db

So this just needs to be backported.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug target/98618] aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21
  2021-01-11 10:37 [Bug target/98618] New: aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 nsz at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2021-01-11 11:48 ` wilco at gcc dot gnu.org
@ 2021-01-11 12:15 ` nsz at gcc dot gnu.org
  2021-01-11 12:19 ` nsz at gcc dot gnu.org
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: nsz at gcc dot gnu.org @ 2021-01-11 12:15 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98618

--- Comment #4 from nsz at gcc dot gnu.org ---
(In reply to Florian Weimer from comment #1)
> Is the test case really valid? It involves an out-of-bounds array access,
> after all.

sorry you are right the indexes are too far, a better test is

long n;
struct s { long a[100]; };
extern struct s obj __attribute__((visibility("hidden")));
void foo()
{
  long *a = obj.a;
  a[n - 0x70000000] = n;
  a[0x70000000 - n + 99] = n;
}

(i wanted to have an example with both + and - offset)
it compiles to

foo:
        adrp    x0, :got:n
        adrp    x2, obj-15032385536
        add     x2, x2, :lo12:obj-15032385536
        adrp    x1, obj+15032386328
        ldr     x0, [x0, #:got_lo12:n]
        add     x1, x1, :lo12:obj+15032386328
        ldr     x0, [x0]
        neg     x3, x0, lsl 3
        str     x0, [x2, x0, lsl 3]
        str     x0, [x3, x1]
        ret

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug target/98618] aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21
  2021-01-11 10:37 [Bug target/98618] New: aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 nsz at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2021-01-11 12:15 ` nsz at gcc dot gnu.org
@ 2021-01-11 12:19 ` nsz at gcc dot gnu.org
  2021-01-21 12:51 ` cvs-commit at gcc dot gnu.org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: nsz at gcc dot gnu.org @ 2021-01-11 12:19 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98618

--- Comment #5 from nsz at gcc dot gnu.org ---
(In reply to Wilco from comment #3)
> I fixed this in GCC10:
> https://gcc.gnu.org/git/?p=gcc.git&a=commit;
> h=7d3b27ff12610fde9d6c4b56abc70c6ee9b6b3db
> 
> So this just needs to be backported.

thanks, i'll try that, i'm still looking for
a simple workaround in glibc, this affects
this code in elf_get_dynamic_info:

...
  63       else if ((d_tag_utype) DT_VERSIONTAGIDX (dyn->d_tag) <
DT_VERSIONTAGNUM)
  64         info[VERSYMIDX (dyn->d_tag)] = dyn;
  65       else if ((d_tag_utype) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM)
  66         info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
  67              + DT_VERSIONTAGNUM] = dyn;
  68       else if ((d_tag_utype) DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM)
  69         info[DT_VALTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
  70              + DT_VERSIONTAGNUM + DT_EXTRANUM] = dyn;
  71       else if ((d_tag_utype) DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM)
  72         info[DT_ADDRTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
  73              + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn;
...

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug target/98618] aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21
  2021-01-11 10:37 [Bug target/98618] New: aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 nsz at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2021-01-11 12:19 ` nsz at gcc dot gnu.org
@ 2021-01-21 12:51 ` cvs-commit at gcc dot gnu.org
  2021-01-21 17:55 ` cvs-commit at gcc dot gnu.org
  2021-01-21 17:58 ` wilco at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2021-01-21 12:51 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98618

--- Comment #6 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-9 branch has been updated by Wilco Dijkstra
<wilco@gcc.gnu.org>:

https://gcc.gnu.org/g:1e18f4bbd8318db1e606f7092a224e4bb21a8a26

commit r9-9193-g1e18f4bbd8318db1e606f7092a224e4bb21a8a26
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)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug target/98618] aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21
  2021-01-11 10:37 [Bug target/98618] New: aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 nsz at gcc dot gnu.org
                   ` (5 preceding siblings ...)
  2021-01-21 12:51 ` cvs-commit at gcc dot gnu.org
@ 2021-01-21 17:55 ` cvs-commit at gcc dot gnu.org
  2021-01-21 17:58 ` wilco at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2021-01-21 17:55 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98618

--- Comment #7 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-8 branch has been updated by Wilco Dijkstra
<wilco@gcc.gnu.org>:

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)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug target/98618] aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21
  2021-01-11 10:37 [Bug target/98618] New: aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 nsz at gcc dot gnu.org
                   ` (6 preceding siblings ...)
  2021-01-21 17:55 ` cvs-commit at gcc dot gnu.org
@ 2021-01-21 17:58 ` wilco at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: wilco at gcc dot gnu.org @ 2021-01-21 17:58 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98618

Wilco <wilco at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED
   Target Milestone|---                         |8.5

--- Comment #8 from Wilco <wilco at gcc dot gnu.org> ---
Backported to GCC8 and GCC9, so fixed on all active branches.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-01-21 17:58 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-11 10:37 [Bug target/98618] New: aarch64: oob adrp offset causes relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 nsz at gcc dot gnu.org
2021-01-11 10:51 ` [Bug target/98618] " fw at gcc dot gnu.org
2021-01-11 10:59 ` nsz at gcc dot gnu.org
2021-01-11 11:48 ` wilco at gcc dot gnu.org
2021-01-11 12:15 ` nsz at gcc dot gnu.org
2021-01-11 12:19 ` nsz at gcc dot gnu.org
2021-01-21 12:51 ` cvs-commit at gcc dot gnu.org
2021-01-21 17:55 ` cvs-commit at gcc dot gnu.org
2021-01-21 17:58 ` wilco at gcc dot gnu.org

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).