Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 2 Nov 2018 08:30:17 -0700
From:      Mark Millard <marklmi26-fbsd@yahoo.com>
To:        Konstantin Belousov <kib@freebsd.org>
Cc:        svn-src-head@freebsd.org, Alexander Richardson <arichardson@freebsd.org>
Subject:   Re: svn commit: r339876 - head/libexec/rtld-elf
Message-ID:  <7B29A4C8-228D-41CB-B594-98DFA456E9C8@yahoo.com>
In-Reply-To: <20181102113827.GM5335@kib.kiev.ua>
References:  <8E5A5F3A-F1A7-4702-A2F7-65D74CC5B2E5@yahoo.com> <20181102004101.GI5335@kib.kiev.ua> <E44F5772-1F8A-40B8-9C4E-B8362B768F37@yahoo.com> <003A49D7-6E8B-4775-A70B-E0EB44505D4B@yahoo.com> <20181102113827.GM5335@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help


On 2018-Nov-2, at 4:38 AM, Konstantin Belousov <kib at freebsd.org> =
wrote:

> On Fri, Nov 02, 2018 at 12:16:23AM -0700, Mark Millard wrote:
>> It stops when the dcbst in __syncicache runs into an address in
>> the p_align 65536 caused hole between the two PT_LOAD's with PF_X.
>> /bin/ls itself has such a hole, as do the .so libraries involved.
>=20
> Try this.  I only compile-tested the change.
>=20
> diff --git a/libexec/rtld-elf/powerpc/reloc.c =
b/libexec/rtld-elf/powerpc/reloc.c
> index e921a4dc7d1..5f21e33bee3 100644
> --- a/libexec/rtld-elf/powerpc/reloc.c
> +++ b/libexec/rtld-elf/powerpc/reloc.c
> @@ -294,6 +294,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, =
int flags,
> {
> 	const Elf_Rela *relalim;
> 	const Elf_Rela *rela;
> +	const Elf_Phdr *phdr;
> 	SymCache *cache;
> 	int r =3D -1;
>=20
> @@ -327,8 +328,18 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry =
*obj_rtld, int flags,
> 	if (cache !=3D NULL)
> 		free(cache);
>=20
> -	/* Synchronize icache for text seg in case we made any changes =
*/
> -	__syncicache(obj->mapbase, obj->textsize);
> +	/*
> +	 * Synchronize icache for executable segments in case we made
> +	 * any changes.
> +	 */
> +	for (phdr =3D obj->phdr;
> +	    (const char *)phdr < (const char *)obj->phdr + obj->phsize;
> +	    phdr++) {
> +		if (phdr->p_type =3D=3D PT_LOAD && (phdr->p_flags & =
PF_X) !=3D 0) {
> +			__syncicache(obj->mapbase + phdr->p_vaddr,
> +			    phdr->p_memsz);
> +		}
> +	}
>=20
> 	return (r);
> }
> diff --git a/libexec/rtld-elf/powerpc64/reloc.c =
b/libexec/rtld-elf/powerpc64/reloc.c
> index c2d6dac13b1..980b4933afe 100644
> --- a/libexec/rtld-elf/powerpc64/reloc.c
> +++ b/libexec/rtld-elf/powerpc64/reloc.c
> @@ -291,6 +291,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, =
int flags,
> {
> 	const Elf_Rela *relalim;
> 	const Elf_Rela *rela;
> +	const Elf_Phdr *phdr;
> 	SymCache *cache;
> 	int bytes =3D obj->dynsymcount * sizeof(SymCache);
> 	int r =3D -1;
> @@ -327,8 +328,18 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry =
*obj_rtld, int flags,
> 	if (cache)
> 		munmap(cache, bytes);
>=20
> -	/* Synchronize icache for text seg in case we made any changes =
*/
> -	__syncicache(obj->mapbase, obj->textsize);
> +	/*
> +	 * Synchronize icache for executable segments in case we made
> +	 * any changes.
> +	 */
> +	for (phdr =3D obj->phdr;
> +	    (const char *)phdr < (const char *)obj->phdr + obj->phsize;
> +	    phdr++) {
> +		if (phdr->p_type =3D=3D PT_LOAD && (phdr->p_flags & =
PF_X) !=3D 0) {
> +			__syncicache(obj->mapbase + phdr->p_vaddr,
> +			    phdr->p_memsz);
> +		}
> +	}
>=20
> 	return (r);
> }
>=20

Unfortunately, that failed:

(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: =
/usr/obj/powerpcvtsc_gcc421/powerpc.powerpc/usr/src/powerpc.powerpc/libexe=
c/rtld-elf/ld-elf.so.1.full /bin/ls

Breakpoint 4, reloc_non_plt (obj=3D0x41041000, obj_rtld=3D0x1801cc7, =
flags=3D4, lockstate=3D0x0) at =
/usr/src/libexec/rtld-elf/powerpc/reloc.c:338
338				__syncicache(obj->mapbase + =
phdr->p_vaddr,
1: x/i $pc
=3D> 0x1012b90 <reloc_non_plt+276>:	lwz     r0,36(r29)
(gdb) print/x obj->mapbase+phdr->p_vaddr
$17 =3D 0x3000000
(gdb) print/x obj->mapbase             =20
$18 =3D 0x1800000
(gdb) print/x phdr->p_vaddr
$19 =3D 0x1800000
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
__syncicache (from=3D0x3000000, len=3D34112) at =
/usr/src/lib/libc/powerpc/gen/syncicache.c:94
94			__asm __volatile ("dcbst 0,%0" :: "r"(p));
1: x/i $pc
=3D> 0x10228b8 <__syncicache+96>:	dcbst   0,r11



It looks to me like the 0x1800000 component of the
overall figure was double counted. ( phdr->p_vaddr
would vary but obj->mapbase would not. )

Omit "obj->mapbase + "?


=3D=3D=3D
Mark Millard
marklmi at yahoo.com
( dsl-only.net went
away in early 2018-Mar)




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?7B29A4C8-228D-41CB-B594-98DFA456E9C8>