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?

Reply via email to