strace/mem.c

345 lines
8.6 KiB
C
Raw Normal View History

1999-02-19 03:21:36 +03:00
/*
* Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
* Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
* Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
1999-12-23 17:20:14 +03:00
* Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
* Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH
* port by Greg Banks <gbanks@pocketpenguins.com>
1999-02-19 03:21:36 +03:00
* All rights reserved.
*
* 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.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "defs.h"
#include <asm/mman.h>
#include <sys/mman.h>
Clean up mmap decoding Previous code merges too many similar, but different ways of decoding mmap. For example, sys_old_mmap is "params in memory" API... except SH[64], where it is "params in regs", i.e. what sys_mmap ("new mmap") function does on other arches! It's much simpler when every mmap handler has same API regardless of arch. Where API means whether params are in regs or in memory, and whether offset is in bytes, pages, or 4k blocks. Then we just insert correct function pointers into arch syscall tables. It turns out there are four common mmap APIs over all architectures which exist in Linux kernel, and one outlier for S390. A number of mmap decoders were plain wrong in arch tables. For example, BFIN has no old_mmap. It returns ENOSYS. I checked kernel sources for all arches nad fixed the tables. There was dead code for x86_64 for old_mmap: x86_64 has no old_mmap. * mem.c: Refactor mmap functions so that we have five mmap syscall handlers, each with the fixed API (not varying by arch). * pathtrace.c (pathtrace_match): Adjust sys_func == mmap_func checks. * linux/syscall.h: Declare new mmap syscall handler functions. * linux/arm/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/avr32/syscallent.h: mmap is sys_mmap_pgoff. * linux/bfin/syscallent.h: old_mmap is ENOSYS, mmap2 is sys_mmap_pgoff. * linux/hppa/syscallent.h: mmap2 is sys_mmap_4koff. * linux/i386/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/ia64/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/m68k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/microblaze/syscallent.h: old_mmap is sys_mmap, mmap2 is sys_mmap_pgoff. * linux/mips/syscallent.h: mmap is sys_mmap_4kgoff. * linux/or1k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/powerpc/syscallent.h: mmap2 is sys_mmap_4kgoff. * linux/s390/syscallent.h: mmap2 is sys_old_mmap_pgoff. * linux/s390x/syscallent.h: mmap is sys_old_mmap and thus has 1 arg. * linux/sh/syscallent.h: old_mmap2 is sys_mmap, mmap2 is sys_mmap_4koff. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent1.h: mmap is TD|TM. * linux/tile/syscallent1.h: mmap2 is sys_mmap_4koff. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-19 14:28:20 +04:00
unsigned long
get_pagesize(void)
{
static unsigned long pagesize;
if (!pagesize)
pagesize = sysconf(_SC_PAGESIZE);
return pagesize;
}
1999-02-19 03:21:36 +03:00
SYS_FUNC(brk)
1999-02-19 03:21:36 +03:00
{
printaddr(tcp->u_arg[0]);
return RVAL_DECODED | RVAL_HEX;
1999-02-19 03:21:36 +03:00
}
#include "xlat/mmap_prot.h"
#include "xlat/mmap_flags.h"
1999-02-19 03:21:36 +03:00
static void
print_mmap(struct tcb *tcp, long *u_arg, unsigned long long offset)
1999-02-19 03:21:36 +03:00
{
const unsigned long addr = u_arg[0];
const unsigned long len = u_arg[1];
const unsigned long prot = u_arg[2];
const unsigned long flags = u_arg[3];
const int fd = u_arg[4];
printaddr(addr);
tprintf(", %lu, ", len);
printflags_long(mmap_prot, prot, "PROT_???");
tprints(", ");
2000-09-02 01:03:06 +04:00
#ifdef MAP_TYPE
printxval_long(mmap_flags, flags & MAP_TYPE, "MAP_???");
addflags(mmap_flags, flags & ~MAP_TYPE);
2000-09-02 01:03:06 +04:00
#else
printflags_long(mmap_flags, flags, "MAP_???");
2000-09-02 01:03:06 +04:00
#endif
tprints(", ");
printfd(tcp, fd);
tprintf(", %#llx", offset);
1999-02-19 03:21:36 +03:00
}
Clean up mmap decoding Previous code merges too many similar, but different ways of decoding mmap. For example, sys_old_mmap is "params in memory" API... except SH[64], where it is "params in regs", i.e. what sys_mmap ("new mmap") function does on other arches! It's much simpler when every mmap handler has same API regardless of arch. Where API means whether params are in regs or in memory, and whether offset is in bytes, pages, or 4k blocks. Then we just insert correct function pointers into arch syscall tables. It turns out there are four common mmap APIs over all architectures which exist in Linux kernel, and one outlier for S390. A number of mmap decoders were plain wrong in arch tables. For example, BFIN has no old_mmap. It returns ENOSYS. I checked kernel sources for all arches nad fixed the tables. There was dead code for x86_64 for old_mmap: x86_64 has no old_mmap. * mem.c: Refactor mmap functions so that we have five mmap syscall handlers, each with the fixed API (not varying by arch). * pathtrace.c (pathtrace_match): Adjust sys_func == mmap_func checks. * linux/syscall.h: Declare new mmap syscall handler functions. * linux/arm/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/avr32/syscallent.h: mmap is sys_mmap_pgoff. * linux/bfin/syscallent.h: old_mmap is ENOSYS, mmap2 is sys_mmap_pgoff. * linux/hppa/syscallent.h: mmap2 is sys_mmap_4koff. * linux/i386/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/ia64/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/m68k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/microblaze/syscallent.h: old_mmap is sys_mmap, mmap2 is sys_mmap_pgoff. * linux/mips/syscallent.h: mmap is sys_mmap_4kgoff. * linux/or1k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/powerpc/syscallent.h: mmap2 is sys_mmap_4kgoff. * linux/s390/syscallent.h: mmap2 is sys_old_mmap_pgoff. * linux/s390x/syscallent.h: mmap is sys_old_mmap and thus has 1 arg. * linux/sh/syscallent.h: old_mmap2 is sys_mmap, mmap2 is sys_mmap_4koff. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent1.h: mmap is TD|TM. * linux/tile/syscallent1.h: mmap2 is sys_mmap_4koff. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-19 14:28:20 +04:00
/* Syscall name<->function correspondence is messed up on many arches.
* For example:
* i386 has __NR_mmap == 90, and it is "old mmap", and
* also it has __NR_mmap2 == 192, which is a "new mmap with page offsets".
* But x86_64 has just one __NR_mmap == 9, a "new mmap with byte offsets".
* Confused? Me too!
*/
#if defined AARCH64 || defined ARM \
|| defined I386 || defined X86_64 || defined X32 \
|| defined M68K \
|| defined S390 || defined S390X
Clean up mmap decoding Previous code merges too many similar, but different ways of decoding mmap. For example, sys_old_mmap is "params in memory" API... except SH[64], where it is "params in regs", i.e. what sys_mmap ("new mmap") function does on other arches! It's much simpler when every mmap handler has same API regardless of arch. Where API means whether params are in regs or in memory, and whether offset is in bytes, pages, or 4k blocks. Then we just insert correct function pointers into arch syscall tables. It turns out there are four common mmap APIs over all architectures which exist in Linux kernel, and one outlier for S390. A number of mmap decoders were plain wrong in arch tables. For example, BFIN has no old_mmap. It returns ENOSYS. I checked kernel sources for all arches nad fixed the tables. There was dead code for x86_64 for old_mmap: x86_64 has no old_mmap. * mem.c: Refactor mmap functions so that we have five mmap syscall handlers, each with the fixed API (not varying by arch). * pathtrace.c (pathtrace_match): Adjust sys_func == mmap_func checks. * linux/syscall.h: Declare new mmap syscall handler functions. * linux/arm/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/avr32/syscallent.h: mmap is sys_mmap_pgoff. * linux/bfin/syscallent.h: old_mmap is ENOSYS, mmap2 is sys_mmap_pgoff. * linux/hppa/syscallent.h: mmap2 is sys_mmap_4koff. * linux/i386/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/ia64/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/m68k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/microblaze/syscallent.h: old_mmap is sys_mmap, mmap2 is sys_mmap_pgoff. * linux/mips/syscallent.h: mmap is sys_mmap_4kgoff. * linux/or1k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/powerpc/syscallent.h: mmap2 is sys_mmap_4kgoff. * linux/s390/syscallent.h: mmap2 is sys_old_mmap_pgoff. * linux/s390x/syscallent.h: mmap is sys_old_mmap and thus has 1 arg. * linux/sh/syscallent.h: old_mmap2 is sys_mmap, mmap2 is sys_mmap_4koff. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent1.h: mmap is TD|TM. * linux/tile/syscallent1.h: mmap2 is sys_mmap_4koff. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-19 14:28:20 +04:00
/* Params are pointed to by u_arg[0], offset is in bytes */
SYS_FUNC(old_mmap)
1999-12-23 17:20:14 +03:00
{
Clean up mmap decoding Previous code merges too many similar, but different ways of decoding mmap. For example, sys_old_mmap is "params in memory" API... except SH[64], where it is "params in regs", i.e. what sys_mmap ("new mmap") function does on other arches! It's much simpler when every mmap handler has same API regardless of arch. Where API means whether params are in regs or in memory, and whether offset is in bytes, pages, or 4k blocks. Then we just insert correct function pointers into arch syscall tables. It turns out there are four common mmap APIs over all architectures which exist in Linux kernel, and one outlier for S390. A number of mmap decoders were plain wrong in arch tables. For example, BFIN has no old_mmap. It returns ENOSYS. I checked kernel sources for all arches nad fixed the tables. There was dead code for x86_64 for old_mmap: x86_64 has no old_mmap. * mem.c: Refactor mmap functions so that we have five mmap syscall handlers, each with the fixed API (not varying by arch). * pathtrace.c (pathtrace_match): Adjust sys_func == mmap_func checks. * linux/syscall.h: Declare new mmap syscall handler functions. * linux/arm/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/avr32/syscallent.h: mmap is sys_mmap_pgoff. * linux/bfin/syscallent.h: old_mmap is ENOSYS, mmap2 is sys_mmap_pgoff. * linux/hppa/syscallent.h: mmap2 is sys_mmap_4koff. * linux/i386/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/ia64/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/m68k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/microblaze/syscallent.h: old_mmap is sys_mmap, mmap2 is sys_mmap_pgoff. * linux/mips/syscallent.h: mmap is sys_mmap_4kgoff. * linux/or1k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/powerpc/syscallent.h: mmap2 is sys_mmap_4kgoff. * linux/s390/syscallent.h: mmap2 is sys_old_mmap_pgoff. * linux/s390x/syscallent.h: mmap is sys_old_mmap and thus has 1 arg. * linux/sh/syscallent.h: old_mmap2 is sys_mmap, mmap2 is sys_mmap_4koff. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent1.h: mmap is TD|TM. * linux/tile/syscallent1.h: mmap2 is sys_mmap_4koff. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-19 14:28:20 +04:00
long u_arg[6];
# if defined AARCH64 || defined X86_64
/* We are here only in a 32-bit personality. */
unsigned int narrow_arg[6];
if (umove_or_printaddr(tcp, tcp->u_arg[0], &narrow_arg))
return RVAL_DECODED | RVAL_HEX;
unsigned int i;
for (i = 0; i < 6; i++)
u_arg[i] = narrow_arg[i];
# else
if (umove_or_printaddr(tcp, tcp->u_arg[0], &u_arg))
return RVAL_DECODED | RVAL_HEX;
# endif
print_mmap(tcp, u_arg, (unsigned long) u_arg[5]);
return RVAL_DECODED | RVAL_HEX;
1999-12-23 17:20:14 +03:00
}
#endif /* old_mmap architectures */
1999-12-23 17:20:14 +03:00
Clean up mmap decoding Previous code merges too many similar, but different ways of decoding mmap. For example, sys_old_mmap is "params in memory" API... except SH[64], where it is "params in regs", i.e. what sys_mmap ("new mmap") function does on other arches! It's much simpler when every mmap handler has same API regardless of arch. Where API means whether params are in regs or in memory, and whether offset is in bytes, pages, or 4k blocks. Then we just insert correct function pointers into arch syscall tables. It turns out there are four common mmap APIs over all architectures which exist in Linux kernel, and one outlier for S390. A number of mmap decoders were plain wrong in arch tables. For example, BFIN has no old_mmap. It returns ENOSYS. I checked kernel sources for all arches nad fixed the tables. There was dead code for x86_64 for old_mmap: x86_64 has no old_mmap. * mem.c: Refactor mmap functions so that we have five mmap syscall handlers, each with the fixed API (not varying by arch). * pathtrace.c (pathtrace_match): Adjust sys_func == mmap_func checks. * linux/syscall.h: Declare new mmap syscall handler functions. * linux/arm/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/avr32/syscallent.h: mmap is sys_mmap_pgoff. * linux/bfin/syscallent.h: old_mmap is ENOSYS, mmap2 is sys_mmap_pgoff. * linux/hppa/syscallent.h: mmap2 is sys_mmap_4koff. * linux/i386/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/ia64/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/m68k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/microblaze/syscallent.h: old_mmap is sys_mmap, mmap2 is sys_mmap_pgoff. * linux/mips/syscallent.h: mmap is sys_mmap_4kgoff. * linux/or1k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/powerpc/syscallent.h: mmap2 is sys_mmap_4kgoff. * linux/s390/syscallent.h: mmap2 is sys_old_mmap_pgoff. * linux/s390x/syscallent.h: mmap is sys_old_mmap and thus has 1 arg. * linux/sh/syscallent.h: old_mmap2 is sys_mmap, mmap2 is sys_mmap_4koff. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent1.h: mmap is TD|TM. * linux/tile/syscallent1.h: mmap2 is sys_mmap_4koff. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-19 14:28:20 +04:00
#if defined(S390)
/* Params are pointed to by u_arg[0], offset is in pages */
SYS_FUNC(old_mmap_pgoff)
Clean up mmap decoding Previous code merges too many similar, but different ways of decoding mmap. For example, sys_old_mmap is "params in memory" API... except SH[64], where it is "params in regs", i.e. what sys_mmap ("new mmap") function does on other arches! It's much simpler when every mmap handler has same API regardless of arch. Where API means whether params are in regs or in memory, and whether offset is in bytes, pages, or 4k blocks. Then we just insert correct function pointers into arch syscall tables. It turns out there are four common mmap APIs over all architectures which exist in Linux kernel, and one outlier for S390. A number of mmap decoders were plain wrong in arch tables. For example, BFIN has no old_mmap. It returns ENOSYS. I checked kernel sources for all arches nad fixed the tables. There was dead code for x86_64 for old_mmap: x86_64 has no old_mmap. * mem.c: Refactor mmap functions so that we have five mmap syscall handlers, each with the fixed API (not varying by arch). * pathtrace.c (pathtrace_match): Adjust sys_func == mmap_func checks. * linux/syscall.h: Declare new mmap syscall handler functions. * linux/arm/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/avr32/syscallent.h: mmap is sys_mmap_pgoff. * linux/bfin/syscallent.h: old_mmap is ENOSYS, mmap2 is sys_mmap_pgoff. * linux/hppa/syscallent.h: mmap2 is sys_mmap_4koff. * linux/i386/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/ia64/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/m68k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/microblaze/syscallent.h: old_mmap is sys_mmap, mmap2 is sys_mmap_pgoff. * linux/mips/syscallent.h: mmap is sys_mmap_4kgoff. * linux/or1k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/powerpc/syscallent.h: mmap2 is sys_mmap_4kgoff. * linux/s390/syscallent.h: mmap2 is sys_old_mmap_pgoff. * linux/s390x/syscallent.h: mmap is sys_old_mmap and thus has 1 arg. * linux/sh/syscallent.h: old_mmap2 is sys_mmap, mmap2 is sys_mmap_4koff. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent1.h: mmap is TD|TM. * linux/tile/syscallent1.h: mmap2 is sys_mmap_4koff. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-19 14:28:20 +04:00
{
long u_arg[5];
int i;
unsigned narrow_arg[6];
unsigned long long offset;
if (umoven(tcp, tcp->u_arg[0], sizeof(narrow_arg), narrow_arg) == -1)
Clean up mmap decoding Previous code merges too many similar, but different ways of decoding mmap. For example, sys_old_mmap is "params in memory" API... except SH[64], where it is "params in regs", i.e. what sys_mmap ("new mmap") function does on other arches! It's much simpler when every mmap handler has same API regardless of arch. Where API means whether params are in regs or in memory, and whether offset is in bytes, pages, or 4k blocks. Then we just insert correct function pointers into arch syscall tables. It turns out there are four common mmap APIs over all architectures which exist in Linux kernel, and one outlier for S390. A number of mmap decoders were plain wrong in arch tables. For example, BFIN has no old_mmap. It returns ENOSYS. I checked kernel sources for all arches nad fixed the tables. There was dead code for x86_64 for old_mmap: x86_64 has no old_mmap. * mem.c: Refactor mmap functions so that we have five mmap syscall handlers, each with the fixed API (not varying by arch). * pathtrace.c (pathtrace_match): Adjust sys_func == mmap_func checks. * linux/syscall.h: Declare new mmap syscall handler functions. * linux/arm/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/avr32/syscallent.h: mmap is sys_mmap_pgoff. * linux/bfin/syscallent.h: old_mmap is ENOSYS, mmap2 is sys_mmap_pgoff. * linux/hppa/syscallent.h: mmap2 is sys_mmap_4koff. * linux/i386/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/ia64/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/m68k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/microblaze/syscallent.h: old_mmap is sys_mmap, mmap2 is sys_mmap_pgoff. * linux/mips/syscallent.h: mmap is sys_mmap_4kgoff. * linux/or1k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/powerpc/syscallent.h: mmap2 is sys_mmap_4kgoff. * linux/s390/syscallent.h: mmap2 is sys_old_mmap_pgoff. * linux/s390x/syscallent.h: mmap is sys_old_mmap and thus has 1 arg. * linux/sh/syscallent.h: old_mmap2 is sys_mmap, mmap2 is sys_mmap_4koff. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent1.h: mmap is TD|TM. * linux/tile/syscallent1.h: mmap2 is sys_mmap_4koff. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-19 14:28:20 +04:00
return 0;
for (i = 0; i < 5; i++)
u_arg[i] = (unsigned long) narrow_arg[i];
offset = narrow_arg[5];
offset *= get_pagesize();
print_mmap(tcp, u_arg, offset);
return RVAL_DECODED | RVAL_HEX;
Clean up mmap decoding Previous code merges too many similar, but different ways of decoding mmap. For example, sys_old_mmap is "params in memory" API... except SH[64], where it is "params in regs", i.e. what sys_mmap ("new mmap") function does on other arches! It's much simpler when every mmap handler has same API regardless of arch. Where API means whether params are in regs or in memory, and whether offset is in bytes, pages, or 4k blocks. Then we just insert correct function pointers into arch syscall tables. It turns out there are four common mmap APIs over all architectures which exist in Linux kernel, and one outlier for S390. A number of mmap decoders were plain wrong in arch tables. For example, BFIN has no old_mmap. It returns ENOSYS. I checked kernel sources for all arches nad fixed the tables. There was dead code for x86_64 for old_mmap: x86_64 has no old_mmap. * mem.c: Refactor mmap functions so that we have five mmap syscall handlers, each with the fixed API (not varying by arch). * pathtrace.c (pathtrace_match): Adjust sys_func == mmap_func checks. * linux/syscall.h: Declare new mmap syscall handler functions. * linux/arm/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/avr32/syscallent.h: mmap is sys_mmap_pgoff. * linux/bfin/syscallent.h: old_mmap is ENOSYS, mmap2 is sys_mmap_pgoff. * linux/hppa/syscallent.h: mmap2 is sys_mmap_4koff. * linux/i386/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/ia64/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/m68k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/microblaze/syscallent.h: old_mmap is sys_mmap, mmap2 is sys_mmap_pgoff. * linux/mips/syscallent.h: mmap is sys_mmap_4kgoff. * linux/or1k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/powerpc/syscallent.h: mmap2 is sys_mmap_4kgoff. * linux/s390/syscallent.h: mmap2 is sys_old_mmap_pgoff. * linux/s390x/syscallent.h: mmap is sys_old_mmap and thus has 1 arg. * linux/sh/syscallent.h: old_mmap2 is sys_mmap, mmap2 is sys_mmap_4koff. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent1.h: mmap is TD|TM. * linux/tile/syscallent1.h: mmap2 is sys_mmap_4koff. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-19 14:28:20 +04:00
}
#endif
/* Params are passed directly, offset is in bytes */
SYS_FUNC(mmap)
1999-12-23 17:20:14 +03:00
{
unsigned long long offset =
#if HAVE_STRUCT_TCB_EXT_ARG
tcp->ext_arg[5]; /* try test/x32_mmap.c */
#else
(unsigned long) tcp->u_arg[5];
#endif
Clean up mmap decoding Previous code merges too many similar, but different ways of decoding mmap. For example, sys_old_mmap is "params in memory" API... except SH[64], where it is "params in regs", i.e. what sys_mmap ("new mmap") function does on other arches! It's much simpler when every mmap handler has same API regardless of arch. Where API means whether params are in regs or in memory, and whether offset is in bytes, pages, or 4k blocks. Then we just insert correct function pointers into arch syscall tables. It turns out there are four common mmap APIs over all architectures which exist in Linux kernel, and one outlier for S390. A number of mmap decoders were plain wrong in arch tables. For example, BFIN has no old_mmap. It returns ENOSYS. I checked kernel sources for all arches nad fixed the tables. There was dead code for x86_64 for old_mmap: x86_64 has no old_mmap. * mem.c: Refactor mmap functions so that we have five mmap syscall handlers, each with the fixed API (not varying by arch). * pathtrace.c (pathtrace_match): Adjust sys_func == mmap_func checks. * linux/syscall.h: Declare new mmap syscall handler functions. * linux/arm/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/avr32/syscallent.h: mmap is sys_mmap_pgoff. * linux/bfin/syscallent.h: old_mmap is ENOSYS, mmap2 is sys_mmap_pgoff. * linux/hppa/syscallent.h: mmap2 is sys_mmap_4koff. * linux/i386/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/ia64/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/m68k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/microblaze/syscallent.h: old_mmap is sys_mmap, mmap2 is sys_mmap_pgoff. * linux/mips/syscallent.h: mmap is sys_mmap_4kgoff. * linux/or1k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/powerpc/syscallent.h: mmap2 is sys_mmap_4kgoff. * linux/s390/syscallent.h: mmap2 is sys_old_mmap_pgoff. * linux/s390x/syscallent.h: mmap is sys_old_mmap and thus has 1 arg. * linux/sh/syscallent.h: old_mmap2 is sys_mmap, mmap2 is sys_mmap_4koff. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent1.h: mmap is TD|TM. * linux/tile/syscallent1.h: mmap2 is sys_mmap_4koff. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-19 14:28:20 +04:00
/* Example of kernel-side handling of this variety of mmap:
* arch/x86/kernel/sys_x86_64.c::SYSCALL_DEFINE6(mmap, ...) calls
* sys_mmap_pgoff(..., off >> PAGE_SHIFT); i.e. off is in bytes,
* since the above code converts off to pages.
*/
print_mmap(tcp, tcp->u_arg, offset);
return RVAL_DECODED | RVAL_HEX;
Clean up mmap decoding Previous code merges too many similar, but different ways of decoding mmap. For example, sys_old_mmap is "params in memory" API... except SH[64], where it is "params in regs", i.e. what sys_mmap ("new mmap") function does on other arches! It's much simpler when every mmap handler has same API regardless of arch. Where API means whether params are in regs or in memory, and whether offset is in bytes, pages, or 4k blocks. Then we just insert correct function pointers into arch syscall tables. It turns out there are four common mmap APIs over all architectures which exist in Linux kernel, and one outlier for S390. A number of mmap decoders were plain wrong in arch tables. For example, BFIN has no old_mmap. It returns ENOSYS. I checked kernel sources for all arches nad fixed the tables. There was dead code for x86_64 for old_mmap: x86_64 has no old_mmap. * mem.c: Refactor mmap functions so that we have five mmap syscall handlers, each with the fixed API (not varying by arch). * pathtrace.c (pathtrace_match): Adjust sys_func == mmap_func checks. * linux/syscall.h: Declare new mmap syscall handler functions. * linux/arm/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/avr32/syscallent.h: mmap is sys_mmap_pgoff. * linux/bfin/syscallent.h: old_mmap is ENOSYS, mmap2 is sys_mmap_pgoff. * linux/hppa/syscallent.h: mmap2 is sys_mmap_4koff. * linux/i386/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/ia64/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/m68k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/microblaze/syscallent.h: old_mmap is sys_mmap, mmap2 is sys_mmap_pgoff. * linux/mips/syscallent.h: mmap is sys_mmap_4kgoff. * linux/or1k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/powerpc/syscallent.h: mmap2 is sys_mmap_4kgoff. * linux/s390/syscallent.h: mmap2 is sys_old_mmap_pgoff. * linux/s390x/syscallent.h: mmap is sys_old_mmap and thus has 1 arg. * linux/sh/syscallent.h: old_mmap2 is sys_mmap, mmap2 is sys_mmap_4koff. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent1.h: mmap is TD|TM. * linux/tile/syscallent1.h: mmap2 is sys_mmap_4koff. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-19 14:28:20 +04:00
}
/* Params are passed directly, offset is in pages */
SYS_FUNC(mmap_pgoff)
Clean up mmap decoding Previous code merges too many similar, but different ways of decoding mmap. For example, sys_old_mmap is "params in memory" API... except SH[64], where it is "params in regs", i.e. what sys_mmap ("new mmap") function does on other arches! It's much simpler when every mmap handler has same API regardless of arch. Where API means whether params are in regs or in memory, and whether offset is in bytes, pages, or 4k blocks. Then we just insert correct function pointers into arch syscall tables. It turns out there are four common mmap APIs over all architectures which exist in Linux kernel, and one outlier for S390. A number of mmap decoders were plain wrong in arch tables. For example, BFIN has no old_mmap. It returns ENOSYS. I checked kernel sources for all arches nad fixed the tables. There was dead code for x86_64 for old_mmap: x86_64 has no old_mmap. * mem.c: Refactor mmap functions so that we have five mmap syscall handlers, each with the fixed API (not varying by arch). * pathtrace.c (pathtrace_match): Adjust sys_func == mmap_func checks. * linux/syscall.h: Declare new mmap syscall handler functions. * linux/arm/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/avr32/syscallent.h: mmap is sys_mmap_pgoff. * linux/bfin/syscallent.h: old_mmap is ENOSYS, mmap2 is sys_mmap_pgoff. * linux/hppa/syscallent.h: mmap2 is sys_mmap_4koff. * linux/i386/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/ia64/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/m68k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/microblaze/syscallent.h: old_mmap is sys_mmap, mmap2 is sys_mmap_pgoff. * linux/mips/syscallent.h: mmap is sys_mmap_4kgoff. * linux/or1k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/powerpc/syscallent.h: mmap2 is sys_mmap_4kgoff. * linux/s390/syscallent.h: mmap2 is sys_old_mmap_pgoff. * linux/s390x/syscallent.h: mmap is sys_old_mmap and thus has 1 arg. * linux/sh/syscallent.h: old_mmap2 is sys_mmap, mmap2 is sys_mmap_4koff. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent1.h: mmap is TD|TM. * linux/tile/syscallent1.h: mmap2 is sys_mmap_4koff. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-19 14:28:20 +04:00
{
/* Try test/mmap_offset_decode.c */
unsigned long long offset;
offset = (unsigned long) tcp->u_arg[5];
offset *= get_pagesize();
print_mmap(tcp, tcp->u_arg, offset);
return RVAL_DECODED | RVAL_HEX;
Clean up mmap decoding Previous code merges too many similar, but different ways of decoding mmap. For example, sys_old_mmap is "params in memory" API... except SH[64], where it is "params in regs", i.e. what sys_mmap ("new mmap") function does on other arches! It's much simpler when every mmap handler has same API regardless of arch. Where API means whether params are in regs or in memory, and whether offset is in bytes, pages, or 4k blocks. Then we just insert correct function pointers into arch syscall tables. It turns out there are four common mmap APIs over all architectures which exist in Linux kernel, and one outlier for S390. A number of mmap decoders were plain wrong in arch tables. For example, BFIN has no old_mmap. It returns ENOSYS. I checked kernel sources for all arches nad fixed the tables. There was dead code for x86_64 for old_mmap: x86_64 has no old_mmap. * mem.c: Refactor mmap functions so that we have five mmap syscall handlers, each with the fixed API (not varying by arch). * pathtrace.c (pathtrace_match): Adjust sys_func == mmap_func checks. * linux/syscall.h: Declare new mmap syscall handler functions. * linux/arm/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/avr32/syscallent.h: mmap is sys_mmap_pgoff. * linux/bfin/syscallent.h: old_mmap is ENOSYS, mmap2 is sys_mmap_pgoff. * linux/hppa/syscallent.h: mmap2 is sys_mmap_4koff. * linux/i386/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/ia64/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/m68k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/microblaze/syscallent.h: old_mmap is sys_mmap, mmap2 is sys_mmap_pgoff. * linux/mips/syscallent.h: mmap is sys_mmap_4kgoff. * linux/or1k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/powerpc/syscallent.h: mmap2 is sys_mmap_4kgoff. * linux/s390/syscallent.h: mmap2 is sys_old_mmap_pgoff. * linux/s390x/syscallent.h: mmap is sys_old_mmap and thus has 1 arg. * linux/sh/syscallent.h: old_mmap2 is sys_mmap, mmap2 is sys_mmap_4koff. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent1.h: mmap is TD|TM. * linux/tile/syscallent1.h: mmap2 is sys_mmap_4koff. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-19 14:28:20 +04:00
}
/* Params are passed directly, offset is in 4k units */
SYS_FUNC(mmap_4koff)
Clean up mmap decoding Previous code merges too many similar, but different ways of decoding mmap. For example, sys_old_mmap is "params in memory" API... except SH[64], where it is "params in regs", i.e. what sys_mmap ("new mmap") function does on other arches! It's much simpler when every mmap handler has same API regardless of arch. Where API means whether params are in regs or in memory, and whether offset is in bytes, pages, or 4k blocks. Then we just insert correct function pointers into arch syscall tables. It turns out there are four common mmap APIs over all architectures which exist in Linux kernel, and one outlier for S390. A number of mmap decoders were plain wrong in arch tables. For example, BFIN has no old_mmap. It returns ENOSYS. I checked kernel sources for all arches nad fixed the tables. There was dead code for x86_64 for old_mmap: x86_64 has no old_mmap. * mem.c: Refactor mmap functions so that we have five mmap syscall handlers, each with the fixed API (not varying by arch). * pathtrace.c (pathtrace_match): Adjust sys_func == mmap_func checks. * linux/syscall.h: Declare new mmap syscall handler functions. * linux/arm/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/avr32/syscallent.h: mmap is sys_mmap_pgoff. * linux/bfin/syscallent.h: old_mmap is ENOSYS, mmap2 is sys_mmap_pgoff. * linux/hppa/syscallent.h: mmap2 is sys_mmap_4koff. * linux/i386/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/ia64/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/m68k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/microblaze/syscallent.h: old_mmap is sys_mmap, mmap2 is sys_mmap_pgoff. * linux/mips/syscallent.h: mmap is sys_mmap_4kgoff. * linux/or1k/syscallent.h: mmap2 is sys_mmap_pgoff. * linux/powerpc/syscallent.h: mmap2 is sys_mmap_4kgoff. * linux/s390/syscallent.h: mmap2 is sys_old_mmap_pgoff. * linux/s390x/syscallent.h: mmap is sys_old_mmap and thus has 1 arg. * linux/sh/syscallent.h: old_mmap2 is sys_mmap, mmap2 is sys_mmap_4koff. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent1.h: mmap is TD|TM. * linux/tile/syscallent1.h: mmap2 is sys_mmap_4koff. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-19 14:28:20 +04:00
{
unsigned long long offset;
offset = (unsigned long) tcp->u_arg[5];
offset <<= 12;
print_mmap(tcp, tcp->u_arg, offset);
return RVAL_DECODED | RVAL_HEX;
1999-12-23 17:20:14 +03:00
}
SYS_FUNC(munmap)
1999-02-19 03:21:36 +03:00
{
printaddr(tcp->u_arg[0]);
tprintf(", %lu", tcp->u_arg[1]);
return RVAL_DECODED;
1999-02-19 03:21:36 +03:00
}
SYS_FUNC(mprotect)
1999-02-19 03:21:36 +03:00
{
printaddr(tcp->u_arg[0]);
tprintf(", %lu, ", tcp->u_arg[1]);
printflags_long(mmap_prot, tcp->u_arg[2], "PROT_???");
return RVAL_DECODED;
1999-02-19 03:21:36 +03:00
}
#include "xlat/mremap_flags.h"
SYS_FUNC(mremap)
{
printaddr(tcp->u_arg[0]);
tprintf(", %lu, %lu, ", tcp->u_arg[1], tcp->u_arg[2]);
printflags_long(mremap_flags, tcp->u_arg[3], "MREMAP_???");
#ifdef MREMAP_FIXED
if ((tcp->u_arg[3] & (MREMAP_MAYMOVE | MREMAP_FIXED)) ==
(MREMAP_MAYMOVE | MREMAP_FIXED)) {
tprints(", ");
printaddr(tcp->u_arg[4]);
}
#endif
return RVAL_DECODED | RVAL_HEX;
}
#include "xlat/madvise_cmds.h"
SYS_FUNC(madvise)
{
printaddr(tcp->u_arg[0]);
tprintf(", %lu, ", tcp->u_arg[1]);
printxval(madvise_cmds, tcp->u_arg[2], "MADV_???");
return RVAL_DECODED;
}
#include "xlat/mlockall_flags.h"
SYS_FUNC(mlockall)
{
printflags(mlockall_flags, tcp->u_arg[0], "MCL_???");
return RVAL_DECODED;
}
#include "xlat/mctl_sync.h"
1999-02-19 03:21:36 +03:00
SYS_FUNC(msync)
1999-02-19 03:21:36 +03:00
{
/* addr */
printaddr(tcp->u_arg[0]);
/* len */
tprintf(", %lu, ", tcp->u_arg[1]);
/* flags */
printflags(mctl_sync, tcp->u_arg[2], "MS_???");
return RVAL_DECODED;
1999-02-19 03:21:36 +03:00
}
#include "xlat/mlock_flags.h"
SYS_FUNC(mlock2)
{
printaddr(tcp->u_arg[0]);
tprintf(", %lu, ", tcp->u_arg[1]);
printflags(mlock_flags, tcp->u_arg[2], "MLOCK_???");
return RVAL_DECODED;
}
SYS_FUNC(mincore)
1999-02-19 03:21:36 +03:00
{
if (entering(tcp)) {
printaddr(tcp->u_arg[0]);
tprintf(", %lu, ", tcp->u_arg[1]);
1999-02-19 03:21:36 +03:00
} else {
const unsigned long page_size = get_pagesize();
const unsigned long page_mask = page_size - 1;
unsigned long len = tcp->u_arg[1];
unsigned char *vec = NULL;
len = len / page_size + (len & page_mask ? 1 : 0);
if (syserror(tcp) || !verbose(tcp) ||
!tcp->u_arg[2] || !(vec = malloc(len)) ||
umoven(tcp, tcp->u_arg[2], len, vec) < 0)
printaddr(tcp->u_arg[2]);
1999-02-19 03:21:36 +03:00
else {
unsigned long i;
tprints("[");
1999-02-19 03:21:36 +03:00
for (i = 0; i < len; i++) {
if (abbrev(tcp) && i >= max_strlen) {
tprints("...");
1999-02-19 03:21:36 +03:00
break;
}
tprints((vec[i] & 1) ? "1" : "0");
1999-02-19 03:21:36 +03:00
}
tprints("]");
1999-02-19 03:21:36 +03:00
}
free(vec);
1999-02-19 03:21:36 +03:00
}
return 0;
}
#if defined ALPHA || defined IA64 || defined M68K \
|| defined SPARC || defined SPARC64
SYS_FUNC(getpagesize)
1999-02-19 03:21:36 +03:00
{
return RVAL_DECODED | RVAL_HEX;
1999-02-19 03:21:36 +03:00
}
#endif
1999-02-19 03:21:36 +03:00
SYS_FUNC(remap_file_pages)
{
const unsigned long addr = tcp->u_arg[0];
const unsigned long size = tcp->u_arg[1];
const unsigned long prot = tcp->u_arg[2];
const unsigned long pgoff = tcp->u_arg[3];
const unsigned long flags = tcp->u_arg[4];
printaddr(addr);
tprintf(", %lu, ", size);
printflags_long(mmap_prot, prot, "PROT_???");
tprintf(", %lu, ", pgoff);
#ifdef MAP_TYPE
printxval_long(mmap_flags, flags & MAP_TYPE, "MAP_???");
addflags(mmap_flags, flags & ~MAP_TYPE);
#else
printflags_long(mmap_flags, flags, "MAP_???");
#endif
return RVAL_DECODED;
}
#if defined(POWERPC)
static bool
print_protmap_entry(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
{
tprintf("%#08x", * (unsigned int *) elem_buf);
return true;
}
SYS_FUNC(subpage_prot)
{
unsigned long addr = tcp->u_arg[0];
unsigned long len = tcp->u_arg[1];
unsigned long nmemb = len >> 16;
unsigned long map = tcp->u_arg[2];
printaddr(addr);
tprintf(", %lu, ", len);
unsigned int entry;
print_array(tcp, map, nmemb, &entry, sizeof(entry),
umoven_or_printaddr, print_protmap_entry, 0);
return RVAL_DECODED;
}
#endif