ppc64 vDSO update

Steve Munroe sjmunroe at us.ibm.com
Wed Jan 5 09:02:04 EST 2005

Benjamin Herrenschmidt <benh at kernel.crashing.org> wrote on 11/21/2004 
09:38:36 PM:

> At the URL below, you can find a new version of the ppc64 vDSO patch 
> a recent Linus bk tree. I intend to submit it upstream real soon as the 
> on non-executable stack is waiting for it, though we must first make 
sure the
> way symbols are exported to userland is ok for glibc.
> http://gate.crashing.org/~benh/ppc64-vdso-20041122.diff
> ...
> (Craig: the signal issue is fixed now, either when building with 
> descriptors or
> without).
> Ben.

Still haveing problems with VDSO/GLIBC integration. Basically any glibc 
make check test that uses signals is a space shot for both PPC32/PPC64. 

First it seems that glibc is expecting a (fairly normal) DSO image 
including two (2) LOAD entries in the program header. The current PPC64 
kernel vdso images only contain one (1) LOAD entry:

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00100000 0x00100000 0x00e10 0x00e10 R E 
  DYNAMIC        0x000d98 0x00100d98 0x00100d98 0x00078 0x00078 R   0x4
  GNU_EH_FRAME   0x000000 0x00000000 0x00000000 0x00000 0x00000     0x4

This caused problems for the code in libc/elf/rtld.c that attempts to 
extract l_map_start/l_map_end for the vdso:

              else if (ph->p_type == PT_LOAD)
                  if (! l->l_addr)
                    l->l_addr = ph->p_vaddr;
                  else if (ph->p_vaddr + ph->p_memsz >= l->l_map_end)
                    l->l_map_end = ph->p_vaddr + ph->p_memsz;
                  else if ((ph->p_flags & PF_X)
                           && ph->p_vaddr + ph->p_memsz >= l->l_text_end)
                    l->l_text_end = ph->p_vaddr + ph->p_memsz;

This code will set l_addr but not l_map_end or l_text_end because it 
grabbed the p_vaddr from the 1st and only LOAD entry then continue the 
loop looking for the 2nd LOAD entry (which is not there!). On PPC32 this 
causes the "assert (mapend > mapstart)" in __elf_preferred_address to 
fail. I hacked around this by removing the "else" from the "else if" but 
it just fails later.

The remaining problem is we are getting into dl_iterate_phdr and taking a 
wild branch. This could be from the callback in dl_iterate_phdr and due to 
the incomplete nature of our vsdo. This is difficult to debug as the stack 
point (and TOC pointer in PPC64) are both clobbered by this point and 
GDB-6.1 gets totally confused.

Ben: it would be handy if you could update the corefile support to include 
the vdso segments. Also please try a vdso with 2 LOAD segments. 

Steven J. Munroe
Linux on Power Toolchain Architect
IBM Corporation, Linux Technology Center

More information about the Linuxppc64-dev mailing list