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