6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26
27 /*
28 * The Sun Studio and GCC (patched for opensolaris/illumos) compilers
29 * implement a argument saving scheme on amd64 via the -Wu,save-args or
30 * options. When the option is specified, INTEGER type function arguments
31 * passed via registers will be saved on the stack immediately after %rbp, and
32 * will not be modified through out the life of the routine.
33 *
34 * +--------+
35 * %rbp --> | %rbp |
36 * +--------+
37 * -0x8(%rbp) | %rdi |
38 * +--------+
39 * -0x10(%rbp) | %rsi |
40 * +--------+
41 * -0x18(%rbp) | %rdx |
42 * +--------+
43 * -0x20(%rbp) | %rcx |
44 * +--------+
45 * -0x28(%rbp) | %r8 |
214 return (dis_instrlen(dhp, i));
215 }
216
217 static boolean_t
218 has_saved_fp(dis_handle_t *dhp, uint8_t *ins, int size)
219 {
220 int i, j;
221 uint32_t n;
222 boolean_t found_push = B_FALSE;
223 ssize_t sz = 0;
224
225 for (i = 0; i < size; i += sz) {
226 if ((sz = instr_size(dhp, ins, i, size)) < 1)
227 return (B_FALSE);
228
229 if (found_push == B_FALSE) {
230 if (sz != 1)
231 continue;
232
233 n = INSTR1(ins, i);
234 for (j = 0; j <= NUM_FP_PUSHES; j++)
235 if (save_fp_pushes[j] == n) {
236 found_push = B_TRUE;
237 break;
238 }
239 } else {
240 if (sz != 3)
241 continue;
242 n = INSTR3(ins, i);
243 for (j = 0; j <= NUM_FP_MOVS; j++)
244 if (save_fp_movs[j] == n)
245 return (B_TRUE);
246 }
247 }
248
249 return (B_FALSE);
250 }
251
252 int
253 saveargs_has_args(uint8_t *ins, size_t size, uint_t argc, int start_index)
254 {
255 int i, j;
256 uint32_t n;
257 uint8_t found = 0;
258 ssize_t sz = 0;
259 dis_handle_t *dhp = NULL;
260 int ret = SAVEARGS_NO_ARGS;
261
262 argc = MIN((start_index + argc), INSTR_ARRAY_SIZE);
263
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * Copyright 2019 Joyent, Inc.
28 */
29
30 /*
31 * The Sun Studio and GCC (patched for opensolaris/illumos) compilers
32 * implement a argument saving scheme on amd64 via the -Wu,save-args or
33 * options. When the option is specified, INTEGER type function arguments
34 * passed via registers will be saved on the stack immediately after %rbp, and
35 * will not be modified through out the life of the routine.
36 *
37 * +--------+
38 * %rbp --> | %rbp |
39 * +--------+
40 * -0x8(%rbp) | %rdi |
41 * +--------+
42 * -0x10(%rbp) | %rsi |
43 * +--------+
44 * -0x18(%rbp) | %rdx |
45 * +--------+
46 * -0x20(%rbp) | %rcx |
47 * +--------+
48 * -0x28(%rbp) | %r8 |
217 return (dis_instrlen(dhp, i));
218 }
219
220 static boolean_t
221 has_saved_fp(dis_handle_t *dhp, uint8_t *ins, int size)
222 {
223 int i, j;
224 uint32_t n;
225 boolean_t found_push = B_FALSE;
226 ssize_t sz = 0;
227
228 for (i = 0; i < size; i += sz) {
229 if ((sz = instr_size(dhp, ins, i, size)) < 1)
230 return (B_FALSE);
231
232 if (found_push == B_FALSE) {
233 if (sz != 1)
234 continue;
235
236 n = INSTR1(ins, i);
237 for (j = 0; j < NUM_FP_PUSHES; j++)
238 if (save_fp_pushes[j] == n) {
239 found_push = B_TRUE;
240 break;
241 }
242 } else {
243 if (sz != 3)
244 continue;
245 n = INSTR3(ins, i);
246 for (j = 0; j < NUM_FP_MOVS; j++)
247 if (save_fp_movs[j] == n)
248 return (B_TRUE);
249 }
250 }
251
252 return (B_FALSE);
253 }
254
255 int
256 saveargs_has_args(uint8_t *ins, size_t size, uint_t argc, int start_index)
257 {
258 int i, j;
259 uint32_t n;
260 uint8_t found = 0;
261 ssize_t sz = 0;
262 dis_handle_t *dhp = NULL;
263 int ret = SAVEARGS_NO_ARGS;
264
265 argc = MIN((start_index + argc), INSTR_ARRAY_SIZE);
266
|