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
105687 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
#ifdef __FreeBSD__
33
#include <sys/_mutex.h>
34
#endif
35
#include <sys/proc.h>
36
#ifdef illumos
37
#include <sys/cmn_err.h>
38
#include <sys/archsystm.h>
39
#include <sys/copyops.h>
40
#include <vm/seg_enum.h>
41
#include <sys/privregs.h>
42
#else
43
#include <sys/cred.h>
44
#include <cddl/dev/dtrace/dtrace_cddl.h>
45
46
typedef u_int model_t;
47
#define DATAMODEL_NATIVE 0
48
int dtrace_dis_get_byte(void *);
49
int dtrace_instr_size(uint8_t *);
50
int dtrace_instr_size_isa(uint8_t *, model_t, int *);
51
#endif
52
53
#include <dis_tables.h>
54
55
/*
56
* This subsystem (with the minor exception of the instr_size() function) is
57
* is called from DTrace probe context. This imposes several requirements on
58
* the implementation:
59
*
60
* 1. External subsystems and functions may not be referenced. The one current
61
* exception is for cmn_err, but only to signal the detection of table
62
* errors. Assuming the tables are correct, no combination of input is to
63
* trigger a cmn_err call.
64
*
65
* 2. These functions can't be allowed to be traced. To prevent this,
66
* all functions in the probe path (everything except instr_size()) must
67
* have names that begin with "dtrace_".
68
*/
69
70
typedef enum dis_isize {
71
DIS_ISIZE_INSTR,
72
DIS_ISIZE_OPERAND
73
} dis_isize_t;
74
75
76
/*
77
* get a byte from instruction stream
78
*/
79
int
80
dtrace_dis_get_byte(void *p)
81
{
82
int ret;
83
uint8_t **instr = p;
84
85
ret = **instr;
86
*instr += 1;
87
88
return (ret);
89
}
90
91
/*
92
* Returns either the size of a given instruction, in bytes, or the size of that
93
* instruction's memory access (if any), depending on the value of `which'.
94
* If a programming error in the tables is detected, the system will panic to
95
* ease diagnosis. Invalid instructions will not be flagged. They will appear
96
* to have an instruction size between 1 and the actual size, and will be
97
* reported as having no memory impact.
98
*/
99
/* ARGSUSED2 */
100
static int
101
dtrace_dis_isize(uint8_t *instr, dis_isize_t which, model_t model, int *rmindex)
102
{
103
int sz;
104
dis86_t x;
105
uint_t mode = SIZE32;
106
107
mode = (model == DATAMODEL_LP64) ? SIZE64 : SIZE32;
108
109
x.d86_data = (void **)&instr;
110
x.d86_get_byte = dtrace_dis_get_byte;
111
x.d86_check_func = NULL;
112
113
if (dtrace_disx86(&x, mode) != 0)
114
return (-1);
115
116
if (which == DIS_ISIZE_INSTR)
117
sz = x.d86_len; /* length of the instruction */
118
else
119
sz = x.d86_memsize; /* length of memory operand */
120
121
if (rmindex != NULL)
122
*rmindex = x.d86_rmindex;
123
return (sz);
124
}
125
126
int
127
dtrace_instr_size_isa(uint8_t *instr, model_t model, int *rmindex)
128
{
129
return (dtrace_dis_isize(instr, DIS_ISIZE_INSTR, model, rmindex));
130
}
131
132
int
133
dtrace_instr_size(uint8_t *instr)
134
{
135
return (dtrace_dis_isize(instr, DIS_ISIZE_INSTR, DATAMODEL_NATIVE,
136
NULL));
137
}
138
139