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