svn commit: r339876 - head/libexec/rtld-elf
Michael Tuexen
tuexen at freebsd.org
Wed Oct 31 15:08:11 UTC 2018
> On 31. Oct 2018, at 15:33, Mark Millard <marklmi at yahoo.com> wrote:
>
> On 2018-Oct-30, at 3:59 AM, Michael Tuexen <tuexen at freebsd.org> wrote:
>
>> FYI
>>
>>> Begin forwarded message:
>>>
>>> From: Michael Tuexen <Michael.Tuexen at macmic.franken.de>
>>> Subject: Re: svn commit: r339876 - head/libexec/rtld-elf
>>> Date: 30. October 2018 at 11:17:39 CET
>>> To: Alex Richardson <arichardson at FreeBSD.org>
>>> Cc: src-committers <src-committers at freebsd.org>, svn-src-all at freebsd.org, svn-src-head at freebsd.org
>>>
>>>> On 29. Oct 2018, at 22:08, Alex Richardson <arichardson at FreeBSD.org> wrote:
>>>>
>>>> Author: arichardson
>>>> Date: Mon Oct 29 21:08:02 2018
>>>> New Revision: 339876
>>>> URL: https://svnweb.freebsd.org/changeset/base/339876
>>>>
>>>> Log:
>>>> rtld: set obj->textsize correctly
>>>>
>>>> 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.
>>>>
>>>> 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.
>
> Which have you tried: 32 bit? 64 bit? Both? If both, do both fail?
Both. Only the 32-bit version shows the problem. Reverting this commit
and rebuilding /libexec/ld-elf.so.1 resolves the problem. So I can
confirm that this commit results in problems for 32-bit powerppc.
>
> What version did the buildworld buildkernel ? What version was
> built by the buildworld buildkernel (that was later installed
> and had failures)?
I was building r339914.
>
> Do you know what version did the prior buildworld buildkernel (that
> produced the version that did this buildworld buildkernel)? If yes,
> what was it?
No. Just reverting this commit resolves the issue.
>
>>> Buildword
>>> ends up with a world where almost all binaries are segfaulting.... Especially gdb
>>> (but svn, ls or so all segfault).
>
> Which fail:
>
> /usr/local/bin/gdb ? /usr/libexec/gdb ? Both?
> /usr/local/bin/svn ? /usr/bin/svnlite ? Both?
> /bin/ls ? /rescue/ls ? Both?
>
> That last may be the more important comparison.
Not the ones from /rescue. I used these tools to recover the system.
Failing binaries where /usr/local/bin/gdb, /usr/local/bin/svn.
You can reproduce the issue. Just update the sources and to make and make install
in head/libexec/rtld-elf
Best regards
Michael
>
>>>
>>> Best regards
>>> Michael
>>>>
>>>> Reviewed By: kib
>>>> Approved By: brooks (mentor)
>>>> Differential Revision: https://reviews.freebsd.org/D17117
>>>>
>>>> Modified:
>>>> head/libexec/rtld-elf/map_object.c
>>>> head/libexec/rtld-elf/rtld.c
>>>>
>>>> Modified: head/libexec/rtld-elf/map_object.c
>>>> ==============================================================================
>>>> --- head/libexec/rtld-elf/map_object.c Mon Oct 29 21:03:43 2018 (r339875)
>>>> +++ head/libexec/rtld-elf/map_object.c Mon Oct 29 21:08:02 2018 (r339876)
>>>> @@ -93,6 +93,7 @@ map_object(int fd, const char *path, const struct stat
>>>> Elf_Addr note_end;
>>>> char *note_map;
>>>> size_t note_map_len;
>>>> + Elf_Addr text_end;
>>>>
>>>> hdr = get_elf_header(fd, path, sb);
>>>> if (hdr == NULL)
>>>> @@ -116,6 +117,7 @@ map_object(int fd, const char *path, const struct stat
>>>> note_map = NULL;
>>>> segs = alloca(sizeof(segs[0]) * hdr->e_phnum);
>>>> stack_flags = RTLD_DEFAULT_STACK_PF_EXEC | PF_R | PF_W;
>>>> + text_end = 0;
>>>> while (phdr < phlimit) {
>>>> switch (phdr->p_type) {
>>>>
>>>> @@ -130,6 +132,10 @@ map_object(int fd, const char *path, const struct stat
>>>> path, nsegs);
>>>> goto error;
>>>> }
>>>> + if ((segs[nsegs]->p_flags & PF_X) == PF_X) {
>>>> + text_end = MAX(text_end,
>>>> + round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz));
>>>> + }
>>>> break;
>>>>
>>>> case PT_PHDR:
>>>> @@ -280,8 +286,7 @@ map_object(int fd, const char *path, const struct stat
>>>> }
>>>> obj->mapbase = mapbase;
>>>> obj->mapsize = mapsize;
>>>> - obj->textsize = round_page(segs[0]->p_vaddr + segs[0]->p_memsz) -
>>>> - base_vaddr;
>>>> + obj->textsize = text_end - base_vaddr;
>>>> obj->vaddrbase = base_vaddr;
>>>> obj->relocbase = mapbase - base_vaddr;
>>>> obj->dynamic = (const Elf_Dyn *) (obj->relocbase + phdyn->p_vaddr);
>>>>
>>>> Modified: head/libexec/rtld-elf/rtld.c
>>>> ==============================================================================
>>>> --- head/libexec/rtld-elf/rtld.c Mon Oct 29 21:03:43 2018 (r339875)
>>>> +++ head/libexec/rtld-elf/rtld.c Mon Oct 29 21:08:02 2018 (r339876)
>>>> @@ -1390,13 +1390,15 @@ digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t e
>>>> if (nsegs == 0) { /* First load segment */
>>>> obj->vaddrbase = trunc_page(ph->p_vaddr);
>>>> obj->mapbase = obj->vaddrbase + obj->relocbase;
>>>> - obj->textsize = round_page(ph->p_vaddr + ph->p_memsz) -
>>>> - obj->vaddrbase;
>>>> } else { /* Last load segment */
>>>> obj->mapsize = round_page(ph->p_vaddr + ph->p_memsz) -
>>>> obj->vaddrbase;
>>>> }
>>>> nsegs++;
>>>> + if ((ph->p_flags & PF_X) == PF_X) {
>>>> + obj->textsize = MAX(obj->textsize,
>>>> + round_page(ph->p_vaddr + ph->p_memsz) - obj->vaddrbase);
>>>> + }
>>>> break;
>>>>
>>>> case PT_DYNAMIC:
>>>>
>>>
>>>
>>
>
>
> ===
> Mark Millard
> marklmi at yahoo.com
> ( dsl-only.net went
> away in early 2018-Mar)
>
More information about the freebsd-ppc
mailing list