1*f70c5a09SBrooks Davis /*-
2*f70c5a09SBrooks Davis * SPDX-License-Identifier: BSD-2-Clause
3*f70c5a09SBrooks Davis *
4*f70c5a09SBrooks Davis * Copyright (c) 2009 Alan L. Cox <alc@cs.rice.edu>
5*f70c5a09SBrooks Davis * All rights reserved.
6*f70c5a09SBrooks Davis *
7*f70c5a09SBrooks Davis * Redistribution and use in source and binary forms, with or without
8*f70c5a09SBrooks Davis * modification, are permitted provided that the following conditions
9*f70c5a09SBrooks Davis * are met:
10*f70c5a09SBrooks Davis * 1. Redistributions of source code must retain the above copyright
11*f70c5a09SBrooks Davis * notice, this list of conditions and the following disclaimer.
12*f70c5a09SBrooks Davis * 2. Redistributions in binary form must reproduce the above copyright
13*f70c5a09SBrooks Davis * notice, this list of conditions and the following disclaimer in the
14*f70c5a09SBrooks Davis * documentation and/or other materials provided with the distribution.
15*f70c5a09SBrooks Davis *
16*f70c5a09SBrooks Davis * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*f70c5a09SBrooks Davis * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*f70c5a09SBrooks Davis * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*f70c5a09SBrooks Davis * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*f70c5a09SBrooks Davis * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*f70c5a09SBrooks Davis * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*f70c5a09SBrooks Davis * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*f70c5a09SBrooks Davis * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*f70c5a09SBrooks Davis * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*f70c5a09SBrooks Davis * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*f70c5a09SBrooks Davis * SUCH DAMAGE.
27*f70c5a09SBrooks Davis */
28*f70c5a09SBrooks Davis
29*f70c5a09SBrooks Davis #include <sys/param.h>
30*f70c5a09SBrooks Davis #include <sys/auxv.h>
31*f70c5a09SBrooks Davis #include <sys/errno.h>
32*f70c5a09SBrooks Davis
33*f70c5a09SBrooks Davis #include "libc_private.h"
34*f70c5a09SBrooks Davis
35*f70c5a09SBrooks Davis /*
36*f70c5a09SBrooks Davis * Retrieves page size information from the system. Specifically, returns the
37*f70c5a09SBrooks Davis * number of distinct page sizes that are supported by the system, if
38*f70c5a09SBrooks Davis * "pagesize" is NULL and "nelem" is 0. Otherwise, assigns up to "nelem" of
39*f70c5a09SBrooks Davis * the system-supported page sizes to consecutive elements of the array
40*f70c5a09SBrooks Davis * referenced by "pagesize", and returns the number of such page sizes that it
41*f70c5a09SBrooks Davis * assigned to the array. These page sizes are expressed in bytes.
42*f70c5a09SBrooks Davis *
43*f70c5a09SBrooks Davis * The implementation of this function does not directly or indirectly call
44*f70c5a09SBrooks Davis * malloc(3) or any other dynamic memory allocator that may itself call this
45*f70c5a09SBrooks Davis * function.
46*f70c5a09SBrooks Davis */
47*f70c5a09SBrooks Davis int
getpagesizes(size_t pagesize[],int nelem)48*f70c5a09SBrooks Davis getpagesizes(size_t pagesize[], int nelem)
49*f70c5a09SBrooks Davis {
50*f70c5a09SBrooks Davis static u_long ps[MAXPAGESIZES];
51*f70c5a09SBrooks Davis static int nops;
52*f70c5a09SBrooks Davis int i;
53*f70c5a09SBrooks Davis
54*f70c5a09SBrooks Davis if (nelem < 0 || (nelem > 0 && pagesize == NULL)) {
55*f70c5a09SBrooks Davis errno = EINVAL;
56*f70c5a09SBrooks Davis return (-1);
57*f70c5a09SBrooks Davis }
58*f70c5a09SBrooks Davis /* Cache the result */
59*f70c5a09SBrooks Davis if (nops == 0) {
60*f70c5a09SBrooks Davis if (_elf_aux_info(AT_PAGESIZES, ps, sizeof(ps)) != 0)
61*f70c5a09SBrooks Davis ps[0] = PAGE_SIZE;
62*f70c5a09SBrooks Davis /* Count the number of page sizes that are supported. */
63*f70c5a09SBrooks Davis nops = nitems(ps);
64*f70c5a09SBrooks Davis while (nops > 0 && ps[nops - 1] == 0)
65*f70c5a09SBrooks Davis nops--;
66*f70c5a09SBrooks Davis }
67*f70c5a09SBrooks Davis if (pagesize == NULL)
68*f70c5a09SBrooks Davis return (nops);
69*f70c5a09SBrooks Davis /* Return up to "nelem" page sizes from the cached result. */
70*f70c5a09SBrooks Davis if (nelem > nops)
71*f70c5a09SBrooks Davis nelem = nops;
72*f70c5a09SBrooks Davis for (i = 0; i < nelem; i++)
73*f70c5a09SBrooks Davis pagesize[i] = ps[i];
74*f70c5a09SBrooks Davis return (nelem);
75*f70c5a09SBrooks Davis }
76