Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 May 2020 16:51:26 +0000
From:      bugzilla-noreply@freebsd.org
To:        bugs@FreeBSD.org
Subject:   [Bug 246561] [PATCH] rtld-elf: dlinfo() returns wrong address in RTLD_DI_LINKMAP's l_addr  (breaking Wine, gdb, etc.)
Message-ID:  <bug-246561-227-SbUIPICEH1@https.bugs.freebsd.org/bugzilla/>
In-Reply-To: <bug-246561-227@https.bugs.freebsd.org/bugzilla/>
References:  <bug-246561-227@https.bugs.freebsd.org/bugzilla/>

next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D246561

--- Comment #4 from John Baldwin <jhb@FreeBSD.org> ---
GDB doesn't use the special field for MIPS (it ignores it).  GDB also uses =
the
structure embedded in the rtld itself, it does not call dlinfo().  GDB does
seem to expect l_addr + offset of ".dynamic" in the binary =3D=3D l_ld.

I think what we have now only works because all of our shared libraries are
linked at a virtual address of 0.  If we did "pre-linking" to set preferred
addresses for shared libraries GDB would stop working.

Here's stepping through the function (gdb/solib-svr4.c:lm_addr_check()) that
finds the base address of a shared library (libutil.so in this case):

(top-gdb) p *li
$10 =3D {<lm_info_base> =3D {<No data fields>}, l_addr =3D 0x0,=20
  l_addr_inferior =3D 0x800250000, l_addr_p =3D false, lm_addr =3D 0x800232=
638,=20
  l_ld =3D 0x800263360, l_next =3D 0x800232a38, l_prev =3D 0x800232238,=20
  l_name =3D 0x800230260}
(top-gdb) n
225           l_addr =3D li->l_addr_inferior;
(top-gdb) n
227           if (! abfd || ! has_lm_dynamic_from_link_map ())
(top-gdb)=20
230           l_dynaddr =3D li->l_ld;
(top-gdb)=20
232           dyninfo_sect =3D bfd_get_section_by_name (abfd, ".dynamic");
(top-gdb)=20
233           if (dyninfo_sect =3D=3D NULL)
(top-gdb)=20
236           dynaddr =3D bfd_section_vma (abfd, dyninfo_sect);
(top-gdb)=20
238           if (dynaddr + l_addr !=3D l_dynaddr)
(top-gdb) p dynaddr
$11 =3D 0x13360
(top-gdb) p l_addr
$12 =3D 0x800250000
(top-gdb) p l_dynaddr
$13 =3D 0x800263360

li->l_addr_inferior is the value of 'l_addr' from the linkmap, li->l_ld is
'l_ld'.

readelf -t libutil.so:

  [20] .dynamic
       DYNAMIC          0000000000013360  0000000000013360  6
       0000000000000160 0000000000000010  0                 8
       [0000000000000003]: WRITE, ALLOC

readelf -l shows first PT_LOAD with an offset of 0:

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flg    Align
  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                 0x00000000000001f8 0x00000000000001f8  R      0x8
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x00000000000075cc 0x00000000000075cc  R      0x1000
  LOAD           0x0000000000008000 0x0000000000008000 0x0000000000008000
                 0x000000000000a5d0 0x000000000000a5d0  R E    0x1000

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-246561-227-SbUIPICEH1>