https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60465
--- Comment #30 from Sergei Trofimovich <slyfox at inbox dot ru> --- 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?