1 1.2 wiz /* $NetBSD: decode.c,v 1.2 2006/11/24 21:20:05 wiz Exp $ */ 2 1.1 cherry 3 1.1 cherry /* Contributed to the NetBSD foundation by Cherry G. Mathew 4 1.1 cherry * This file contains routines to decode unwind descriptors into 5 1.1 cherry * easily an readable data structure ( unwind_desc ) 6 1.2 wiz * This is the lowest layer of the unwind stack hierarchy. 7 1.1 cherry */ 8 1.1 cherry 9 1.1 cherry #include <sys/cdefs.h> 10 1.1 cherry #include <sys/types.h> 11 1.1 cherry #include <sys/param.h> 12 1.1 cherry #include <sys/systm.h> 13 1.1 cherry 14 1.1 cherry #include <ia64/unwind/decode.h> 15 1.1 cherry 16 1.1 cherry /* Decode ULE128 string */ 17 1.1 cherry 18 1.1 cherry char * 19 1.1 cherry unwind_decode_ule128(char *buf, unsigned long *val) 20 1.1 cherry { 21 1.1 cherry int i = 0; 22 1.1 cherry 23 1.1 cherry val[0] = 0; 24 1.1 cherry do { 25 1.1 cherry val[0] += ((buf[i] & 0x7f) << (i * 7)); 26 1.1 cherry 27 1.1 cherry }while((0x80 & buf[i++]) && (i < 9)); 28 1.1 cherry 29 1.1 cherry if(i > 9) { 30 1.1 cherry printf("Warning: ULE128 won't fit in an unsigned long. decode aborted!!!\n"); 31 1.1 cherry return 0; 32 1.1 cherry } 33 1.1 cherry 34 1.1 cherry buf+= i; 35 1.1 cherry return buf; 36 1.1 cherry } 37 1.1 cherry 38 1.1 cherry 39 1.1 cherry char * 40 1.1 cherry unwind_decode_R1(char *buf, union unwind_desc *uwd) 41 1.1 cherry { 42 1.1 cherry 43 1.1 cherry if(!IS_R1(buf[0])) return NULL; 44 1.1 cherry uwd->R1.r = ((buf[0] & 0x20) == 0x20); 45 1.1 cherry uwd->R1.rlen = (buf[0] & 0x1f); 46 1.1 cherry buf++; 47 1.1 cherry return buf; 48 1.1 cherry } 49 1.1 cherry 50 1.1 cherry char * 51 1.1 cherry unwind_decode_R2(char *buf, union unwind_desc *uwd) 52 1.1 cherry { 53 1.1 cherry 54 1.1 cherry if(!IS_R2(buf[0])) return NULL; 55 1.1 cherry 56 1.1 cherry uwd->R2.mask = (((buf[0] & 0x07) << 1) | ( (buf[1] >> 7) & 0xff)); 57 1.1 cherry uwd->R2.grsave = (buf[1] & 0x7f); 58 1.1 cherry 59 1.1 cherry buf += 2; 60 1.1 cherry buf = unwind_decode_ule128(buf, &uwd->R2.rlen); 61 1.1 cherry return buf; 62 1.1 cherry } 63 1.1 cherry 64 1.1 cherry char * 65 1.1 cherry unwind_decode_R3(char *buf, union unwind_desc *uwd) 66 1.1 cherry { 67 1.1 cherry 68 1.1 cherry if(!IS_R3(buf[0])) return NULL; 69 1.1 cherry 70 1.1 cherry uwd->R3.r = ((buf[0] & 0x03) == 0x01); 71 1.1 cherry 72 1.1 cherry buf++; 73 1.1 cherry buf = unwind_decode_ule128(buf, &uwd->R3.rlen); 74 1.1 cherry return buf; 75 1.1 cherry } 76 1.1 cherry 77 1.1 cherry char * 78 1.1 cherry unwind_decode_P1(char *buf, union unwind_desc *uwd) 79 1.1 cherry { 80 1.1 cherry 81 1.1 cherry 82 1.1 cherry if(!IS_P1(buf[0])) return NULL; 83 1.1 cherry 84 1.1 cherry uwd->P1.brmask = (buf[0] & 0x1f); 85 1.1 cherry buf++; 86 1.1 cherry return buf; 87 1.1 cherry } 88 1.1 cherry 89 1.1 cherry char * 90 1.1 cherry unwind_decode_P2(char *buf, union unwind_desc *uwd) 91 1.1 cherry { 92 1.1 cherry 93 1.1 cherry if(!IS_P2(buf[0])) return NULL; 94 1.1 cherry 95 1.1 cherry uwd->P2.brmask = (((buf[0] & 0x0f) << 1) | ( (buf[1] >> 7) & 0xff)); 96 1.1 cherry uwd->P2.gr = (buf[1] & 0x7f); 97 1.1 cherry buf += 2; 98 1.1 cherry return buf; 99 1.1 cherry } 100 1.1 cherry 101 1.1 cherry char * 102 1.1 cherry unwind_decode_P3(char *buf, union unwind_desc *uwd) 103 1.1 cherry { 104 1.1 cherry 105 1.1 cherry if(!IS_P3(buf[0])) return NULL; 106 1.1 cherry 107 1.1 cherry uwd->P3.r = (((0x07 & buf[0]) << 1) | ((0x80 & buf[1]) >> 7)); 108 1.1 cherry uwd->P3.grbr = (buf[1] & 0x7f); 109 1.1 cherry buf +=2; 110 1.1 cherry return buf; 111 1.1 cherry } 112 1.1 cherry 113 1.1 cherry char * 114 1.1 cherry unwind_decode_P4(char *buf, union unwind_desc *uwd, vsize_t len) 115 1.1 cherry { 116 1.1 cherry 117 1.1 cherry if(!IS_P4(buf[0])) return NULL; 118 1.1 cherry 119 1.1 cherry uwd->P4.imask = 0; /* XXX: Unimplemented */ 120 1.1 cherry 121 1.1 cherry /* XXX: adjust buf for imask length on return!!! 122 1.1 cherry * don't know the length of imask here. 123 1.1 cherry */ 124 1.1 cherry buf += roundup(len << 1, 8); 125 1.1 cherry return buf; 126 1.1 cherry } 127 1.1 cherry 128 1.1 cherry char * 129 1.1 cherry unwind_decode_P5(char *buf, union unwind_desc *uwd) 130 1.1 cherry { 131 1.1 cherry 132 1.1 cherry if(!IS_P5(buf[0])) return NULL; 133 1.1 cherry 134 1.1 cherry uwd->P5.grmask = (buf[1] >> 4); 135 1.1 cherry uwd->P5.frmask = ((buf[1] & 0x0f << 16) | (buf[2] << 8) | buf[3]); 136 1.1 cherry buf += 4; 137 1.1 cherry return buf; 138 1.1 cherry } 139 1.1 cherry 140 1.1 cherry char * 141 1.1 cherry unwind_decode_P6(char *buf, union unwind_desc *uwd) 142 1.1 cherry { 143 1.1 cherry 144 1.1 cherry if(!IS_P6(buf[0])) return NULL; 145 1.1 cherry 146 1.1 cherry uwd->P6.r = ((buf[0] & 0x10) == 0x10); 147 1.1 cherry uwd->P6.rmask = (buf[0] & 0x0f); 148 1.1 cherry buf++; 149 1.1 cherry return buf; 150 1.1 cherry } 151 1.1 cherry 152 1.1 cherry 153 1.1 cherry char * 154 1.1 cherry unwind_decode_P7(char *buf, union unwind_desc *uwd) 155 1.1 cherry { 156 1.1 cherry 157 1.1 cherry if (!IS_P7(buf[0])) return NULL; 158 1.1 cherry 159 1.1 cherry uwd->P7.r = (buf[0] & 0x0f); 160 1.1 cherry 161 1.1 cherry buf++; 162 1.1 cherry 163 1.1 cherry buf = unwind_decode_ule128(buf, &uwd->P7.t); 164 1.1 cherry if (uwd->P7.r == 0) /* memstack_f */ 165 1.1 cherry buf = unwind_decode_ule128(buf, &uwd->P7.size); 166 1.1 cherry return buf; 167 1.1 cherry } 168 1.1 cherry 169 1.1 cherry char * 170 1.1 cherry unwind_decode_P8(char *buf, union unwind_desc *uwd) 171 1.1 cherry { 172 1.1 cherry 173 1.1 cherry if(!IS_P8(buf[0])) return NULL; 174 1.1 cherry 175 1.1 cherry uwd->P8.r = buf[1]; 176 1.1 cherry 177 1.1 cherry buf +=2; 178 1.1 cherry buf = unwind_decode_ule128(buf, &uwd->P8.t); 179 1.1 cherry return buf; 180 1.1 cherry } 181 1.1 cherry 182 1.1 cherry char * 183 1.1 cherry unwind_decode_P9(char *buf, union unwind_desc *uwd) 184 1.1 cherry { 185 1.1 cherry 186 1.1 cherry 187 1.1 cherry if(!IS_P9(buf[0])) return NULL; 188 1.1 cherry 189 1.1 cherry uwd->P9.grmask = buf[1] & 0x0f; 190 1.1 cherry uwd->P9.gr = buf[2] & 0x7f; 191 1.1 cherry buf += 3; 192 1.1 cherry return buf; 193 1.1 cherry } 194 1.1 cherry 195 1.1 cherry 196 1.1 cherry char * 197 1.1 cherry unwind_decode_P10(char *buf, union unwind_desc *uwd) 198 1.1 cherry { 199 1.1 cherry 200 1.1 cherry 201 1.1 cherry if(!IS_P10(buf[0])) return NULL; 202 1.1 cherry 203 1.1 cherry uwd->P10.abi = buf[1]; 204 1.1 cherry uwd->P10.context = buf[2]; 205 1.1 cherry buf += 3; 206 1.1 cherry return buf; 207 1.1 cherry } 208 1.1 cherry 209 1.1 cherry char * 210 1.1 cherry unwind_decode_B1(char *buf, union unwind_desc *uwd) 211 1.1 cherry { 212 1.1 cherry 213 1.1 cherry 214 1.1 cherry if(!IS_B1(buf[0])) return NULL; 215 1.1 cherry 216 1.1 cherry uwd->B1.r = ((buf[0] & 0x20) == 0x20); 217 1.1 cherry uwd->B1.label = (buf[0] & 0x1f); 218 1.1 cherry 219 1.1 cherry buf++; 220 1.1 cherry return buf; 221 1.1 cherry } 222 1.1 cherry 223 1.1 cherry char * 224 1.1 cherry unwind_decode_B2(char *buf, union unwind_desc *uwd) 225 1.1 cherry { 226 1.1 cherry 227 1.1 cherry 228 1.1 cherry if(!IS_B2(buf[0])) return NULL; 229 1.1 cherry 230 1.1 cherry uwd->B2.ecount = (buf[0] & 0x1f); 231 1.1 cherry 232 1.1 cherry buf++; 233 1.1 cherry buf = unwind_decode_ule128(buf, &uwd->B2.t); 234 1.1 cherry return buf; 235 1.1 cherry } 236 1.1 cherry 237 1.1 cherry char * 238 1.1 cherry unwind_decode_B3(char *buf, union unwind_desc *uwd) 239 1.1 cherry { 240 1.1 cherry 241 1.1 cherry 242 1.1 cherry if(!IS_B3(buf[0])) return NULL; 243 1.1 cherry 244 1.1 cherry buf++; 245 1.1 cherry buf = unwind_decode_ule128(buf, &uwd->B3.t); 246 1.1 cherry buf = unwind_decode_ule128(buf, &uwd->B3.ecount); 247 1.1 cherry return buf; 248 1.1 cherry } 249 1.1 cherry 250 1.1 cherry char * 251 1.1 cherry unwind_decode_B4(char *buf, union unwind_desc *uwd) 252 1.1 cherry { 253 1.1 cherry 254 1.1 cherry 255 1.1 cherry if(!IS_B4(buf[0])) return NULL; 256 1.1 cherry 257 1.1 cherry uwd->B4.r = ((buf[0] & 0x08) == 0x08); 258 1.1 cherry 259 1.1 cherry buf++; 260 1.1 cherry buf = unwind_decode_ule128(buf, &uwd->B4.label); 261 1.1 cherry return buf; 262 1.1 cherry } 263 1.1 cherry 264 1.1 cherry 265 1.1 cherry char * 266 1.1 cherry unwind_decode_X1(char *buf, union unwind_desc *uwd) 267 1.1 cherry { 268 1.1 cherry 269 1.1 cherry 270 1.1 cherry if(!IS_X1(buf[0])) return NULL; 271 1.1 cherry 272 1.1 cherry uwd->X1.r = ((buf[1] & 0x80) == 0x80); 273 1.1 cherry uwd->X1.a = ((buf[1] & 0x40) == 0x40); 274 1.1 cherry uwd->X1.b = ((buf[1] & 0x20) == 0x20); 275 1.1 cherry uwd->X1.reg = (buf[1] & 0x1f); 276 1.1 cherry 277 1.1 cherry buf += 2; 278 1.1 cherry buf = unwind_decode_ule128(buf, &uwd->X1.t); 279 1.1 cherry buf = unwind_decode_ule128(buf, &uwd->X1.offset); 280 1.1 cherry return buf; 281 1.1 cherry } 282 1.1 cherry 283 1.1 cherry 284 1.1 cherry char * 285 1.1 cherry unwind_decode_X2(char *buf, union unwind_desc *uwd) 286 1.1 cherry { 287 1.1 cherry 288 1.1 cherry 289 1.1 cherry if(!IS_X2(buf[0])) return NULL; 290 1.1 cherry 291 1.1 cherry uwd->X2.x = ((buf[1] & 0x80) == 0x80); 292 1.1 cherry uwd->X2.a = ((buf[1] & 0x40) == 0x40); 293 1.1 cherry uwd->X2.b = ((buf[1] & 0x20) == 0x20); 294 1.1 cherry uwd->X2.reg = (buf[1] & 0x1f); 295 1.1 cherry uwd->X2.y = ((buf[2] & 0x80) == 0x80); 296 1.1 cherry uwd->X2.treg = (buf[2] & 0x7f); 297 1.1 cherry 298 1.1 cherry buf += 3; 299 1.1 cherry buf = unwind_decode_ule128(buf, &uwd->X2.t); 300 1.1 cherry return buf; 301 1.1 cherry } 302 1.1 cherry 303 1.1 cherry char * 304 1.1 cherry unwind_decode_X3(char *buf, union unwind_desc *uwd) 305 1.1 cherry { 306 1.1 cherry 307 1.1 cherry 308 1.1 cherry if(!IS_X3(buf[0])) return NULL; 309 1.1 cherry 310 1.1 cherry uwd->X3.r = ((buf[1] & 0x80) == 0x80); 311 1.1 cherry uwd->X3.qp = (buf[1] & 0x3f); 312 1.1 cherry uwd->X3.a = ((buf[1] & 0x40) == 0x40); 313 1.1 cherry uwd->X3.b = ((buf[1] & 0x20) == 0x20); 314 1.1 cherry uwd->X3.reg = (buf[1] & 0x1f); 315 1.1 cherry 316 1.1 cherry buf += 3; 317 1.1 cherry buf = unwind_decode_ule128(buf, &uwd->X3.t); 318 1.1 cherry buf = unwind_decode_ule128(buf, &uwd->X3.offset ); 319 1.1 cherry return buf; 320 1.1 cherry } 321 1.1 cherry 322 1.1 cherry char * 323 1.1 cherry unwind_decode_X4(char *buf, union unwind_desc *uwd) 324 1.1 cherry { 325 1.1 cherry 326 1.1 cherry 327 1.1 cherry if(!IS_X4(buf[0])) return NULL; 328 1.1 cherry 329 1.1 cherry uwd->X4.qp = (buf[1] & 0x3f); 330 1.1 cherry uwd->X4.x = ((buf[2] & 0x80) == 0x80); 331 1.1 cherry uwd->X4.a = ((buf[2] & 0x40) == 0x40); 332 1.1 cherry uwd->X4.b = ((buf[2] & 0x20) == 0x20); 333 1.1 cherry uwd->X4.reg = (buf[2] & 0x1f); 334 1.1 cherry uwd->X4.y = ((buf[3] & 0x80) == 0x80); 335 1.1 cherry uwd->X4.treg = (buf[3] & 0x7f); 336 1.1 cherry 337 1.1 cherry buf +=4; 338 1.1 cherry buf = unwind_decode_ule128(buf, &uwd->X4.t); 339 1.1 cherry return buf; 340 1.1 cherry } 341 1.1 cherry 342