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 47 offsetok(void) 48 { 49 last_off = -1; 50 } 51 52 /* 53 * Get adb.s dot to the right offset. 54 */ 55 void 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 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 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 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