|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * @OSF_COPYRIGHT@ ! 24: */ ! 25: /* ! 26: * HISTORY ! 27: * ! 28: * Revision 1.1.1.1 1998/09/22 21:05:48 wsanchez ! 29: * Import of Mac OS X kernel (~semeria) ! 30: * ! 31: * Revision 1.1.1.1 1998/03/07 02:26:09 wsanchez ! 32: * Import of OSF Mach kernel (~mburg) ! 33: * ! 34: * Revision 1.2.19.1 1997/03/27 18:46:35 barbou ! 35: * ri-osc CR1561: make operators "logical and", "logical or" ! 36: * lex correctly. ! 37: * [1995/09/20 15:26:38 bolinger] ! 38: * [97/02/25 barbou] ! 39: * ! 40: * Revision 1.2.10.2 1995/01/06 19:10:13 devrcs ! 41: * mk6 CR668 - 1.3b26 merge ! 42: * * Revision 1.2.3.5 1994/05/06 18:39:16 tmt ! 43: * Merged osc1.3dec/shared with osc1.3b19 ! 44: * Merge Alpha changes into osc1.312b source code. ! 45: * 64bit cleanup. ! 46: * * End1.3merge ! 47: * [1994/11/04 08:49:27 dwm] ! 48: * ! 49: * Revision 1.2.10.1 1994/09/23 01:19:06 ezf ! 50: * change marker to not FREE ! 51: * [1994/09/22 21:09:53 ezf] ! 52: * ! 53: * Revision 1.2.3.3 1993/07/27 18:27:15 elliston ! 54: * Add ANSI prototypes. CR #9523. ! 55: * [1993/07/27 18:11:36 elliston] ! 56: * ! 57: * Revision 1.2.3.2 1993/06/09 02:20:06 gm ! 58: * Added to OSF/1 R1.3 from NMK15.0. ! 59: * [1993/06/02 20:56:16 jeffc] ! 60: * ! 61: * Revision 1.2 1993/04/19 16:02:09 devrcs ! 62: * Allow unprefixed (0x) hexadecimal constants starting by a letter: ! 63: * unknown symbols are tentatively interpreted as hexadecimal constants, ! 64: * and ambiguities are reported. ! 65: * [93/03/24 barbou] ! 66: * ! 67: * Changes from mk78: ! 68: * Removed unused variable from db_unary(). ! 69: * [92/05/16 jfriedl] ! 70: * [93/02/02 bruel] ! 71: * ! 72: * Added string format arguments [[email protected]] ! 73: * [92/12/03 bernadat] ! 74: * ! 75: * Revision 1.1 1992/09/30 02:01:04 robert ! 76: * Initial revision ! 77: * ! 78: * $EndLog$ ! 79: */ ! 80: /* CMU_HIST */ ! 81: /* ! 82: * Revision 2.5 91/10/09 15:59:46 af ! 83: * Revision 2.4.3.1 91/10/05 13:06:04 jeffreyh ! 84: * Added relational expression etc. to support condition expression. ! 85: * Supported modifier after indirect expression to specify size, ! 86: * sign extention and non current task space indirection. ! 87: * Changed error messages to print more information. ! 88: * [91/08/29 tak] ! 89: * ! 90: * Revision 2.4.3.1 91/10/05 13:06:04 jeffreyh ! 91: * Added relational expression etc. to support condition expression. ! 92: * Supported modifier after indirect expression to specify size, ! 93: * sign extention and non current task space indirection. ! 94: * Changed error messages to print more information. ! 95: * [91/08/29 tak] ! 96: * ! 97: * Revision 2.4 91/05/14 15:33:45 mrt ! 98: * Correcting copyright ! 99: * ! 100: * Revision 2.3 91/02/05 17:06:25 mrt ! 101: * Changed to new Mach copyright ! 102: * [91/01/31 16:17:46 mrt] ! 103: * ! 104: * Revision 2.2 90/08/27 21:50:57 dbg ! 105: * Use '..' instead of '$$' for db_prev. ! 106: * Use '+' for db_next. ! 107: * [90/08/22 dbg] ! 108: * ! 109: * Allow repeated unary operators. ! 110: * [90/08/20 dbg] ! 111: * ! 112: * Reflected back rename of db_symbol_value->db_value_of_name ! 113: * [90/08/20 af] ! 114: * Reduce lint. ! 115: * [90/08/07 dbg] ! 116: * Created. ! 117: * [90/07/25 dbg] ! 118: * ! 119: */ ! 120: /* CMU_ENDHIST */ ! 121: /* ! 122: * Mach Operating System ! 123: * Copyright (c) 1991,1990 Carnegie Mellon University ! 124: * All Rights Reserved. ! 125: * ! 126: * Permission to use, copy, modify and distribute this software and its ! 127: * documentation is hereby granted, provided that both the copyright ! 128: * notice and this permission notice appear in all copies of the ! 129: * software, derivative works or modified versions, and any portions ! 130: * thereof, and that both notices appear in supporting documentation. ! 131: * ! 132: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 133: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 134: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 135: * ! 136: * Carnegie Mellon requests users of this software to return to ! 137: * ! 138: * Software Distribution Coordinator or [email protected] ! 139: * School of Computer Science ! 140: * Carnegie Mellon University ! 141: * Pittsburgh PA 15213-3890 ! 142: * ! 143: * any improvements or extensions that they make and grant Carnegie Mellon ! 144: * the rights to redistribute these changes. ! 145: */ ! 146: /* ! 147: */ ! 148: /* ! 149: * Author: David B. Golub, Carnegie Mellon University ! 150: * Date: 7/90 ! 151: */ ! 152: ! 153: #include <mach/boolean.h> ! 154: #include <machine/db_machdep.h> ! 155: #include <ddb/db_access.h> ! 156: #include <ddb/db_command.h> ! 157: #include <ddb/db_expr.h> ! 158: #include <ddb/db_lex.h> ! 159: #include <ddb/db_output.h> /* For db_printf() */ ! 160: #include <ddb/db_sym.h> ! 161: #include <ddb/db_variables.h> ! 162: #include <kern/task.h> ! 163: ! 164: ! 165: ! 166: /* Prototypes for functions local to this file. XXX -- should be static! ! 167: */ ! 168: boolean_t db_term(db_expr_t *valuep); ! 169: boolean_t db_unary(db_expr_t *valuep); ! 170: boolean_t db_mult_expr(db_expr_t *valuep); ! 171: boolean_t db_add_expr(db_expr_t *valuep); ! 172: boolean_t db_shift_expr(db_expr_t *valuep); ! 173: boolean_t db_logical_relation_expr(db_expr_t *valuep); ! 174: boolean_t db_logical_and_expr(db_expr_t *valuep); ! 175: boolean_t db_logical_or_expr(db_expr_t *valuep); ! 176: ! 177: ! 178: /* try to interpret unknown symbols as hexadecimal constants */ ! 179: int db_allow_unprefixed_hexa = 1; ! 180: ! 181: boolean_t ! 182: db_term(db_expr_t *valuep) ! 183: { ! 184: int t; ! 185: boolean_t valid_symbol = FALSE; ! 186: boolean_t valid_hexa = FALSE; ! 187: ! 188: switch(t = db_read_token()) { ! 189: case tIDENT: ! 190: if (db_value_of_name(db_tok_string, valuep)) { ! 191: valid_symbol = TRUE; ! 192: } ! 193: if (db_allow_unprefixed_hexa && db_radix == 16 && ! 194: db_tok_string) { ! 195: char *cp; ! 196: int value; ! 197: ! 198: value = 0; ! 199: valid_hexa = TRUE; ! 200: for (cp = db_tok_string; *cp; cp++) { ! 201: if (*cp >= 'a' && *cp <= 'f') { ! 202: value = value * 16 + 10 + (*cp - 'a'); ! 203: } else if (*cp >= 'A' && *cp <= 'F') { ! 204: value = value * 16 + 10 + (*cp - 'A'); ! 205: } else if (*cp >= '0' && *cp <= '9') { ! 206: value = value * 16 + (*cp - '0'); ! 207: } else { ! 208: valid_hexa = FALSE; ! 209: break; ! 210: } ! 211: } ! 212: if (valid_hexa) { ! 213: if (valid_symbol) { ! 214: db_printf("Ambiguous constant %x used as a symbol\n", ! 215: value); ! 216: } else { ! 217: *valuep = (db_expr_t)value; ! 218: } ! 219: } ! 220: } ! 221: if (!valid_symbol && !valid_hexa) { ! 222: db_printf("Symbol \"%s\" not found\n", db_tok_string); ! 223: db_error(0); ! 224: /*NOTREACHED*/ ! 225: } ! 226: return (TRUE); ! 227: case tNUMBER: ! 228: *valuep = /*(db_expr_t)*/db_tok_number; ! 229: return (TRUE); ! 230: case tDOT: ! 231: *valuep = (db_expr_t)db_dot; ! 232: return (TRUE); ! 233: case tDOTDOT: ! 234: *valuep = (db_expr_t)db_prev; ! 235: return (TRUE); ! 236: case tPLUS: ! 237: *valuep = (db_expr_t) db_next; ! 238: return (TRUE); ! 239: case tQUOTE: ! 240: *valuep = (db_expr_t)db_last_addr; ! 241: return (TRUE); ! 242: case tDOLLAR: ! 243: if (!db_get_variable(valuep)) ! 244: return (FALSE); ! 245: return (TRUE); ! 246: case tLPAREN: ! 247: if (!db_expression(valuep)) { ! 248: db_error("Unmached ()s\n"); ! 249: /*NOTREACHED*/ ! 250: } ! 251: t = db_read_token(); ! 252: if (t != tRPAREN) { ! 253: db_printf("')' expected at \"%s...\"\n", db_tok_string); ! 254: db_error(0); ! 255: /*NOTREACHED*/ ! 256: } ! 257: return (TRUE); ! 258: case tSTRING: ! 259: { ! 260: static db_tok_offset = 0; ! 261: char *sp, *cp; ! 262: ! 263: sp = (char *)db_tok_string + db_tok_offset; ! 264: *valuep = *(int *)sp; ! 265: for (cp = sp; ! 266: *cp && cp < sp + sizeof (int); ! 267: cp++); ! 268: if (cp == sp + sizeof (int) && *cp) { ! 269: db_tok_offset += sizeof (int); ! 270: db_unread_token(t); ! 271: } else { ! 272: db_tok_offset = 0; ! 273: } ! 274: return (TRUE); ! 275: } ! 276: default: ! 277: db_unread_token(t); ! 278: return (FALSE); ! 279: } ! 280: } ! 281: ! 282: int ! 283: db_size_option( ! 284: char *modif, ! 285: boolean_t *u_option, ! 286: boolean_t *t_option) ! 287: { ! 288: register char *p; ! 289: int size = sizeof(int); ! 290: ! 291: *u_option = FALSE; ! 292: *t_option = FALSE; ! 293: for (p = modif; *p; p++) { ! 294: switch(*p) { ! 295: case 'b': ! 296: size = sizeof(char); ! 297: break; ! 298: case 'h': ! 299: size = sizeof(short); ! 300: break; ! 301: case 'l': ! 302: size = sizeof(long); ! 303: break; ! 304: case 'u': ! 305: *u_option = TRUE; ! 306: break; ! 307: case 't': ! 308: *t_option = TRUE; ! 309: break; ! 310: } ! 311: } ! 312: return(size); ! 313: } ! 314: ! 315: boolean_t ! 316: db_unary(db_expr_t *valuep) ! 317: { ! 318: int t; ! 319: int size; ! 320: boolean_t u_opt, t_opt; ! 321: task_t task; ! 322: extern task_t db_default_task; ! 323: ! 324: t = db_read_token(); ! 325: if (t == tMINUS) { ! 326: if (!db_unary(valuep)) { ! 327: db_error("Expression syntax error after '-'\n"); ! 328: /*NOTREACHED*/ ! 329: } ! 330: *valuep = -*valuep; ! 331: return (TRUE); ! 332: } ! 333: if (t == tSTAR) { ! 334: /* indirection */ ! 335: if (!db_unary(valuep)) { ! 336: db_error("Expression syntax error after '*'\n"); ! 337: /*NOTREACHED*/ ! 338: } ! 339: task = TASK_NULL; ! 340: size = sizeof(db_addr_t); ! 341: u_opt = FALSE; ! 342: t = db_read_token(); ! 343: if (t == tIDENT && db_tok_string[0] == ':') { ! 344: size = db_size_option(&db_tok_string[1], &u_opt, &t_opt); ! 345: if (t_opt) ! 346: task = db_default_task; ! 347: } else ! 348: db_unread_token(t); ! 349: *valuep = db_get_task_value((db_addr_t)*valuep, size, !u_opt, task); ! 350: return (TRUE); ! 351: } ! 352: if (t == tEXCL) { ! 353: if (!db_unary(valuep)) { ! 354: db_error("Expression syntax error after '!'\n"); ! 355: /*NOTREACHED*/ ! 356: } ! 357: *valuep = (!(*valuep)); ! 358: return (TRUE); ! 359: } ! 360: db_unread_token(t); ! 361: return (db_term(valuep)); ! 362: } ! 363: ! 364: boolean_t ! 365: db_mult_expr(db_expr_t *valuep) ! 366: { ! 367: db_expr_t lhs, rhs; ! 368: int t; ! 369: char c; ! 370: ! 371: if (!db_unary(&lhs)) ! 372: return (FALSE); ! 373: ! 374: t = db_read_token(); ! 375: while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH ! 376: || t == tBIT_AND) { ! 377: c = db_tok_string[0]; ! 378: if (!db_term(&rhs)) { ! 379: db_printf("Expression syntax error after '%c'\n", c); ! 380: db_error(0); ! 381: /*NOTREACHED*/ ! 382: } ! 383: switch(t) { ! 384: case tSTAR: ! 385: lhs *= rhs; ! 386: break; ! 387: case tBIT_AND: ! 388: lhs &= rhs; ! 389: break; ! 390: default: ! 391: if (rhs == 0) { ! 392: db_error("Divide by 0\n"); ! 393: /*NOTREACHED*/ ! 394: } ! 395: if (t == tSLASH) ! 396: lhs /= rhs; ! 397: else if (t == tPCT) ! 398: lhs %= rhs; ! 399: else ! 400: lhs = ((lhs+rhs-1)/rhs)*rhs; ! 401: } ! 402: t = db_read_token(); ! 403: } ! 404: db_unread_token(t); ! 405: *valuep = lhs; ! 406: return (TRUE); ! 407: } ! 408: ! 409: boolean_t ! 410: db_add_expr(db_expr_t *valuep) ! 411: { ! 412: db_expr_t lhs, rhs; ! 413: int t; ! 414: char c; ! 415: ! 416: if (!db_mult_expr(&lhs)) ! 417: return (FALSE); ! 418: ! 419: t = db_read_token(); ! 420: while (t == tPLUS || t == tMINUS || t == tBIT_OR) { ! 421: c = db_tok_string[0]; ! 422: if (!db_mult_expr(&rhs)) { ! 423: db_printf("Expression syntax error after '%c'\n", c); ! 424: db_error(0); ! 425: /*NOTREACHED*/ ! 426: } ! 427: if (t == tPLUS) ! 428: lhs += rhs; ! 429: else if (t == tMINUS) ! 430: lhs -= rhs; ! 431: else ! 432: lhs |= rhs; ! 433: t = db_read_token(); ! 434: } ! 435: db_unread_token(t); ! 436: *valuep = lhs; ! 437: return (TRUE); ! 438: } ! 439: ! 440: boolean_t ! 441: db_shift_expr(db_expr_t *valuep) ! 442: { ! 443: db_expr_t lhs, rhs; ! 444: int t; ! 445: ! 446: if (!db_add_expr(&lhs)) ! 447: return (FALSE); ! 448: ! 449: t = db_read_token(); ! 450: while (t == tSHIFT_L || t == tSHIFT_R) { ! 451: if (!db_add_expr(&rhs)) { ! 452: db_printf("Expression syntax error after \"%s\"\n", ! 453: (t == tSHIFT_L)? "<<": ">>"); ! 454: db_error(0); ! 455: /*NOTREACHED*/ ! 456: } ! 457: if (rhs < 0) { ! 458: db_error("Negative shift amount\n"); ! 459: /*NOTREACHED*/ ! 460: } ! 461: if (t == tSHIFT_L) ! 462: lhs <<= rhs; ! 463: else { ! 464: /* Shift right is unsigned */ ! 465: lhs = (natural_t) lhs >> rhs; ! 466: } ! 467: t = db_read_token(); ! 468: } ! 469: db_unread_token(t); ! 470: *valuep = lhs; ! 471: return (TRUE); ! 472: } ! 473: ! 474: boolean_t ! 475: db_logical_relation_expr(db_expr_t *valuep) ! 476: { ! 477: db_expr_t lhs, rhs; ! 478: int t; ! 479: char op[3]; ! 480: ! 481: if (!db_shift_expr(&lhs)) ! 482: return(FALSE); ! 483: ! 484: t = db_read_token(); ! 485: while (t == tLOG_EQ || t == tLOG_NOT_EQ ! 486: || t == tGREATER || t == tGREATER_EQ ! 487: || t == tLESS || t == tLESS_EQ) { ! 488: op[0] = db_tok_string[0]; ! 489: op[1] = db_tok_string[1]; ! 490: op[2] = 0; ! 491: if (!db_shift_expr(&rhs)) { ! 492: db_printf("Expression syntax error after \"%s\"\n", op); ! 493: db_error(0); ! 494: /*NOTREACHED*/ ! 495: } ! 496: switch(t) { ! 497: case tLOG_EQ: ! 498: lhs = (lhs == rhs); ! 499: break; ! 500: case tLOG_NOT_EQ: ! 501: lhs = (lhs != rhs); ! 502: break; ! 503: case tGREATER: ! 504: lhs = (lhs > rhs); ! 505: break; ! 506: case tGREATER_EQ: ! 507: lhs = (lhs >= rhs); ! 508: break; ! 509: case tLESS: ! 510: lhs = (lhs < rhs); ! 511: break; ! 512: case tLESS_EQ: ! 513: lhs = (lhs <= rhs); ! 514: break; ! 515: } ! 516: t = db_read_token(); ! 517: } ! 518: db_unread_token(t); ! 519: *valuep = lhs; ! 520: return (TRUE); ! 521: } ! 522: ! 523: boolean_t ! 524: db_logical_and_expr(db_expr_t *valuep) ! 525: { ! 526: db_expr_t lhs, rhs; ! 527: int t; ! 528: ! 529: if (!db_logical_relation_expr(&lhs)) ! 530: return(FALSE); ! 531: ! 532: t = db_read_token(); ! 533: while (t == tLOG_AND) { ! 534: if (!db_logical_relation_expr(&rhs)) { ! 535: db_error("Expression syntax error after \"&&\"\n"); ! 536: /*NOTREACHED*/ ! 537: } ! 538: lhs = (lhs && rhs); ! 539: t = db_read_token(); ! 540: } ! 541: db_unread_token(t); ! 542: *valuep = lhs; ! 543: return (TRUE); ! 544: } ! 545: ! 546: boolean_t ! 547: db_logical_or_expr(db_expr_t *valuep) ! 548: { ! 549: db_expr_t lhs, rhs; ! 550: int t; ! 551: ! 552: if (!db_logical_and_expr(&lhs)) ! 553: return(FALSE); ! 554: ! 555: t = db_read_token(); ! 556: while (t == tLOG_OR) { ! 557: if (!db_logical_and_expr(&rhs)) { ! 558: db_error("Expression syntax error after \"||\"\n"); ! 559: /*NOTREACHED*/ ! 560: } ! 561: lhs = (lhs || rhs); ! 562: t = db_read_token(); ! 563: } ! 564: db_unread_token(t); ! 565: *valuep = lhs; ! 566: return (TRUE); ! 567: } ! 568: ! 569: int ! 570: db_expression(db_expr_t *valuep) ! 571: { ! 572: return (db_logical_or_expr(valuep)); ! 573: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.