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 #pragma ident "%Z%%M% %I% %E% SMI"
23
24 /*
25 * Copyright (c) 1983-1998 by Sun Microsystems, Inc.
26 * All rights reserved.
27 */
28
29 /*
30 * Subroutines to be called by adbgen2.c, the C program generated
31 * by adbgen1.c.
32 */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <sys/types.h>
37
38 off_t last_off;
39 int warnings = 1;
40 int warns = 0;
41
42 /*
43 * User claims offset is ok.
44 * This usually follows call to another script, which we cannot handle.
45 */
46 void
offsetok(void)47 offsetok(void)
48 {
49 last_off = -1;
50 }
51
52 /*
53 * Get adb.s dot to the right offset.
54 */
55 void
offset(off_t off)56 offset(off_t off)
57 {
58 off_t off_diff;
59
60 if (last_off == -1) {
61 last_off = off;
62 return;
63 }
64 off_diff = off - last_off;
65 if (off_diff) {
66 if (off_diff > 0) {
67 if (off_diff > 1) {
68 printf("%ld", off_diff);
69 }
70 printf("+");
71 }
72 if (off_diff < 0) {
73 if (off_diff < -1) {
74 printf("%ld", -off_diff);
75 }
76 printf("-");
77 }
78 }
79 last_off = off;
80 }
81
82 /*
83 * Emit the format command, return the size.
84 */
85 int
do_fmt(char * acp)86 do_fmt(char *acp)
87 {
88 int rcount, width, sum, i;
89 char *cp;
90
91 cp = acp;
92 sum = rcount = 0;
93 do {
94 while (*cp >= '0' && *cp <= '9') {
95 rcount = rcount * 10 + *cp++ - '0';
96 }
97 if (rcount == 0) {
98 rcount = 1;
99 }
100 switch (*cp) {
101 case 'e':
102 case 'E':
103 case 'F':
104 case 'g':
105 case 'G':
106 case 'J':
107 width = 8;
108 break;
109 case 'K':
110 #ifdef _LP64
111 width = 8;
112 #else /* _LP64 */
113 width = 4;
114 #endif /* _LP64 */
115 break;
116 case 'X':
117 case 'O':
118 case 'Q':
119 case 'D':
120 case 'U':
121 case 'f':
122 case 'Y':
123 case 'p':
124 case 'P':
125 width = 4;
126 break;
127 case 'x':
128 case 'o':
129 case 'q':
130 case 'd':
131 case 'u':
132 width = 2;
133 break;
134 case 'v':
135 case 'V':
136 case 'b':
137 case 'B':
138 case 'c':
139 case 'C':
140 case '+':
141 width = 1;
142 break;
143 case 'I':
144 case 'a':
145 case 'A':
146 case 't':
147 case 'r':
148 case 'n':
149 width = 0;
150 break;
151 case '-':
152 width = -1;
153 break;
154 case 's':
155 case 'S':
156 case 'i':
157 if (warnings) {
158 fprintf(stderr,
159 "Unknown format size \"%s\", assuming zero\n",
160 acp);
161 warns++;
162 }
163 width = 0;
164 break;
165 default:
166 fprintf(stderr, "Unknown format size: %s\n", acp);
167 exit(1);
168 }
169 for (i = 0; i < rcount; i++) {
170 putchar(*cp);
171 }
172 cp++;
173 sum += width * rcount;
174 } while (*cp);
175 return (sum);
176 }
177
178 /*
179 * Format struct member, checking size.
180 */
181 void
format(char * name,size_t size,char * fmt)182 format(char *name, size_t size, char *fmt)
183 {
184 int fs;
185
186 fs = do_fmt(fmt);
187 if (fs != size && warnings) {
188 fprintf(stderr,
189 "warning: \"%s\" size is %ld, \"%s\" width is %d\n",
190 name, size, fmt, fs);
191 warns++;
192 }
193 last_off += fs;
194 }
195
196 /*
197 * Get the value at offset based on base.
198 */
199 void
indirect(off_t offset,size_t size,char * base,char * member)200 indirect(off_t offset, size_t size, char *base, char *member)
201 {
202 if (size == 8 || size == 4) {
203 if (offset == 0) {
204 printf("*%s", base);
205 } else {
206 printf("*(%s+0t%ld)", base, offset);
207 }
208 } else if (size == 2) {
209 if (offset == 2) {
210 printf("(*%s&0xffff)", base);
211 } else {
212 printf("(*(%s+0t%ld)&0xffff)", base, offset - 2);
213 }
214 } else if (size == 1) {
215 if (offset == 3) {
216 printf("(*%s&0xff)", base);
217 } else {
218 if ((offset & 0x1) == 0x1) {
219 printf("(*(%s+0t%ld)&0xff)", base, offset - 3);
220 } else {
221 printf("((*(%s+0t%ld)&0xff00)/0x100)",
222 base, offset - 2);
223 }
224 }
225 } else {
226 fprintf(stderr, "Indirect size %ld not 1, 2, or 4: %s\n",
227 size, member);
228 exit(1);
229 }
230 }
231