diff options
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/aarch64/Symbol.map | 4 | ||||
-rw-r--r-- | lib/libc/aarch64/gen/Makefile.inc | 2 | ||||
-rw-r--r-- | lib/libc/aarch64/gen/_setjmp.S | 2 | ||||
-rw-r--r-- | lib/libc/aarch64/gen/fpgetmask.c | 47 | ||||
-rw-r--r-- | lib/libc/aarch64/gen/fpsetmask.c | 52 | ||||
-rw-r--r-- | lib/libc/aarch64/gen/setjmp.S | 2 | ||||
-rw-r--r-- | lib/libc/aarch64/gen/sigsetjmp.S | 2 | ||||
-rw-r--r-- | lib/libc/aarch64/sys/brk.S | 29 | ||||
-rw-r--r-- | lib/libc/aarch64/sys/sbrk.S | 19 | ||||
-rw-r--r-- | lib/libc/stdio/Symbol.map | 4 | ||||
-rw-r--r-- | lib/libc/stdio/fclose.3 | 82 | ||||
-rw-r--r-- | lib/libc/stdio/fclose.c | 75 | ||||
-rw-r--r-- | lib/libc/sys/ptrace.2 | 191 |
13 files changed, 443 insertions, 68 deletions
diff --git a/lib/libc/aarch64/Symbol.map b/lib/libc/aarch64/Symbol.map index a0b33da..3d8ad25 100644 --- a/lib/libc/aarch64/Symbol.map +++ b/lib/libc/aarch64/Symbol.map @@ -14,6 +14,9 @@ FBSD_1.0 { _setjmp; _longjmp; fabs; + __flt_rounds; + fpgetmask; + fpsetmask; setjmp; longjmp; sigsetjmp; @@ -25,6 +28,7 @@ FBSD_1.0 { FBSDprivate_1.0 { _set_tp; + _end; curbrk; minbrk; }; diff --git a/lib/libc/aarch64/gen/Makefile.inc b/lib/libc/aarch64/gen/Makefile.inc index c4f7c80..bb70a36 100644 --- a/lib/libc/aarch64/gen/Makefile.inc +++ b/lib/libc/aarch64/gen/Makefile.inc @@ -2,6 +2,8 @@ SRCS+= fabs.S \ flt_rounds.c \ + fpgetmask.c \ + fpsetmask.c \ ldexp.c \ _setjmp.S \ _set_tp.c \ diff --git a/lib/libc/aarch64/gen/_setjmp.S b/lib/libc/aarch64/gen/_setjmp.S index 504423b..ae00195 100644 --- a/lib/libc/aarch64/gen/_setjmp.S +++ b/lib/libc/aarch64/gen/_setjmp.S @@ -59,8 +59,8 @@ ENTRY(_setjmp) /* Return value */ mov x0, #0 ret -.Lmagic: .align 3 +.Lmagic: .quad _JB_MAGIC__SETJMP END(_setjmp) diff --git a/lib/libc/aarch64/gen/fpgetmask.c b/lib/libc/aarch64/gen/fpgetmask.c new file mode 100644 index 0000000..afc05b4 --- /dev/null +++ b/lib/libc/aarch64/gen/fpgetmask.c @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2015 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Andrew Turner under + * sponsorship from the FreeBSD Foundation. + * + * 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 <ieeefp.h> + +#define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) + +fp_except_t +fpgetmask(void) +{ + uint64_t mask; + + /* Read the current mask */ + __asm __volatile("mrs %0, fpcr" : "=&r"(mask)); + + return (mask & FP_X_MASK); +} diff --git a/lib/libc/aarch64/gen/fpsetmask.c b/lib/libc/aarch64/gen/fpsetmask.c new file mode 100644 index 0000000..de9ac04 --- /dev/null +++ b/lib/libc/aarch64/gen/fpsetmask.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2015 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Andrew Turner under + * sponsorship from the FreeBSD Foundation. + * + * 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 <ieeefp.h> + +#define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) + +fp_except_t +fpsetmask(fp_except_t mask) +{ + uint64_t old, new; + + mask &= FP_X_MASK; + + /* Read the current mask */ + __asm __volatile("mrs %0, fpcr" : "=&r"(old)); + new = old & ~FP_X_MASK; + new |= mask; + __asm __volatile("msr fpcr, %0" :: "r"(new)); + + return ((fp_except_t)old); +} diff --git a/lib/libc/aarch64/gen/setjmp.S b/lib/libc/aarch64/gen/setjmp.S index 790ed73..a30ed6a 100644 --- a/lib/libc/aarch64/gen/setjmp.S +++ b/lib/libc/aarch64/gen/setjmp.S @@ -69,8 +69,8 @@ ENTRY(setjmp) /* Return value */ mov x0, #0 ret -.Lmagic: .align 3 +.Lmagic: .quad _JB_MAGIC_SETJMP END(setjmp) diff --git a/lib/libc/aarch64/gen/sigsetjmp.S b/lib/libc/aarch64/gen/sigsetjmp.S index 8a13c9f..be49f53 100644 --- a/lib/libc/aarch64/gen/sigsetjmp.S +++ b/lib/libc/aarch64/gen/sigsetjmp.S @@ -47,7 +47,7 @@ ENTRY(siglongjmp) cmp x2, x3 b.eq _C_LABEL(_longjmp) b _C_LABEL(longjmp) -.Lmagic: .align 3 +.Lmagic: .quad _JB_MAGIC__SETJMP END(siglongjmp) diff --git a/lib/libc/aarch64/sys/brk.S b/lib/libc/aarch64/sys/brk.S index 09167b6..1e9a215 100644 --- a/lib/libc/aarch64/sys/brk.S +++ b/lib/libc/aarch64/sys/brk.S @@ -32,6 +32,8 @@ __FBSDID("$FreeBSD$"); #include "SYS.h" + .globl _C_LABEL(_end) + .data .align 3 .globl _C_LABEL(minbrk) @@ -47,15 +49,8 @@ ENTRY(_brk) WEAK_REFERENCE(_brk, brk) /* Load the address of minbrk */ -#ifdef __PIC__ - adrp x2, :got:minbrk - ldr x3, [x2, #:got_lo12:minbrk] -#else - ldr x3, .Lminbrk -#endif - - /* Get the minimum allowable brk address */ - ldr x2, [x3] + adrp x3, minbrk + ldr x2, [x3, :lo12:minbrk] /* Validate the address */ cmp x0, x2 @@ -70,24 +65,12 @@ ENTRY(_brk) _SYSCALL(break) b.cs cerror -#ifdef __PIC__ - adrp x2, :got:curbrk - ldr x3, [x2, #:got_lo12:curbrk] -#else - ldr x3, .Lcurbrk -#endif - /* Store the new curbrk value */ - str x4, [x3] + adrp x2, curbrk + str x4, [x2, :lo12:curbrk] /* Return success */ mov x0, #0 ret -#ifndef __PIC__ -.Lcurbrk: - .quad _C_LABEL(curbrk) -.Lminbrk: - .quad _C_LABEL(minbrk) -#endif END(_brk) diff --git a/lib/libc/aarch64/sys/sbrk.S b/lib/libc/aarch64/sys/sbrk.S index db9d7e1..4880cc2 100644 --- a/lib/libc/aarch64/sys/sbrk.S +++ b/lib/libc/aarch64/sys/sbrk.S @@ -32,6 +32,8 @@ __FBSDID("$FreeBSD$"); #include "SYS.h" + .globl _C_LABEL(_end) + .data .align 3 .global _C_LABEL(curbrk) @@ -47,15 +49,10 @@ ENTRY(_sbrk) WEAK_REFERENCE(_sbrk, sbrk) /* Load the address of curbrk */ -#ifdef __PIC__ - adrp x2, :got:curbrk - ldr x3, [x2, #:got_lo12:curbrk] -#else - ldr x3, .Lcurbrk -#endif + adrp x3, curbrk /* Get the current brk address */ - ldr x2, [x3] + ldr x2, [x3, :lo12:curbrk] /* Calculate the new value */ add x0, x2, x0 @@ -66,14 +63,10 @@ ENTRY(_sbrk) b.cs cerror /* Load the old value to return */ - ldr x0, [x3] + ldr x0, [x3, :lo12:curbrk] /* Store the new curbrk value */ - str x4, [x3] + str x4, [x3, :lo12:curbrk] ret -#ifndef __PIC__ -.Lcurbrk: - .quad _C_LABEL(curbrk) -#endif END(_sbrk) diff --git a/lib/libc/stdio/Symbol.map b/lib/libc/stdio/Symbol.map index d2a8c92..a332ab2 100644 --- a/lib/libc/stdio/Symbol.map +++ b/lib/libc/stdio/Symbol.map @@ -162,6 +162,10 @@ FBSD_1.3 { mkostemps; }; +FBSD_1.4 { + fdclose; +}; + FBSDprivate_1.0 { _flockfile; _flockfile_debug_stub; diff --git a/lib/libc/stdio/fclose.3 b/lib/libc/stdio/fclose.3 index 883aa10..596ee3d 100644 --- a/lib/libc/stdio/fclose.3 +++ b/lib/libc/stdio/fclose.3 @@ -1,5 +1,6 @@ -.\" Copyright (c) 1990, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. +.\" Copyright (c) 1990, 1991, 1993 The Regents of the University of California. +.\" Copyright (c) 2015 Mariusz Zaborski <oshogbo@FreeBSD.org> +.\" All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" Chris Torek and the American National Standards Committee X3, @@ -32,11 +33,12 @@ .\" @(#)fclose.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd April 22, 2006 +.Dd July 4, 2015 .Dt FCLOSE 3 .Os .Sh NAME .Nm fclose , +.Nm fdclose , .Nm fcloseall .Nd close a stream .Sh LIBRARY @@ -45,6 +47,8 @@ .In stdio.h .Ft int .Fn fclose "FILE *stream" +.Ft int +.Fn fdclose "FILE *stream" "int *fdp" .Ft void .Fn fcloseall void .Sh DESCRIPTION @@ -59,36 +63,77 @@ first, using .Xr fflush 3 . .Pp The +.Fn fdclose +function is equivalent to +.Fn fclose +except that it does not close the underlying file descriptor. +If +.Fa fdp +is not +.Dv NULL , +the file descriptor will be written to it. +If the +.Fa fdp +argument will be different then NULL the file descriptor will be returned in it, +If the stream does not have an associated file descriptor, +.Fa fdp +will be set to -1. +This type of stream is created with functions such as +.Xr fmemopen 3 , +.Xr funopen 3 , +or +.Xr open_memstream 3 . +.Pp +The .Fn fcloseall function calls .Fn fclose on all open streams. .Sh RETURN VALUES -Upon successful completion 0 is returned. +.Fn fcloseall +does not return a value. +.Pp +Upon successful completion the +.Fn fclose +and +.Fn fdclose +functions return 0. Otherwise, .Dv EOF is returned and the global variable .Va errno is set to indicate the error. -In either case no further access to the stream is possible. .Sh ERRORS +.Fn fdclose +fails if: +.Bl -tag -width Er +.It Bq Er EOPNOTSUPP +The stream does not have an associated file descriptor. +.El +.Pp The .Fn fclose -function -may also fail and set +and +.Fn fdclose +functions may also fail and set .Va errno -for any of the errors specified for the routines -.Xr close 2 -or +for any of the errors specified for .Xr fflush 3 . +.Pp +The +.Fn fclose +function may also fail and set errno for any of the errors specified for +.Xr close 2 . .Sh NOTES The .Fn fclose -function -does not handle NULL arguments; they will result in a segmentation -violation. -This is intentional - it makes it easier to make sure programs written -under +and +.Fn fdclose +functions do not handle NULL arguments in the +.Fa stream +variable; this will result in a segmentation violation. +This is intentional. +It makes it easier to make sure programs written under .Fx are bug free. This behaviour is an implementation detail, and programs should not @@ -104,8 +149,13 @@ The function conforms to .St -isoC . -.Pp +.Sh HISTORY The .Fn fcloseall function first appeared in .Fx 7.0 . +.Pp +The +.Fn fdclose +function first appeared in +.Fx 11.0 . diff --git a/lib/libc/stdio/fclose.c b/lib/libc/stdio/fclose.c index 5ed8b2c..24b9b90 100644 --- a/lib/libc/stdio/fclose.c +++ b/lib/libc/stdio/fclose.c @@ -1,6 +1,7 @@ /*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. + * Copyright (c) 1990, 1993 The Regents of the University of California. + * Copyright (c) 2013 Mariusz Zaborski <oshogbo@FreeBSD.org> + * All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. @@ -38,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include <errno.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include "un-namespace.h" @@ -45,19 +47,17 @@ __FBSDID("$FreeBSD$"); #include "libc_private.h" #include "local.h" -int -fclose(FILE *fp) +static int +cleanfile(FILE *fp, bool c) { int r; - if (fp->_flags == 0) { /* not open! */ - errno = EBADF; - return (EOF); - } - FLOCKFILE(fp); r = fp->_flags & __SWR ? __sflush(fp) : 0; - if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0) - r = EOF; + if (c) { + if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0) + r = EOF; + } + if (fp->_flags & __SMBF) free((char *)fp->_bf._base); if (HASUB(fp)) @@ -80,6 +80,59 @@ fclose(FILE *fp) STDIO_THREAD_LOCK(); fp->_flags = 0; /* Release this FILE for reuse. */ STDIO_THREAD_UNLOCK(); + + return (r); +} + +int +fdclose(FILE *fp, int *fdp) +{ + int r, err; + + if (fdp != NULL) + *fdp = -1; + + if (fp->_flags == 0) { /* not open! */ + errno = EBADF; + return (EOF); + } + + FLOCKFILE(fp); + r = 0; + if (fp->_close != __sclose) { + r = EOF; + errno = EOPNOTSUPP; + } else if (fp->_file < 0) { + r = EOF; + errno = EBADF; + } + if (r == EOF) { + err = errno; + (void)cleanfile(fp, true); + errno = err; + } else { + if (fdp != NULL) + *fdp = fp->_file; + r = cleanfile(fp, false); + } FUNLOCKFILE(fp); + + return (r); +} + +int +fclose(FILE *fp) +{ + int r; + + if (fp->_flags == 0) { /* not open! */ + errno = EBADF; + return (EOF); + } + + FLOCKFILE(fp); + r = cleanfile(fp, true); + FUNLOCKFILE(fp); + return (r); } diff --git a/lib/libc/sys/ptrace.2 b/lib/libc/sys/ptrace.2 index 458ad8d..71b432f 100644 --- a/lib/libc/sys/ptrace.2 +++ b/lib/libc/sys/ptrace.2 @@ -2,7 +2,7 @@ .\" $NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $ .\" .\" This file is in the public domain. -.Dd July 22, 2013 +.Dd July 3, 2015 .Dt PTRACE 2 .Os .Sh NAME @@ -503,8 +503,163 @@ The .Fa data argument is ignored. .El +.Sh x86 MACHINE-SPECIFIC REQUESTS +.Bl -tag -width "Dv PT_GETXSTATE_INFO" +.It Dv PT_GETXMMREGS +Copy the XMM FPU state into the buffer pointed to by the +argument +.Fa addr . +The buffer has the same layout as the 32-bit save buffer for the +machine instruction +.Dv FXSAVE . +.Pp +This request is only valid for i386 programs, both on native 32-bit +systems and on amd64 kernels. +For 64-bit amd64 programs, the XMM state is reported as part of +the FPU state returned by the +.Dv PT_GETFPREGS +request. +.Pp +The +.Fa data +argument is ignored. +.It Dv PT_SETXMMREGS +Load the XMM FPU state for the thread from the buffer pointed to +by the argument +.Fa addr . +The buffer has the same layout as the 32-bit load buffer for the +machine instruction +.Dv FXRSTOR . +.Pp +As with +.Dv PT_GETXMMREGS, +this request is only valid for i386 programs. +.Pp +The +.Fa data +argument is ignored. +.It Dv PT_GETXSTATE_INFO +Report which XSAVE FPU extensions are supported by the CPU +and allowed in userspace programs. +The +.Fa addr +argument must point to a variable of type +.Vt struct ptrace_xstate_info , +which contains the information on the request return. +.Vt struct ptrace_xstate_info +is defined as follows: +.Bd -literal +struct ptrace_xstate_info { + uint64_t xsave_mask; + uint32_t xsave_len; +}; +.Ed +The +.Dv xsave_mask +field is a bitmask of the currently enabled extensions. +The meaning of the bits is defined in the Intel and AMD +processor documentation. +The +.Dv xsave_len +field reports the length of the XSAVE area for storing the hardware +state for currently enabled extensions in the format defined by the x86 +.Dv XSAVE +machine instruction. +.Pp +The +.Fa data +argument value must be equal to the size of the +.Vt struct ptrace_xstate_info . +.It Dv PT_GETXSTATE +Return the content of the XSAVE area for the thread. +The +.Fa addr +argument points to the buffer where the content is copied, and the +.Fa data +argument specifies the size of the buffer. +The kernel copies out as much content as allowed by the buffer size. +The buffer layout is specified by the layout of the save area for the +.Dv XSAVE +machine instruction. +.It Dv PT_SETXSTATE +Load the XSAVE state for the thread from the buffer specified by the +.Fa addr +pointer. +The buffer size is passed in the +.Fa data +argument. +The buffer must be at least as large as the +.Vt struct savefpu +(defined in +.Pa x86/fpu.h ) +to allow the complete x87 FPU and XMM state load. +It must not be larger than the XSAVE state length, as reported by the +.Dv xsave_len +field from the +.Vt struct ptrace_xstate_info +of the +.Dv PT_GETXSTATE_INFO +request. +Layout of the buffer is identical to the layout of the load area for the +.Dv XRSTOR +machine instruction. +.It Dv PT_GETFSBASE +Return the value of the base used when doing segmented +memory addressing using the %fs segment register. +The +.Fa addr +argument points to an +.Vt unsigned long +variable where the base value is stored. +.Pp +The +.Fa data +argument is ignored. +.It Dv PT_GETGSBASE +Like the +.Dv PT_GETFSBASE +request, but returns the base for the %gs segment register. +.It Dv PT_SETFSBASE +Set the base for the %fs segment register to the value pointed to +by the +.Fa addr +argument. +.Fa addr +must point to the +.Vt unsigned long +variable containing the new base. +.Pp +The +.Fa data +argument is ignored. +.It Dv PT_SETGSBASE +Like the +.Dv PT_SETFSBASE +request, but sets the base for the %gs segment register. +.El +.Sh PowerPC MACHINE-SPECIFIC REQUESTS +.Bl -tag -width "Dv PT_SETVRREGS" +.It Dv PT_GETVRREGS +Return the thread's +.Dv ALTIVEC +machine state in the buffer pointed to by +.Fa addr . +.Pp +The +.Fa data +argument is ignored. +.It Dv PT_SETVRREGS +Set the thread's +.Dv ALTIVEC +machine state from the buffer pointed to by +.Fa addr . .Pp -Additionally, machine-specific requests can exist. +The +.Fa data +argument is ignored. +.El +.Pp +Additionally, other machine-specific requests can exist. .Sh RETURN VALUES Some requests can cause .Fn ptrace @@ -564,6 +719,38 @@ provided to was less than or equal to zero, or larger than the .Vt ptrace_lwpinfo structure known to the kernel. +.It +The size (in +.Fa data ) +provided to the x86-specific +.Dv PT_GETXSTATE_INFO +request was not equal to the size of the +.Vt struct ptrace_xstate_info . +.It +The size (in +.Fa data ) +provided to the x86-specific +.Dv PT_SETXSTATE +request was less than the size of the x87 plus the XMM save area. +.It +The size (in +.Fa data ) +provided to the x86-specific +.Dv PT_SETXSTATE +request was larger than returned in the +.Dv xsave_len +member of the +.Vt struct ptrace_xstate_info +from the +.Dv PT_GETXSTATE_INFO +request. +.It +The base value, provided to the amd64-specific requests +.Dv PT_SETFSBASE +or +.Dv PT_SETGSBASE , +pointed outside of the valid user address space. +This error will not occur in 32-bit programs. .El .It Bq Er EBUSY .Bl -bullet -compact |