Path: blob/main/sys/cddl/dev/dtrace/x86/instr_size.c
48375 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#include <sys/proc.h>32#ifdef illumos33#include <sys/cmn_err.h>34#include <sys/archsystm.h>35#include <sys/copyops.h>36#include <vm/seg_enum.h>37#include <sys/privregs.h>38#else39#include <sys/cred.h>40#include <cddl/dev/dtrace/dtrace_cddl.h>4142typedef u_int model_t;43#define DATAMODEL_NATIVE 044int dtrace_dis_get_byte(void *);45int dtrace_instr_size(uint8_t *);46int dtrace_instr_size_isa(uint8_t *, model_t, int *);47#endif4849#include <dis_tables.h>5051/*52* This subsystem (with the minor exception of the instr_size() function) is53* is called from DTrace probe context. This imposes several requirements on54* the implementation:55*56* 1. External subsystems and functions may not be referenced. The one current57* exception is for cmn_err, but only to signal the detection of table58* errors. Assuming the tables are correct, no combination of input is to59* trigger a cmn_err call.60*61* 2. These functions can't be allowed to be traced. To prevent this,62* all functions in the probe path (everything except instr_size()) must63* have names that begin with "dtrace_".64*/6566typedef enum dis_isize {67DIS_ISIZE_INSTR,68DIS_ISIZE_OPERAND69} dis_isize_t;707172/*73* get a byte from instruction stream74*/75int76dtrace_dis_get_byte(void *p)77{78int ret;79uint8_t **instr = p;8081ret = **instr;82*instr += 1;8384return (ret);85}8687/*88* Returns either the size of a given instruction, in bytes, or the size of that89* instruction's memory access (if any), depending on the value of `which'.90* If a programming error in the tables is detected, the system will panic to91* ease diagnosis. Invalid instructions will not be flagged. They will appear92* to have an instruction size between 1 and the actual size, and will be93* reported as having no memory impact.94*/95/* ARGSUSED2 */96static int97dtrace_dis_isize(uint8_t *instr, dis_isize_t which, model_t model, int *rmindex)98{99int sz;100dis86_t x;101uint_t mode = SIZE32;102103mode = (model == DATAMODEL_LP64) ? SIZE64 : SIZE32;104105x.d86_data = (void **)&instr;106x.d86_get_byte = dtrace_dis_get_byte;107x.d86_check_func = NULL;108109if (dtrace_disx86(&x, mode) != 0)110return (-1);111112if (which == DIS_ISIZE_INSTR)113sz = x.d86_len; /* length of the instruction */114else115sz = x.d86_memsize; /* length of memory operand */116117if (rmindex != NULL)118*rmindex = x.d86_rmindex;119return (sz);120}121122int123dtrace_instr_size_isa(uint8_t *instr, model_t model, int *rmindex)124{125return (dtrace_dis_isize(instr, DIS_ISIZE_INSTR, model, rmindex));126}127128int129dtrace_instr_size(uint8_t *instr)130{131return (dtrace_dis_isize(instr, DIS_ISIZE_INSTR, DATAMODEL_NATIVE,132NULL));133}134135136