Date: Tue, 30 Oct 2018 15:05:42 -0700 From: Mark Millard <marklmi26-fbsd@yahoo.com> To: Alexander Richardson <arichardson@freebsd.org> Cc: svn-src-head@freebsd.org Subject: Re: svn commit: r339876 - head/libexec/rtld-elf Message-ID: <2D7C5FC6-CA8D-4AAB-BD64-CC883531F737@yahoo.com> In-Reply-To: <CA%2BZ_v8q-pdd0cVC3A6OYZb6i9AnjvCJfD-EUjfR2b8zqRN2MXw@mail.gmail.com> References: <7DC6D9C4-C153-4BCE-851C-22C890AB0D73@yahoo.com> <CA%2BZ_v8oZDqfrO0EsJjQXAat287TeDAO7C5omSaDaUNEj6q0oCw@mail.gmail.com> <A392133D-3E02-422C-81FF-5BAD4D15665D@yahoo.com> <CA%2BZ_v8q-pdd0cVC3A6OYZb6i9AnjvCJfD-EUjfR2b8zqRN2MXw@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On 2018-Oct-30, at 2:40 PM, Alexander Richardson <arichardson at = freebsd.org> wrote: > On Tue, 30 Oct 2018 at 21:32, Mark Millard <marklmi26-fbsd at = yahoo.com> wrote: >>=20 >>=20 >>=20 >> On 2018-Oct-30, at 2:23 PM, Alexander Richardson <arichardson at = freebsd.org> wrote: >>=20 >>> On Tue, 30 Oct 2018 at 18:19, Mark Millard <marklmi26-fbsd at = yahoo.com> wrote: >>>>=20 >>>> Alexander Richardson arichardson at freebsd.org wrote on >>>> Tue Oct 30 15:33:00 UTC 2018 : >>>>=20 >>>>> On Tue, 30 Oct 2018 at 10:17, Michael Tuexen >>>>> <Michael.Tuexen at macmic.franken.de> wrote: >>>>>>=20 >>>>>>> On 29. Oct 2018, at 22:08, Alex Richardson <arichardson at = FreeBSD.org> wrote: >>>>>>>=20 >>>>>>> Author: arichardson >>>>>>> Date: Mon Oct 29 21:08:02 2018 >>>>>>> New Revision: 339876 >>>>>>> URL: https://svnweb.freebsd.org/changeset/base/339876 >>>>>>>=20 >>>>>>> Log: >>>>>>> rtld: set obj->textsize correctly >>>>>>>=20 >>>>>>> With lld-generated binaries the first PT_LOAD will usually be a = read-only >>>>>>> segment unless you pass --no-rosegment. For those binaries the = textsize is >>>>>>> determined by the next PT_LOAD. To allow both LLD and bfd 2.17 = binaries to >>>>>>> be parsed correctly use the end of the last PT_LOAD that is = marked as >>>>>>> executable instead. >>>>>>>=20 >>>>>>> I noticed that the value was wrong while adding some debug = prints for some rtld >>>>>>> changes for CHERI binaries. `obj->textsize` only seems to be = used by PPC so the >>>>>>> effect is untested. However, the value before was definitely = wrong and the new >>>>>>> result matches the phdrs. >>>>>> I build kernel and world with a revision later than this on a = PPC. Buildword >>>>>> ends up with a world where almost all binaries are = segfaulting.... Especially gdb >>>>>> (but svn, ls or so all segfault). >>>>>>=20 >>>>>> Best regards >>>>>> Michael >>>>>=20 >>>>> This is rather surprising since if anything the range of the = icache >>>>> flush should increase rather than decrease after this change. >>>>>=20 >>>>> I can only see this causing a behaviour change if we actually need = to >>>>> flush more than just the executable segments. >>>>> Is it possible that some binary/library contains a non-executable >>>>> segment as the first PT_LOAD? >>>>> Or is there some linker script that adds custom PHDRS? >>>>=20 >>>> The following is based on using devel/powerpc64-xtoolchain-gcc >>>> to buildworld buildkernel on/for powerpc64. (I experiment with >>>> using fairly modern tools to target powerpc64 and powerpc.) >>>> The build context is head -r339076 based, both for what >>>> did the build and for what it was building. >>>>=20 >>>> I report from both elfdump and objdump output >>>> because each seems to have some oddities in what >>>> it outputs. >>>>=20 >>>> I start with elfdump (which leaves sh_flags blank >>>> and shows a section header with sh_name empty >>>> that objdump does not list at all): >>>>=20 >>>> # elfdump -pc /bin/ls | less >>>>=20 >>>> . . . >>>>=20 >>>> As for objdump on the same file (section >>>> one less than elfdump listed, no empty sh_name >>>> section listed): >>>>=20 >>>> # objdump -ph /bin/ls | less >>>>=20 >>>> /bin/ls: file format elf64-powerpc-freebsd >>>>=20 >>>> Program Header: >>>> PHDR off 0x0000000000000040 vaddr 0x0000000010000040 paddr = 0x0000000010000040 align 2**3 >>>> filesz 0x0000000000000188 memsz 0x0000000000000188 flags r-- >>>> INTERP off 0x00000000000001c8 vaddr 0x00000000100001c8 paddr = 0x00000000100001c8 align 2**0 >>>> filesz 0x0000000000000015 memsz 0x0000000000000015 flags r-- >>>> LOAD off 0x0000000000000000 vaddr 0x0000000010000000 paddr = 0x0000000010000000 align 2**16 >>>> filesz 0x000000000000910c memsz 0x000000000000910c flags r-x >>>> LOAD off 0x0000000000009110 vaddr 0x0000000010019110 paddr = 0x0000000010019110 align 2**16 >>>> filesz 0x0000000000000ee0 memsz 0x00000000000010e8 flags rw- >>>> DYNAMIC off 0x0000000000009138 vaddr 0x0000000010019138 paddr = 0x0000000010019138 align 2**3 >>>> filesz 0x00000000000001c0 memsz 0x00000000000001c0 flags rw- >>>> NOTE off 0x00000000000001e0 vaddr 0x00000000100001e0 paddr = 0x00000000100001e0 align 2**2 >>>> filesz 0x0000000000000030 memsz 0x0000000000000030 flags r-- >>>> STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr = 0x0000000000000000 align 2**4 >>>> filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw- >>>>=20 >>>> Dynamic Section: >>>> NEEDED libutil.so.9 >>>> NEEDED libncursesw.so.8 >>>> NEEDED libc.so.7 >>>> INIT 0x0000000010019328 >>>> FINI 0x0000000010019340 >>>> HASH 0x0000000010000210 >>>> STRTAB 0x0000000010000d00 >>>> SYMTAB 0x0000000010000490 >>>> STRSZ 0x000000000000035a >>>> SYMENT 0x0000000000000018 >>>> DEBUG 0x0000000000000000 >>>> PLTGOT 0x0000000010019898 >>>> PLTRELSZ 0x00000000000006f0 >>>> PLTREL 0x0000000000000007 >>>> JMPREL 0x00000000100012f8 >>>> 0x70000000 0x00000000100089b4 >>>> RELA 0x0000000010001160 >>>> RELASZ 0x0000000000000198 >>>> RELAENT 0x0000000000000018 >>>> VERNEED 0x0000000010001110 >>>> VERNEEDNUM 0x0000000000000001 >>>> VERSYM 0x000000001000105a >>>>=20 >>>> Version References: >>>> required from libc.so.7: >>>> 0x077a28b3 0x00 05 FBSD_1.3 >>>> 0x077a28b1 0x00 04 FBSD_1.1 >>>> 0x077a28b5 0x00 03 FBSD_1.5 >>>> 0x077a28b0 0x00 02 FBSD_1.0 >>>> private flags =3D 0x1: [abiv1] >>>>=20 >>>> Sections: >>>> Idx Name Size VMA LMA = File off Algn >>>> 0 .interp 00000015 00000000100001c8 00000000100001c8 = 000001c8 2**0 >>>> CONTENTS, ALLOC, LOAD, READONLY, DATA >>>> 1 .note.tag 00000030 00000000100001e0 00000000100001e0 = 000001e0 2**2 >>>> CONTENTS, ALLOC, LOAD, READONLY, DATA >>>> 2 .hash 0000027c 0000000010000210 0000000010000210 = 00000210 2**3 >>>> CONTENTS, ALLOC, LOAD, READONLY, DATA >>>> 3 .dynsym 00000870 0000000010000490 0000000010000490 = 00000490 2**3 >>>> CONTENTS, ALLOC, LOAD, READONLY, DATA >>>> 4 .dynstr 0000035a 0000000010000d00 0000000010000d00 = 00000d00 2**0 >>>> CONTENTS, ALLOC, LOAD, READONLY, DATA >>>> 5 .gnu.version 000000b4 000000001000105a 000000001000105a = 0000105a 2**1 >>>> CONTENTS, ALLOC, LOAD, READONLY, DATA >>>> 6 .gnu.version_r 00000050 0000000010001110 0000000010001110 = 00001110 2**3 >>>> CONTENTS, ALLOC, LOAD, READONLY, DATA >>>> 7 .rela.dyn 00000198 0000000010001160 0000000010001160 = 00001160 2**3 >>>> CONTENTS, ALLOC, LOAD, READONLY, DATA >>>> 8 .rela.plt 000006f0 00000000100012f8 00000000100012f8 = 000012f8 2**3 >>>> CONTENTS, ALLOC, LOAD, READONLY, DATA >>>> 9 .init 0000002c 00000000100019f0 00000000100019f0 = 000019f0 2**4 >>>> CONTENTS, ALLOC, LOAD, READONLY, CODE >>>> 10 .text 00007204 0000000010001a20 0000000010001a20 = 00001a20 2**5 >>>> CONTENTS, ALLOC, LOAD, READONLY, CODE >>>> 11 .fini 00000024 0000000010008c30 0000000010008c30 = 00008c30 2**4 >>>> CONTENTS, ALLOC, LOAD, READONLY, CODE >>>> 12 .rodata 000004b0 0000000010008c58 0000000010008c58 = 00008c58 2**3 >>>> CONTENTS, ALLOC, LOAD, READONLY, DATA >>>> 13 .eh_frame 00000004 0000000010009108 0000000010009108 = 00009108 2**2 >>>> CONTENTS, ALLOC, LOAD, READONLY, DATA >>>> 14 .ctors 00000010 0000000010019110 0000000010019110 = 00009110 2**3 >>>> CONTENTS, ALLOC, LOAD, DATA >>>> 15 .dtors 00000010 0000000010019120 0000000010019120 = 00009120 2**3 >>>> CONTENTS, ALLOC, LOAD, DATA >>>> 16 .jcr 00000008 0000000010019130 0000000010019130 = 00009130 2**3 >>>> CONTENTS, ALLOC, LOAD, DATA >>>> 17 .dynamic 000001c0 0000000010019138 0000000010019138 = 00009138 2**3 >>>> CONTENTS, ALLOC, LOAD, DATA >>>> 18 .opd 00000468 00000000100192f8 00000000100192f8 = 000092f8 2**3 >>>> CONTENTS, ALLOC, LOAD, DATA >>>> 19 .got 00000098 0000000010019800 0000000010019800 = 00009800 2**8 >>>> CONTENTS, ALLOC, LOAD, DATA >>>> 20 .plt 00000708 0000000010019898 0000000010019898 = 00009898 2**3 >>>> ALLOC >>>> 21 .data 00000050 0000000010019fa0 0000000010019fa0 = 00009fa0 2**3 >>>> CONTENTS, ALLOC, LOAD, DATA >>>> 22 .bss 00000208 0000000010019ff0 0000000010019ff0 = 00009ff0 2**3 >>>> ALLOC >>>> 23 .comment 000002b5 0000000000000000 0000000000000000 = 00009ff0 2**0 >>>> CONTENTS, READONLY >>>> 24 .gnu_debuglink 00000010 0000000000000000 0000000000000000 = 0000a2a8 2**2 >>>> CONTENTS, READONLY >>>>=20 >>>>=20 >>>=20 >>> The first PT_LOAD is also executable so there will be no be = behaviour >>> change. It must be one of the library dependencies that is = different. >>> The difference in section headers output doesn't matter here since = all >>> that RTLD looks at is the PHDRS. >>>=20 >>=20 >> I think you missed the fact that the .got and .plt are in the >> material from the 2nd PT_LOAD: there are writeable code areas >> involved for powerpc64. >>=20 >> So both PT_LOAD's contribute code areas and there is a space >> between the two contributions. The first PT_LOAD loads most >> code (the readonly code, to be specific). The 2nd contributes >> a writable-code area. >>=20 >> But may be i've misunderstood the assumptions that your change >> is based on. >=20 > Before my change the second PT would also not be included in > obj->textsize since we were setting obj->textsize as end of > PT_LOAD[0]. > After the change it will be end of last executable PT_LOAD (which will > usually be PT_LOAD[0] but could also include more now). > Since there is only one executable PT_LOAD which happens to be also be > PT_LOAD[0], there will be no change to obj->textsize. >=20 > The only time this commit could change anything is if there is a > PT_LOAD that is executable but is not PT_LOAD[0] or if PT_LOAD[0] is > not executable. > I think it must be the former case since as far as I know ld.bfd will > always create a read/execute segment as PT_LOAD[0] unless it is given > a custom linker script. I do not see any evidence that PF_X would match the tests for either of the following from the 2nd PT_LOAD: 19 .got 00000098 0000000010019800 0000000010019800 00009800 = 2**8 CONTENTS, ALLOC, LOAD, DATA 20 .plt 00000708 0000000010019898 0000000010019898 00009898 = 2**3 ALLOC in the likes of: 135 if ((segs[nsegs]->p_flags & PF_X) =3D=3D PF_X) { 136 text_end =3D MAX(text_end, 137 round_page(segs[nsegs]->p_vaddr + = segs[nsegs]->p_memsz)); 138 } in map_object.c This is possibly to avoid: 467 if (elfflags & PF_X) 468 prot |=3D PROT_EXEC; because of writable code. rtld.c also, for: 1397 nsegs++; 1398 if ((ph->p_flags & PF_X) =3D=3D PF_X) { 1399 obj->textsize =3D MAX(obj->textsize, 1400 round_page(ph->p_vaddr + ph->p_memsz) - = obj->vaddrbase); 1401 } Still, I may be missing something in my understanding. =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?2D7C5FC6-CA8D-4AAB-BD64-CC883531F737>