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 (the "License").
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 /*
23  * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 
26 #include <stdio.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <libelf.h>
32 #include <sys/param.h>
33 
34 #include "rdb.h"
35 
36 void
perr(char * s)37 perr(char *s)
38 {
39 	perror(s);
40 	exit(1);
41 }
42 
43 ulong_t
hexstr_to_num(const char * str)44 hexstr_to_num(const char *str)
45 {
46 	ulong_t		num = 0;
47 	size_t		i, len = strlen(str);
48 
49 	for (i = 0; i < len; i++)
50 		if (str[i] >= '0' && str[i] <= '9')
51 			num = num * 16 +((int)str[i] - (int)'0');
52 		else if (str[i] >= 'a' && str[i] <= 'f')
53 			num = num * 16 +((int)str[i] - (int)'a' + 10);
54 		else if (str[i] >= 'A' && str[i] <= 'F')
55 			num = num * 16 + ((int)str[i] - (int)'A' + 10);
56 	return (num);
57 }
58 
59 #define	STBUFSIZ	1024
60 
61 retc_t
proc_string_read(struct ps_prochandle * ph,ulong_t addr,char * buf,int bufsiz)62 proc_string_read(struct ps_prochandle *ph, ulong_t addr, char *buf, int bufsiz)
63 {
64 	char	intbuf[STBUFSIZ];
65 	int	bufind = 0, intbufind = STBUFSIZ, cont = 1;
66 	ssize_t	bufbytes = 0;
67 
68 	if (lseek(ph->pp_asfd, addr, SEEK_SET) == -1)
69 		return (RET_FAILED);
70 	while (cont && (bufind < bufsiz)) {
71 		if (intbufind >= bufbytes) {
72 			if ((bufbytes = read(ph->pp_asfd, intbuf,
73 			    STBUFSIZ)) == -1)
74 				return (RET_FAILED);
75 			intbufind = 0;
76 		}
77 		buf[bufind] = intbuf[intbufind];
78 		if (buf[bufind] == '\0')
79 			return (RET_OK);
80 		bufind++;
81 		intbufind++;
82 	}
83 	return (RET_FAILED);
84 }
85 
86 void
print_varstring(struct ps_prochandle * ph,const char * varname)87 print_varstring(struct ps_prochandle *ph, const char *varname)
88 {
89 	(void) printf("print_varstring: %s\n", varname);
90 	if (strcmp(varname, "regs") == 0) {
91 		(void) display_all_regs(ph);
92 		return;
93 	}
94 	print_mach_varstring(ph, varname);
95 }
96 
97 void
print_mem(struct ps_prochandle * ph,ulong_t address,int count,char * format)98 print_mem(struct ps_prochandle *ph, ulong_t address, int count, char *format)
99 {
100 	(void) printf("\n%17s:", print_address_ps(ph, address, FLG_PAP_SONAME));
101 
102 	if ((*format == 'X') || (*format == 'x')) {
103 		int	i;
104 
105 		for (i = 0; i < count; i++) {
106 			unsigned long word;
107 			if ((i % 4) == 0)
108 				(void) printf("\n  0x%08lx: ", address);
109 
110 			if (ps_pread(ph, address, (char *)&word,
111 			    sizeof (unsigned long)) != PS_OK) {
112 				(void) printf("\nfailed to read memory at: "
113 				    "0x%lx\n", address);
114 				return;
115 			}
116 			(void) printf("  0x%08lx", word);
117 			address += 4;
118 		}
119 		(void) putchar('\n');
120 		return;
121 	}
122 
123 	if (*format == 'b') {
124 		int	i;
125 
126 		for (i = 0; i < count; i++, address ++) {
127 			unsigned char	byte;
128 
129 			if ((i % 8) == 0)
130 				(void) printf("\n 0x%08lx: ", address);
131 
132 			if (ps_pread(ph, address, (char *)&byte,
133 			    sizeof (unsigned char)) != PS_OK) {
134 				(void) fprintf(stderr, "\nfailed to read byte "
135 				    "at: 0x%lx\n", address);
136 				return;
137 			}
138 			(void) printf("  %02x", (unsigned)byte);
139 		}
140 		(void) putchar('\n');
141 		return;
142 	}
143 
144 	if (*format == 's') {
145 		char	buf[MAXPATHLEN];
146 		if (proc_string_read(ph, address, buf,
147 		    MAXPATHLEN) != RET_OK) {
148 			(void) printf("unable to read string at: %lx\n",
149 			    address);
150 			return;
151 		}
152 		(void) printf(" %s\n", buf);
153 		return;
154 	}
155 }
156