svn commit: r334626 - in head: lib/libc/amd64 lib/libc/amd64/sys lib/libc/arm lib/libc/arm/sys lib/libc/i386 lib/libc/i386/sys lib/libc/mips lib/libc/mips/sys lib/libc/powerpc lib/libc/powerpc/sys ...

Ganbold Tsagaankhuu ganbold at gmail.com
Tue Jun 5 07:50:15 UTC 2018


On Tue, Jun 5, 2018 at 3:35 AM, Mark Johnston <markj at freebsd.org> wrote:

> Author: markj
> Date: Mon Jun  4 19:35:15 2018
> New Revision: 334626
> URL: https://svnweb.freebsd.org/changeset/base/334626
>
> Log:
>   Reimplement brk() and sbrk() to avoid the use of _end.
>
>   Previously, libc.so would initialize its notion of the break address
>   using _end, a special symbol emitted by the static linker following
>   the bss section.  Compatibility issues between lld and ld.bfd could
>   cause the wrong definition of _end (libc.so's definition rather than
>   that of the executable) to be used, breaking the brk()/sbrk()
>   interface.
>
>   Avoid this problem and future interoperability issues by simply not
>   relying on _end.  Instead, modify the break() system call to return
>   the kernel's view of the current break address, and have libc
>   initialize its state using an extra syscall upon the first use of the
>   interface.  As a side effect, this appears to fix brk()/sbrk() usage
>   in executables run with rtld direct exec, since the kernel and libc.so
>   no longer maintain separate views of the process' break address.
>


Maybe it is not really related, or I'm doing something wrong, but when I
try to run release.sh script on FreeBSD 11.0-RELEASE-p9 to build pine64
image, it stops with error:
...
/usr/obj/usr/src/arm64.aarch64/tmp/usr/bin/ld: error: undefined symbol: brk
>>> referenced by brk_test.c:52 (/usr/src/lib/libc/tests/sys/brk_test.c:52)
>>>               brk_test.o:(atfu_brk_basic_body)

/usr/obj/usr/src/arm64.aarch64/tmp/usr/bin/ld: error: undefined symbol: sbrk
>>> referenced by brk_test.c:55 (/usr/src/lib/libc/tests/sys/brk_test.c:55)
>>>               brk_test.o:(atfu_brk_basic_body)

/usr/obj/usr/src/arm64.aarch64/tmp/usr/bin/ld: error: undefined symbol: brk
>>> referenced by brk_test.c:59 (/usr/src/lib/libc/tests/sys/brk_test.c:59)
>>>               brk_test.o:(atfu_brk_basic_body)

/usr/obj/usr/src/arm64.aarch64/tmp/usr/bin/ld: error: undefined symbol: brk
>>> referenced by brk_test.c:65 (/usr/src/lib/libc/tests/sys/brk_test.c:65)
>>>               brk_test.o:(atfu_brk_basic_body)

/usr/obj/usr/src/arm64.aarch64/tmp/usr/bin/ld: error: undefined symbol: sbrk
>>> referenced by brk_test.c:67 (/usr/src/lib/libc/tests/sys/brk_test.c:67)
>>>               brk_test.o:(atfu_brk_basic_body)

/usr/obj/usr/src/arm64.aarch64/tmp/usr/bin/ld: error: undefined symbol: sbrk
>>> referenced by brk_test.c:82 (/usr/src/lib/libc/tests/sys/brk_test.c:82)
>>>               brk_test.o:(atfu_sbrk_basic_body)
...

Ganbold


>
>   PR:           228574
>   Reviewed by:  kib (previous version)
>   MFC after:    2 months
>   Differential Revision:        https://reviews.freebsd.org/D15663
>
> Added:
>   head/lib/libc/sys/brk.c   (contents, props changed)
>   head/lib/libc/tests/sys/brk_test.c   (contents, props changed)
> Deleted:
>   head/lib/libc/amd64/sys/brk.S
>   head/lib/libc/amd64/sys/sbrk.S
>   head/lib/libc/arm/sys/brk.S
>   head/lib/libc/arm/sys/sbrk.S
>   head/lib/libc/i386/sys/brk.S
>   head/lib/libc/i386/sys/sbrk.S
>   head/lib/libc/mips/sys/brk.S
>   head/lib/libc/mips/sys/sbrk.S
>   head/lib/libc/powerpc/sys/brk.S
>   head/lib/libc/powerpc/sys/sbrk.S
>   head/lib/libc/powerpc64/sys/brk.S
>   head/lib/libc/powerpc64/sys/sbrk.S
>   head/lib/libc/sparc64/sys/brk.S
>   head/lib/libc/sparc64/sys/sbrk.S
> Modified:
>   head/lib/libc/amd64/Symbol.map
>   head/lib/libc/amd64/sys/Makefile.inc
>   head/lib/libc/arm/Symbol.map
>   head/lib/libc/arm/sys/Makefile.inc
>   head/lib/libc/i386/Symbol.map
>   head/lib/libc/i386/sys/Makefile.inc
>   head/lib/libc/mips/Symbol.map
>   head/lib/libc/mips/sys/Makefile.inc
>   head/lib/libc/powerpc/Symbol.map
>   head/lib/libc/powerpc/sys/Makefile.inc
>   head/lib/libc/powerpc64/Symbol.map
>   head/lib/libc/powerpc64/sys/Makefile.inc
>   head/lib/libc/riscv/sys/Makefile.inc
>   head/lib/libc/sparc64/Symbol.map
>   head/lib/libc/sparc64/sys/Makefile.inc
>   head/lib/libc/sys/Makefile.inc
>   head/lib/libc/sys/brk.2
>   head/lib/libc/tests/sys/Makefile
>   head/sys/compat/freebsd32/syscalls.master
>   head/sys/kern/syscalls.master
>   head/sys/vm/vm_unix.c
>
> Modified: head/lib/libc/amd64/Symbol.map
> ============================================================
> ==================
> --- head/lib/libc/amd64/Symbol.map      Mon Jun  4 18:51:06 2018
> (r334625)
> +++ head/lib/libc/amd64/Symbol.map      Mon Jun  4 19:35:15 2018
> (r334626)
> @@ -63,7 +63,6 @@ FBSDprivate_1.0 {
>         signalcontext;
>         __siglongjmp;
>         _brk;
> -       _end;
>         __sys_vfork;
>         _vfork;
>  };
>
> Modified: head/lib/libc/amd64/sys/Makefile.inc
> ============================================================
> ==================
> --- head/lib/libc/amd64/sys/Makefile.inc        Mon Jun  4 18:51:06 2018
>       (r334625)
> +++ head/lib/libc/amd64/sys/Makefile.inc        Mon Jun  4 19:35:15 2018
>       (r334626)
> @@ -8,7 +8,7 @@ SRCS+=  \
>         amd64_set_fsbase.c \
>         amd64_set_gsbase.c
>
> -MDASM= vfork.S brk.S cerror.S getcontext.S sbrk.S
> +MDASM= vfork.S cerror.S getcontext.S
>
>  # Don't generate default code for these syscalls:
> -NOASM+=        vfork.o
> +NOASM+=        sbrk.o vfork.o
>
> Modified: head/lib/libc/arm/Symbol.map
> ============================================================
> ==================
> --- head/lib/libc/arm/Symbol.map        Mon Jun  4 18:51:06 2018
> (r334625)
> +++ head/lib/libc/arm/Symbol.map        Mon Jun  4 19:35:15 2018
> (r334626)
> @@ -58,7 +58,6 @@ FBSDprivate_1.0 {
>         __sys_vfork;
>         _vfork;
>         _brk;
> -       _end;
>         _sbrk;
>
>         _libc_arm_fpu_present;
>
> Modified: head/lib/libc/arm/sys/Makefile.inc
> ============================================================
> ==================
> --- head/lib/libc/arm/sys/Makefile.inc  Mon Jun  4 18:51:06 2018
> (r334625)
> +++ head/lib/libc/arm/sys/Makefile.inc  Mon Jun  4 19:35:15 2018
> (r334626)
> @@ -2,7 +2,7 @@
>
>  SRCS+= __vdso_gettc.c
>
> -MDASM= Ovfork.S brk.S cerror.S sbrk.S syscall.S
> +MDASM= Ovfork.S cerror.S syscall.S
>
>  # Don't generate default code for these syscalls:
> -NOASM+=        vfork.o
> +NOASM+=        sbrk.o vfork.o
>
> Modified: head/lib/libc/i386/Symbol.map
> ============================================================
> ==================
> --- head/lib/libc/i386/Symbol.map       Mon Jun  4 18:51:06 2018
> (r334625)
> +++ head/lib/libc/i386/Symbol.map       Mon Jun  4 19:35:15 2018
> (r334626)
> @@ -61,6 +61,5 @@ FBSDprivate_1.0 {
>         __siglongjmp;
>         __sys_vfork;
>         _vfork;
> -       _end;
>         _brk;
>  };
>
> Modified: head/lib/libc/i386/sys/Makefile.inc
> ============================================================
> ==================
> --- head/lib/libc/i386/sys/Makefile.inc Mon Jun  4 18:51:06 2018
> (r334625)
> +++ head/lib/libc/i386/sys/Makefile.inc Mon Jun  4 19:35:15 2018
> (r334626)
> @@ -7,9 +7,9 @@ SRCS+=  i386_clr_watch.c i386_set_watch.c i386_vm86.c
>  SRCS+= i386_get_fsbase.c i386_get_gsbase.c i386_get_ioperm.c
> i386_get_ldt.c \
>         i386_set_fsbase.c i386_set_gsbase.c i386_set_ioperm.c
> i386_set_ldt.c
>
> -MDASM= Ovfork.S brk.S cerror.S getcontext.S sbrk.S syscall.S
> +MDASM= Ovfork.S cerror.S getcontext.S syscall.S
>
> -NOASM+=        vfork.o
> +NOASM+=        sbrk.o vfork.o
>
>  MAN+=  i386_get_ioperm.2 i386_get_ldt.2 i386_vm86.2
>  MAN+=  i386_set_watch.3
>
> Modified: head/lib/libc/mips/Symbol.map
> ============================================================
> ==================
> --- head/lib/libc/mips/Symbol.map       Mon Jun  4 18:51:06 2018
> (r334625)
> +++ head/lib/libc/mips/Symbol.map       Mon Jun  4 19:35:15 2018
> (r334626)
> @@ -50,7 +50,6 @@ FBSDprivate_1.0 {
>         __siglongjmp;
>         __sys_vfork;
>         _vfork;
> -       _end;
>         _brk;
>         _sbrk;
>  };
>
> Modified: head/lib/libc/mips/sys/Makefile.inc
> ============================================================
> ==================
> --- head/lib/libc/mips/sys/Makefile.inc Mon Jun  4 18:51:06 2018
> (r334625)
> +++ head/lib/libc/mips/sys/Makefile.inc Mon Jun  4 19:35:15 2018
> (r334626)
> @@ -2,7 +2,7 @@
>
>  SRCS+= trivial-vdso_tc.c
>
> -MDASM=  Ovfork.S brk.S cerror.S sbrk.S syscall.S
> +MDASM=  Ovfork.S cerror.S syscall.S
>
>  # Don't generate default code for these syscalls:
> -NOASM+=        vfork.o
> +NOASM+=        sbrk.o vfork.o
>
> Modified: head/lib/libc/powerpc/Symbol.map
> ============================================================
> ==================
> --- head/lib/libc/powerpc/Symbol.map    Mon Jun  4 18:51:06 2018
> (r334625)
> +++ head/lib/libc/powerpc/Symbol.map    Mon Jun  4 19:35:15 2018
> (r334626)
> @@ -54,5 +54,4 @@ FBSDprivate_1.0 {
>         signalcontext;
>         __signalcontext;
>         __syncicache;
> -       _end;
>  };
>
> Modified: head/lib/libc/powerpc/sys/Makefile.inc
> ============================================================
> ==================
> --- head/lib/libc/powerpc/sys/Makefile.inc      Mon Jun  4 18:51:06 2018
>       (r334625)
> +++ head/lib/libc/powerpc/sys/Makefile.inc      Mon Jun  4 19:35:15 2018
>       (r334626)
> @@ -1,3 +1,3 @@
>  # $FreeBSD$
>
> -MDASM+=        brk.S cerror.S sbrk.S
> +MDASM+=        cerror.S
>
> Modified: head/lib/libc/powerpc64/Symbol.map
> ============================================================
> ==================
> --- head/lib/libc/powerpc64/Symbol.map  Mon Jun  4 18:51:06 2018
> (r334625)
> +++ head/lib/libc/powerpc64/Symbol.map  Mon Jun  4 19:35:15 2018
> (r334626)
> @@ -50,5 +50,4 @@ FBSDprivate_1.0 {
>         signalcontext;
>         __signalcontext;
>         __syncicache;
> -       _end;
>  };
>
> Modified: head/lib/libc/powerpc64/sys/Makefile.inc
> ============================================================
> ==================
> --- head/lib/libc/powerpc64/sys/Makefile.inc    Mon Jun  4 18:51:06 2018
>       (r334625)
> +++ head/lib/libc/powerpc64/sys/Makefile.inc    Mon Jun  4 19:35:15 2018
>       (r334626)
> @@ -1,3 +1,3 @@
>  # $FreeBSD$
>
> -MDASM+=        brk.S cerror.S sbrk.S
> +MDASM+=        cerror.S
>
> Modified: head/lib/libc/riscv/sys/Makefile.inc
> ============================================================
> ==================
> --- head/lib/libc/riscv/sys/Makefile.inc        Mon Jun  4 18:51:06 2018
>       (r334625)
> +++ head/lib/libc/riscv/sys/Makefile.inc        Mon Jun  4 19:35:15 2018
>       (r334626)
> @@ -7,4 +7,4 @@ MDASM=  cerror.S \
>         vfork.S
>
>  # Don't generate default code for these syscalls:
> -NOASM+=        vfork.o
> +NOASM+=        sbrk.o vfork.o
>
> Modified: head/lib/libc/sparc64/Symbol.map
> ============================================================
> ==================
> --- head/lib/libc/sparc64/Symbol.map    Mon Jun  4 18:51:06 2018
> (r334625)
> +++ head/lib/libc/sparc64/Symbol.map    Mon Jun  4 19:35:15 2018
> (r334626)
> @@ -81,7 +81,6 @@ FBSDprivate_1.0 {
>         __siglongjmp;
>         __sys_brk;
>         _brk;
> -       _end;
>         __sys_sbrk;
>         _sbrk;
>         __sys_vfork;
>
> Modified: head/lib/libc/sparc64/sys/Makefile.inc
> ============================================================
> ==================
> --- head/lib/libc/sparc64/sys/Makefile.inc      Mon Jun  4 18:51:06 2018
>       (r334625)
> +++ head/lib/libc/sparc64/sys/Makefile.inc      Mon Jun  4 19:35:15 2018
>       (r334626)
> @@ -12,4 +12,4 @@ SRCS+=        __sparc_sigtramp_setup.c \
>
>  CFLAGS+= -I${LIBC_SRCTOP}/sparc64/fpu
>
> -MDASM+=        brk.S cerror.S sbrk.S sigaction1.S
> +MDASM+=        cerror.S sigaction1.S
>
> Modified: head/lib/libc/sys/Makefile.inc
> ============================================================
> ==================
> --- head/lib/libc/sys/Makefile.inc      Mon Jun  4 18:51:06 2018
> (r334625)
> +++ head/lib/libc/sys/Makefile.inc      Mon Jun  4 19:35:15 2018
> (r334626)
> @@ -17,8 +17,7 @@
>  # While historically machine dependent, all architectures have the
> following
>  # declarations in common:
>  #
> -NOASM= break.o \
> -       exit.o \
> +NOASM= exit.o \
>         getlogin.o \
>         sstk.o \
>         yield.o
> @@ -45,6 +44,7 @@ SRCS+= getdirentries.c
>  NOASM+= getdirentries.o
>  PSEUDO+= _getdirentries.o
>
> +SRCS+= brk.c
>  SRCS+= pipe.c
>  SRCS+= vadvise.c
>
>
> Modified: head/lib/libc/sys/brk.2
> ============================================================
> ==================
> --- head/lib/libc/sys/brk.2     Mon Jun  4 18:51:06 2018        (r334625)
> +++ head/lib/libc/sys/brk.2     Mon Jun  4 19:35:15 2018        (r334626)
> @@ -28,7 +28,7 @@
>  .\"     @(#)brk.2      8.4 (Berkeley) 5/1/95
>  .\" $FreeBSD$
>  .\"
> -.Dd May 24, 2018
> +.Dd June 2, 2018
>  .Dt BRK 2
>  .Os
>  .Sh NAME
> @@ -183,3 +183,8 @@ is sometimes used to monitor heap use by calling with
>  The result is unlikely to reflect actual utilization in combination with
> an
>  .Xr mmap 2
>  based malloc.
> +.Pp
> +.Fn brk
> +and
> +.Fn sbrk
> +are not thread-safe.
>
> Added: head/lib/libc/sys/brk.c
> ============================================================
> ==================
> --- /dev/null   00:00:00 1970   (empty, because file is newly added)
> +++ head/lib/libc/sys/brk.c     Mon Jun  4 19:35:15 2018        (r334626)
> @@ -0,0 +1,107 @@
> +/*-
> + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
> + *
> + * Copyright (c) 2018 Mark Johnston <markj at FreeBSD.org>
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
> STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
> WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + */
> +
> +#include <sys/cdefs.h>
> +__FBSDID("$FreeBSD$");
> +
> +#include <sys/types.h>
> +#include <sys/syscall.h>
> +#include <errno.h>
> +#include <stdint.h>
> +#include <stdlib.h>
> +
> +void *__sys_break(char *nsize);
> +
> +static uintptr_t curbrk, minbrk;
> +static int curbrk_initted;
> +
> +static int
> +initbrk(void)
> +{
> +       void *newbrk;
> +
> +       if (!curbrk_initted) {
> +               newbrk = __sys_break(NULL);
> +               if (newbrk == (void *)-1)
> +                       return (-1);
> +               curbrk = minbrk = (uintptr_t)newbrk;
> +               curbrk_initted = 1;
> +       }
> +       return (0);
> +}
> +
> +static void *
> +mvbrk(void *addr)
> +{
> +       uintptr_t oldbrk;
> +
> +       if ((uintptr_t)addr < minbrk) {
> +               /* Emulate legacy error handling in the syscall. */
> +               errno = EINVAL;
> +               return ((void *)-1);
> +       }
> +       if (__sys_break(addr) == (void *)-1)
> +               return ((void *)-1);
> +       oldbrk = curbrk;
> +       curbrk = (uintptr_t)addr;
> +       return ((void *)oldbrk);
> +}
> +
> +int
> +brk(const void *addr)
> +{
> +
> +       if (initbrk() == -1)
> +               return (-1);
> +       if ((uintptr_t)addr < minbrk)
> +               addr = (void *)minbrk;
> +       return (mvbrk(__DECONST(void *, addr)) == (void *)-1 ? -1 : 0);
> +}
> +
> +int
> +_brk(const void *addr)
> +{
> +
> +       if (initbrk() == -1)
> +               return (-1);
> +       return (mvbrk(__DECONST(void *, addr)) == (void *)-1 ? -1 : 0);
> +}
> +
> +void *
> +sbrk(intptr_t incr)
> +{
> +
> +       if (initbrk() == -1)
> +               return ((void *)-1);
> +       if ((incr > 0 && curbrk + incr < curbrk) ||
> +           (incr < 0 && curbrk + incr > curbrk)) {
> +               /* Emulate legacy error handling in the syscall. */
> +               errno = EINVAL;
> +               return ((void *)-1);
> +       }
> +       return (mvbrk((void *)(curbrk + incr)));
> +}
>
> Modified: head/lib/libc/tests/sys/Makefile
> ============================================================
> ==================
> --- head/lib/libc/tests/sys/Makefile    Mon Jun  4 18:51:06 2018
> (r334625)
> +++ head/lib/libc/tests/sys/Makefile    Mon Jun  4 19:35:15 2018
> (r334626)
> @@ -4,6 +4,7 @@ PACKAGE=                        tests
>
>  .include <bsd.own.mk>
>
> +ATF_TESTS_C+=                  brk_test
>  ATF_TESTS_C+=                  queue_test
>
>  # TODO: clone, lwp_create, lwp_ctl, posix_fadvise, recvmmsg,
>
> Added: head/lib/libc/tests/sys/brk_test.c
> ============================================================
> ==================
> --- /dev/null   00:00:00 1970   (empty, because file is newly added)
> +++ head/lib/libc/tests/sys/brk_test.c  Mon Jun  4 19:35:15 2018
> (r334626)
> @@ -0,0 +1,149 @@
> +/*-
> + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
> + *
> + * Copyright (c) 2018 Mark Johnston <markj at FreeBSD.org>
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
> STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
> WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + */
> +
> +#include <sys/cdefs.h>
> +__FBSDID("$FreeBSD$");
> +
> +#include <sys/param.h>
> +#include <sys/mman.h>
> +
> +#include <errno.h>
> +#include <stdint.h>
> +#include <string.h>
> +#include <unistd.h>
> +
> +#include <atf-c.h>
> +
> +ATF_TC(brk_basic);
> +ATF_TC_HEAD(brk_basic, tc)
> +{
> +       atf_tc_set_md_var(tc, "descr", "Verify basic brk() functionality");
> +}
> +ATF_TC_BODY(brk_basic, tc)
> +{
> +       void *oldbrk, *newbrk;
> +       int error;
> +
> +       /* Reset the break. */
> +       error = brk(0);
> +       ATF_REQUIRE_MSG(error == 0, "brk: %s", strerror(errno));
> +
> +       oldbrk = sbrk(0);
> +       ATF_REQUIRE(oldbrk != (void *)-1);
> +
> +       /* Try to allocate a page. */
> +       error = brk((void *)((intptr_t)oldbrk + PAGE_SIZE * 2));
> +       ATF_REQUIRE_MSG(error == 0, "brk: %s", strerror(errno));
> +
> +       /*
> +        * Attempt to set the break below minbrk.  This should have no
> effect.
> +        */
> +       error = brk((void *)((intptr_t)oldbrk - 1));
> +       ATF_REQUIRE_MSG(error == 0, "brk: %s", strerror(errno));
> +       newbrk = sbrk(0);
> +       ATF_REQUIRE_MSG(newbrk != (void *)-1, "sbrk: %s", strerror(errno));
> +       ATF_REQUIRE(newbrk == oldbrk);
> +}
> +
> +ATF_TC(sbrk_basic);
> +ATF_TC_HEAD(sbrk_basic, tc)
> +{
> +       atf_tc_set_md_var(tc, "descr", "Verify basic sbrk()
> functionality");
> +}
> +ATF_TC_BODY(sbrk_basic, tc)
> +{
> +       void *newbrk, *oldbrk;
> +       int *p;
> +
> +       oldbrk = sbrk(0);
> +       ATF_REQUIRE_MSG(oldbrk != (void *)-1, "sbrk: %s", strerror(errno));
> +       p = sbrk(sizeof(*p));
> +       *p = 0;
> +       ATF_REQUIRE(oldbrk == p);
> +
> +       newbrk = sbrk(-sizeof(*p));
> +       ATF_REQUIRE_MSG(newbrk != (void *)-1, "sbrk: %s", strerror(errno));
> +       ATF_REQUIRE(oldbrk == sbrk(0));
> +
> +       oldbrk = sbrk(PAGE_SIZE * 2 + 1);
> +       ATF_REQUIRE_MSG(oldbrk != (void *)-1, "sbrk: %s", strerror(errno));
> +       memset(oldbrk, 0, PAGE_SIZE * 2 + 1);
> +       newbrk = sbrk(-(PAGE_SIZE * 2 + 1));
> +       ATF_REQUIRE_MSG(newbrk != (void *)-1, "sbrk: %s", strerror(errno));
> +       ATF_REQUIRE(sbrk(0) == oldbrk);
> +}
> +
> +ATF_TC(mlockfuture);
> +ATF_TC_HEAD(mlockfuture, tc)
> +{
> +       atf_tc_set_md_var(tc, "descr",
> +           "Verify that mlockall(MCL_FUTURE) applies to the data
> segment");
> +}
> +ATF_TC_BODY(mlockfuture, tc)
> +{
> +       void *oldbrk, *n, *newbrk;
> +       int error;
> +       char v;
> +
> +       error = mlockall(MCL_FUTURE);
> +       ATF_REQUIRE_MSG(error == 0,
> +           "mlockall: %s", strerror(errno));
> +
> +       /*
> +        * Advance the break so that at least one page is added to the data
> +        * segment.  This page should be automatically faulted in to the
> address
> +        * space.
> +        */
> +       oldbrk = sbrk(0);
> +       ATF_REQUIRE(oldbrk != (void *)-1);
> +       newbrk = sbrk(PAGE_SIZE * 2);
> +       ATF_REQUIRE(newbrk != (void *)-1);
> +
> +       n = (void *)(((uintptr_t)oldbrk + PAGE_SIZE) & ~PAGE_SIZE);
> +       v = 0;
> +       error = mincore(n, PAGE_SIZE, &v);
> +       ATF_REQUIRE_MSG(error == 0,
> +           "mincore: %s", strerror(errno));
> +       ATF_REQUIRE_MSG((v & MINCORE_INCORE) != 0,
> +           "unexpected page flags %#x", v);
> +
> +       error = brk(oldbrk);
> +       ATF_REQUIRE(error == 0);
> +
> +       error = munlockall();
> +       ATF_REQUIRE_MSG(error == 0,
> +           "munlockall: %s", strerror(errno));
> +}
> +
> +ATF_TP_ADD_TCS(tp)
> +{
> +       ATF_TP_ADD_TC(tp, brk_basic);
> +       ATF_TP_ADD_TC(tp, sbrk_basic);
> +       ATF_TP_ADD_TC(tp, mlockfuture);
> +
> +       return (atf_no_error());
> +}
>
> Modified: head/sys/compat/freebsd32/syscalls.master
> ============================================================
> ==================
> --- head/sys/compat/freebsd32/syscalls.master   Mon Jun  4 18:51:06 2018
>       (r334625)
> +++ head/sys/compat/freebsd32/syscalls.master   Mon Jun  4 19:35:15 2018
>       (r334626)
> @@ -87,7 +87,7 @@
>                                         int mode, int dev); }
>  15     AUE_CHMOD       NOPROTO { int chmod(char *path, int mode); }
>  16     AUE_CHOWN       NOPROTO { int chown(char *path, int uid, int gid);
> }
> -17     AUE_NULL        NOPROTO { int obreak(char *nsize); } break \
> +17     AUE_NULL        NOPROTO { caddr_t obreak(char *nsize); } break \
>                                     obreak_args int
>  18     AUE_GETFSSTAT   COMPAT4 { int freebsd32_getfsstat( \
>                                     struct statfs32 *buf, long bufsize, \
>
> Modified: head/sys/kern/syscalls.master
> ============================================================
> ==================
> --- head/sys/kern/syscalls.master       Mon Jun  4 18:51:06 2018
> (r334625)
> +++ head/sys/kern/syscalls.master       Mon Jun  4 19:35:15 2018
> (r334626)
> @@ -118,7 +118,7 @@
>  15     AUE_CHMOD       STD     { int chmod(_In_z_ char *path, int mode); }
>  16     AUE_CHOWN       STD     { int chown(_In_z_ char *path, \
>                                     int uid, int gid); }
> -17     AUE_NULL        STD     { int obreak(_In_ char *nsize); } break \
> +17     AUE_NULL        STD     { caddr_t obreak(_In_ char *nsize); }
> break \
>                                     obreak_args int
>  18     AUE_GETFSSTAT   COMPAT4 { int getfsstat( \
>                                     _Out_writes_bytes_opt_(bufsize) \
>
> Modified: head/sys/vm/vm_unix.c
> ============================================================
> ==================
> --- head/sys/vm/vm_unix.c       Mon Jun  4 18:51:06 2018        (r334625)
> +++ head/sys/vm/vm_unix.c       Mon Jun  4 19:35:15 2018        (r334626)
> @@ -102,13 +102,16 @@ sys_obreak(struct thread *td, struct obreak_args
> *uap)
>                 }
>         } else if (new < base) {
>                 /*
> -                * This is simply an invalid value.  If someone wants to
> -                * do fancy address space manipulations, mmap and munmap
> -                * can do most of what the user would want.
> +                * Simply return the current break address without
> +                * modifying any state.  This is an ad-hoc interface
> +                * used by libc to determine the initial break address,
> +                * avoiding a dependency on magic features in the system
> +                * linker.
>                  */
> -               error = EINVAL;
> +               new = old;
>                 goto done;
>         }
> +
>         if (new > old) {
>                 if (!old_mlock && map->flags & MAP_WIREFUTURE) {
>                         if (ptoa(pmap_wired_count(map->pmap)) +
> @@ -224,6 +227,9 @@ done:
>         if (do_map_wirefuture)
>                 (void) vm_map_wire(map, old, new,
>                     VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES);
> +
> +       if (error == 0)
> +               td->td_retval[0] = new;
>
>         return (error);
>  #else /* defined(__aarch64__) || defined(__riscv__) */
>
>


More information about the svn-src-head mailing list