Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/cddl/dev/dtrace/x86/instr_size.c
48375 views
1
/*
2
* CDDL HEADER START
3
*
4
* The contents of this file are subject to the terms of the
5
* Common Development and Distribution License, Version 1.0 only
6
* (the "License"). You may not use this file except in compliance
7
* with the License.
8
*
9
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10
* or http://www.opensolaris.org/os/licensing.
11
* See the License for the specific language governing permissions
12
* and limitations under the License.
13
*
14
* When distributing Covered Code, include this CDDL HEADER in each
15
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16
* If applicable, add the following below this CDDL HEADER, with the
17
* fields enclosed by brackets "[]" replaced with your own identifying
18
* information: Portions Copyright [yyyy] [name of copyright owner]
19
*
20
* CDDL HEADER END
21
*/
22
/*
23
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24
* Use is subject to license terms.
25
*/
26
27
/* Copyright (c) 1988 AT&T */
28
/* All Rights Reserved */
29
30
#include <sys/types.h>
31
#include <sys/param.h>
32
#include <sys/proc.h>
33
#ifdef illumos
34
#include <sys/cmn_err.h>
35
#include <sys/archsystm.h>
36
#include <sys/copyops.h>
37
#include <vm/seg_enum.h>
38
#include <sys/privregs.h>
39
#else
40
#include <sys/cred.h>
41
#include <cddl/dev/dtrace/dtrace_cddl.h>
42
43
typedef u_int model_t;
44
#define DATAMODEL_NATIVE 0
45
int dtrace_dis_get_byte(void *);
46
int dtrace_instr_size(uint8_t *);
47
int dtrace_instr_size_isa(uint8_t *, model_t, int *);
48
#endif
49
50
#include <dis_tables.h>
51
52
/*
53
* This subsystem (with the minor exception of the instr_size() function) is
54
* is called from DTrace probe context. This imposes several requirements on
55
* the implementation:
56
*
57
* 1. External subsystems and functions may not be referenced. The one current
58
* exception is for cmn_err, but only to signal the detection of table
59
* errors. Assuming the tables are correct, no combination of input is to
60
* trigger a cmn_err call.
61
*
62
* 2. These functions can't be allowed to be traced. To prevent this,
63
* all functions in the probe path (everything except instr_size()) must
64
* have names that begin with "dtrace_".
65
*/
66
67
typedef enum dis_isize {
68
DIS_ISIZE_INSTR,
69
DIS_ISIZE_OPERAND
70
} dis_isize_t;
71
72
73
/*
74
* get a byte from instruction stream
75
*/
76
int
77
dtrace_dis_get_byte(void *p)
78
{
79
int ret;
80
uint8_t **instr = p;
81
82
ret = **instr;
83
*instr += 1;
84
85
return (ret);
86
}
87
88
/*
89
* Returns either the size of a given instruction, in bytes, or the size of that
90
* instruction's memory access (if any), depending on the value of `which'.
91
* If a programming error in the tables is detected, the system will panic to
92
* ease diagnosis. Invalid instructions will not be flagged. They will appear
93
* to have an instruction size between 1 and the actual size, and will be
94
* reported as having no memory impact.
95
*/
96
/* ARGSUSED2 */
97
static int
98
dtrace_dis_isize(uint8_t *instr, dis_isize_t which, model_t model, int *rmindex)
99
{
100
int sz;
101
dis86_t x;
102
uint_t mode = SIZE32;
103
104
mode = (model == DATAMODEL_LP64) ? SIZE64 : SIZE32;
105
106
x.d86_data = (void **)&instr;
107
x.d86_get_byte = dtrace_dis_get_byte;
108
x.d86_check_func = NULL;
109
110
if (dtrace_disx86(&x, mode) != 0)
111
return (-1);
112
113
if (which == DIS_ISIZE_INSTR)
114
sz = x.d86_len; /* length of the instruction */
115
else
116
sz = x.d86_memsize; /* length of memory operand */
117
118
if (rmindex != NULL)
119
*rmindex = x.d86_rmindex;
120
return (sz);
121
}
122
123
int
124
dtrace_instr_size_isa(uint8_t *instr, model_t model, int *rmindex)
125
{
126
return (dtrace_dis_isize(instr, DIS_ISIZE_INSTR, model, rmindex));
127
}
128
129
int
130
dtrace_instr_size(uint8_t *instr)
131
{
132
return (dtrace_dis_isize(instr, DIS_ISIZE_INSTR, DATAMODEL_NATIVE,
133
NULL));
134
}
135
136