Subject: port-i386/3920: linux emulation doesn't support mremap()
To: None <gnats-bugs@gnats.netbsd.org>
From: Matthias Scheler <tron@lyssa.owl.de>
List: netbsd-bugs
Date: 07/27/1997 22:34:35
>Number: 3920
>Category: port-i386
>Synopsis: linux emulation doesn't support mremap()
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: gnats-admin (GNATS administrator)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Jul 27 13:35:00 1997
>Last-Modified:
>Originator: Matthias Scheler
>Organization:
Matthias Scheler http://home.owl.de/~tron/
>Release: 970716
>Environment:
System: NetBSD lyssa 1.2G NetBSD 1.2G (LYSSA) #1: Sun Jul 27 22:12:15 MEST 1997 tron@lyssa:/usr/src/sys/arch/i386/compile/LYSSA i386
>Description:
When I tried to use a Linux GCC environment under NetBSD I discovered that
"cpp" died sometimes because it uses the unsupported mremap() syscall.
After looking through the source of linux libc 5.4.23 I found that it is
only called in "dl-malloc/malloc.c":
#if __STD_C
static mchunkptr mremap_chunk(mchunkptr p, size_t new_size)
#else
static mchunkptr mremap_chunk(p, new_size) mchunkptr p; size_t new_size;
#endif
{
...
cp = (char *)mremap((char *)p - offset, size + offset, new_size, 1);
if (cp == (char *)-1) return 0;
...
}
...
#if __STD_C
Void_t* rEALLOc(Void_t* oldmem, size_t bytes)
#else
Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
#endif
{
...
#if HAVE_MMAP
if (chunk_is_mmapped(oldp))
{
#if HAVE_MREMAP
newp = mremap_chunk(oldp, nb);
if(newp) return chunk2mem(newp);
#endif
...
As one can see a dummy function returning an error on mremap() will solve
the problem.
>How-To-Repeat:
Start a linux binary which uses realloc() from a recent "libc" (5.4.x).
>Fix:
*** src/sys/compat/linux/linux_file.c.orig Fri Jun 27 13:23:39 1997
--- src/sys/compat/linux/linux_file.c Sun Jul 27 22:00:47 1997
*************** linux_sys_fdatasync(p, v, retval)
*** 822,824 ****
--- 822,844 ----
#endif
return sys_fsync(p, v, retval);
}
+
+ /*
+ * mremap() dummy
+ */
+ int
+ linux_sys_mremap(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+ {
+ #ifdef notdef
+ struct linux_sys_mremap_args /* {
+ syscallarg(void *) old_address;
+ syscallarg(size_t) old_size;
+ syscallarg(size_t) new_size;
+ syscallarg(unsigned long) flags;
+ } */ *uap = v;
+ #endif
+ return ENOMEM;
+ }
*** src/sys/compat/linux/linux_syscallargs.h.orig Sat Jun 14 13:27:51 1997
--- src/sys/compat/linux/linux_syscallargs.h Sun Jul 27 22:11:28 1997
*************** struct linux_sys___sysctl_args {
*** 330,335 ****
--- 330,342 ----
syscallarg(struct linux___sysctl *) lsp;
};
+ struct linux_sys_mremap_args {
+ syscallarg(void *) old_address;
+ syscallarg(size_t) old_size;
+ syscallarg(size_t) new_size;
+ syscallarg(unsigned long) flags;
+ };
+
/*
* System call prototypes.
*/
*************** int linux_sys_fdatasync __P((struct proc
*** 462,464 ****
--- 469,472 ----
int linux_sys___sysctl __P((struct proc *, void *, register_t *));
int sys_mlock __P((struct proc *, void *, register_t *));
int sys_munlock __P((struct proc *, void *, register_t *));
+ int linux_sys_mremap __P((struct proc *, void *, register_t *));
*** src/sys/compat/linux/linux_syscalls.c.orig Sat Jun 14 13:27:52 1997
--- src/sys/compat/linux/linux_syscalls.c Sun Jul 27 22:02:16 1997
*************** char *linux_syscallnames[] = {
*** 181,185 ****
"#160 (unimplemented sched_get_priority_min)", /* 160 = unimplemented sched_get_priority_min */
"#161 (unimplemented sched_rr_get_interval)", /* 161 = unimplemented sched_rr_get_interval */
"#162 (unimplemented nanosleep)", /* 162 = unimplemented nanosleep */
! "#163 (unimplemented mremap)", /* 163 = unimplemented mremap */
};
--- 181,185 ----
"#160 (unimplemented sched_get_priority_min)", /* 160 = unimplemented sched_get_priority_min */
"#161 (unimplemented sched_rr_get_interval)", /* 161 = unimplemented sched_rr_get_interval */
"#162 (unimplemented nanosleep)", /* 162 = unimplemented nanosleep */
! "mremap", /* 163 = mremap */
};
*** src/sys/compat/linux/linux_sysent.c.orig Sat Jun 14 13:27:52 1997
--- src/sys/compat/linux/linux_sysent.c Sun Jul 27 22:07:28 1997
*************** struct sysent linux_sysent[] = {
*** 359,365 ****
sys_nosys }, /* 161 = unimplemented sched_rr_get_interval */
{ 0, 0,
sys_nosys }, /* 162 = unimplemented nanosleep */
! { 0, 0,
! sys_nosys }, /* 163 = unimplemented mremap */
};
--- 359,365 ----
sys_nosys }, /* 161 = unimplemented sched_rr_get_interval */
{ 0, 0,
sys_nosys }, /* 162 = unimplemented nanosleep */
! { 4, s(struct linux_sys_mremap_args),
! linux_sys_mremap }, /* 163 = mremap */
};
>Audit-Trail:
>Unformatted: