Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 2 Nov 2018 20:50:14 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Mark Millard <marklmi26-fbsd@yahoo.com>
Cc:        svn-src-head@freebsd.org, Alexander Richardson <arichardson@freebsd.org>
Subject:   Re: svn commit: r339876 - head/libexec/rtld-elf
Message-ID:  <20181102185014.GP5335@kib.kiev.ua>
In-Reply-To: <E93B3880-281E-482C-9DA7-851398543B97@yahoo.com>
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> <7B29A4C8-228D-41CB-B594-98DFA456E9C8@yahoo.com> <20181102155234.GN5335@kib.kiev.ua> <E93B3880-281E-482C-9DA7-851398543B97@yahoo.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, Nov 02, 2018 at 10:38:08AM -0700, Mark Millard wrote:
> On 2018-Nov-2, at 8:52 AM, Konstantin Belousov <kostikbel at gmail.com> wrote:
> 
> > On Fri, Nov 02, 2018 at 08:30:17AM -0700, Mark Millard wrote:
> >> 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 + "?
> > I used the wrong addend.  Try this fix.
> > 
> > diff --git a/libexec/rtld-elf/powerpc/reloc.c b/libexec/rtld-elf/powerpc/reloc.c
> > index e921a4dc7d1..fae28dd9224 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->relocbase + 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..15f31738ab7 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->relocbase + phdr->p_vaddr,
> > +			    phdr->p_memsz);
> > +		}
> > +	}
> > 
> > 	return (r);
> > }
> 
> That seems better. But it crashes during /bin/ls execution
> ( 0x0180???? addresses ), apparently in a library routine
> ( 0x41?????? addresses ):
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0x411220b4 in ?? ()
> (gdb) bt
> #0  0x411220b4 in ?? ()
> #1  0x4112200c in ?? ()
> #2  0x01803c84 in ?? ()
> #3  0x018023b4 in ?? ()
> #4  0x010121a0 in .rtld_start () at /usr/src/libexec/rtld-elf/powerpc/rtld_start.S:112
> 
> Using a normal gdb run of /bin/ls suggests:
> 
> #2  0x01803c84 in ?? () should be in main and seems to be: bl 0x1818914 <getopt_long@plt>
> #3  0x018023b4 in ?? () should be in _start
> 
> Looking in the test context:
> 
>    0x1803c80:	bl      0x1818914
>    0x1803c84:	cmpwi   cr7,r3,-1
> 
> and:
> 
>    0x1818914:	li      r11,59
>    0x1818918:	b       0x18186f4
> 
> and:
> 
>    0x18186f4:	rlwinm  r11,r11,2,0,29
>    0x18186f8:	addis   r11,r11,386
>    0x18186fc:	lwz     r11,-30316(r11)
>    0x1818700:	mtctr   r11
>    0x1818704:	bctr
> 
> Breaking at the bctr and using info reg:
> 
> r11            0x4125ffa0	1093009312
> 
> It looks like there is some amount of
> activity before the traceback addresses
> show up.
> 
> I've not found a good way to fill in the "in ??()"
> (or analogous) information. The addresses 0x411220??
> do not match up with a normal run of /bin/ls from
> gdb: the addresses can not be accessed.
> 
> 
> 
> It does appear that the code is in /lib/libc.so.7 in the
> test context:
> 
> Breakpoint 2, reloc_non_plt (obj=0x41041600, obj_rtld=0x41104b57, flags=4, lockstate=0x0) at /usr/src/libexec/rtld-elf/powerpc/reloc.c:338
> 338				__syncicache(obj->relocbase + phdr->p_vaddr,
> 1: /x obj->relocbase + phdr->p_vaddr = 0x410ec000
> 2: /x obj->relocbase + phdr->p_vaddr + phdr->p_memsz = 0x4127f9d0
> 4: *obj = {magic = 0, version = 0, next = {tqe_next = 0x0, tqe_prev = 0x41041408}, path = 0x4103f100 "/lib/libc.so.7", origin_path = 0x0, refcount = 1, holdcount = 0, dl_refcount = 0, 
>   mapbase = 0x410ec000 "\177ELF\001\002\001\t", mapsize = 1908736, textsize = 1908736, vaddrbase = 0, relocbase = 0x410ec000 "\177ELF\001\002\001\t", dynamic = 0x412938e0, 
>   entry = 0x41119d20 "\224!\377\340|\b\002\246H\027\374\001\223\301", phdr = 0x410ec034, phsize = 192, interp = 0x0, stack_flags = 6, tlsindex = 2, tlsinit = 0x4128f9d0, tlsinitsize = 2832, 
>   tlssize = 2860, tlsoffset = 8, tlsalign = 16, relro_page = 0x410ec000 "\177ELF\001\002\001\t", relro_size = 0, pltgot = 0x41299ba8, rel = 0x0, relsize = 0, rela = 0x41106530, relasize = 79800, 
>   pltrel = 0x0, pltrelsize = 0, pltrela = 0x41116d6c, pltrelasize = 12156, symtab = 0x410f12a0, strtab = 0x410fd8e0 "", strsize = 29303, verneed = 0x0, verneednum = 0, verdef = 0x41106420, 
>   verdefnum = 8, versyms = 0x41104b58, buckets = 0x410ec0fc, nbuckets = 2053, chains = 0x410ee110, nchains = 3172, nbuckets_gnu = 0, symndx_gnu = 0, maskwords_bm_gnu = 0, shift2_gnu = 0, 
>   dynsymcount = 3172, bloom_gnu = 0x0, buckets_gnu = 0x0, chain_zero_gnu = 0x0, rpath = 0x0, runpath = 0x0, needed = 0x0, needed_filtees = 0x0, needed_aux_filtees = 0x0, names = {
>     stqh_first = 0x4103f120, stqh_last = 0x4103f140}, vertab = 0x41040400, vernum = 9, init = 1091673320, fini = 1093063668, preinit_array = 0, init_array = 0, fini_array = 0, preinit_array_num = 0, 
>   init_array_num = 0, fini_array_num = 0, osrel = 0, mainprog = 0 '\000', rtld = 0 '\000', relocated = 1 '\001', ver_checked = 1 '\001', textrel = 0 '\000', symbolic = 0 '\000', bind_now = 0 '\000', 
>   traced = 0 '\000', jmpslots_done = 0 '\000', init_done = 0 '\000', tls_done = 1 '\001', phdr_alloc = 0 '\000', z_origin = 0 '\000', z_nodelete = 0 '\000', z_noopen = 0 '\000', 
>   z_loadfltr = 0 '\000', z_interpose = 0 '\000', z_nodeflib = 0 '\000', z_global = 0 '\000', ref_nodel = 0 '\000', init_scanned = 0 '\000', on_fini_list = 0 '\000', dag_inited = 0 '\000', 
>   filtees_loaded = 0 '\000', irelative = 0 '\000', gnu_ifunc = 0 '\000', non_plt_gnu_ifunc = 0 '\000', crt_no_init = 0 '\000', valid_hash_sysv = 1 '\001', valid_hash_gnu = 0 '\000', 
>   dlopened = 0 '\000', marker = 0 '\000', unholdfree = 0 '\000', doomed = 0 '\000', linkmap = {l_addr = 0x410ec000 "\177ELF\001\002\001\t", l_name = 0x4103f100 "/lib/libc.so.7", l_ld = 0x412938e0, 
>     l_next = 0x103ec1c <obj_rtld+308>, l_prev = 0x41041534}, dldags = {stqh_first = 0x0, stqh_last = 0x41041748}, dagmembers = {stqh_first = 0x0, stqh_last = 0x41041750}, dev = 137, ino = 3370513, 
>   priv = 0x0}
> (gdb) c
> Continuing.
> 
> Breakpoint 2, reloc_non_plt (obj=0x41041600, obj_rtld=0xffffff50, flags=4, lockstate=0x0) at /usr/src/libexec/rtld-elf/powerpc/reloc.c:338
> 338				__syncicache(obj->relocbase + phdr->p_vaddr,
> 1: /x obj->relocbase + phdr->p_vaddr = 0x4128f9d0
> 2: /x obj->relocbase + phdr->p_vaddr + phdr->p_memsz = 0x412bdef0
> 4: *obj = {magic = 0, version = 0, next = {tqe_next = 0x0, tqe_prev = 0x41041408}, path = 0x4103f100 "/lib/libc.so.7", origin_path = 0x0, refcount = 1, holdcount = 0, dl_refcount = 0, 
>   mapbase = 0x410ec000 "\177ELF\001\002\001\t", mapsize = 1908736, textsize = 1908736, vaddrbase = 0, relocbase = 0x410ec000 "\177ELF\001\002\001\t", dynamic = 0x412938e0, 
>   entry = 0x41119d20 "\224!\377\340|\b\002\246H\027\374\001\223\301", phdr = 0x410ec034, phsize = 192, interp = 0x0, stack_flags = 6, tlsindex = 2, tlsinit = 0x4128f9d0, tlsinitsize = 2832, 
>   tlssize = 2860, tlsoffset = 8, tlsalign = 16, relro_page = 0x410ec000 "\177ELF\001\002\001\t", relro_size = 0, pltgot = 0x41299ba8, rel = 0x0, relsize = 0, rela = 0x41106530, relasize = 79800, 
>   pltrel = 0x0, pltrelsize = 0, pltrela = 0x41116d6c, pltrelasize = 12156, symtab = 0x410f12a0, strtab = 0x410fd8e0 "", strsize = 29303, verneed = 0x0, verneednum = 0, verdef = 0x41106420, 
>   verdefnum = 8, versyms = 0x41104b58, buckets = 0x410ec0fc, nbuckets = 2053, chains = 0x410ee110, nchains = 3172, nbuckets_gnu = 0, symndx_gnu = 0, maskwords_bm_gnu = 0, shift2_gnu = 0, 
>   dynsymcount = 3172, bloom_gnu = 0x0, buckets_gnu = 0x0, chain_zero_gnu = 0x0, rpath = 0x0, runpath = 0x0, needed = 0x0, needed_filtees = 0x0, needed_aux_filtees = 0x0, names = {
>     stqh_first = 0x4103f120, stqh_last = 0x4103f140}, vertab = 0x41040400, vernum = 9, init = 1091673320, fini = 1093063668, preinit_array = 0, init_array = 0, fini_array = 0, preinit_array_num = 0, 
>   init_array_num = 0, fini_array_num = 0, osrel = 0, mainprog = 0 '\000', rtld = 0 '\000', relocated = 1 '\001', ver_checked = 1 '\001', textrel = 0 '\000', symbolic = 0 '\000', bind_now = 0 '\000', 
>   traced = 0 '\000', jmpslots_done = 0 '\000', init_done = 0 '\000', tls_done = 1 '\001', phdr_alloc = 0 '\000', z_origin = 0 '\000', z_nodelete = 0 '\000', z_noopen = 0 '\000', 
>   z_loadfltr = 0 '\000', z_interpose = 0 '\000', z_nodeflib = 0 '\000', z_global = 0 '\000', ref_nodel = 0 '\000', init_scanned = 0 '\000', on_fini_list = 0 '\000', dag_inited = 0 '\000', 
>   filtees_loaded = 0 '\000', irelative = 0 '\000', gnu_ifunc = 0 '\000', non_plt_gnu_ifunc = 0 '\000', crt_no_init = 0 '\000', valid_hash_sysv = 1 '\001', valid_hash_gnu = 0 '\000', 
>   dlopened = 0 '\000', marker = 0 '\000', unholdfree = 0 '\000', doomed = 0 '\000', linkmap = {l_addr = 0x410ec000 "\177ELF\001\002\001\t", l_name = 0x4103f100 "/lib/libc.so.7", l_ld = 0x412938e0, 
>     l_next = 0x103ec1c <obj_rtld+308>, l_prev = 0x41041534}, dldags = {stqh_first = 0x0, stqh_last = 0x41041748}, dagmembers = {stqh_first = 0x0, stqh_last = 0x41041750}, dev = 137, ino = 3370513, 
>   priv = 0x0}
> 
> 
> I'm going to at least go eat before investigating more.
> 
There seems to be an issue with the direct execution mode on ppc.
Even otherwise working ld-elf.so.1 segfaults if I try to use it as
standalone binary.

But if I specify patched ld-elf.so.1 as the interpreter for some program,
using 'cc -Wl,-I,<path>/ld-elf.so.1' it works.  So I see there two bugs,
one is regression due to textsize calculation, which should be fixed by
my patch.  Another is the direct exec problem.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20181102185014.GP5335>