Path: blob/main/cddl/contrib/opensolaris/lib/libdtrace/arm/dt_isadep.c
39563 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* Copyright 2014 Howard Su25* Copyright 2015 George V. Neville-Neil26*27*/2829#pragma ident "%Z%%M% %I% %E% SMI"3031#include <stdlib.h>32#include <assert.h>33#include <errno.h>34#include <string.h>35#include <libgen.h>3637#include <dt_impl.h>38#include <dt_pid.h>3940#ifdef __FreeBSD__41#include <libproc_compat.h>42#endif4344#define OP(x) ((x) >> 30)45#define OP2(x) (((x) >> 22) & 0x07)46#define COND(x) (((x) >> 25) & 0x0f)47#define A(x) (((x) >> 29) & 0x01)4849#define OP_BRANCH 05051#define OP2_BPcc 0x152#define OP2_Bicc 0x253#define OP2_BPr 0x354#define OP2_FBPfcc 0x555#define OP2_FBfcc 0x65657/*ARGSUSED*/58int59dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,60fasttrap_probe_spec_t *ftp, const GElf_Sym *symp)61{62ftp->ftps_type = DTFTP_ENTRY;63ftp->ftps_pc = (uintptr_t)symp->st_value;64ftp->ftps_size = (size_t)symp->st_size;65ftp->ftps_noffs = 1;66ftp->ftps_offs[0] = 0;6768if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {69dt_dprintf("fasttrap probe creation ioctl failed: %s\n",70strerror(errno));71return (dt_set_errno(dtp, errno));72}7374return (1);75}7677int78dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,79fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret)80{8182uint32_t *text;83int i;84int srdepth = 0;8586dt_dprintf("%s: unimplemented\n", __func__);87return (DT_PROC_ERR);8889if ((text = malloc(symp->st_size + 4)) == NULL) {90dt_dprintf("mr sparkle: malloc() failed\n");91return (DT_PROC_ERR);92}9394if (Pread(P, text, symp->st_size, symp->st_value) != symp->st_size) {95dt_dprintf("mr sparkle: Pread() failed\n");96free(text);97return (DT_PROC_ERR);98}99100/*101* Leave a dummy instruction in the last slot to simplify edge102* conditions.103*/104text[symp->st_size / 4] = 0;105106ftp->ftps_type = DTFTP_RETURN;107ftp->ftps_pc = symp->st_value;108ftp->ftps_size = symp->st_size;109ftp->ftps_noffs = 0;110111112free(text);113if (ftp->ftps_noffs > 0) {114if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {115dt_dprintf("fasttrap probe creation ioctl failed: %s\n",116strerror(errno));117return (dt_set_errno(dtp, errno));118}119}120121122return (ftp->ftps_noffs);123}124125/*ARGSUSED*/126int127dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,128fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off)129{130if (off & 0x3)131return (DT_PROC_ALIGN);132133ftp->ftps_type = DTFTP_OFFSETS;134ftp->ftps_pc = (uintptr_t)symp->st_value;135ftp->ftps_size = (size_t)symp->st_size;136ftp->ftps_noffs = 1;137ftp->ftps_offs[0] = off;138139if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {140dt_dprintf("fasttrap probe creation ioctl failed: %s\n",141strerror(errno));142return (dt_set_errno(dtp, errno));143}144145return (1);146}147148/*ARGSUSED*/149int150dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp,151fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern)152{153ulong_t i;154155ftp->ftps_type = DTFTP_OFFSETS;156ftp->ftps_pc = (uintptr_t)symp->st_value;157ftp->ftps_size = (size_t)symp->st_size;158ftp->ftps_noffs = 0;159160/*161* If we're matching against everything, just iterate through each162* instruction in the function, otherwise look for matching offset163* names by constructing the string and comparing it against the164* pattern.165*/166if (strcmp("*", pattern) == 0) {167for (i = 0; i < symp->st_size; i += 4) {168ftp->ftps_offs[ftp->ftps_noffs++] = i;169}170} else {171char name[sizeof (i) * 2 + 1];172173for (i = 0; i < symp->st_size; i += 4) {174(void) sprintf(name, "%lx", i);175if (gmatch(name, pattern))176ftp->ftps_offs[ftp->ftps_noffs++] = i;177}178}179180if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {181dt_dprintf("fasttrap probe creation ioctl failed: %s\n",182strerror(errno));183return (dt_set_errno(dtp, errno));184}185186return (ftp->ftps_noffs);187}188189190