UInt flags, UInt fd, OffT offset)
{
SysRes res;
-# if defined(VGP_x86_linux)
- {
- UWord args[6];
- args[0] = (UWord)start;
- args[1] = length;
- args[2] = prot;
- args[3] = flags;
- args[4] = fd;
- args[5] = offset;
- res = VG_(do_syscall1)(__NR_mmap, (UWord)args );
- }
+# if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
+ res = VG_(do_syscall6)(__NR_mmap2, (UWord)start, length,
+ prot, flags, fd, offset / VKI_PAGE_SIZE));
# elif defined(VGP_amd64_linux)
res = VG_(do_syscall6)(__NR_mmap, (UWord)start, length,
prot, flags, fd, offset);
-# elif defined(VGP_ppc32_linux)
- res = VG_(do_syscall6)(__NR_mmap, (UWord)(start), (length),
- prot, flags, fd, offset);
# else
# error Unknown platform
# endif
extern void ML_(generic_PRE_sys_shmctl) ( TId, UW, UW, UW );
extern void ML_(generic_POST_sys_shmctl) ( TId, UW, UW, UW, UW );
+extern SysRes ML_(generic_PRE_sys_mmap) ( TId, UW, UW, UW, UW, UW, UW );
+
#undef TId
#undef UW
#undef SR
DECL_TEMPLATE(linux, sys_sendfile);
DECL_TEMPLATE(linux, sys_sendfile64);
DECL_TEMPLATE(linux, sys_futex);
-DECL_TEMPLATE(linux, sys_mmap2);
DECL_TEMPLATE(linux, sys_epoll_create);
DECL_TEMPLATE(linux, sys_epoll_ctl);
DECL_TEMPLATE(amd64_linux, sys_pread64);
DECL_TEMPLATE(amd64_linux, sys_pwrite64);
DECL_TEMPLATE(amd64_linux, sys_fadvise64);
+DECL_TEMPLATE(amd64_linux, sys_mmap);
PRE(sys_clone)
int, fd, vki_loff_t, offset, vki_size_t, len, int, advice);
}
+PRE(sys_mmap)
+{
+ SysRes r;
+
+ PRINT("sys_mmap ( %p, %llu, %d, %d, %d, %d )",
+ ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
+ PRE_REG_READ6(long, "mmap",
+ unsigned long, start, unsigned long, length,
+ unsigned long, prot, unsigned long, flags,
+ unsigned long, fd, unsigned long, offset);
+
+ r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
+ SET_STATUS_from_SysRes(r);
+}
+
#undef PRE
#undef POST
GENXY(__NR_lstat, sys_newlstat), // 6
GENXY(__NR_poll, sys_poll), // 7
LINX_(__NR_lseek, sys_lseek), // 8
- LINX_(__NR_mmap, sys_mmap2), // 9
+ PLAX_(__NR_mmap, sys_mmap), // 9
GENXY(__NR_mprotect, sys_mprotect), // 10
GENXY(__NR_munmap, sys_munmap), // 11
}
+/* ---------------------------------------------------------------------
+ Generic handler for mmap
+ ------------------------------------------------------------------ */
+
+SysRes
+ML_(generic_PRE_sys_mmap) ( ThreadId tid,
+ UWord arg1, UWord arg2, UWord arg3,
+ UWord arg4, UWord arg5, UWord arg6 )
+{
+ Addr advised;
+ SysRes sres;
+ MapRequest mreq;
+ Bool mreq_ok;
+
+ if (arg2 == 0) {
+ /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
+ shall be established. */
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
+ }
+
+ if (!VG_IS_PAGE_ALIGNED(arg1)) {
+ /* zap any misaligned addresses. */
+ /* SuSV3 says misaligned addresses only cause the MAP_FIXED case
+ to fail. Here, we catch them all. */
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
+ }
+
+ /* Figure out what kind of allocation constraints there are
+ (fixed/hint/any), and ask aspacem what we should do. */
+ mreq.start = arg1;
+ mreq.len = arg2;
+ if (arg4 & VKI_MAP_FIXED) {
+ mreq.rkind = MFixed;
+ } else
+ if (arg1 != 0) {
+ mreq.rkind = MHint;
+ } else {
+ mreq.rkind = MAny;
+ }
+
+ /* Enquire ... */
+ advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
+ if (!mreq_ok) {
+ /* Our request was bounced, so we'd better fail. */
+ return VG_(mk_SysRes_Error)( VKI_EINVAL );
+ }
+
+ /* Otherwise we're OK (so far). Install aspacem's choice of
+ address, and let the mmap go through. */
+ sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
+ arg4 | VKI_MAP_FIXED,
+ arg5, arg6);
+
+ if (!sres.isError) {
+ /* Notify aspacem and the tool. */
+ ML_(notify_aspacem_and_tool_of_mmap)(
+ (Addr)sres.val, /* addr kernel actually assigned */
+ arg2, arg3,
+ arg4, /* the original flags value */
+ arg5, arg6
+ );
+ /* Load symbols? */
+ VG_(di_notify_mmap)( (Addr)sres.val );
+ }
+
+ /* Stay sane */
+ if (!sres.isError && (arg4 & VKI_MAP_FIXED))
+ vg_assert(sres.val == arg1);
+
+ return sres;
+}
+
+
/* ---------------------------------------------------------------------
The Main Entertainment ... syscall wrappers
------------------------------------------------------------------ */
}
}
-PRE(sys_mmap2)
-{
- Addr advised;
- SysRes sres;
- OffT offset;
- MapRequest mreq;
- Bool mreq_ok;
-
- // Exactly like old_mmap() in x86-linux except:
- // - all 6 args are passed in regs, rather than in a memory-block.
- // - on x86-linux, the file offset is specified in pagesize units
- // rather than bytes, so that it can be used for files bigger
- // than 2^32 bytes. On amd64-linux and ppc32-linux it appears
- // to be in bytes.
- PRINT("sys_mmap2 ( %p, %llu, %d, %d, %d, %d )",
- ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
- PRE_REG_READ6(long, "mmap2",
- unsigned long, start, unsigned long, length,
- unsigned long, prot, unsigned long, flags,
- unsigned long, fd, unsigned long, offset);
-
- if (ARG2 == 0) {
- /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
- shall be established. */
- SET_STATUS_Failure( VKI_EINVAL );
- return;
- }
-
- if (!VG_IS_PAGE_ALIGNED(ARG1)) {
- /* zap any misaligned addresses. */
- /* SuSV3 says misaligned addresses only cause the MAP_FIXED case
- to fail. Here, we catch them all. */
- SET_STATUS_Failure( VKI_EINVAL );
- return;
- }
-
- /* Figure out what kind of allocation constraints there are
- (fixed/hint/any), and ask aspacem what we should do. */
- mreq.start = ARG1;
- mreq.len = ARG2;
- if (ARG4 & VKI_MAP_FIXED) {
- mreq.rkind = MFixed;
- } else
- if (ARG1 != 0) {
- mreq.rkind = MHint;
- } else {
- mreq.rkind = MAny;
- }
-
- /* Enquire ... */
- advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
- if (!mreq_ok) {
- /* Our request was bounced, so we'd better fail. */
- SET_STATUS_Failure( VKI_EINVAL );
- return;
- }
-
- vg_assert(! FAILURE);
-
-# if defined(VGP_x86_linux)
- offset = ARG6 * VKI_PAGE_SIZE;
-# elif defined(VGP_amd64_linux) || defined(VGP_ppc32_linux)
- offset = ARG6;
-# else
-# error Unknown platform
-# endif
-
- /* Otherwise we're OK (so far). Install aspacem's choice of
- address, and let the mmap go through. */
- sres = VG_(am_do_mmap_NO_NOTIFY)(advised, ARG2, ARG3,
- ARG4 | VKI_MAP_FIXED,
- ARG5, offset);
- SET_STATUS_from_SysRes(sres);
-
- if (!sres.isError) {
- /* Notify aspacem and the tool. */
- ML_(notify_aspacem_and_tool_of_mmap)(
- (Addr)sres.val, /* addr kernel actually assigned */
- ARG2, ARG3,
- ARG4, /* the original flags value */
- ARG5, offset
- );
- /* Load symbols? */
- VG_(di_notify_mmap)( (Addr)sres.val );
- }
-
- /* Stay sane */
- if (SUCCESS && (ARG4 & VKI_MAP_FIXED))
- vg_assert(RES == ARG1);
-}
-
/* ---------------------------------------------------------------------
epoll_* wrappers
magic. */
DECL_TEMPLATE(ppc32_linux, sys_socketcall);
+DECL_TEMPLATE(ppc32_linux, sys_mmap);
+DECL_TEMPLATE(ppc32_linux, sys_mmap2);
DECL_TEMPLATE(ppc32_linux, sys_stat64);
DECL_TEMPLATE(ppc32_linux, sys_lstat64);
DECL_TEMPLATE(ppc32_linux, sys_fstat64);
# undef ARG2_5
}
+PRE(sys_mmap)
+{
+ SysRes r;
+
+ PRINT("sys_mmap ( %p, %llu, %d, %d, %d, %d )",
+ ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
+ PRE_REG_READ6(long, "mmap",
+ unsigned long, start, unsigned long, length,
+ unsigned long, prot, unsigned long, flags,
+ unsigned long, fd, unsigned long, offset);
+
+ r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
+ SET_STATUS_from_SysRes(r);
+}
+
+PRE(sys_mmap2)
+{
+ SysRes r;
+
+ // Exactly like old_mmap() except:
+ // - the file offset is specified in pagesize units rather than bytes,
+ // so that it can be used for files bigger than 2^32 bytes.
+ PRINT("sys_mmap2 ( %p, %llu, %d, %d, %d, %d )",
+ ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
+ PRE_REG_READ6(long, "mmap2",
+ unsigned long, start, unsigned long, length,
+ unsigned long, prot, unsigned long, flags,
+ unsigned long, fd, unsigned long, offset);
+
+ r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 * VKI_PAGE_SIZE );
+ SET_STATUS_from_SysRes(r);
+}
+
// XXX: lstat64/fstat64/stat64 are generic, but not necessarily
// applicable to every architecture -- I think only to 32-bit archs.
// We're going to need something like linux/core_os32.h for such
//.. // (__NR_reboot, sys_reboot), // 88 */Linux
//.. // (__NR_readdir, old_readdir), // 89 -- superseded
- LINX_(__NR_mmap, sys_mmap2), // 90
+ PLAX_(__NR_mmap, sys_mmap), // 90
GENXY(__NR_munmap, sys_munmap), // 91
//.. GENX_(__NR_truncate, sys_truncate), // 92
GENX_(__NR_ftruncate, sys_ftruncate), // 93
GENX_(__NR_vfork, sys_fork), // 189
GENXY(__NR_ugetrlimit, sys_getrlimit), // 190
//__NR_readahead // 191 ppc/Linux only?
- LINX_(__NR_mmap2, sys_mmap2), // 192
+ PLAX_(__NR_mmap2, sys_mmap2), // 192
//.. GENX_(__NR_truncate64, sys_truncate64), // 193
//.. GENX_(__NR_ftruncate64, sys_ftruncate64), // 194
//..
DECL_TEMPLATE(x86_linux, sys_lstat64);
DECL_TEMPLATE(x86_linux, sys_clone);
DECL_TEMPLATE(x86_linux, old_mmap);
+DECL_TEMPLATE(x86_linux, sys_mmap2);
DECL_TEMPLATE(x86_linux, sys_sigreturn);
DECL_TEMPLATE(x86_linux, sys_ipc);
DECL_TEMPLATE(x86_linux, sys_rt_sigreturn);
unsigned long offset;
}; */
UWord a1, a2, a3, a4, a5, a6;
- Addr advised;
- SysRes sres;
- MapRequest mreq;
- Bool mreq_ok;
+ SysRes r;
UWord* args = (UWord*)ARG1;
PRE_REG_READ1(long, "old_mmap", struct mmap_arg_struct *, args);
PRINT("old_mmap ( %p, %llu, %d, %d, %d, %d )",
a1, (ULong)a2, a3, a4, a5, a6 );
- if (a2 == 0) {
- /* SuSV3 says: If len is zero, mmap() shall fail and no mapping
- shall be established. */
- SET_STATUS_Failure( VKI_EINVAL );
- return;
- }
-
- if (!VG_IS_PAGE_ALIGNED(a1)) {
- /* zap any misaligned addresses. */
- SET_STATUS_Failure( VKI_EINVAL );
- return;
- }
-
- /* Figure out what kind of allocation constraints there are
- (fixed/hint/any), and ask aspacem what we should do. */
- mreq.start = a1;
- mreq.len = a2;
- if (a4 & VKI_MAP_FIXED) {
- mreq.rkind = MFixed;
- } else
- if (a1 != 0) {
- mreq.rkind = MHint;
- } else {
- mreq.rkind = MAny;
- }
-
- /* Enquire ... */
- advised = VG_(am_get_advisory)( &mreq, True/*client*/, &mreq_ok );
- if (!mreq_ok) {
- /* Our request was bounced, so we'd better fail. */
- SET_STATUS_Failure( VKI_EINVAL );
- return;
- }
+ r = ML_(generic_PRE_sys_mmap)( tid, a1, a2, a3, a4, a5, a6 );
+ SET_STATUS_from_SysRes(r);
+}
- /* Otherwise we're OK (so far). Install aspacem's choice of
- address, and let the mmap go through. */
- a1 = advised;
- a4 |= VKI_MAP_FIXED;
-
- vg_assert(! FAILURE);
-
- sres = VG_(am_do_mmap_NO_NOTIFY)(a1, a2, a3, a4, a5, a6);
- SET_STATUS_from_SysRes(sres);
-
- if (!sres.isError) {
- /* Notify aspacem and the tool. */
- ML_(notify_aspacem_and_tool_of_mmap)(
- (Addr)sres.val, /* addr kernel actually assigned */
- a2, a3,
- args[4-1], /* the original flags value */
- a5, a6
- );
- /* Load symbols? */
- VG_(di_notify_mmap)( (Addr)sres.val );
- }
+PRE(sys_mmap2)
+{
+ SysRes r;
- /* Stay sane */
- if (SUCCESS && (args[4-1] & VKI_MAP_FIXED))
- vg_assert(RES == args[0]);
+ // Exactly like old_mmap() except:
+ // - all 6 args are passed in regs, rather than in a memory-block.
+ // - the file offset is specified in pagesize units rather than bytes,
+ // so that it can be used for files bigger than 2^32 bytes.
+ PRINT("sys_mmap2 ( %p, %llu, %d, %d, %d, %d )",
+ ARG1, (ULong)ARG2, ARG3, ARG4, ARG5, ARG6 );
+ PRE_REG_READ6(long, "mmap2",
+ unsigned long, start, unsigned long, length,
+ unsigned long, prot, unsigned long, flags,
+ unsigned long, fd, unsigned long, offset);
+
+ r = ML_(generic_PRE_sys_mmap)( tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 * VKI_PAGE_SIZE );
+ SET_STATUS_from_SysRes(r);
}
// XXX: lstat64/fstat64/stat64 are generic, but not necessarily
// Nb: we treat vfork as fork
GENX_(__NR_vfork, sys_fork), // 190
GENXY(__NR_ugetrlimit, sys_getrlimit), // 191
- LINX_(__NR_mmap2, sys_mmap2), // 192
+ PLAX_(__NR_mmap2, sys_mmap2), // 192
GENX_(__NR_truncate64, sys_truncate64), // 193
GENX_(__NR_ftruncate64, sys_ftruncate64), // 194