From owner-svn-src-head@freebsd.org Mon Oct 29 21:08:04 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 D991A10EA197; Mon, 29 Oct 2018 21:08:03 +0000 (UTC) (envelope-from arichardson@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 8EEC983016; Mon, 29 Oct 2018 21:08:03 +0000 (UTC) (envelope-from arichardson@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 6B4AB13ADB; Mon, 29 Oct 2018 21:08:03 +0000 (UTC) (envelope-from arichardson@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w9TL83Gb041915; Mon, 29 Oct 2018 21:08:03 GMT (envelope-from arichardson@FreeBSD.org) Received: (from arichardson@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w9TL83bO041913; Mon, 29 Oct 2018 21:08:03 GMT (envelope-from arichardson@FreeBSD.org) Message-Id: <201810292108.w9TL83bO041913@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: arichardson set sender to arichardson@FreeBSD.org using -f From: Alex Richardson Date: Mon, 29 Oct 2018 21:08:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r339876 - head/libexec/rtld-elf X-SVN-Group: head X-SVN-Commit-Author: arichardson X-SVN-Commit-Paths: head/libexec/rtld-elf X-SVN-Commit-Revision: 339876 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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: Mon, 29 Oct 2018 21:08:04 -0000 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. 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: