Ejemplo n.º 1
0
static int
netlink_parse_response(const void *data, const int data_len,
		       const unsigned long inode, void *opaque_data)
{
	const char *proto_name = opaque_data;
	const struct netlink_diag_msg *const diag_msg = data;
	const char *netlink_proto;
	char *details;

	if (data_len < (int) NLMSG_LENGTH(sizeof(*diag_msg)))
		return -1;
	if (diag_msg->ndiag_ino != inode)
		return 0;

	if (diag_msg->ndiag_family != AF_NETLINK)
		return -1;

	netlink_proto = xlookup(netlink_protocols,
				diag_msg->ndiag_protocol);

	if (netlink_proto) {
		netlink_proto = STR_STRIP_PREFIX(netlink_proto, "NETLINK_");
		if (asprintf(&details, "%s:[%s:%u]", proto_name,
			     netlink_proto, diag_msg->ndiag_portid) < 0)
			return -1;
	} else {
		if (asprintf(&details, "%s:[%u]", proto_name,
			     (unsigned) diag_msg->ndiag_protocol) < 0)
			return -1;
	}

	return cache_inode_details(inode, details);
}
Ejemplo n.º 2
0
static void
btrfs_print_objectid(uint64_t objectid)
{
	const char *str = xlookup(btrfs_tree_objectids, objectid);
	tprintf("%" PRIu64, objectid);
	if (str)
		tprintf(" /* %s */", str);
}
Ejemplo n.º 3
0
static void
btrfs_print_key_type(uint32_t type)
{
	const char *str = xlookup(btrfs_key_types, type);
	tprintf("%u", type);
	if (str)
		tprintf(" /* %s */", str);
}
Ejemplo n.º 4
0
static int
do_adjtimex(struct tcb *tcp, long addr)
{
	if (print_timex(tcp, addr))
		return 0;
	tcp->auxstr = xlookup(adjtimex_state, tcp->u_rval);
	if (tcp->auxstr)
		return RVAL_STR;
	return 0;
}
Ejemplo n.º 5
0
/*
 * Print entry in struct xlat table, if there.
 */
void
printxval(const struct xlat *xlat, int val, const char *dflt)
{
	const char *str = xlookup(xlat, val);

	if (str)
		tprints(str);
	else
		tprintf("%#x /* %s */", val, dflt);
}
Ejemplo n.º 6
0
static void
print_keyring_serial_number(key_serial_t id)
{
    const char *str = xlookup(key_spec, id);

    if (str)
        tprints(str);
    else
        tprintf("%d", id);
}
Ejemplo n.º 7
0
int EiC_ymark(char *file,
	  int lineno, void *p, char mark)
{
    int found;
    found = xlookup(p);
    assertp(found < 0,STDMSG);
    MTAB[BNO(p)].dbuf[found].mark = mark;

    return 1;
}
Ejemplo n.º 8
0
/*
 * low bits of the socket type define real socket type,
 * other bits are socket type flags.
 */
static void
tprint_sock_type(int flags)
{
	const char *str = xlookup(socktypes, flags & SOCK_TYPE_MASK);

	if (str) {
		tprints(str);
		flags &= ~SOCK_TYPE_MASK;
		if (!flags)
			return;
		tprints("|");
	}
	printflags(sock_type_flags, flags, "SOCK_???");
}
Ejemplo n.º 9
0
void EiC_yfree(char *file, int lineno, void * p)
{
    int found,bno = BNO(p);
    found = xlookup(p);
    if(found < 0) {
	/*EiC_warningerror("free non-xalloc ptr: from %s line %d", file, lineno);*/
	(free)(p);
    } else {
	EiC_tot_memory -= MTAB[bno].dbuf[found].nbytes;
	EiC_tot_alloc--;
	(free)(p);
	MTAB[bno].dbuf[found].p = NULL;
	MTAB[bno].dbuf[found].mark = freemark;
    }
}
Ejemplo n.º 10
0
static int
do_adjtimex(struct tcb *tcp, long addr)
{
	if (addr == 0)
		tprints("NULL");
	else if (syserror(tcp) || !verbose(tcp))
		tprintf("%#lx", addr);
	else if (tprint_timex(tcp, addr) < 0)
		tprints("{...}");
	if (syserror(tcp))
		return 0;
	tcp->auxstr = xlookup(adjtimex_state, tcp->u_rval);
	if (tcp->auxstr)
		return RVAL_STR;
	return 0;
}
Ejemplo n.º 11
0
void * EiC_yrealloc(char *file, int lineno, void *oldp, size_t nbytes)
{
    void *newp;
    int found, d;
    
    if(oldp != NULL) {
	found =  xlookup(oldp);
	assertp(found < 0,STDMSG);
    }
    
    newp = realloc(oldp,nbytes);
    
    assertp(nbytes && newp == NULL,("line %d in file %s\n",lineno,file));
    
    if(oldp) {
	int bno = BNO(oldp);
	d = nbytes - MTAB[bno].dbuf[found].nbytes;
	if(bno != BNO(newp)) {

	    int i;
	    
	    MTAB[bno].dbuf[found].p = NULL;
	    MTAB[bno].dbuf[found].mark = freemark;
	    i = install(file,lineno,newp,nbytes);
	    /* retain creation time stamp */
	    MTAB[BNO(newp)].dbuf[i].alloc_num
	    	    = MTAB[bno].dbuf[found].alloc_num;

	} else {
	    MTAB[bno].dbuf[found].p = newp;
	    MTAB[bno].dbuf[found].nbytes = nbytes;
	    MTAB[bno].dbuf[found].crt_file = file;
	    MTAB[bno].dbuf[found].crt_lineno = lineno;
	}
	EiC_tot_memory += d;
    } else
	install(file,lineno,newp,nbytes);
    

    return newp;
}
Ejemplo n.º 12
0
/*
 * low bits of the open(2) flags define access mode,
 * other bits are real flags.
 */
const char *
sprint_open_modes(unsigned int flags)
{
	static char outstr[(1 + ARRAY_SIZE(open_mode_flags)) * sizeof("O_LARGEFILE")];
	char *p;
	char sep;
	const char *str;
	const struct xlat *x;

	sep = ' ';
	p = stpcpy(outstr, "flags");
	str = xlookup(open_access_modes, flags & 3);
	if (str) {
		*p++ = sep;
		p = stpcpy(p, str);
		flags &= ~3;
		if (!flags)
			return outstr;
		sep = '|';
	}

	for (x = open_mode_flags; x->str; x++) {
		if ((flags & x->val) == x->val) {
			*p++ = sep;
			p = stpcpy(p, x->str);
			flags &= ~x->val;
			if (!flags)
				return outstr;
			sep = '|';
		}
	}
	/* flags is still nonzero */
	*p++ = sep;
	sprintf(p, "%#x", flags);
	return outstr;
}
Ejemplo n.º 13
0
void * EiC_yrealloc(char *file, int lineno, void *oldp, size_t nbytes)
{
    void *newp;
    int found = 0, d, bOld = 0, bno = 0; //maks

	if(nbytes <= 0 && oldp)
	{
		//maks: realloc definition
		EiC_yfree(file, lineno, oldp);
		return 0;
	}
    
    if(oldp != NULL) 
	{
		found =  xlookup(oldp);
		assertp(found < 0,STDMSG);
		bOld = 1; //maks
		bno = BNO(oldp);
    }

	if(GetGameMode())
	{
		unsigned long total = EiC_tot_memory + nbytes;
		if(total > gedMaxGameMem) //maks
		{
			//Don't alloc more then gedMaxGameMem
			EiC_error("Attempt to access %lu bytes.\n    If is correct, set the variable gedMaxGameMem=%lu or more\n    in an action before the allocation", nbytes, total);
			nbytes = 4;
		}
	}
	realAllocatedMem = nbytes;
    
    newp = realloc(oldp,nbytes);
    
    assertp(nbytes && newp == NULL,("line %d in file %s\n",lineno,file));
    
    if(bOld) //maks
	{
		d = nbytes - MTAB[bno].dbuf[found].nbytes;
		EiC_tot_memory -= MTAB[bno].dbuf[found].nbytes; //maks

		if(bno != BNO(newp)) 
		{
			
			int i;
			
			MTAB[bno].dbuf[found].p = NULL;
			MTAB[bno].dbuf[found].mark = freemark;
			i = install(file,lineno,newp,nbytes);
			/* retain creation time stamp */
			MTAB[BNO(newp)].dbuf[i].alloc_num
				= MTAB[bno].dbuf[found].alloc_num;
			
		} 
		else 
		{
			MTAB[bno].dbuf[found].p = newp;
			MTAB[bno].dbuf[found].nbytes = nbytes;
			MTAB[bno].dbuf[found].crt_file = file;
			MTAB[bno].dbuf[found].crt_lineno = lineno;

			EiC_tot_memory += nbytes; //maks
		}

		
    } 
	else
	{
		install(file,lineno,newp,nbytes);
	}
    

    return newp;
}
Ejemplo n.º 14
0
MPERS_PRINTER_DECL(int, btrfs_ioctl,
		   struct tcb *tcp, const unsigned int code, const long arg)
{
	switch (code) {
	/* Take no arguments; command only. */
	case BTRFS_IOC_TRANS_START:
	case BTRFS_IOC_TRANS_END:
	case BTRFS_IOC_SYNC:
	case BTRFS_IOC_SCRUB_CANCEL:
	case BTRFS_IOC_QUOTA_RESCAN_WAIT:
	/*
	 * The codes for these ioctls are based on each accepting a
	 * vol_args but none of them actually consume an argument.
	 */
	case BTRFS_IOC_DEFRAG:
	case BTRFS_IOC_BALANCE:
		break;

	/* takes a signed int */
	case BTRFS_IOC_BALANCE_CTL:
		tprints(", ");
		printxval(btrfs_balance_ctl_cmds, arg, "BTRFS_BALANCE_CTL_???");
		break;

	/* returns a 64 */
	case BTRFS_IOC_START_SYNC: /* R */
		if (entering(tcp))
			return 0;
	/* fall through */
	/* takes a u64 */
	case BTRFS_IOC_DEFAULT_SUBVOL: /* W */
	case BTRFS_IOC_WAIT_SYNC: /* W */
		tprints(", ");
		printnum_int64(tcp, arg, "%" PRIu64);
		break;

	/* u64 but describe a flags bitfield; we can make that symbolic */
	case BTRFS_IOC_SUBVOL_GETFLAGS: { /* R */
		uint64_t flags;

		if (entering(tcp))
			return 0;

		tprints(", ");

		if (umove_or_printaddr(tcp, arg, &flags))
			break;

		printflags64(btrfs_snap_flags_v2, flags, "BTRFS_SUBVOL_???");
		break;
	}

	case BTRFS_IOC_SUBVOL_SETFLAGS: { /* W */
		uint64_t flags;

		tprints(", ");

		if (umove_or_printaddr(tcp, arg, &flags))
			break;

		printflags64(btrfs_snap_flags_v2, flags, "BTRFS_SUBVOL_???");
		break;
	}

	/* More complex types */
	case BTRFS_IOC_BALANCE_V2: /* RW */
		if (entering(tcp)) {
			tprints(", ");
			btrfs_print_balance(tcp, arg, false);
			return 0;
		}

		if (syserror(tcp))
			break;

		tprints(" => ");
		btrfs_print_balance(tcp, arg, true);
		break;
	case BTRFS_IOC_BALANCE_PROGRESS: /* R */
		if (entering(tcp))
			return 0;

		tprints(", ");
		btrfs_print_balance(tcp, arg, true);
		break;

	case BTRFS_IOC_DEFRAG_RANGE: { /* W */
		struct btrfs_ioctl_defrag_range_args args;

		tprints(", ");

		if (umove_or_printaddr(tcp, arg, &args))
			break;

		tprintf("{start=%" PRIu64 ", len=", (uint64_t)args.start);

		tprintf("%" PRIu64, (uint64_t) args.len);
		if (args.len == UINT64_MAX)
			tprints(" /* UINT64_MAX */");

		tprints(", flags=");
		printflags64(btrfs_defrag_flags, args.flags,
			     "BTRFS_DEFRAG_RANGE_???");
		tprintf(", extent_thresh=%u, compress_type=",
			args.extent_thresh);
		printxval(btrfs_compress_types, args.compress_type,
			  "BTRFS_COMPRESS_???");
		tprints("}");
		break;
	}

	case BTRFS_IOC_DEV_INFO: { /* RW */
		struct btrfs_ioctl_dev_info_args args;
		char uuid[UUID_STRING_SIZE+1];
		int valid;

		if (entering(tcp))
			tprints(", ");
		else if (syserror(tcp))
			break;
		else
			tprints(" => ");
		if (umove_or_printaddr(tcp, arg, &args))
			break;
		tprints("{");

		valid = btrfs_unparse_uuid(args.uuid, uuid);
		if (entering(tcp)) {
			tprintf("devid=%" PRI__u64, args.devid);
			if (valid)
				tprintf(", uuid=%s", uuid);
			tprints("}");
			return 0;
		}
		if (valid)
			tprintf("uuid=%s, ", uuid);
		tprintf("bytes_used=%" PRI__u64
			", total_bytes=%" PRI__u64 ", path=",
			args.bytes_used, args.total_bytes);
		print_quoted_string((const char *)args.path, sizeof(args.path),
				    QUOTE_0_TERMINATED);
		tprints("}");
		break;
	}

	case BTRFS_IOC_DEV_REPLACE: { /* RW */
		struct_btrfs_ioctl_dev_replace_args args;

		if (entering(tcp))
			tprints(", ");
		else if (syserror(tcp))
			break;
		else
			tprints(" => ");

		if (umove_or_printaddr(tcp, arg, &args))
			break;

		if (entering(tcp)) {
			tprints("{cmd=");
			printxval64(btrfs_dev_replace_cmds, args.cmd,
				    "BTRFS_IOCTL_DEV_REPLACE_CMD_???");
			if (args.cmd == BTRFS_IOCTL_DEV_REPLACE_CMD_START) {
				const char *str;
				tprintf(", start={srcdevid=%" PRIu64
				   ", cont_reading_from_srcdev_mode=%" PRIu64
				   ", srcdev_name=",
				   (uint64_t) args.start.srcdevid,
				   (uint64_t) args.start.cont_reading_from_srcdev_mode);

				str = (const char*) args.start.srcdev_name;
				print_quoted_string(str,
						sizeof(args.start.srcdev_name),
						QUOTE_0_TERMINATED);
				tprints(", tgtdev_name=");
				str = (const char*) args.start.tgtdev_name;
				print_quoted_string(str,
						sizeof(args.start.tgtdev_name),
						QUOTE_0_TERMINATED);
				tprints("}");

			}
			tprints("}");
			return 0;
		}

		tprints("{result=");
		printxval64(btrfs_dev_replace_results, args.result,
			    "BTRFS_IOCTL_DEV_REPLACE_RESULT_???");
		if (args.cmd == BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS) {
			char buf[sizeof("HH:MM:SS") + 1];
			time_t time;
			tprints(", ");
			printxval64(btrfs_dev_replace_state,
				   args.status.replace_state,
				   "BTRFS_IOCTL_DEV_REPLACE_STATE_???");
			tprintf(", progress_1000=%" PRIu64 " /* ",
				(uint64_t) args.status.progress_1000);
			if (args.status.progress_1000 <= 1000)
				tprintf("%" PRIu64 ".%.2" PRIu64 "%%",
					(uint64_t) args.status.progress_1000 / 10,
					(uint64_t) args.status.progress_1000 % 10);
			else
				tprints("???");
			tprints(" */ ,");

			time = args.status.time_started;
			strftime(buf, sizeof(buf), "%T",
				 localtime(&time));
			tprintf("time_started=%" PRIu64" /* %s */, ",
				(uint64_t) args.status.time_started, buf);

			time = args.status.time_stopped;
			strftime(buf, sizeof(buf), "%T",
				 localtime(&time));
			tprintf("time_stopped=%" PRIu64" /* %s */, ",
				(uint64_t) args.status.time_stopped, buf);

			tprintf("num_write_errors=%" PRIu64
				", num_uncorrectable_read_errors=%" PRIu64,
				(uint64_t) args.status.num_write_errors,
				(uint64_t) args.status.num_uncorrectable_read_errors);
		}
		tprints("}");
		break;
	}

	case BTRFS_IOC_GET_FEATURES: { /* R */
		struct btrfs_ioctl_feature_flags flags;

		if (entering(tcp))
			return 0;

		tprints(", ");
		if (umove_or_printaddr(tcp, arg, &flags))
			break;

		btrfs_print_features(&flags);
		break;
	}

	case BTRFS_IOC_SET_FEATURES: { /* W */
		struct btrfs_ioctl_feature_flags flarg[2];

		tprints(", ");

		if (umove_or_printaddr(tcp, arg, &flarg))
			break;

		tprints("[");
		btrfs_print_features(&flarg[0]);
		tprints(", ");
		btrfs_print_features(&flarg[1]);
		tprints("]");
		break;
	}

	case BTRFS_IOC_GET_SUPPORTED_FEATURES: { /* R */
		struct btrfs_ioctl_feature_flags flarg[3];

		if (entering(tcp))
			return 0;

		tprints(", ");
		if (umove_or_printaddr(tcp, arg, &flarg))
			break;

		tprints("[ /* supported */ ");
		btrfs_print_features(&flarg[0]);

		tprints(", /* safe to set */ ");
		btrfs_print_features(&flarg[1]);

		tprints(", /* safe to clear */ ");
		btrfs_print_features(&flarg[2]);
		tprints("]");

		break;
	}

	case BTRFS_IOC_FS_INFO: { /* R */
		struct btrfs_ioctl_fs_info_args args;
		char uuid[UUID_STRING_SIZE+1];
		uint32_t nodesize, sectorsize, clone_alignment;
#ifndef HAVE_STRUCT_BTRFS_IOCTL_FS_INFO_ARGS_NODESIZE
		__u32 *reserved32;
#endif

		if (entering(tcp))
			return 0;

		tprints(", ");
		if (umove_or_printaddr(tcp, arg, &args))
			break;

#ifdef HAVE_STRUCT_BTRFS_IOCTL_FS_INFO_ARGS_NODESIZE
		nodesize = args.nodesize,
		sectorsize = args.sectorsize,
		clone_alignment = args.clone_alignment;
#else
		reserved32 = (__u32 *) (void *) args.reserved;
		nodesize = reserved32[0];
		sectorsize = reserved32[1];
		clone_alignment = reserved32[2];
#endif
		btrfs_unparse_uuid(args.fsid, uuid);

		tprints("{");
		tprintf("max_id=%" PRI__u64 ", num_devices=%" PRI__u64
			", fsid=%s, nodesize=%u, sectorsize=%u"
			", clone_alignment=%u",
			args.max_id, args.num_devices, uuid,
			nodesize, sectorsize, clone_alignment);
		tprints("}");
		break;
	}

	case BTRFS_IOC_GET_DEV_STATS: { /* RW */
		struct btrfs_ioctl_get_dev_stats args;
		uint64_t i;

		if (entering(tcp))
			tprints(", ");
		else if (syserror(tcp))
			break;
		else
			tprints(" => ");
		if (umove_or_printaddr(tcp, arg, &args))
			break;

		tprints("{");

		if (entering(tcp))
			tprintf("devid=%" PRI__u64 ", ", args.devid);

		tprintf("nr_items=%" PRI__u64 ", flags=", args.nr_items);
		printflags64(btrfs_dev_stats_flags, args.flags,
			     "BTRFS_DEV_STATS_???");

		if (entering(tcp)) {
			tprints("}");
			return 0;
		}

		/*
		 * The structure has a 1k limit; Let's make sure we don't
		 * go off into the middle of nowhere with a bad nr_items
		 * value.
		 */
		tprints(", [");
		for (i = 0; i < args.nr_items; i++) {
			if (i)
				tprints(", ");
			if (i >= ARRAY_SIZE(args.values)) {
				tprints("...");
				break;
			}
			const char *name = xlookup(btrfs_dev_stats_values, i);
			if (name)
				tprintf("/* %s */ ", name);
			tprintf("%" PRI__u64, args.values[i]);
		}
		tprints("]}");
		break;
	}

	case BTRFS_IOC_INO_LOOKUP: { /* RW */
		struct btrfs_ioctl_ino_lookup_args args;

		if (entering(tcp))
			tprints(", ");
		else if (syserror(tcp))
			break;
		else
			tprints(" => ");

		if (umove_or_printaddr(tcp, arg, &args))
			break;

		if (entering(tcp)) {
			/* Use subvolume id of the containing root */
			if (args.treeid == 0)
				set_tcb_priv_ulong(tcp, 1);

			tprints("{treeid=");
			btrfs_print_objectid(args.treeid);
			tprints(", objectid=");
			btrfs_print_objectid(args.objectid);
			tprints("}");
			return 0;
		}

		tprints("{");
		if (get_tcb_priv_ulong(tcp)) {
			tprints("treeid=");
			btrfs_print_objectid(args.treeid);
			tprints(", ");
		}

		tprints("name=");
		print_quoted_string(args.name, sizeof(args.name),
				    QUOTE_0_TERMINATED);
		tprints("}");
		break;
	}

	case BTRFS_IOC_INO_PATHS: { /* RW */
		struct btrfs_ioctl_ino_path_args args;

		if (entering(tcp))
			tprints(", ");
		else if (syserror(tcp))
			break;
		else
			tprints(" => ");

		if (umove_or_printaddr(tcp, arg, &args))
			break;

		tprints("{");

		if (entering(tcp)) {
			tprintf("inum=%" PRI__u64 ", size=%" PRI__u64,
				args.inum, args.size);
			tprintf(", fspath=0x%" PRI__x64 "}", args.fspath);
			return 0;
		}

		tprints("fspath=");
		btrfs_print_ino_path_container(tcp, args.fspath);

		tprints("}");
		break;
	}

	case BTRFS_IOC_LOGICAL_INO: { /* RW */
		struct btrfs_ioctl_logical_ino_args args;

		if (entering(tcp))
			tprints(", ");
		else if (syserror(tcp))
			break;
		else
			tprints(" => ");

		if (umove_or_printaddr(tcp, arg, &args))
			break;

		tprints("{");

		if (entering(tcp)) {
			tprintf("logical=%" PRI__u64 ", size=%" PRI__u64,
				args.logical, args.size);
			tprintf(", inodes=0x%" PRI__x64 "}", args.inodes);
			return 0;
		}

		tprints("inodes=");
		btrfs_print_logical_ino_container(tcp, args.inodes);

		tprints("}");
		break;
	}

	case BTRFS_IOC_QGROUP_ASSIGN: { /* W */
		struct btrfs_ioctl_qgroup_assign_args args;

		tprints(", ");
		if (umove_or_printaddr(tcp, arg, &args))
			break;

		tprintf("{assign=%" PRI__u64 ", src=%" PRI__u64
			", dst=%" PRI__u64 "}",
			args.assign, args.src, args.dst);
		break;
	}

	case BTRFS_IOC_QGROUP_CREATE: { /* W */
		struct btrfs_ioctl_qgroup_create_args args;

		tprints(", ");
		if (umove_or_printaddr(tcp, arg, &args))
			break;

		tprintf("{create=%" PRI__u64 ", qgroupid=%" PRI__u64 "}",
			args.create, args.qgroupid);
		break;
	}

	case BTRFS_IOC_QGROUP_LIMIT: { /* R */
		struct btrfs_ioctl_qgroup_limit_args args;

		if (entering(tcp))
			return 0;

		tprints(", ");
		if (umove_or_printaddr(tcp, arg, &args))
			break;

		tprintf("{qgroupid=%" PRI__u64 ", lim=", args.qgroupid);
		btrfs_print_qgroup_limit(&args.lim);
		tprints("}");
		break;
	}

	case BTRFS_IOC_QUOTA_CTL: { /* W */
		struct btrfs_ioctl_quota_ctl_args args;

		tprints(", ");
		if (umove_or_printaddr(tcp, arg, &args))
			break;

		printxval64(btrfs_qgroup_ctl_cmds, args.cmd,
			    "BTRFS_QUOTA_CTL_???");
		tprints("}");

		break;
	}

	case BTRFS_IOC_QUOTA_RESCAN: { /* W */
		struct btrfs_ioctl_quota_rescan_args args;

		tprints(", ");
		if (umove_or_printaddr(tcp, arg, &args))
			break;

		tprintf("{flags=%" PRIu64 "}", (uint64_t) args.flags);
		break;
	}

	case BTRFS_IOC_QUOTA_RESCAN_STATUS: { /* R */
		struct btrfs_ioctl_quota_rescan_args args;

		if (entering(tcp))
			return 0;

		tprints(", ");
		if (umove_or_printaddr(tcp, arg, &args))
			break;

		tprintf("{flags=%" PRIu64 ", progress=", (uint64_t) args.flags);
		btrfs_print_objectid(args.progress);
		tprints("}");
		break;
	}

	case BTRFS_IOC_SET_RECEIVED_SUBVOL: { /* RW */
		struct_btrfs_ioctl_received_subvol_args args;
		char uuid[UUID_STRING_SIZE+1];

		if (entering(tcp))
			tprints(", ");
		else if (syserror(tcp))
			break;
		else
			tprints(" => ");

		if (umove_or_printaddr(tcp, arg, &args))
			break;

		if (entering(tcp)) {
			btrfs_unparse_uuid((unsigned char *)args.uuid, uuid);
			tprintf("{uuid=%s, stransid=%" PRIu64
				", stime=%" PRIu64 ".%u, flags=%" PRIu64
				"}", uuid, (uint64_t) args.stransid,
				(uint64_t) args.stime.sec, args.stime.nsec,
				(uint64_t) args.flags);
			return 0;
		}
		tprintf("{rtransid=%" PRIu64 ", rtime=%" PRIu64 ".%u}",
			(uint64_t) args.rtransid, (uint64_t) args.rtime.sec,
			args.rtime.nsec);
		break;
	}

	case BTRFS_IOC_SCRUB: /* RW */
	case BTRFS_IOC_SCRUB_PROGRESS: { /* RW */
		struct btrfs_ioctl_scrub_args args;

		if (entering(tcp))
			tprints(", ");
		else if (syserror(tcp))
			break;
		else
			tprints(" => ");

		if (umove_or_printaddr(tcp, arg, &args))
			break;

		if (entering(tcp)) {
			tprintf("{devid=%" PRI__u64, args.devid);
			if (code == BTRFS_IOC_SCRUB) {
				tprintf(", start=%" PRI__u64 ", end=",
					args.start);
				tprintf("%" PRI__u64, args.end);
				if (args.end == UINT64_MAX)
					tprints(" /* UINT64_MAX */");
				tprints(", flags=");
				printflags64(btrfs_scrub_flags, args.flags,
					     "BTRFS_SCRUB_???");
			}
			tprints("}");
			return 0;
		}
		tprintf("{data_extents_scrubbed=%" PRI__u64
			", tree_extents_scrubbed=%" PRI__u64
			", data_bytes_scrubbed=%" PRI__u64
			", tree_bytes_scrubbed=%" PRI__u64
			", read_errors=%" PRI__u64
			", csum_errors=%" PRI__u64
			", verify_errors=%" PRI__u64
			", no_csum=%" PRI__u64
			", csum_discards=%" PRI__u64
			", super_errors=%" PRI__u64
			", malloc_errors=%" PRI__u64
			", uncorrectable_errors=%" PRI__u64
			", corrected_errors=%" PRI__u64
			", last_physical=%" PRI__u64
			", unverified_errors=%" PRI__u64 "}",
			args.progress.data_extents_scrubbed,
			args.progress.tree_extents_scrubbed,
			args.progress.data_bytes_scrubbed,
			args.progress.tree_bytes_scrubbed,
			args.progress.read_errors,
			args.progress.csum_errors,
			args.progress.verify_errors,
			args.progress.no_csum,
			args.progress.csum_discards,
			args.progress.super_errors,
			args.progress.malloc_errors,
			args.progress.uncorrectable_errors,
			args.progress.corrected_errors,
			args.progress.last_physical,
			args.progress.unverified_errors);
		break;
	}

	case BTRFS_IOC_TREE_SEARCH: { /* RW */
		struct btrfs_ioctl_search_args args;
		uint64_t buf_offset;

		if (entering(tcp))
			tprints(", ");
		else if (syserror(tcp))
			break;
		else
			tprints(" => ");

		if (umove_or_printaddr(tcp, arg, &args))
			break;

		buf_offset = offsetof(struct btrfs_ioctl_search_args, buf);
		btrfs_print_tree_search(tcp, &args.key, arg + buf_offset,
					sizeof(args.buf), false);
		if (entering(tcp))
			return 0;
		break;
	}

	case BTRFS_IOC_TREE_SEARCH_V2: { /* RW */
		struct btrfs_ioctl_search_args_v2 args;
		uint64_t buf_offset;

		if (entering(tcp))
			tprints(", ");
		else if (syserror(tcp)) {
			if (tcp->u_error == EOVERFLOW) {
				tprints(" => ");
				tcp->u_error = 0;
				if (!umove_or_printaddr(tcp, arg, &args))
					tprintf("{buf_size=%" PRIu64 "}",
						(uint64_t)args.buf_size);
				tcp->u_error = EOVERFLOW;
			}
			break;
		} else
			tprints(" => ");

		if (umove_or_printaddr(tcp, arg, &args))
			break;

		buf_offset = offsetof(struct btrfs_ioctl_search_args_v2, buf);
		btrfs_print_tree_search(tcp, &args.key, arg + buf_offset,
					args.buf_size, true);
		if (entering(tcp))
			return 0;
		break;
	}

	case BTRFS_IOC_SEND: { /* W */
		struct_btrfs_ioctl_send_args args;

		tprints(", ");
		if (umove_or_printaddr(tcp, arg, &args))
			break;

		tprints("{send_fd=");
		printfd(tcp, args.send_fd);
		tprintf(", clone_sources_count=%" PRIu64 ", clone_sources=",
			(uint64_t) args.clone_sources_count);

		if (abbrev(tcp))
			tprints("...");
		else {
			uint64_t record;
			print_array(tcp, (unsigned long) args.clone_sources,
				    args.clone_sources_count,
				    &record, sizeof(record),
				    umoven_or_printaddr,
				    print_objectid_callback, 0);
		}
		tprints(", parent_root=");
		btrfs_print_objectid(args.parent_root);
		tprints(", flags=");
		printflags64(btrfs_send_flags, args.flags,
			     "BTRFS_SEND_FLAGS_???");
		tprints("}");
		break;
	}

	case BTRFS_IOC_SPACE_INFO: { /* RW */
		struct btrfs_ioctl_space_args args;

		if (entering(tcp))
			tprints(", ");
		else if (syserror(tcp))
			break;
		else
			tprints(" => ");

		if (umove_or_printaddr(tcp, arg, &args))
			break;

		tprints("{");
		if (entering(tcp)) {
			tprintf("space_slots=%" PRI__u64 "}", args.space_slots);
			return 0;
		}

		tprintf("total_spaces=%" PRI__u64, args.total_spaces);

		if (args.space_slots == 0 && args.total_spaces) {
			tprints("}");
			break;
		}

		tprints(", spaces=");

		if (abbrev(tcp))
			tprints("...");
		else {
			struct btrfs_ioctl_space_info info;
			print_array(tcp, arg + offsetof(typeof(args), spaces),
				    args.total_spaces,
				    &info, sizeof(info), umoven_or_printaddr,
				    print_btrfs_ioctl_space_info, 0);
		}
		tprints("}");
		break;
	}

	case BTRFS_IOC_SNAP_CREATE:
	case BTRFS_IOC_RESIZE:
	case BTRFS_IOC_SCAN_DEV:
	case BTRFS_IOC_ADD_DEV:
	case BTRFS_IOC_RM_DEV:
	case BTRFS_IOC_SUBVOL_CREATE:
	case BTRFS_IOC_SNAP_DESTROY:
	case BTRFS_IOC_DEVICES_READY: { /* W */
		struct btrfs_ioctl_vol_args args;

		tprints(", ");
		if (umove_or_printaddr(tcp, arg, &args))
			break;

		tprints("{fd=");
		printfd(tcp, args.fd);
		tprints(", name=");
		print_quoted_string(args.name, sizeof(args.name),
				    QUOTE_0_TERMINATED);
		tprints("}");
		break;
	}

	case BTRFS_IOC_SNAP_CREATE_V2:
	case BTRFS_IOC_SUBVOL_CREATE_V2: { /* code is W, but is actually RW */
		struct btrfs_ioctl_vol_args_v2 args;

		if (entering(tcp))
			tprints(", ");
		else if (syserror(tcp))
			break;
		else
			tprints(" => ");

		if (umove_or_printaddr(tcp, arg, &args))
			break;

		if (entering(tcp)) {
			tprints("{fd=");
			printfd(tcp, args.fd);
			tprints(", flags=");
			printflags64(btrfs_snap_flags_v2, args.flags,
				     "BTRFS_SUBVOL_???");
			if (args.flags & BTRFS_SUBVOL_QGROUP_INHERIT) {
				tprintf(", size=%" PRI__u64 ", qgroup_inherit=",
					args.size);

				btrfs_print_qgroup_inherit(tcp,
					(unsigned long)args.qgroup_inherit);
			}
			tprintf(", name=");
			print_quoted_string(args.name, sizeof(args.name),
					    QUOTE_0_TERMINATED);
			tprints("}");
			return 0;
		}
		tprintf("{transid=%" PRI__u64 "}", args.transid);
		break;
	}

	case BTRFS_IOC_GET_FSLABEL: /* R */
		if (entering(tcp))
			return 0;
		/* fall through */
	case BTRFS_IOC_SET_FSLABEL: { /* W */
		char label[BTRFS_LABEL_SIZE];

		tprints(", ");
		if (umove_or_printaddr(tcp, arg, &label))
			break;
		print_quoted_string(label, sizeof(label), QUOTE_0_TERMINATED);
		break;
	}

	case BTRFS_IOC_CLONE:			/* FICLONE */
	case BTRFS_IOC_CLONE_RANGE:		/* FICLONERANGE */
#ifdef BTRFS_IOC_FILE_EXTENT_SAME
	case BTRFS_IOC_FILE_EXTENT_SAME:	/* FIDEDUPERANGE */
#endif
		/*
		 * FICLONE, FICLONERANGE, and FIDEDUPERANGE started out as
		 * btrfs ioctls and the code was kept for the generic
		 * implementations.  We use the BTRFS_* names here because
		 * they will be available on older systems.
		 */
		return file_ioctl(tcp, code, arg);

	default:
		return RVAL_DECODED;
	};
	return RVAL_DECODED | 1;
}
Ejemplo n.º 15
0
int
sys_fcntl(struct tcb *tcp)
{
	if (entering(tcp)) {
		printfd(tcp, tcp->u_arg[0]);
		tprints(", ");
		printxval(fcntlcmds, tcp->u_arg[1], "F_???");
		switch (tcp->u_arg[1]) {
		case F_SETFD:
			tprints(", ");
			printflags(fdflags, tcp->u_arg[2], "FD_???");
			break;
		case F_SETOWN: case F_DUPFD:
#ifdef F_DUPFD_CLOEXEC
		case F_DUPFD_CLOEXEC:
#endif
			tprintf(", %ld", tcp->u_arg[2]);
			break;
		case F_SETFL:
			tprints(", ");
			tprint_open_modes(tcp->u_arg[2]);
			break;
		case F_SETLK: case F_SETLKW:
			tprints(", ");
			printflock(tcp, tcp->u_arg[2], 0);
			break;
#if USE_PRINTFLOCK64
		case F_SETLK64: case F_SETLKW64:
			tprints(", ");
			printflock64(tcp, tcp->u_arg[2], 0);
			break;
#endif /* USE_PRINTFLOCK64 */
#ifdef F_NOTIFY
		case F_NOTIFY:
			tprints(", ");
			printflags(notifyflags, tcp->u_arg[2], "DN_???");
			break;
#endif
#ifdef F_SETLEASE
		case F_SETLEASE:
			tprints(", ");
			printxval(lockfcmds, tcp->u_arg[2], "F_???");
			break;
#endif
		}
	}
	else {
		switch (tcp->u_arg[1]) {
		case F_DUPFD:
#ifdef F_DUPFD_CLOEXEC
		case F_DUPFD_CLOEXEC:
#endif
		case F_SETFD: case F_SETFL:
		case F_SETLK: case F_SETLKW:
		case F_SETOWN: case F_GETOWN:
#ifdef F_NOTIFY
		case F_NOTIFY:
#endif
#ifdef F_SETLEASE
		case F_SETLEASE:
#endif
			break;
		case F_GETFD:
			if (syserror(tcp) || tcp->u_rval == 0)
				return 0;
			tcp->auxstr = sprintflags("flags ", fdflags, tcp->u_rval);
			return RVAL_HEX|RVAL_STR;
		case F_GETFL:
			if (syserror(tcp))
				return 0;
			tcp->auxstr = sprint_open_modes(tcp->u_rval);
			return RVAL_HEX|RVAL_STR;
		case F_GETLK:
			tprints(", ");
			printflock(tcp, tcp->u_arg[2], 1);
			break;
#if USE_PRINTFLOCK64
		case F_GETLK64:
			tprints(", ");
			printflock64(tcp, tcp->u_arg[2], 1);
			break;
#endif
#ifdef F_GETLEASE
		case F_GETLEASE:
			if (syserror(tcp))
				return 0;
			tcp->auxstr = xlookup(lockfcmds, tcp->u_rval);
			return RVAL_HEX|RVAL_STR;
#endif
		default:
			tprintf(", %#lx", tcp->u_arg[2]);
			break;
		}
	}
	return 0;
}
Ejemplo n.º 16
0
int
sys_fcntl(struct tcb *tcp)
{
	if (entering(tcp)) {
		tprintf("%ld, ", tcp->u_arg[0]);
		printxval(fcntlcmds, tcp->u_arg[1], "F_???");
		switch (tcp->u_arg[1]) {
		case F_SETFD:
			tprintf(", ");
			printflags(fdflags, tcp->u_arg[2], "FD_???");
			break;
		case F_SETOWN: case F_DUPFD:
#ifdef F_DUPFD_CLOEXEC
		case F_DUPFD_CLOEXEC:
#endif
			tprintf(", %ld", tcp->u_arg[2]);
			break;
		case F_SETFL:
			tprintf(", ");
			tprint_open_modes(tcp->u_arg[2]);
			break;
		case F_SETLK: case F_SETLKW:
#ifdef F_FREESP
		case F_FREESP:
#endif
			tprintf(", ");
			printflock(tcp, tcp->u_arg[2], 0);
			break;
#if _LFS64_LARGEFILE
#ifdef F_FREESP64
		case F_FREESP64:
#endif
		/* Linux glibc defines SETLK64 as SETLK,
		   even though the kernel has different values - as does Solaris. */
#if defined(F_SETLK64) && F_SETLK64 + 0 != F_SETLK
		case F_SETLK64:
#endif
#if defined(F_SETLKW64) && F_SETLKW64 + 0 != F_SETLKW
		case F_SETLKW64:
#endif
			tprintf(", ");
			printflock64(tcp, tcp->u_arg[2], 0);
			break;
#endif
#ifdef F_NOTIFY
		case F_NOTIFY:
			tprintf(", ");
			printflags(notifyflags, tcp->u_arg[2], "DN_???");
			break;
#endif
#ifdef F_SETLEASE
		case F_SETLEASE:
			tprintf(", ");
			printxval(lockfcmds, tcp->u_arg[2], "F_???");
			break;
#endif
		}
	}
	else {
		switch (tcp->u_arg[1]) {
		case F_DUPFD:
#ifdef F_DUPFD_CLOEXEC
		case F_DUPFD_CLOEXEC:
#endif
		case F_SETFD: case F_SETFL:
		case F_SETLK: case F_SETLKW:
		case F_SETOWN: case F_GETOWN:
#ifdef F_NOTIFY
		case F_NOTIFY:
#endif
#ifdef F_SETLEASE
		case F_SETLEASE:
#endif
			break;
		case F_GETFD:
			if (syserror(tcp) || tcp->u_rval == 0)
				return 0;
			tcp->auxstr = sprintflags("flags ", fdflags, tcp->u_rval);
			return RVAL_HEX|RVAL_STR;
		case F_GETFL:
			if (syserror(tcp))
				return 0;
			tcp->auxstr = sprint_open_modes(tcp->u_rval);
			return RVAL_HEX|RVAL_STR;
		case F_GETLK:
			tprintf(", ");
			printflock(tcp, tcp->u_arg[2], 1);
			break;
#if _LFS64_LARGEFILE
#if defined(F_GETLK64) && F_GETLK64+0!=F_GETLK
		case F_GETLK64:
#endif
			tprintf(", ");
			printflock64(tcp, tcp->u_arg[2], 1);
			break;
#endif
#ifdef F_GETLEASE
		case F_GETLEASE:
			if (syserror(tcp))
				return 0;
			tcp->auxstr = xlookup(lockfcmds, tcp->u_rval);
			return RVAL_HEX|RVAL_STR;
#endif
		default:
			tprintf(", %#lx", tcp->u_arg[2]);
			break;
		}
	}
	return 0;
}
Ejemplo n.º 17
0
static void
print_si_code(int si_signo, unsigned int si_code)
{
	const char *code = xlookup(siginfo_codes, si_code);

	if (!code) {
		switch (si_signo) {
		case SIGTRAP:
			code = xlookup(sigtrap_codes, si_code);
			break;
		case SIGCHLD:
			code = xlookup(sigchld_codes, si_code);
			break;
		case SIGPOLL:
			code = xlookup(sigpoll_codes, si_code);
			break;
		case SIGPROF:
			code = xlookup(sigprof_codes, si_code);
			break;
		case SIGILL:
			code = xlookup(sigill_codes, si_code);
			break;
#ifdef SIGEMT
		case SIGEMT:
			code = xlookup(sigemt_codes, si_code);
			break;
#endif
		case SIGFPE:
			code = xlookup(sigfpe_codes, si_code);
			break;
		case SIGSEGV:
			code = xlookup(sigsegv_codes, si_code);
			break;
		case SIGBUS:
			code = xlookup(sigbus_codes, si_code);
			break;
		case SIGSYS:
			code = xlookup(sigsys_codes, si_code);
			break;
		}
	}

	if (code)
		tprints(code);
	else
		tprintf("%#x", si_code);
}
Ejemplo n.º 18
0
void
printsiginfo(siginfo_t *sip, int verbose)
{
	const char *code;

	if (sip->si_signo == 0) {
		tprints("{}");
		return;
	}
	tprints("{si_signo=");
	printsignal(sip->si_signo);
	code = xlookup(siginfo_codes, sip->si_code);
	if (!code) {
		switch (sip->si_signo) {
		case SIGTRAP:
			code = xlookup(sigtrap_codes, sip->si_code);
			break;
		case SIGCHLD:
			code = xlookup(sigchld_codes, sip->si_code);
			break;
		case SIGPOLL:
			code = xlookup(sigpoll_codes, sip->si_code);
			break;
		case SIGPROF:
			code = xlookup(sigprof_codes, sip->si_code);
			break;
		case SIGILL:
			code = xlookup(sigill_codes, sip->si_code);
			break;
#ifdef SIGEMT
		case SIGEMT:
			code = xlookup(sigemt_codes, sip->si_code);
			break;
#endif
		case SIGFPE:
			code = xlookup(sigfpe_codes, sip->si_code);
			break;
		case SIGSEGV:
			code = xlookup(sigsegv_codes, sip->si_code);
			break;
		case SIGBUS:
			code = xlookup(sigbus_codes, sip->si_code);
			break;
		}
	}
	if (code)
		tprintf(", si_code=%s", code);
	else
		tprintf(", si_code=%#x", sip->si_code);
#ifdef SI_NOINFO
	if (sip->si_code != SI_NOINFO)
#endif
	{
		if (sip->si_errno) {
			if (sip->si_errno < 0 || sip->si_errno >= nerrnos)
				tprintf(", si_errno=%d", sip->si_errno);
			else
				tprintf(", si_errno=%s",
					errnoent[sip->si_errno]);
		}
#ifdef SI_FROMUSER
		if (SI_FROMUSER(sip)) {
			tprintf(", si_pid=%lu, si_uid=%lu",
				(unsigned long) sip->si_pid,
				(unsigned long) sip->si_uid);
			switch (sip->si_code) {
#ifdef SI_USER
			case SI_USER:
				break;
#endif
#ifdef SI_TKILL
			case SI_TKILL:
				break;
#endif
#ifdef SI_TIMER
			case SI_TIMER:
				tprintf(", si_value=%d", sip->si_int);
				break;
#endif
			default:
				if (!sip->si_ptr)
					break;
				if (!verbose)
					tprints(", ...");
				else
					tprintf(", si_value={int=%u, ptr=%#lx}",
						sip->si_int,
						(unsigned long) sip->si_ptr);
				break;
			}
		}
		else
#endif /* SI_FROMUSER */
		{
			switch (sip->si_signo) {
			case SIGCHLD:
				tprintf(", si_pid=%ld, si_status=",
					(long) sip->si_pid);
				if (sip->si_code == CLD_EXITED)
					tprintf("%d", sip->si_status);
				else
					printsignal(sip->si_status);
				if (!verbose)
					tprints(", ...");
				else
					tprintf(", si_utime=%llu, si_stime=%llu",
						(unsigned long long) sip->si_utime,
						(unsigned long long) sip->si_stime);
				break;
			case SIGILL: case SIGFPE:
			case SIGSEGV: case SIGBUS:
				tprintf(", si_addr=%#lx",
					(unsigned long) sip->si_addr);
				break;
			case SIGPOLL:
				switch (sip->si_code) {
				case POLL_IN: case POLL_OUT: case POLL_MSG:
					tprintf(", si_band=%ld",
						(long) sip->si_band);
					break;
				}
				break;
			default:
				if (sip->si_pid || sip->si_uid)
				        tprintf(", si_pid=%lu, si_uid=%lu",
						(unsigned long) sip->si_pid,
						(unsigned long) sip->si_uid);
				if (!sip->si_ptr)
					break;
				if (!verbose)
					tprints(", ...");
				else {
					tprintf(", si_value={int=%u, ptr=%#lx}",
						sip->si_int,
						(unsigned long) sip->si_ptr);
				}

			}
		}
	}
	tprints("}");
}
Ejemplo n.º 19
0
char *
print_arg(struct syscall_args *sc, unsigned long *args, long retval,
    struct trussinfo *trussinfo)
{
	char *tmp;
	pid_t pid;

	tmp = NULL;
	pid = trussinfo->pid;
	switch (sc->type & ARG_MASK) {
	case Hex:
		asprintf(&tmp, "0x%x", (int)args[sc->offset]);
		break;
	case Octal:
		asprintf(&tmp, "0%o", (int)args[sc->offset]);
		break;
	case Int:
		asprintf(&tmp, "%d", (int)args[sc->offset]);
		break;
	case Name: {
		/* NULL-terminated string. */
		char *tmp2;
		tmp2 = get_string(pid, (void*)args[sc->offset], 0);
		asprintf(&tmp, "\"%s\"", tmp2);
		free(tmp2);
		break;
	}
	case BinString: {
		/* Binary block of data that might have printable characters.
		   XXX If type|OUT, assume that the length is the syscall's
		   return value.  Otherwise, assume that the length of the block
		   is in the next syscall argument. */
		int max_string = trussinfo->strsize;
		char tmp2[max_string+1], *tmp3;
		int len;
		int truncated = 0;

		if (sc->type & OUT)
			len = retval;
		else
			len = args[sc->offset + 1];

		/* Don't print more than max_string characters, to avoid word
		   wrap.  If we have to truncate put some ... after the string.
		*/
		if (len > max_string) {
			len = max_string;
			truncated = 1;
		}
		if (len && get_struct(pid, (void*)args[sc->offset], &tmp2, len)
		    != -1) {
			tmp3 = malloc(len * 4 + 1);
			while (len) {
				if (strvisx(tmp3, tmp2, len,
				    VIS_CSTYLE|VIS_TAB|VIS_NL) <= max_string)
					break;
				len--;
				truncated = 1;
			};
			asprintf(&tmp, "\"%s\"%s", tmp3, truncated ?
			    "..." : "");
			free(tmp3);
		} else {
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		}
		break;
	}
	case StringArray: {
		int num, size, i;
		char *tmp2;
		char *string;
		char *strarray[100];	/* XXX This is ugly. */

		if (get_struct(pid, (void *)args[sc->offset],
		    (void *)&strarray, sizeof(strarray)) == -1)
			err(1, "get_struct %p", (void *)args[sc->offset]);
		num = 0;
		size = 0;

		/* Find out how large of a buffer we'll need. */
		while (strarray[num] != NULL) {
			string = get_string(pid, (void*)strarray[num], 0);
			size += strlen(string);
			free(string);
			num++;
		}
		size += 4 + (num * 4);
		tmp = (char *)malloc(size);
		tmp2 = tmp;

		tmp2 += sprintf(tmp2, " [");
		for (i = 0; i < num; i++) {
			string = get_string(pid, (void*)strarray[i], 0);
			tmp2 += sprintf(tmp2, " \"%s\"%c", string,
			    (i + 1 == num) ? ' ' : ',');
			free(string);
		}
		tmp2 += sprintf(tmp2, "]");
		break;
	}
#ifdef __LP64__
	case Quad:
		asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
#else
	case Quad: {
		unsigned long long ll;
		ll = *(unsigned long long *)(args + sc->offset);
		asprintf(&tmp, "0x%llx", ll);
		break;
	}
#endif
	case Ptr:
		asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	case Readlinkres: {
		char *tmp2;
		if (retval == -1) {
			tmp = strdup("");
			break;
		}
		tmp2 = get_string(pid, (void*)args[sc->offset], retval);
		asprintf(&tmp, "\"%s\"", tmp2);
		free(tmp2);
		break;
	}
	case Ioctl: {
		const char *temp = ioctlname(args[sc->offset]);
		if (temp)
			tmp = strdup(temp);
		else {
			unsigned long arg = args[sc->offset];
			asprintf(&tmp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }",
			    arg, arg & IOC_OUT ? "R" : "",
			    arg & IOC_IN ? "W" : "", IOCGROUP(arg),
			    isprint(IOCGROUP(arg)) ? (char)IOCGROUP(arg) : '?',
			    arg & 0xFF, IOCPARM_LEN(arg));
		}
		break;
	}
	case Umtx: {
		struct umtx umtx;
		if (get_struct(pid, (void *)args[sc->offset], &umtx,
		    sizeof(umtx)) != -1)
			asprintf(&tmp, "{ 0x%lx }", (long)umtx.u_owner);
		else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case Timespec: {
		struct timespec ts;
		if (get_struct(pid, (void *)args[sc->offset], &ts,
		    sizeof(ts)) != -1)
			asprintf(&tmp, "{%ld.%09ld }", (long)ts.tv_sec,
			    ts.tv_nsec);
		else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case Timeval: {
		struct timeval tv;
		if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv))
		    != -1)
			asprintf(&tmp, "{%ld.%06ld }", (long)tv.tv_sec,
			    tv.tv_usec);
		else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case Timeval2: {
		struct timeval tv[2];
		if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv))
		    != -1)
			asprintf(&tmp, "{%ld.%06ld, %ld.%06ld }",
			    (long)tv[0].tv_sec, tv[0].tv_usec,
			    (long)tv[1].tv_sec, tv[1].tv_usec);
		else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case Itimerval: {
		struct itimerval itv;
		if (get_struct(pid, (void *)args[sc->offset], &itv,
		    sizeof(itv)) != -1)
			asprintf(&tmp, "{%ld.%06ld, %ld.%06ld }",
			    (long)itv.it_interval.tv_sec,
			    itv.it_interval.tv_usec,
			    (long)itv.it_value.tv_sec,
			    itv.it_value.tv_usec);
		else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case LinuxSockArgs:
	{
		struct linux_socketcall_args largs;
		if (get_struct(pid, (void *)args[sc->offset], (void *)&largs,
		    sizeof(largs)) == -1) {
			err(1, "get_struct %p", (void *)args[sc->offset]);
		}
		const char *what;
		char buf[30];

		switch (largs.what) {
		case LINUX_SOCKET:
			what = "LINUX_SOCKET";
			break;
		case LINUX_BIND:
			what = "LINUX_BIND";
			break;
		case LINUX_CONNECT:
			what = "LINUX_CONNECT";
			break;
		case LINUX_LISTEN:
			what = "LINUX_LISTEN";
			break;
		case LINUX_ACCEPT:
			what = "LINUX_ACCEPT";
			break;
		case LINUX_GETSOCKNAME:
			what = "LINUX_GETSOCKNAME";
			break;
		case LINUX_GETPEERNAME:
			what = "LINUX_GETPEERNAME";
			break;
		case LINUX_SOCKETPAIR:
			what = "LINUX_SOCKETPAIR";
			break;
		case LINUX_SEND:   
			what = "LINUX_SEND";
			break;
		case LINUX_RECV: 
			what = "LINUX_RECV";
			break;
		case LINUX_SENDTO:
			what = "LINUX_SENDTO";
			break;
		case LINUX_RECVFROM:
			what = "LINUX_RECVFROM";
			break;
		case LINUX_SHUTDOWN:
			what = "LINUX_SHUTDOWN";
			break;
		case LINUX_SETSOCKOPT:
			what = "LINUX_SETSOCKOPT";
			break;
		case LINUX_GETSOCKOPT:
			what = "LINUX_GETSOCKOPT";
			break;
		case LINUX_SENDMSG:
			what = "LINUX_SENDMSG";
			break;
		case LINUX_RECVMSG:
			what = "LINUX_RECVMSG";
			break;
		default:
			sprintf(buf, "%d", largs.what);
			what = buf;
			break;
		}
		asprintf(&tmp, "(0x%lx)%s, 0x%lx", args[sc->offset], what, (long unsigned int)largs.args);
		break;
	}
	case Pollfd: {
		/*
		 * XXX: A Pollfd argument expects the /next/ syscall argument
		 * to be the number of fds in the array. This matches the poll
		 * syscall.
		 */
		struct pollfd *pfd;
		int numfds = args[sc->offset+1];
		int bytes = sizeof(struct pollfd) * numfds;
		int i, tmpsize, u, used;
		const int per_fd = 100;

		if ((pfd = malloc(bytes)) == NULL)
			err(1, "Cannot malloc %d bytes for pollfd array",
			    bytes);
		if (get_struct(pid, (void *)args[sc->offset], pfd, bytes)
		    != -1) {
			used = 0;
			tmpsize = 1 + per_fd * numfds + 2;
			if ((tmp = malloc(tmpsize)) == NULL)
				err(1, "Cannot alloc %d bytes for poll output",
				    tmpsize);

			tmp[used++] = '{';
			for (i = 0; i < numfds; i++) {

				u = snprintf(tmp + used, per_fd, "%s%d/%s",
				    i > 0 ? " " : "", pfd[i].fd,
				    xlookup_bits(poll_flags, pfd[i].events));
				if (u > 0)
					used += u < per_fd ? u : per_fd;
			}
			tmp[used++] = '}';
			tmp[used++] = '\0';
		} else {
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		}
		free(pfd);
		break;
	}
	case Fd_set: {
		/*
		 * XXX: A Fd_set argument expects the /first/ syscall argument
		 * to be the number of fds in the array.  This matches the
		 * select syscall.
		 */
		fd_set *fds;
		int numfds = args[0];
		int bytes = _howmany(numfds, _NFDBITS) * _NFDBITS;
		int i, tmpsize, u, used;
		const int per_fd = 20;

		if ((fds = malloc(bytes)) == NULL)
			err(1, "Cannot malloc %d bytes for fd_set array",
			    bytes);
		if (get_struct(pid, (void *)args[sc->offset], fds, bytes)
		    != -1) {
			used = 0;
			tmpsize = 1 + numfds * per_fd + 2;
			if ((tmp = malloc(tmpsize)) == NULL)
				err(1, "Cannot alloc %d bytes for fd_set "
				    "output", tmpsize);

			tmp[used++] = '{';
			for (i = 0; i < numfds; i++) {
				if (FD_ISSET(i, fds)) {
					u = snprintf(tmp + used, per_fd, "%d ",
					    i);
					if (u > 0)
						used += u < per_fd ? u : per_fd;
				}
			}
			if (tmp[used-1] == ' ')
				used--;
			tmp[used++] = '}';
			tmp[used++] = '\0';
		} else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		free(fds);
		break;
	}
	case Signal:
		tmp = strsig2(args[sc->offset]);
		break;
	case Sigset: {
		long sig;
		sigset_t ss;
		int i, used;
		char *signame;

		sig = args[sc->offset];
		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
		    sizeof(ss)) == -1) {
			asprintf(&tmp, "0x%lx", args[sc->offset]);
			break;
		}
		tmp = malloc(sys_nsig * 8); /* 7 bytes avg per signal name */
		used = 0;
		for (i = 1; i < sys_nsig; i++) {
			if (sigismember(&ss, i)) {
				signame = strsig(i);
				used += sprintf(tmp + used, "%s|", signame);
				free(signame);
			}
		}
		if (used)
			tmp[used-1] = 0;
		else
			strcpy(tmp, "0x0");
		break;
	}
	case Sigprocmask: {
		switch (args[sc->offset]) {
#define	S(a)	case a: tmp = strdup(#a); break;
			S(SIG_BLOCK);
			S(SIG_UNBLOCK);
			S(SIG_SETMASK);
#undef S
		}
		if (tmp == NULL)
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case Fcntlflag: {
		/* XXX output depends on the value of the previous argument */
		switch (args[sc->offset-1]) {
		case F_SETFD:
			tmp = strdup(xlookup_bits(fcntlfd_arg,
			    args[sc->offset]));
			break;
		case F_SETFL:
			tmp = strdup(xlookup_bits(fcntlfl_arg,
			    args[sc->offset]));
			break;
		case F_GETFD:
		case F_GETFL:
		case F_GETOWN:
			tmp = strdup("");
			break;
		default:
			asprintf(&tmp, "0x%lx", args[sc->offset]);
			break;
		}
		break;
	}
	case Open:
		tmp = strdup(xlookup_bits(open_flags, args[sc->offset]));
		break;
	case Fcntl:
		tmp = strdup(xlookup(fcntl_arg, args[sc->offset]));
		break;
	case Mprot:
		tmp = strdup(xlookup_bits(mprot_flags, args[sc->offset]));
		break;
	case Mmapflags: {
		char *base, *alignstr;
		int align, flags;

		/*
		 * MAP_ALIGNED can't be handled by xlookup_bits(), so
		 * generate that string manually and prepend it to the
		 * string from xlookup_bits().  Have to be careful to
		 * avoid outputting MAP_ALIGNED|0 if MAP_ALIGNED is
		 * the only flag.
		 */
		flags = args[sc->offset] & ~MAP_ALIGNMENT_MASK;
		align = args[sc->offset] & MAP_ALIGNMENT_MASK;
		if (align != 0) {
			if (align == MAP_ALIGNED_SUPER)
				alignstr = strdup("MAP_ALIGNED_SUPER");
			else
				asprintf(&alignstr, "MAP_ALIGNED(%d)",
				    align >> MAP_ALIGNMENT_SHIFT);
			if (flags == 0) {
				tmp = alignstr;
				break;
			}
		} else
			alignstr = NULL;
		base = strdup(xlookup_bits(mmap_flags, flags));
		if (alignstr == NULL) {
			tmp = base;
			break;
		}
		asprintf(&tmp, "%s|%s", alignstr, base);
		free(alignstr);
		free(base);
		break;
	}
	case Whence:
		tmp = strdup(xlookup(whence_arg, args[sc->offset]));
		break;
	case Sockdomain:
		tmp = strdup(xlookup(sockdomain_arg, args[sc->offset]));
		break;
	case Socktype:
		tmp = strdup(xlookup(socktype_arg, args[sc->offset]));
		break;
	case Shutdown:
		tmp = strdup(xlookup(shutdown_arg, args[sc->offset]));
		break;
	case Resource:
		tmp = strdup(xlookup(resource_arg, args[sc->offset]));
		break;
	case Pathconf:
		tmp = strdup(xlookup(pathconf_arg, args[sc->offset]));
		break;
	case Rforkflags:
		tmp = strdup(xlookup_bits(rfork_flags, args[sc->offset]));
		break;
	case Sockaddr: {
		struct sockaddr_storage ss;
		char addr[64];
		struct sockaddr_in *lsin;
		struct sockaddr_in6 *lsin6;
		struct sockaddr_un *sun;
		struct sockaddr *sa;
		char *p;
		u_char *q;
		int i;

		if (args[sc->offset] == 0) {
			asprintf(&tmp, "NULL");
			break;
		}

		/* yuck: get ss_len */
		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
		    sizeof(ss.ss_len) + sizeof(ss.ss_family)) == -1)
			err(1, "get_struct %p", (void *)args[sc->offset]);
		/*
		 * If ss_len is 0, then try to guess from the sockaddr type.
		 * AF_UNIX may be initialized incorrectly, so always frob
		 * it by using the "right" size.
		 */
		if (ss.ss_len == 0 || ss.ss_family == AF_UNIX) {
			switch (ss.ss_family) {
			case AF_INET:
				ss.ss_len = sizeof(*lsin);
				break;
			case AF_UNIX:
				ss.ss_len = sizeof(*sun);
				break;
			default:
				/* hurrrr */
				break;
			}
		}
		if (get_struct(pid, (void *)args[sc->offset], (void *)&ss,
		    ss.ss_len) == -1) {
			err(2, "get_struct %p", (void *)args[sc->offset]);
		}

		switch (ss.ss_family) {
		case AF_INET:
			lsin = (struct sockaddr_in *)&ss;
			inet_ntop(AF_INET, &lsin->sin_addr, addr, sizeof addr);
			asprintf(&tmp, "{ AF_INET %s:%d }", addr,
			    htons(lsin->sin_port));
			break;
		case AF_INET6:
			lsin6 = (struct sockaddr_in6 *)&ss;
			inet_ntop(AF_INET6, &lsin6->sin6_addr, addr,
			    sizeof addr);
			asprintf(&tmp, "{ AF_INET6 [%s]:%d }", addr,
			    htons(lsin6->sin6_port));
			break;
		case AF_UNIX:
			sun = (struct sockaddr_un *)&ss;
			asprintf(&tmp, "{ AF_UNIX \"%s\" }", sun->sun_path);
			break;
		default:
			sa = (struct sockaddr *)&ss;
			asprintf(&tmp, "{ sa_len = %d, sa_family = %d, sa_data "
			    "= {%n%*s } }", (int)sa->sa_len, (int)sa->sa_family,
			    &i, 6 * (int)(sa->sa_len - ((char *)&sa->sa_data -
			    (char *)sa)), "");
			if (tmp != NULL) {
				p = tmp + i;
				for (q = (u_char *)&sa->sa_data;
				    q < (u_char *)sa + sa->sa_len; q++)
					p += sprintf(p, " %#02x,", *q);
			}
		}
		break;
	}
	case Sigaction: {
		struct sigaction sa;
		char *hand;
		const char *h;

		if (get_struct(pid, (void *)args[sc->offset], &sa, sizeof(sa))
		    != -1) {
			asprintf(&hand, "%p", sa.sa_handler);
			if (sa.sa_handler == SIG_DFL)
				h = "SIG_DFL";
			else if (sa.sa_handler == SIG_IGN)
				h = "SIG_IGN";
			else
				h = hand;

			asprintf(&tmp, "{ %s %s ss_t }", h,
			    xlookup_bits(sigaction_flags, sa.sa_flags));
			free(hand);
		} else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case Kevent: {
		/*
		 * XXX XXX: the size of the array is determined by either the
		 * next syscall argument, or by the syscall returnvalue,
		 * depending on which argument number we are.  This matches the
		 * kevent syscall, but luckily that's the only syscall that uses
		 * them.
		 */
		struct kevent *ke;
		int numevents = -1;
		int bytes = 0;
		int i, tmpsize, u, used;
		const int per_ke = 100;

		if (sc->offset == 1)
			numevents = args[sc->offset+1];
		else if (sc->offset == 3 && retval != -1)
			numevents = retval;

		if (numevents >= 0)
			bytes = sizeof(struct kevent) * numevents;
		if ((ke = malloc(bytes)) == NULL)
			err(1, "Cannot malloc %d bytes for kevent array",
			    bytes);
		if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset],
		    ke, bytes) != -1) {
			used = 0;
			tmpsize = 1 + per_ke * numevents + 2;
			if ((tmp = malloc(tmpsize)) == NULL)
				err(1, "Cannot alloc %d bytes for kevent "
				    "output", tmpsize);

			tmp[used++] = '{';
			for (i = 0; i < numevents; i++) {
				u = snprintf(tmp + used, per_ke,
				    "%s%p,%s,%s,%d,%p,%p",
				    i > 0 ? " " : "",
				    (void *)ke[i].ident,
				    xlookup(kevent_filters, ke[i].filter),
				    xlookup_bits(kevent_flags, ke[i].flags),
				    ke[i].fflags,
				    (void *)ke[i].data,
				    (void *)ke[i].udata);
				if (u > 0)
					used += u < per_ke ? u : per_ke;
			}
			tmp[used++] = '}';
			tmp[used++] = '\0';
		} else {
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		}
		free(ke);
		break;
	}
	case Stat: {
		struct stat st;
		if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st))
		    != -1) {
			char mode[12];
			strmode(st.st_mode, mode);
			asprintf(&tmp,
			    "{ mode=%s,inode=%jd,size=%jd,blksize=%ld }", mode,
			    (intmax_t)st.st_ino, (intmax_t)st.st_size,
			    (long)st.st_blksize);
		} else {
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		}
		break;
	}
	case Rusage: {
		struct rusage ru;
		if (get_struct(pid, (void *)args[sc->offset], &ru, sizeof(ru))
		    != -1) {
			asprintf(&tmp,
			    "{ u=%ld.%06ld,s=%ld.%06ld,in=%ld,out=%ld }",
			    (long)ru.ru_utime.tv_sec, ru.ru_utime.tv_usec,
			    (long)ru.ru_stime.tv_sec, ru.ru_stime.tv_usec,
			    ru.ru_inblock, ru.ru_oublock);
		} else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case Rlimit: {
		struct rlimit rl;
		if (get_struct(pid, (void *)args[sc->offset], &rl, sizeof(rl))
		    != -1) {
			asprintf(&tmp, "{ cur=%ju,max=%ju }",
			    rl.rlim_cur, rl.rlim_max);
		} else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		break;
	}
	case ExitStatus: {
		char *signame;
		int status;
		signame = NULL;
		if (get_struct(pid, (void *)args[sc->offset], &status,
		    sizeof(status)) != -1) {
			if (WIFCONTINUED(status))
				tmp = strdup("{ CONTINUED }");
			else if (WIFEXITED(status))
				asprintf(&tmp, "{ EXITED,val=%d }",
				    WEXITSTATUS(status));
			else if (WIFSIGNALED(status))
				asprintf(&tmp, "{ SIGNALED,sig=%s%s }",
				    signame = strsig2(WTERMSIG(status)),
				    WCOREDUMP(status) ? ",cored" : "");
			else
				asprintf(&tmp, "{ STOPPED,sig=%s }",
				    signame = strsig2(WTERMSIG(status)));
		} else
			asprintf(&tmp, "0x%lx", args[sc->offset]);
		free(signame);
		break;
	}
	case Waitoptions:
		tmp = strdup(xlookup_bits(wait_options, args[sc->offset]));
		break;
	case Idtype:
		tmp = strdup(xlookup(idtype_arg, args[sc->offset]));
		break;
	case Procctl:
		tmp = strdup(xlookup(procctl_arg, args[sc->offset]));
		break;
	default:
		errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK);
	}
Ejemplo n.º 20
0
static const char *
get_sa_handler_str(kernel_ulong_t handler)
{
	return xlookup(sa_handler_values, handler);
}
Ejemplo n.º 21
0
void
printsiginfo(const siginfo_t *sip, int verbose)
{
	const char *code;

	if (sip->si_signo == 0) {
		tprints("{}");
		return;
	}
	tprints("{si_signo=");
	printsignal(sip->si_signo);
	code = xlookup(siginfo_codes, sip->si_code);
	if (!code) {
		switch (sip->si_signo) {
		case SIGTRAP:
			code = xlookup(sigtrap_codes, sip->si_code);
			break;
		case SIGCHLD:
			code = xlookup(sigchld_codes, sip->si_code);
			break;
		case SIGPOLL:
			code = xlookup(sigpoll_codes, sip->si_code);
			break;
		case SIGPROF:
			code = xlookup(sigprof_codes, sip->si_code);
			break;
		case SIGILL:
			code = xlookup(sigill_codes, sip->si_code);
			break;
#ifdef SIGEMT
		case SIGEMT:
			code = xlookup(sigemt_codes, sip->si_code);
			break;
#endif
		case SIGFPE:
			code = xlookup(sigfpe_codes, sip->si_code);
			break;
		case SIGSEGV:
			code = xlookup(sigsegv_codes, sip->si_code);
			break;
		case SIGBUS:
			code = xlookup(sigbus_codes, sip->si_code);
			break;
		case SIGSYS:
			code = xlookup(sigsys_codes, sip->si_code);
			break;
		}
	}
	if (code)
		tprintf(", si_code=%s", code);
	else
		tprintf(", si_code=%#x", sip->si_code);
#ifdef SI_NOINFO
	if (sip->si_code != SI_NOINFO)
#endif
	{
		if (sip->si_errno) {
			tprints(", si_errno=");
			if ((unsigned) sip->si_errno < nerrnos
			    && errnoent[sip->si_errno])
				tprints(errnoent[sip->si_errno]);
			else
				tprintf("%d", sip->si_errno);
		}
#ifdef SI_FROMUSER
		if (SI_FROMUSER(sip)) {
			switch (sip->si_code) {
#ifdef SI_USER
			case SI_USER:
				printsigsource(sip);
				break;
#endif
#ifdef SI_TKILL
			case SI_TKILL:
				printsigsource(sip);
				break;
#endif
#if defined SI_TIMER \
 && defined HAVE_SIGINFO_T_SI_TIMERID && defined HAVE_SIGINFO_T_SI_OVERRUN
			case SI_TIMER:
				tprintf(", si_timerid=%#x, si_overrun=%d",
					sip->si_timerid, sip->si_overrun);
				printsigval(sip, verbose);
				break;
#endif
			default:
				printsigsource(sip);
				if (sip->si_ptr)
					printsigval(sip, verbose);
				break;
			}
		}
		else
#endif /* SI_FROMUSER */
		{
			switch (sip->si_signo) {
			case SIGCHLD:
				printsigsource(sip);
				tprints(", si_status=");
				if (sip->si_code == CLD_EXITED)
					tprintf("%d", sip->si_status);
				else
					printsignal(sip->si_status);
				if (!verbose)
					tprints(", ...");
				else
					tprintf(", si_utime=%llu, si_stime=%llu",
						(unsigned long long) sip->si_utime,
						(unsigned long long) sip->si_stime);
				break;
			case SIGILL: case SIGFPE:
			case SIGSEGV: case SIGBUS:
				tprintf(", si_addr=%#lx",
					(unsigned long) sip->si_addr);
				break;
			case SIGPOLL:
				switch (sip->si_code) {
				case POLL_IN: case POLL_OUT: case POLL_MSG:
					tprintf(", si_band=%ld",
						(long) sip->si_band);
					break;
				}
				break;
#ifdef HAVE_SIGINFO_T_SI_SYSCALL
			case SIGSYS:
				tprintf(", si_call_addr=%#lx, si_syscall=%d, si_arch=%u",
					(unsigned long) sip->si_call_addr,
					sip->si_syscall, sip->si_arch);
				break;
#endif
			default:
				if (sip->si_pid || sip->si_uid)
				        printsigsource(sip);
				if (sip->si_ptr)
					printsigval(sip, verbose);
			}
		}
	}
	tprints("}");
}