Created attachment 32309 [details] backtrace (glibc-2.18,binutils-2.24,gcc-4.8.2) I tried to build glibc-2.17 and 2.18 with binutils-2.23.2 or 2.24 and gcc-4.8.2, but always run into the same segfault when loading programs with the new runtime linker. Please find a backtrace for the glibc-2.18, binutils-2.24, gcc-4.8.2 combination attached. It crashes in exactly the same way when running without --library-path and when running with ../usr/bin/locale (from glibc-2.18) or /bin/date as argument. Since glibc-2.17 compiled fine with gcc-4.7.3, I assume that gcc-4.8.2 is to blame. The context of the crash is (according to glibc-2.18/elf/get-dynamic-info.h): elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp) { ElfW(Dyn) **info; info = l->l_info; info[DT_ADDRTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn; } GDB reports this function being called as: elf_get_dynamic_info (temp=0x0, l=0x2000000800051458 <_rtld_local+2456>) What I find to be suspicious is the changed order of parameters. I would like to check this with valgrind, too, but it is not available on ia64 (i.e. anything but x86, ppc and arm). See-Also: https://bugs.gentoo.org/show_bug.cgi?id=503838
Created attachment 32310 [details] emerge --info
*** Bug 60558 has been marked as a duplicate of this bug. ***
Mike Frysinger 2014-03-18 07:17:05 UTC if you build current master glibc w/gcc-4.8.2 & binutils-2.23.2 like so: ../configure --prefix=/usr libc_cv_ehdr_start=no make -j4 then try to run a simple app like so: echo 'main(){puts("HI");}' | gcc -x c - -o a.out ./elf/ld.so --library-path $PWD ./a.out it crashes like so: Segmentation fault (core dumped) i suspect bad code generation because: - recompiling only elf/rtld.c w/gcc-4.7.3 produces a working build - the C code looks correct (via poking; see below) - tweaking the code slightly produces a working build w/4.8: - else if ((d_tag_utype) DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM) - info[DT_ADDRTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM - + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn; + { + size_t i = DT_ADDRTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM + + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM; + info[i] = dyn; + } throwing it into a debugger shows: $ gdb --args ./elf/ld.so --library-path $PWD ./a.out Reading symbols from /home/vapier/glibc/build/elf/ld.so...done. (gdb) run Starting program: /home/vapier/glibc/build/./elf/ld.so --library-path /home/vapier/glibc/build ./a.out Program received signal SIGSEGV, Segmentation fault. 0x200000080000b010 in elf_get_dynamic_info (temp=0x0, l=0x2000000800051b08 <_rtld_local+2456>) at get-dynamic-info.h:61 61 + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn; (gdb) list 56 else if ((d_tag_utype) DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM) 57 info[DT_VALTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM 58 + DT_VERSIONTAGNUM + DT_EXTRANUM] = dyn; 59 else if ((d_tag_utype) DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM) 60 info[DT_ADDRTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM 61 + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn; 62 ++dyn; 63 } 64 65 #define DL_RO_DYN_TEMP_CNT 8 the info pointer is sane: (gdb) p &_rtld_global._dl_rtld_map.l_info $1 = (Elf64_Dyn *(*)[77]) 0x20000008000515d8 <_rtld_local+2520> (gdb) print info $2 = (Elf64_Dyn **) 0x20000008000515d8 <_rtld_local+2520> as is the dyn tag: (gdb) print dyn $3 = (Elf64_Dyn *) 0x200000080004c8d8 (gdb) print *dyn $4 = { d_tag = 0x6ffffef5, d_un = { d_val = 0x2d8, d_ptr = 0x2d8 } } that calculated offset is 0x4c and the link map is big enough to hold it: (gdb) print sizeof(_rtld_local._dl_rtld_map.l_info) / sizeof(_rtld_local._dl_rtld_map.l_info[0]) $5 = 0x4d but the assembly is clearly wrong: (gdb) display/i $pc 1: x/i $pc => 0x200000080000b271 <_dl_start+2737>: (p07) st8 [r14]=r15 (gdb) p $r15 $6 = 0x200000080004c8d8 (gdb) p $r14 $7 = 0x51838 $r15 is set to the right value (dyn), but r14 is now incomplete. stepping through the previous ~20 insns shows that the right value doesn't get near $r14 ... but my ia64 asm skills are not great, so i could be missing something.
How about showing the previous ~20 insns here.
Created attachment 32385 [details] gdb session here's the trace from the first insn where dyn is pointing to DT_GNU_HASH. at this point, it has processed DT_SONAME and DT_HASH. $ readelf -d build/elf/ld.so Dynamic section at offset 0x3c8b8 contains 20 entries: Tag Type Name/Value 0x000000000000000e (SONAME) Library soname: [ld-linux-ia64.so.2] 0x0000000000000004 (HASH) 0x190 0x000000006ffffef5 (GNU_HASH) 0x2d8 0x0000000000000005 (STRTAB) 0x998
Did anyone figure out what's going on? Did the gdb log bring new insights?
it's beyond my (ia64 beginners) experience to track this down further i can certainly make available ssh access to interested devs ... it's a fast system on a fast edu connection
(In reply to Mike Frysinger from comment #7) > it's beyond my (ia64 beginners) experience to track this down further > > i can certainly make available ssh access to interested devs ... it's a fast > system on a fast edu connection Similar situation and offer from me: Slow system on a fast connection available for the dev who wants to track this down, but lacks an own machine.
i've verified that 4.8.0 & 4.9.1 fail as well :/ binutils 2.24 doesn't help
i've bisected things back to r188118. before that commit, gcc compiles rtld.c fine and produces a working ldso. starting at that commit, we get segfaults.
This sounds like the same bug which I fixed with the set of patches at https://gcc.gnu.org/ml/gcc-patches/2014-08/msg00932.html .
> i've bisected things back to r188118. before that commit, gcc compiles > rtld.c fine and produces a working ldso. starting at that commit, we get > segfaults. But not on the 4.7 branch, right? In any case, we need preprocessed sources.
> i've bisected things back to r188118. before that commit, gcc compiles > rtld.c fine and produces a working ldso. starting at that commit, we get > segfaults. In fact r188118 undoes a pessimization introduced just before in r188009 so the bug was very likely preexisting on the mainline.
(In reply to Eric Botcazou from comment #12) > > i've bisected things back to r188118. before that commit, gcc compiles > > rtld.c fine and produces a working ldso. starting at that commit, we get > > segfaults. > > But not on the 4.7 branch, right? In any case, we need preprocessed sources. I bet the function f mentioned in the testcase from https://gcc.gnu.org/ml/gcc-patches/2014-08/msg00932.html is enough to reproduce the issue. DT_ADDRTAGIDX (dyn->d_tag) gets preprocessed as (0x6ffffeff - dyn->d_tag). DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM is the same as 34+0+16+3+12.
(In reply to Andrew Pinski from comment #11) i tried 4.8.3 w/those two patches applied but still see the crash :( (In reply to Eric Botcazou from comment #12) correct, gcc-4.6.4 & gcc-4.7.3 work fine
Created attachment 33321 [details] rtld.i preprocessed source the preprocessed output is the same between 4.7.4 & 4.8.3 (checked with `diff`) this was generated with: $ gcc rtld.c -E -dD -std=gnu99 -fgnu89-inline -O2 -Wall -Winline -Wundef -Wwrite-strings -fmerge-all-constants -frounding-math -g -Wstrict-prototypes -fPIC -D'SYSCONFDIR="/etc"' -U_FORTIFY_SOURCE -I../include -I/home/vapier/glibc/build/elf -I/home/vapier/glibc/build -I../sysdeps/unix/sysv/linux/ia64 -I../sysdeps/ia64/nptl -I../sysdeps/unix/sysv/linux/wordsize-64 -I../sysdeps/unix/sysv/linux -I../sysdeps/nptl -I../sysdeps/pthread -I../sysdeps/gnu -I../sysdeps/unix/inet -I../sysdeps/unix/sysv -I../sysdeps/unix -I../sysdeps/posix -I../sysdeps/ia64/fpu -I../sysdeps/ia64 -I../sysdeps/wordsize-64 -I../sysdeps/ieee754/ldbl-96 -I../sysdeps/ieee754/dbl-64 -I../sysdeps/ieee754/flt-32 -I../sysdeps/ieee754 -I../sysdeps/generic -I.. -I../libio -I. -D_LIBC_REENTRANT -include ../include/libc-symbols.h -DPIC -DSHARED -DNOT_IN_libc=1 -DIS_IN_rtld=1 -DIN_LIB=rtld -D_ASM_IA64_CURRENT_H -o /home/vapier/glibc/build/elf/rtld.i
(In reply to Eric Botcazou from comment #13) fwiw, i took latest 4.8 branch and reverted that change, and ldso works i'll test r188009 and related too though
thanks for your help Eric. new bisection shows r187042 as a possible culprit. feel free to de-cc yourself :). Richard: any thoughts here ? this change is a bit harder to test reverting in the latest 4.8 branch to see if it makes a difference.
Created attachment 33340 [details] rtld.s generated -- passing w/r187038
Created attachment 33341 [details] rtld.s generated -- failing w/r187042
> thanks for your help Eric. new bisection shows r187042 as a possible > culprit. feel free to de-cc yourself :). I'll keep investigating because this rings a bell, we had the same issue on SPARC 64-bit at some point and this might be a hole in the IA-64 back-end.
(In reply to Mike Frysinger from comment #18) > thanks for your help Eric. new bisection shows r187042 as a possible > culprit. feel free to de-cc yourself :). > > Richard: any thoughts here ? this change is a bit harder to test reverting > in the latest 4.8 branch to see if it makes a difference. Well, usual errors regarding to sizetype apply - you have to treat it as sign-extending if you promote it to larger types (but I doubt that happens or matters for ia64 as pointers should be DImode, right?). But you should be able to spot code-gen differences and see where they originate from (the revision wasn't supposed to change code-gen though zero differences wasn't really possible). I'll wait for Erics investigation. (ia64 is a dead architecture IMNSHO)
Created attachment 33349 [details] Reduced testcase To be compiled at -O1.
I might have a plausible scenario, but I'd need more info: 1. the options used to link the runtime linker 2. the value of registers r25 and r23 right after: 0x200000080000a8f0 <+304>: [MMI] ld8 r25=[r25] 0x200000080000a8f1 <+305>: ld8 r23=[r23] 0x200000080000a8f2 <+306>: nop.i 0x0;; for the invocation of _dl_start that leads to the segfault.
here's the series of link commands: gcc -nostdlib -nostartfiles -r -o elf/librtld.os \ '-Wl,-(' /home/vapier/glibc/build/elf/dl-allobjs.os elf/rtld-libc.a -lgcc \ '-Wl,-)' -Wl,-Map,elf/librtld.os.map gcc -nostdlib -nostartfiles -shared -o elf/ld.so \ -Wl,-z,combreloc -Wl,-z,relro -Wl,--hash-style=both -Wl,-z,defs \ elf/librtld.os -Wl,--version-script=./ld.map \ -Wl,-soname=ld-linux-ia64.so.2 \ -Wl,-defsym=_begin=0 in my disassembly it's using r24 & r22, but i'm guessing that doesn't matter terribly much: $ gdb --args ./elf/ld.so --library-path $PWD ./a.out Reading symbols from /home/vapier/glibc/build/elf/ld.so...done. (gdb) b *_dl_start+304 Breakpoint 1 at 0xabb0: file get-dynamic-info.h, line 61. (gdb) display /i $pc (gdb) display $r24 (gdb) display $r22 (gdb) r Starting program: /home/vapier/glibc/build/./elf/ld.so --library-path /home/vapier/glibc/build ./a.out Breakpoint 1, elf_get_dynamic_info (temp=0x0, l=0x20000008000510c8 <_rtld_local+2456>) at get-dynamic-info.h:61 61 + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn; 3: $r22 = 0x20000008000505d8 2: $r24 = 0x20000008000505d8 1: x/i $pc => 0x200000080000abb0 <_dl_start+304>: [MMI] ld8 r24=[r24] (gdb) stepi 58 + DT_VERSIONTAGNUM + DT_EXTRANUM] = dyn; 3: $r22 = 0x20000008000505d8 2: $r24 = 0x380050730 1: x/i $pc => 0x200000080000abb1 <_dl_start+305>: ld8 r22=[r22] (gdb) stepi 61 + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn; 3: $r22 = 0x380050730 2: $r24 = 0x380050730 1: x/i $pc => 0x200000080000abb2 <_dl_start+306>: nop.i 0x0;; (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x200000080000b5f1 in elf_get_dynamic_info (temp=0x0, l=0x20000008000510c8 <_rtld_local+2456>) at get-dynamic-info.h:61 61 + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn; 3: $r22 = 0x3800502b0 2: $r24 = 0x380050b10 1: x/i $pc => 0x200000080000b5f1 <_dl_start+2929>: (p07) st8 [r14]=r15 (gdb)
Created attachment 33365 [details] Better reduced testcase
Thanks. This seems to be a conjunction of several factors, the initial one being that the 4.8+ compiler generates (e.g for the reduced testcase at -O): addl r14 = @ltoffx(_rtld_local#+15032385536), r1 ;; ld8.mov r14 = [r14], _rtld_local#+15032385536 The huge number is not problematic per se, although it very likely runs afoul of some limitation/quirk here, since the value loaded from the GOT is truncated. In fact it looks like the value loaded from the GOT is just the huge number, that is to say the value of _rtld_local has been zeroed during the relocation. This may come from _rtld_local being in the .sdata section, in which case there is a relevant comment in sdata_symbolic_operand: /* 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. */ In other words, the compiler skips the efficient @gprel relocation on purpose, only to generate the @ltoffx relocation, which doesn't work either here...
(In reply to Eric Botcazou from comment #27) > Thanks. This seems to be a conjunction of several factors, the initial one > being that the 4.8+ compiler generates (e.g for the reduced testcase at -O): > > addl r14 = @ltoffx(_rtld_local#+15032385536), r1 > ;; > ld8.mov r14 = [r14], _rtld_local#+15032385536 > > The huge number is not problematic per se, although it very likely runs > afoul of some limitation/quirk here, since the value loaded from the GOT is > truncated. > > In fact it looks like the value loaded from the GOT is just the huge number, > that is to say the value of _rtld_local has been zeroed during the > relocation. > > This may come from _rtld_local being in the .sdata section, in which case > there is a relevant comment in sdata_symbolic_operand: > > /* 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. */ > > In other words, the compiler skips the efficient @gprel relocation on > purpose, only to generate the @ltoffx relocation, which doesn't work either > here... Hi Eric! I've poked this bug a bit more and still don't understand what does this instruction mean: ld8.mov r14 = [r14], _rtld_local#+15032385536 Where is '_rtld_local#+15032385536' offset expected to be used?
'_rtld_local#+15032385536' is just a hint that is passed through to the linker in the addend of the R_IA64_LDXMOV relocation for the insn. That tells the linker the addend of the R_IA64_LTOFF22X relocation associated with the corresponding addl insn when processing the R_IA64_LDXMOV relocation during the relaxing pass. This is necessary because the addl/ld8 pair can be separated by arbitrary other insns.
Aha, got it. I've factored out GNU_HASH section setup crash into separate very simple function: void __attribute__ ((unused, noinline)) do_it_again (struct link_map *l, ElfW(Dyn) *dyn) { ElfW(Dyn) **info = l->l_info; info[1879047935 - dyn->d_tag + 66] = dyn; } gcc -O2 specialises this function on 'l=_rtld_local._dl_rtld_map' argument. Broken code looks as: Program received signal SIGSEGV, Segmentation fault. 0x200000080000a9f0 in do_it_again (dyn=0x200000080004e710, l=0x20000008000533f8 <_rtld_local+2456>) at get-dynamic-info.h:42 42 info[1879047935 - dyn->d_tag + 66] = dyn; (gdb) disassemble Dump of assembler code for function do_it_again: 0x200000080000a9c0 <+0>: [MMI] ld8 r14=[r32];; 0x200000080000a9c1 <+1>: shladd r15=r14,3,r0 0x200000080000a9c2 <+2>: addl r14=163312,r1;; 0x200000080000a9d0 <+16>: [MMI] ld8 r14=[r14];; 0x200000080000a9d1 <+17>: adds r14=992,r14 0x200000080000a9d2 <+18>: nop.i 0x0;; 0x200000080000a9e0 <+32>: [MMI] nop.m 0x0 0x200000080000a9e1 <+33>: sub r14=r14,r15 0x200000080000a9e2 <+34>: nop.i 0x0;; => 0x200000080000a9f0 <+48>: [MIB] st8 [r14]=r32 0x200000080000a9f1 <+49>: nop.i 0x0 0x200000080000a9f2 <+50>: br.ret.sptk.many b0;; End of assembler dump. It's a very early setup phase: (gdb) bt #0 0x200000080000a9f0 in do_it_again (dyn=0x200000080004e710, l=0x20000008000533f8 <_rtld_local+2456>) at get-dynamic-info.h:42 #1 0x200000080000abd0 in do_it (l=0x20000008000533f8 <_rtld_local+2456>) at get-dynamic-info.h:78 #2 0x200000080000ac20 in elf_get_dynamic_info (temp=0x0, l=0x20000008000533f8 <_rtld_local+2456>) at get-dynamic-info.h:104 #3 0x200000080000b2a0 in _dl_start (arg=0x60000fffffffb350) at rtld.c:391 #4 0x2000000800001b10 in _start () What I don't like here: 'ld' is a static relocatable binary but the specialised code attempts to write by absolute address stored in ld's memory image: MEM[ MEM[r1 + 163312] + 992 - dyn->d_tag /* absolute address, not r1 relative!*/ ] = dyn; I would expect something in '_start:' https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/ia64/dl-machine.h;h=57d761e48732cfa5de370e7022eef83ae74a9c65;hb=HEAD#l159 to store current gp(r1) address to make code above work. Or PIC code not to rely on any relocations like that: MEM[ r1 /* real PIC */ + MEM[r1 + 163312] + 992 - dyn->d_tag ] = dyn; Who is expected to setup that 'r1 + 163312' location?
@ltoffx on symbol+addend doesn't make any sense. This computes an offset into the GOT, so any addend needs to be added _after_ loading the actual symbol address from the GOT.
(In reply to Andreas Schwab from comment #31) > @ltoffx on symbol+addend doesn't make any sense. This computes an offset > into the GOT, so any addend needs to be added _after_ loading the actual > symbol address from the GOT. Aha. That +addend seems to be some sort of hint to assembler how large addend must be. The real addend is 992. The address '$r1 + 163312' points to a relocation of type R_IA64_REL64LSB itself: (gdb) print *(void**)($r1 + 163312) $1 = (void *) 0x380052a60 readelf -a ld.so ... Relocation section '.rela.dyn' at offset 0xdd0 contains 51 entries: Offset Info Type Sym. Value Sym. Name + Addend ... 000000052910 00000000006f R_IA64_REL64LSB 380052a60 (or how objdump shows the same) objdump -r -R ld.so: DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE ... 0000000000052910 REL64LSB *ABS*+0x0000000380052a60 That dynamic relocation is expected to be fixed after ld reads all elf header types, not before (we see crash exactly at elf header read time): https://sourceware.org/git/?p=glibc.git;a=blob;f=elf/rtld.c;h=52160dfde6be42eba000c4e8136de0d190617270;hb=HEAD 377 /* Figure out the run-time load address of the dynamic linker itself. */ 378 bootstrap_map.l_addr = elf_machine_load_address (); 379 380 /* Read our own dynamic section and fill in the info array. */ 381 bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic (); 382 elf_get_dynamic_info (&bootstrap_map, NULL); 383 ... 392 if (bootstrap_map.l_addr || ! bootstrap_map.l_info[VALIDX(DT_GNU_PRELINKED)]) 393 { 394 /* Relocate ourselves so we can do normal function calls and 395 data access using the global offset table. */ 396 397 ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0, 0); 398 } 399 bootstrap_map.l_relocated = 1; 400 401 /* Please note that we don't allow profiling of this object and 402 therefore need not test whether we have to allocate the array 403 for the relocation results (as done in dl-reloc.c). */ 404 405 /* Now life is sane; we can call functions and access global data. 406 Set up to use the operating system facilities, and find out from 407 the operating system's program loader where to find the program 408 header table in core. Put the rest of _dl_start into a separate 409 function, that way the compiler cannot put accesses to the GOT 410 before ELF_DYNAMIC_RELOCATE. */ Note we crash at line 378 while relocations are processed later(!): at line 397. That's why writing simple selfcontained examples does not make the samples crash: running the example already has relocations adjusted correctly. Behaviour started exhibiting itself as constant propagation got smarter and managed to specialise 'elf_get_dynamic_info ()' for 'elf_get_dynamic_info (&_rtld_local, ...)' where _rtld_local._dl_rtld_map.l_info[(0x6ffffeff - dyn->d_tag) + 66] specialises it to: addl r14=163312,r1;; ld8 r14=[r14];; adds r14=992,r14 Numbers explanation: printf "0x%x\n" $(( (0x6ffffeff + 66) * 8 + 2520)) # 2520 is offset of '_rtld_local._dl_rtld_map.l_info' 0x3800003e0 # 0x3e0 = 992 large offset to an imm overflowing ${something} and pushes it (+ip offset?) out to a separate relocation: DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE ... 0000000000052910 REL64LSB *ABS*+0x0000000380052a60 Sounds plausible? Thus I'd say it's not a gcc/binutils bug and can/should be worked around in glibc.
Sent glibc workaround for review as: https://sourceware.org/ml/libc-alpha/2015-12/msg00556.html
Wrote more details on how exactly things were broken: http://trofi.github.io/posts/189-glibc-on-ia64-or-how-relocations-bootstrap.html
Created attachment 37180 [details] 0001-ia64-don-t-use-dynamic-relocations-for-local-symbols.patch 0001-ia64-don-t-use-dynamic-relocations-for-local-symbols.patch - how about this patch? It tries to capture any local symbol into gprel64 addressing (as opposed to .got addressing). That way relocation will be static.
Tested the patch on top of gcc-5.3.0 / glibc-2.22-r1. Relocation in rtld.os is R_IA64_GPREL64I and is just an immediate offset in ld.so: # objdump -r -d elf/rtld.os | grep -C4 rtld_local+0x38 97c0: 11 00 00 00 01 00 [MIB] nop.m 0x0 97c6: 00 00 00 02 80 03 nop.i 0x0 97cc: 10 01 00 43 (p07) br.cond.dpnt.few 98d0 <_dl_start+0x210>;; 97d0: 04 90 00 4d 00 21 [MLX] adds r18=64,r38 97d1: GPREL64I _rtld_local+0x3800003e0 97d6: 00 00 00 00 00 40 movl r26=0x0 97dc: 03 00 00 60 97e0: 05 b0 40 4d 02 21 [MLX] adds r22=336,r38 97e1: GPREL64I _rtld_local+0x37ffffb80 # objdump -r -d elf/ld.so | grep -C8 '_dl_start+0x210' b200: 11 00 00 00 01 00 [MIB] nop.m 0x0 b206: 00 00 00 02 80 03 nop.i 0x0 b20c: 10 01 00 43 (p07) br.cond.dpnt.few b310 <_dl_start+0x210>;; b210: 04 90 00 4d 00 21 [MLX] adds r18=64,r38 b216: 80 03 00 00 00 40 movl r26=0x380029110 b21c: 03 41 88 64 b220: 05 b0 40 4d 02 21 [MLX] adds r22=336,r38 b226: 80 03 00 00 00 00 movl r24=0x3800288b0;; Sent for review as: https://gcc.gnu.org/ml/gcc-patches/2015-12/msg02193.html
The patch also fixes this old bug: https://bugzilla.redhat.com/show_bug.cgi?id=33354 Despite being marked as fixed it fails on modern toolchain with slight overflow. Address of local constant was done over .got as well: .c source: static char *s90; void f() { s90 = "string 90"; } Compiled as gcc -fpic -S. before: .sbss s90: .skip 8 .section .rodata .LC0: stringz "string 90" .text f: ... addl r14 = @gprel(s90#), gp addl r15 = @ltoffx(.LC0), r1 ld8.mov r15 = [r15], .LC0 st8 [r14] = r15 ... after: .sbss s90: .skip 8 .section .rodata .LC0: stringz "string 90" .text f: ... addl r14 = @gprel(s90#), gp movl r15 = @gprel(.LC0) add r15 = r1, r15 st8 [r14] = r15
Author: law Date: Tue Jan 5 17:57:05 2016 New Revision: 232080 URL: https://gcc.gnu.org/viewcvs?rev=232080&root=gcc&view=rev Log: [PATCH v2] ia64: don't use dynamic relocations for local symbols PR other/60465 * config/ia64/ia64.c (ia64_expand_load_address): Use gprel64 for local symbolic operands. * config/ia64/predicates.md (local_symbolic_operand64): New predicate. PR other/60465 * gcc.target/ia64/pr60465-gprel64.c: New test. * gcc.target/ia64/pr60465-gprel64-c37.c: New test. Added: trunk/gcc/testsuite/gcc.target/ia64/pr60465-gprel64-c37.c trunk/gcc/testsuite/gcc.target/ia64/pr60465-gprel64.c Modified: trunk/gcc/ChangeLog trunk/gcc/config/ia64/ia64.c trunk/gcc/config/ia64/predicates.md trunk/gcc/testsuite/ChangeLog
Fixed on the trunk. Patch is backportable to the active release branches, but I'm not sure it's worth the effort.
(In reply to Jeffrey A. Law from comment #39) we should at least do gcc-5. i'm guessing there won't be another 4.9.
There will be.
cc-ing the people listed as ia64 maintainers ... can we get someone to just approve the patch for gcc-4.9 & gcc-5 branches ? i can take care of actually committing it.
Mike, consider this approval for backporting the fix to the release branches.
Author: vapier Date: Tue Jan 19 23:12:22 2016 New Revision: 232594 URL: https://gcc.gnu.org/viewcvs?rev=232594&root=gcc&view=rev Log: ia64: don't use dynamic relocations for local symbols Backported from trunk for PR other/60465. Added: branches/gcc-5-branch/gcc/testsuite/gcc.target/ia64/pr60465-gprel64-c37.c branches/gcc-5-branch/gcc/testsuite/gcc.target/ia64/pr60465-gprel64.c Modified: branches/gcc-5-branch/gcc/ChangeLog branches/gcc-5-branch/gcc/config/ia64/ia64.c branches/gcc-5-branch/gcc/config/ia64/predicates.md branches/gcc-5-branch/gcc/testsuite/ChangeLog
Author: vapier Date: Tue Jan 19 23:15:12 2016 New Revision: 232595 URL: https://gcc.gnu.org/viewcvs?rev=232595&root=gcc&view=rev Log: ia64: don't use dynamic relocations for local symbols Backported from trunk for PR other/60465. Added: branches/gcc-4_9-branch/gcc/testsuite/gcc.target/ia64/pr60465-gprel64-c37.c branches/gcc-4_9-branch/gcc/testsuite/gcc.target/ia64/pr60465-gprel64.c Modified: branches/gcc-4_9-branch/gcc/ChangeLog branches/gcc-4_9-branch/gcc/config/ia64/ia64.c branches/gcc-4_9-branch/gcc/config/ia64/predicates.md branches/gcc-4_9-branch/gcc/testsuite/ChangeLog
thanks all !
This patch caused a regression on HP-UX/IA between gcc-4.9.3 and gcc-4.9.4. Reverting the patch makes the build on this platform succeed for 4.9.4. However, considering this platform is probably not even actively maintained on GCC anymore, this report might be meaningless.
(In reply to The Written Word from comment #47) > This patch caused a regression on HP-UX/IA between gcc-4.9.3 and gcc-4.9.4. > Reverting the patch makes the build on this platform succeed for 4.9.4. > However, considering this platform is probably not even actively maintained > on GCC anymore, this report might be meaningless. I suggest filing a new bug report with details of what/how does not compile anymore. Perhaps it's easy to tweak.
(In reply to Sergei Trofimovich from comment #48) > I suggest filing a new bug report with details of what/how does not compile > anymore. Perhaps it's easy to tweak. Ok.