Annotation of XNU/osfmk/ddb/db_expr.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.