From owner-svn-src-stable@FreeBSD.ORG Sun Apr 12 06:43:15 2015 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id CD60BA2F; Sun, 12 Apr 2015 06:43:15 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (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 B78192EA; Sun, 12 Apr 2015 06:43:15 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t3C6hFf7004873; Sun, 12 Apr 2015 06:43:15 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t3C6hEcX004866; Sun, 12 Apr 2015 06:43:14 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201504120643.t3C6hEcX004866@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Sun, 12 Apr 2015 06:43:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r281452 - stable/10/libexec/rtld-elf X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 12 Apr 2015 06:43:15 -0000 Author: kib Date: Sun Apr 12 06:43:13 2015 New Revision: 281452 URL: https://svnweb.freebsd.org/changeset/base/281452 Log: MFC r264346 (by alc): Pass MAP_ALIGNED_SUPER to allocate the whole dso region if its text is large enough for the superpage mapping. Modified: stable/10/libexec/rtld-elf/malloc.c stable/10/libexec/rtld-elf/map_object.c stable/10/libexec/rtld-elf/rtld.c stable/10/libexec/rtld-elf/rtld.h Directory Properties: stable/10/ (props changed) Modified: stable/10/libexec/rtld-elf/malloc.c ============================================================================== --- stable/10/libexec/rtld-elf/malloc.c Sun Apr 12 06:21:58 2015 (r281451) +++ stable/10/libexec/rtld-elf/malloc.c Sun Apr 12 06:43:13 2015 (r281452) @@ -139,25 +139,14 @@ botch(s) /* Debugging stuff */ #define TRACE() rtld_printf("TRACE %s:%d\n", __FILE__, __LINE__) -extern int pagesize; - -static int -rtld_getpagesize(void) -{ - int mib[2]; - size_t size; - - if (pagesize != 0) - return (pagesize); - - mib[0] = CTL_HW; - mib[1] = HW_PAGESIZE; - size = sizeof(pagesize); - if (sysctl(mib, 2, &pagesize, &size, NULL, 0) == -1) - return (-1); - return (pagesize); - -} +/* + * The array of supported page sizes is provided by the user, i.e., the + * program that calls this storage allocator. That program must initialize + * the array before making its first call to allocate storage. The array + * must contain at least one page size. The page sizes must be stored in + * increasing order. + */ +extern size_t *pagesizes; void * malloc(nbytes) @@ -173,7 +162,7 @@ malloc(nbytes) * align break pointer so all data will be page aligned. */ if (pagesz == 0) { - pagesz = n = rtld_getpagesize(); + pagesz = n = pagesizes[0]; if (morepages(NPOOLPAGES) == 0) return NULL; op = (union overhead *)(pagepool_start); Modified: stable/10/libexec/rtld-elf/map_object.c ============================================================================== --- stable/10/libexec/rtld-elf/map_object.c Sun Apr 12 06:21:58 2015 (r281451) +++ stable/10/libexec/rtld-elf/map_object.c Sun Apr 12 06:43:13 2015 (r281452) @@ -68,6 +68,7 @@ map_object(int fd, const char *path, con Elf_Addr base_vaddr; Elf_Addr base_vlimit; caddr_t base_addr; + int base_flags; Elf_Off data_offset; Elf_Addr data_vaddr; Elf_Addr data_vlimit; @@ -176,9 +177,11 @@ map_object(int fd, const char *path, con base_vlimit = round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz); mapsize = base_vlimit - base_vaddr; base_addr = (caddr_t) base_vaddr; + base_flags = MAP_PRIVATE | MAP_ANON | MAP_NOCORE; + if (npagesizes > 1 && round_page(segs[0]->p_filesz) >= pagesizes[1]) + base_flags |= MAP_ALIGNED_SUPER; - mapbase = mmap(base_addr, mapsize, PROT_NONE, MAP_ANON | MAP_PRIVATE | - MAP_NOCORE, -1, 0); + mapbase = mmap(base_addr, mapsize, PROT_NONE, base_flags, -1, 0); if (mapbase == (caddr_t) -1) { _rtld_error("%s: mmap of entire address space failed: %s", path, rtld_strerror(errno)); Modified: stable/10/libexec/rtld-elf/rtld.c ============================================================================== --- stable/10/libexec/rtld-elf/rtld.c Sun Apr 12 06:21:58 2015 (r281451) +++ stable/10/libexec/rtld-elf/rtld.c Sun Apr 12 06:43:13 2015 (r281452) @@ -97,6 +97,7 @@ static void *fill_search_info(const char static char *find_library(const char *, const Obj_Entry *); static const char *gethints(bool); static void init_dag(Obj_Entry *); +static void init_pagesizes(Elf_Auxinfo **aux_info); static void init_rtld(caddr_t, Elf_Auxinfo **); static void initlist_add_neededs(Needed_Entry *, Objlist *); static void initlist_add_objects(Obj_Entry *, Obj_Entry **, Objlist *); @@ -206,7 +207,8 @@ extern Elf_Dyn _DYNAMIC; #define RTLD_IS_DYNAMIC() (&_DYNAMIC != NULL) #endif -int osreldate, pagesize; +int npagesizes, osreldate; +size_t *pagesizes; long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -1824,8 +1826,9 @@ init_rtld(caddr_t mapbase, Elf_Auxinfo * /* Now that non-local variables can be accesses, copy out obj_rtld. */ memcpy(&obj_rtld, &objtmp, sizeof(obj_rtld)); - if (aux_info[AT_PAGESZ] != NULL) - pagesize = aux_info[AT_PAGESZ]->a_un.a_val; + /* The page size is required by the dynamic memory allocator. */ + init_pagesizes(aux_info); + if (aux_info[AT_OSRELDATE] != NULL) osreldate = aux_info[AT_OSRELDATE]->a_un.a_val; @@ -1839,6 +1842,50 @@ init_rtld(caddr_t mapbase, Elf_Auxinfo * } /* + * Retrieve the array of supported page sizes. The kernel provides the page + * sizes in increasing order. + */ +static void +init_pagesizes(Elf_Auxinfo **aux_info) +{ + static size_t psa[MAXPAGESIZES]; + int mib[2]; + size_t len, size; + + if (aux_info[AT_PAGESIZES] != NULL && aux_info[AT_PAGESIZESLEN] != + NULL) { + size = aux_info[AT_PAGESIZESLEN]->a_un.a_val; + pagesizes = aux_info[AT_PAGESIZES]->a_un.a_ptr; + } else { + len = 2; + if (sysctlnametomib("hw.pagesizes", mib, &len) == 0) + size = sizeof(psa); + else { + /* As a fallback, retrieve the base page size. */ + size = sizeof(psa[0]); + if (aux_info[AT_PAGESZ] != NULL) { + psa[0] = aux_info[AT_PAGESZ]->a_un.a_val; + goto psa_filled; + } else { + mib[0] = CTL_HW; + mib[1] = HW_PAGESIZE; + len = 2; + } + } + if (sysctl(mib, len, psa, &size, NULL, 0) == -1) { + _rtld_error("sysctl for hw.pagesize(s) failed"); + die(); + } +psa_filled: + pagesizes = psa; + } + npagesizes = size / sizeof(pagesizes[0]); + /* Discard any invalid entries at the end of the array. */ + while (npagesizes > 0 && pagesizes[npagesizes - 1] == 0) + npagesizes--; +} + +/* * Add the init functions from a needed object list (and its recursive * needed objects) to "list". This is not used directly; it is a helper * function for initlist_add_objects(). The write lock must be held Modified: stable/10/libexec/rtld-elf/rtld.h ============================================================================== --- stable/10/libexec/rtld-elf/rtld.h Sun Apr 12 06:21:58 2015 (r281451) +++ stable/10/libexec/rtld-elf/rtld.h Sun Apr 12 06:43:13 2015 (r281452) @@ -71,6 +71,9 @@ extern size_t tls_static_space; extern int tls_dtv_generation; extern int tls_max_index; +extern int npagesizes; +extern size_t *pagesizes; + extern int main_argc; extern char **main_argv; extern char **environ;