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.
> 
> Try this.  I only compile-tested the change.
> 
> 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 = -1;
> 
> @@ -327,8 +328,18 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int 
> flags,
>       if (cache != NULL)
>               free(cache);
> 
> -     /* 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 = obj->phdr;
> +         (const char *)phdr < (const char *)obj->phdr + obj->phsize;
> +         phdr++) {
> +             if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X) != 0) {
> +                     __syncicache(obj->mapbase + phdr->p_vaddr,
> +                         phdr->p_memsz);
> +             }
> +     }
> 
>       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 = obj->dynsymcount * sizeof(SymCache);
>       int r = -1;
> @@ -327,8 +328,18 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int 
> flags,
>       if (cache)
>               munmap(cache, bytes);
> 
> -     /* 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 = obj->phdr;
> +         (const char *)phdr < (const char *)obj->phdr + obj->phsize;
> +         phdr++) {
> +             if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X) != 0) {
> +                     __syncicache(obj->mapbase + phdr->p_vaddr,
> +                         phdr->p_memsz);
> +             }
> +     }
> 
>       return (r);
> }
> 

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/libexec/rtld-elf/ld-elf.so.1.full
 /bin/ls

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

Program received signal SIGSEGV, Segmentation fault.
__syncicache (from=0x3000000, len=34112) at 
/usr/src/lib/libc/powerpc/gen/syncicache.c:94
94                      __asm __volatile ("dcbst 0,%0" :: "r"(p));
1: x/i $pc
=> 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 + "?


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

_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to