Path: blob/main/sys/cddl/dev/dtrace/x86/instr_size.c
105687 views
/*1* CDDL HEADER START2*3* The contents of this file are subject to the terms of the4* Common Development and Distribution License, Version 1.0 only5* (the "License"). You may not use this file except in compliance6* with the License.7*8* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE9* or http://www.opensolaris.org/os/licensing.10* See the License for the specific language governing permissions11* and limitations under the License.12*13* When distributing Covered Code, include this CDDL HEADER in each14* file and include the License file at usr/src/OPENSOLARIS.LICENSE.15* If applicable, add the following below this CDDL HEADER, with the16* fields enclosed by brackets "[]" replaced with your own identifying17* information: Portions Copyright [yyyy] [name of copyright owner]18*19* CDDL HEADER END20*/21/*22* Copyright 2005 Sun Microsystems, Inc. All rights reserved.23* Use is subject to license terms.24*/2526/* Copyright (c) 1988 AT&T */27/* All Rights Reserved */2829#include <sys/types.h>30#include <sys/param.h>31#ifdef __FreeBSD__32#include <sys/_mutex.h>33#endif34#include <sys/proc.h>35#ifdef illumos36#include <sys/cmn_err.h>37#include <sys/archsystm.h>38#include <sys/copyops.h>39#include <vm/seg_enum.h>40#include <sys/privregs.h>41#else42#include <sys/cred.h>43#include <cddl/dev/dtrace/dtrace_cddl.h>4445typedef u_int model_t;46#define DATAMODEL_NATIVE 047int dtrace_dis_get_byte(void *);48int dtrace_instr_size(uint8_t *);49int dtrace_instr_size_isa(uint8_t *, model_t, int *);50#endif5152#include <dis_tables.h>5354/*55* This subsystem (with the minor exception of the instr_size() function) is56* is called from DTrace probe context. This imposes several requirements on57* the implementation:58*59* 1. External subsystems and functions may not be referenced. The one current60* exception is for cmn_err, but only to signal the detection of table61* errors. Assuming the tables are correct, no combination of input is to62* trigger a cmn_err call.63*64* 2. These functions can't be allowed to be traced. To prevent this,65* all functions in the probe path (everything except instr_size()) must66* have names that begin with "dtrace_".67*/6869typedef enum dis_isize {70DIS_ISIZE_INSTR,71DIS_ISIZE_OPERAND72} dis_isize_t;737475/*76* get a byte from instruction stream77*/78int79dtrace_dis_get_byte(void *p)80{81int ret;82uint8_t **instr = p;8384ret = **instr;85*instr += 1;8687return (ret);88}8990/*91* Returns either the size of a given instruction, in bytes, or the size of that92* instruction's memory access (if any), depending on the value of `which'.93* If a programming error in the tables is detected, the system will panic to94* ease diagnosis. Invalid instructions will not be flagged. They will appear95* to have an instruction size between 1 and the actual size, and will be96* reported as having no memory impact.97*/98/* ARGSUSED2 */99static int100dtrace_dis_isize(uint8_t *instr, dis_isize_t which, model_t model, int *rmindex)101{102int sz;103dis86_t x;104uint_t mode = SIZE32;105106mode = (model == DATAMODEL_LP64) ? SIZE64 : SIZE32;107108x.d86_data = (void **)&instr;109x.d86_get_byte = dtrace_dis_get_byte;110x.d86_check_func = NULL;111112if (dtrace_disx86(&x, mode) != 0)113return (-1);114115if (which == DIS_ISIZE_INSTR)116sz = x.d86_len; /* length of the instruction */117else118sz = x.d86_memsize; /* length of memory operand */119120if (rmindex != NULL)121*rmindex = x.d86_rmindex;122return (sz);123}124125int126dtrace_instr_size_isa(uint8_t *instr, model_t model, int *rmindex)127{128return (dtrace_dis_isize(instr, DIS_ISIZE_INSTR, model, rmindex));129}130131int132dtrace_instr_size(uint8_t *instr)133{134return (dtrace_dis_isize(instr, DIS_ISIZE_INSTR, DATAMODEL_NATIVE,135NULL));136}137138139