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>