From owner-svn-src-head@freebsd.org Fri Nov 2 18:50:27 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id F22E310D6EFD for ; Fri, 2 Nov 2018 18:50:26 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from kib.kiev.ua (kib.kiev.ua [IPv6:2001:470:d5e7:1::1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2BA0E79471; Fri, 2 Nov 2018 18:50:26 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from tom.home (kib@localhost [127.0.0.1]) by kib.kiev.ua (8.15.2/8.15.2) with ESMTPS id wA2IoE4T057729 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 2 Nov 2018 20:50:18 +0200 (EET) (envelope-from kostikbel@gmail.com) DKIM-Filter: OpenDKIM Filter v2.10.3 kib.kiev.ua wA2IoE4T057729 Received: (from kostik@localhost) by tom.home (8.15.2/8.15.2/Submit) id wA2IoEC0057726; Fri, 2 Nov 2018 20:50:14 +0200 (EET) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: tom.home: kostik set sender to kostikbel@gmail.com using -f Date: Fri, 2 Nov 2018 20:50:14 +0200 From: Konstantin Belousov To: Mark Millard Cc: svn-src-head@freebsd.org, Alexander Richardson Subject: Re: svn commit: r339876 - head/libexec/rtld-elf Message-ID: <20181102185014.GP5335@kib.kiev.ua> References: <8E5A5F3A-F1A7-4702-A2F7-65D74CC5B2E5@yahoo.com> <20181102004101.GI5335@kib.kiev.ua> <003A49D7-6E8B-4775-A70B-E0EB44505D4B@yahoo.com> <20181102113827.GM5335@kib.kiev.ua> <7B29A4C8-228D-41CB-B594-98DFA456E9C8@yahoo.com> <20181102155234.GN5335@kib.kiev.ua> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_ADSP_CUSTOM_MED,FORGED_GMAIL_RCVD,FREEMAIL_FROM, NML_ADSP_CUSTOM_MED autolearn=no autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on tom.home X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 02 Nov 2018 18:50:27 -0000 On Fri, Nov 02, 2018 at 10:38:08AM -0700, Mark Millard wrote: > On 2018-Nov-2, at 8:52 AM, Konstantin Belousov 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 : 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 > #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 , 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 , 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,/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.