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