Add provisions for variant core dump file formats, depending on the
object format of the executable being dumped. This is the first step toward producing ELF core dumps in the proper format. I will commit the code to generate the ELF core dumps Real Soon Now. In the meantime, ELF executables won't dump core at all. That is probably no less useful than dumping a.out-style core dumps as they have done until now. Submitted by: Alex <garbanzo@hooked.net> (with very minor changes by me)
This commit is contained in:
parent
11a91d3e31
commit
c70000b9a2
@ -25,7 +25,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: linux_sysvec.c,v 1.31 1998/07/29 16:43:00 bde Exp $
|
||||
* $Id: linux_sysvec.c,v 1.32 1998/08/16 01:21:50 bde Exp $
|
||||
*/
|
||||
|
||||
/* XXX we use functions that might not exist. */
|
||||
@ -41,6 +41,7 @@
|
||||
#include <sys/systm.h>
|
||||
#include <sys/sysent.h>
|
||||
#include <sys/imgact.h>
|
||||
#include <sys/imgact_aout.h>
|
||||
#include <sys/imgact_elf.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/malloc.h>
|
||||
@ -401,7 +402,8 @@ struct sysentvec linux_sysvec = {
|
||||
linux_sigcode,
|
||||
&linux_szsigcode,
|
||||
linux_prepsyscall,
|
||||
"Linux a.out"
|
||||
"Linux a.out",
|
||||
aout_coredump
|
||||
};
|
||||
|
||||
struct sysentvec elf_linux_sysvec = {
|
||||
@ -418,7 +420,8 @@ struct sysentvec elf_linux_sysvec = {
|
||||
linux_sigcode,
|
||||
&linux_szsigcode,
|
||||
linux_prepsyscall,
|
||||
"Linux ELF"
|
||||
"Linux ELF",
|
||||
elf_coredump
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -156,7 +156,6 @@ kern/imgact_shell.c standard
|
||||
kern/inflate.c optional gzip
|
||||
kern/init_main.c standard
|
||||
kern/init_sysent.c standard
|
||||
kern/init_sysvec.c standard
|
||||
kern/kern_intr.c standard
|
||||
kern/kern_module.c standard
|
||||
kern/kern_linker.c standard
|
||||
|
@ -27,7 +27,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: ibcs2_sysvec.c,v 1.6 1997/02/22 09:33:28 peter Exp $
|
||||
* $Id: ibcs2_sysvec.c,v 1.7 1998/04/28 18:15:05 eivind Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -55,5 +55,6 @@ struct sysentvec ibcs2_svr3_sysvec = {
|
||||
sigcode, /* use generic trampoline */
|
||||
&szsigcode, /* use generic trampoline size */
|
||||
0, /* prepsyscall */
|
||||
"IBCS2 COFF"
|
||||
"IBCS2 COFF",
|
||||
NULL /* we don't have a COFF coredump function */
|
||||
};
|
||||
|
@ -25,7 +25,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: linux_sysvec.c,v 1.31 1998/07/29 16:43:00 bde Exp $
|
||||
* $Id: linux_sysvec.c,v 1.32 1998/08/16 01:21:50 bde Exp $
|
||||
*/
|
||||
|
||||
/* XXX we use functions that might not exist. */
|
||||
@ -41,6 +41,7 @@
|
||||
#include <sys/systm.h>
|
||||
#include <sys/sysent.h>
|
||||
#include <sys/imgact.h>
|
||||
#include <sys/imgact_aout.h>
|
||||
#include <sys/imgact_elf.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/malloc.h>
|
||||
@ -401,7 +402,8 @@ struct sysentvec linux_sysvec = {
|
||||
linux_sigcode,
|
||||
&linux_szsigcode,
|
||||
linux_prepsyscall,
|
||||
"Linux a.out"
|
||||
"Linux a.out",
|
||||
aout_coredump
|
||||
};
|
||||
|
||||
struct sysentvec elf_linux_sysvec = {
|
||||
@ -418,7 +420,8 @@ struct sysentvec elf_linux_sysvec = {
|
||||
linux_sigcode,
|
||||
&linux_szsigcode,
|
||||
linux_prepsyscall,
|
||||
"Linux ELF"
|
||||
"Linux ELF",
|
||||
elf_coredump
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -23,19 +23,28 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: imgact_aout.c,v 1.40 1998/02/20 13:11:48 bde Exp $
|
||||
* $Id: imgact_aout.c,v 1.41 1998/07/15 05:00:26 bde Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/acct.h>
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/exec.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/imgact.h>
|
||||
#include <sys/imgact_aout.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/pioctl.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysent.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/systm.h>
|
||||
#include <machine/md_var.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
@ -44,9 +53,28 @@
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_map.h>
|
||||
#include <vm/vm_object.h>
|
||||
#include <sys/user.h>
|
||||
|
||||
static int exec_aout_imgact __P((struct image_params *imgp));
|
||||
|
||||
struct sysentvec aout_sysvec = {
|
||||
SYS_MAXSYSCALL,
|
||||
sysent,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
sendsig,
|
||||
sigcode,
|
||||
&szsigcode,
|
||||
0,
|
||||
"FreeBSD a.out",
|
||||
aout_coredump
|
||||
};
|
||||
|
||||
static int
|
||||
exec_aout_imgact(imgp)
|
||||
struct image_params *imgp;
|
||||
@ -203,6 +231,72 @@ exec_aout_imgact(imgp)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump core, into a file named "progname.core", unless the process was
|
||||
* setuid/setgid.
|
||||
*/
|
||||
int
|
||||
aout_coredump(p)
|
||||
register struct proc *p;
|
||||
{
|
||||
register struct vnode *vp;
|
||||
register struct ucred *cred = p->p_cred->pc_ucred;
|
||||
register struct vmspace *vm = p->p_vmspace;
|
||||
struct nameidata nd;
|
||||
struct vattr vattr;
|
||||
int error, error1;
|
||||
char *name; /* name of corefile */
|
||||
|
||||
STOPEVENT(p, S_CORE, 0);
|
||||
|
||||
if (sugid_coredump == 0 && p->p_flag & P_SUGID)
|
||||
return (EFAULT);
|
||||
if (ctob(UPAGES + vm->vm_dsize + vm->vm_ssize) >=
|
||||
p->p_rlimit[RLIMIT_CORE].rlim_cur)
|
||||
return (EFAULT);
|
||||
name = expand_name(p->p_comm, p->p_ucred->cr_uid, p->p_pid);
|
||||
if (name == NULL)
|
||||
return (EFAULT); /* XXX -- not the best error */
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, name, p);
|
||||
error = vn_open(&nd, O_CREAT | FWRITE, S_IRUSR | S_IWUSR);
|
||||
free(name, M_TEMP);
|
||||
if (error)
|
||||
return (error);
|
||||
vp = nd.ni_vp;
|
||||
|
||||
/* Don't dump to non-regular files or files with links. */
|
||||
if (vp->v_type != VREG ||
|
||||
VOP_GETATTR(vp, &vattr, cred, p) || vattr.va_nlink != 1) {
|
||||
error = EFAULT;
|
||||
goto out;
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_size = 0;
|
||||
VOP_LEASE(vp, p, cred, LEASE_WRITE);
|
||||
VOP_SETATTR(vp, &vattr, cred, p);
|
||||
p->p_acflag |= ACORE;
|
||||
bcopy(p, &p->p_addr->u_kproc.kp_proc, sizeof(struct proc));
|
||||
fill_eproc(p, &p->p_addr->u_kproc.kp_eproc);
|
||||
error = cpu_coredump(p, vp, cred);
|
||||
if (error == 0)
|
||||
error = vn_rdwr(UIO_WRITE, vp, vm->vm_daddr,
|
||||
(int)ctob(vm->vm_dsize), (off_t)ctob(UPAGES), UIO_USERSPACE,
|
||||
IO_NODELOCKED|IO_UNIT, cred, (int *) NULL, p);
|
||||
if (error == 0)
|
||||
error = vn_rdwr(UIO_WRITE, vp,
|
||||
(caddr_t) trunc_page(USRSTACK - ctob(vm->vm_ssize)),
|
||||
round_page(ctob(vm->vm_ssize)),
|
||||
(off_t)ctob(UPAGES) + ctob(vm->vm_dsize), UIO_USERSPACE,
|
||||
IO_NODELOCKED|IO_UNIT, cred, (int *) NULL, p);
|
||||
out:
|
||||
VOP_UNLOCK(vp, 0, p);
|
||||
error1 = vn_close(vp, FWRITE, cred, p);
|
||||
if (error == 0)
|
||||
error = error1;
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tell kern_execve.c about it, with a little help from the linker.
|
||||
* Since `const' objects end up in the text segment, TEXT_SET is the
|
||||
|
@ -26,7 +26,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: imgact_elf.c,v 1.28 1998/07/15 05:00:26 bde Exp $
|
||||
* $Id: imgact_elf.c,v 1.29 1998/07/29 18:39:35 dfr Exp $
|
||||
*/
|
||||
|
||||
#include "opt_rlimit.h"
|
||||
@ -101,7 +101,8 @@ static struct sysentvec elf_freebsd_sysvec = {
|
||||
sigcode,
|
||||
&szsigcode,
|
||||
0,
|
||||
"FreeBSD ELF"
|
||||
"FreeBSD ELF",
|
||||
elf_coredump
|
||||
};
|
||||
|
||||
static Elf_Brandinfo freebsd_brand_info = {
|
||||
@ -638,6 +639,14 @@ exec_elf_imgact(struct image_params *imgp)
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
elf_coredump (p)
|
||||
register struct proc *p;
|
||||
{
|
||||
/* Not implemented yet. */
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
static int
|
||||
elf_freebsd_fixup(long **stack_base, struct image_params *imgp)
|
||||
{
|
||||
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* sysentvec for native FreeBSD a.out executable format.
|
||||
*
|
||||
* $Id: init_sysvec.c,v 1.5 1997/08/02 14:31:26 bde Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysent.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <machine/md_var.h>
|
||||
|
||||
struct sysentvec aout_sysvec = {
|
||||
SYS_MAXSYSCALL,
|
||||
sysent,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
sendsig,
|
||||
sigcode,
|
||||
&szsigcode,
|
||||
0,
|
||||
"FreeBSD a.out"
|
||||
};
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)kern_sig.c 8.7 (Berkeley) 4/18/94
|
||||
* $Id: kern_sig.c,v 1.44 1998/07/15 02:32:09 bde Exp $
|
||||
* $Id: kern_sig.c,v 1.45 1998/07/28 22:33:47 joerg Exp $
|
||||
*/
|
||||
|
||||
#include "opt_compat.h"
|
||||
@ -76,11 +76,9 @@
|
||||
#include <vm/vm_map.h>
|
||||
#include <sys/user.h>
|
||||
|
||||
static int coredump __P((struct proc *p));
|
||||
static int killpg1 __P((struct proc *cp, int signum, int pgid, int all));
|
||||
static void setsigvec __P((struct proc *p, int signum, struct sigaction *sa));
|
||||
static void stop __P((struct proc *));
|
||||
static char *expand_name __P((const char*, int, int));
|
||||
|
||||
static int kern_logsigexit = 1;
|
||||
SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW, &kern_logsigexit, 0, "");
|
||||
@ -96,7 +94,7 @@ SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW, &kern_logsigexit, 0,
|
||||
(pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid || \
|
||||
((signum) == SIGCONT && (q)->p_session == (p)->p_session))
|
||||
|
||||
static int sugid_coredump;
|
||||
int sugid_coredump;
|
||||
SYSCTL_INT(_kern, OID_AUTO, sugid_coredump, CTLFLAG_RW, &sugid_coredump, 0, "");
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
@ -1239,7 +1237,12 @@ sigexit(p, signum)
|
||||
* these messages.)
|
||||
* XXX : Todo, as well as euid, write out ruid too
|
||||
*/
|
||||
if (coredump(p) == 0)
|
||||
|
||||
/* Use the correct function to dump core, as stored in
|
||||
the sysentvec struct. This way we can do ELF and a.out
|
||||
dumps without breaking a sweat. */
|
||||
if (p->p_sysent->sv_coredump != NULL &&
|
||||
(*p->p_sysent->sv_coredump)(p) == 0)
|
||||
signum |= WCOREFLAG;
|
||||
if (kern_logsigexit)
|
||||
log(LOG_INFO,
|
||||
@ -1269,7 +1272,7 @@ SYSCTL_STRING(_kern, OID_AUTO, corefile, CTLFLAG_RW, corefilename,
|
||||
* This is controlled by the sysctl variable kern.corefile (see above).
|
||||
*/
|
||||
|
||||
static char *
|
||||
char *
|
||||
expand_name(name, uid, pid)
|
||||
const char *name; int uid; int pid; {
|
||||
char *temp;
|
||||
@ -1334,73 +1337,6 @@ const char *name; int uid; int pid; {
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Dump core, into a file named "progname.core", unless the process was
|
||||
* setuid/setgid.
|
||||
*/
|
||||
static int
|
||||
coredump(p)
|
||||
register struct proc *p;
|
||||
{
|
||||
register struct vnode *vp;
|
||||
register struct ucred *cred = p->p_cred->pc_ucred;
|
||||
register struct vmspace *vm = p->p_vmspace;
|
||||
struct nameidata nd;
|
||||
struct vattr vattr;
|
||||
int error, error1;
|
||||
char *name; /* name of corefile */
|
||||
|
||||
STOPEVENT(p, S_CORE, 0);
|
||||
|
||||
if (sugid_coredump == 0 && p->p_flag & P_SUGID)
|
||||
return (EFAULT);
|
||||
if (ctob(UPAGES + vm->vm_dsize + vm->vm_ssize) >=
|
||||
p->p_rlimit[RLIMIT_CORE].rlim_cur)
|
||||
return (EFAULT);
|
||||
name = expand_name(p->p_comm, p->p_ucred->cr_uid, p->p_pid);
|
||||
if (name == NULL)
|
||||
return (EFAULT); /* XXX -- not the best error */
|
||||
|
||||
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, name, p);
|
||||
error = vn_open(&nd, O_CREAT | FWRITE, S_IRUSR | S_IWUSR);
|
||||
free(name, M_TEMP);
|
||||
if (error)
|
||||
return (error);
|
||||
vp = nd.ni_vp;
|
||||
|
||||
/* Don't dump to non-regular files or files with links. */
|
||||
if (vp->v_type != VREG ||
|
||||
VOP_GETATTR(vp, &vattr, cred, p) || vattr.va_nlink != 1) {
|
||||
error = EFAULT;
|
||||
goto out;
|
||||
}
|
||||
VATTR_NULL(&vattr);
|
||||
vattr.va_size = 0;
|
||||
VOP_LEASE(vp, p, cred, LEASE_WRITE);
|
||||
VOP_SETATTR(vp, &vattr, cred, p);
|
||||
p->p_acflag |= ACORE;
|
||||
bcopy(p, &p->p_addr->u_kproc.kp_proc, sizeof(struct proc));
|
||||
fill_eproc(p, &p->p_addr->u_kproc.kp_eproc);
|
||||
error = cpu_coredump(p, vp, cred);
|
||||
if (error == 0)
|
||||
error = vn_rdwr(UIO_WRITE, vp, vm->vm_daddr,
|
||||
(int)ctob(vm->vm_dsize), (off_t)ctob(UPAGES), UIO_USERSPACE,
|
||||
IO_NODELOCKED|IO_UNIT, cred, (int *) NULL, p);
|
||||
if (error == 0)
|
||||
error = vn_rdwr(UIO_WRITE, vp,
|
||||
(caddr_t) trunc_page(USRSTACK - ctob(vm->vm_ssize)),
|
||||
round_page(ctob(vm->vm_ssize)),
|
||||
(off_t)ctob(UPAGES) + ctob(vm->vm_dsize), UIO_USERSPACE,
|
||||
IO_NODELOCKED|IO_UNIT, cred, (int *) NULL, p);
|
||||
out:
|
||||
VOP_UNLOCK(vp, 0, p);
|
||||
error1 = vn_close(vp, FWRITE, cred, p);
|
||||
if (error == 0)
|
||||
error = error1;
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Nonexistent system call-- signal process (may want to handle it).
|
||||
* Flag error in case process won't see signal immediately (blocked or ignored).
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)exec.h 8.1 (Berkeley) 6/11/93
|
||||
* $Id: imgact_aout.h,v 1.7 1997/02/22 09:45:18 peter Exp $
|
||||
* $Id: imgact_aout.h,v 1.8 1997/12/19 20:44:48 bde Exp $
|
||||
*/
|
||||
|
||||
#ifndef _IMGACT_AOUT_H_
|
||||
@ -147,4 +147,12 @@ struct exec {
|
||||
#define EX_DYNAMIC 0x20 /* contains run-time link-edit info */
|
||||
#define EX_DPMASK 0x30 /* mask for the above */
|
||||
|
||||
#ifdef KERNEL
|
||||
struct proc;
|
||||
|
||||
__BEGIN_DECLS
|
||||
int aout_coredump __P((struct proc *));
|
||||
__END_DECLS
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif /* !_IMGACT_AOUT_H_ */
|
||||
|
@ -25,7 +25,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: imgact_elf.h,v 1.7 1998/06/07 17:13:01 dfr Exp $
|
||||
* $Id: imgact_elf.h,v 1.8 1998/09/07 07:30:44 dfr Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_IMGACT_ELF_H_
|
||||
@ -99,6 +99,11 @@ int elf_remove_brand_entry __P((Elf64_Brandinfo *entry));
|
||||
|
||||
#endif
|
||||
|
||||
struct proc;
|
||||
|
||||
__BEGIN_DECLS
|
||||
int elf_coredump __P((struct proc *));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* KERNEL */
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)signalvar.h 8.6 (Berkeley) 2/19/95
|
||||
* $Id: signalvar.h,v 1.17 1998/02/24 02:01:11 bde Exp $
|
||||
* $Id: signalvar.h,v 1.18 1998/03/28 10:33:23 bde Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_SIGNALVAR_H_ /* tmp for user.h */
|
||||
@ -153,10 +153,13 @@ static int sigprop[NSIG + 1] = {
|
||||
struct pgrp;
|
||||
struct proc;
|
||||
|
||||
extern int sugid_coredump; /* Sysctl variable kern.sugid_coredump */
|
||||
|
||||
/*
|
||||
* Machine-independent functions:
|
||||
*/
|
||||
void execsigs __P((struct proc *p));
|
||||
char *expand_name __P((const char*, int, int));
|
||||
void gsignal __P((int pgid, int sig));
|
||||
int issignal __P((struct proc *p));
|
||||
void killproc __P((struct proc *p, char *why));
|
||||
|
@ -30,7 +30,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: sysent.h,v 1.17 1998/04/28 18:15:08 eivind Exp $
|
||||
* $Id: sysent.h,v 1.18 1998/06/07 17:13:03 dfr Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_SYSENT_H_
|
||||
@ -69,6 +69,8 @@ struct sysentvec {
|
||||
void (*sv_prepsyscall) __P((struct trapframe *, int *,
|
||||
u_int *, caddr_t *));
|
||||
char *sv_name; /* name of binary type */
|
||||
int (*sv_coredump) __P((struct proc *p));
|
||||
/* function to dump core, or NULL */
|
||||
};
|
||||
|
||||
#ifdef KERNEL
|
||||
|
Loading…
Reference in New Issue
Block a user