@@ -680,35 +680,47 @@ static const MatchOpInfo *parseMatchOp(int t)
680680 case ' &' :
681681 static const MatchOpInfo info_BIT_AND = {MATCH_OP_BIT_AND, 2 };
682682 return &info_BIT_AND;
683+ case ' ^' :
684+ static const MatchOpInfo info_BIT_XOR = {MATCH_OP_BIT_XOR, 3 };
685+ return &info_BIT_XOR;
683686 case ' |' :
684- static const MatchOpInfo info_BIT_OR = {MATCH_OP_BIT_OR, 3 };
687+ static const MatchOpInfo info_BIT_OR = {MATCH_OP_BIT_OR, 4 };
685688 return &info_BIT_OR;
686689 case ' -' :
687- static const MatchOpInfo info_SUB = {MATCH_OP_SUB, 4 };
690+ static const MatchOpInfo info_SUB = {MATCH_OP_SUB, 5 };
688691 return &info_SUB;
689692 case ' +' :
690- static const MatchOpInfo info_ADD = {MATCH_OP_ADD, 4 };
693+ static const MatchOpInfo info_ADD = {MATCH_OP_ADD, 5 };
691694 return &info_ADD;
695+ case ' *' :
696+ static const MatchOpInfo info_MUL = {MATCH_OP_MUL, 6 };
697+ return &info_MUL;
698+ case ' /' : case TOKEN_DIV:
699+ static const MatchOpInfo info_DIV = {MATCH_OP_DIV, 6 };
700+ return &info_DIV;
701+ case ' %' : case TOKEN_MOD:
702+ static const MatchOpInfo info_MOD = {MATCH_OP_MOD, 6 };
703+ return &info_MOD;
692704 case TOKEN_IN:
693- static const MatchOpInfo info_IN = {MATCH_OP_IN, 5 };
705+ static const MatchOpInfo info_IN = {MATCH_OP_IN, 7 };
694706 return &info_IN;
695707 case ' <' :
696- static const MatchOpInfo info_LT = {MATCH_OP_LT, 6 };
708+ static const MatchOpInfo info_LT = {MATCH_OP_LT, 8 };
697709 return &info_LT;
698710 case ' >' :
699- static const MatchOpInfo info_GT = {MATCH_OP_GT, 6 };
711+ static const MatchOpInfo info_GT = {MATCH_OP_GT, 8 };
700712 return &info_GT;
701713 case TOKEN_LEQ:
702- static const MatchOpInfo info_LEQ = {MATCH_OP_LEQ, 6 };
714+ static const MatchOpInfo info_LEQ = {MATCH_OP_LEQ, 8 };
703715 return &info_LEQ;
704716 case TOKEN_GEQ:
705- static const MatchOpInfo info_GEQ = {MATCH_OP_GEQ, 6 };
717+ static const MatchOpInfo info_GEQ = {MATCH_OP_GEQ, 8 };
706718 return &info_GEQ;
707719 case ' =' :
708- static const MatchOpInfo info_EQ = {MATCH_OP_EQ, 7 };
720+ static const MatchOpInfo info_EQ = {MATCH_OP_EQ, 9 };
709721 return &info_EQ;
710722 case TOKEN_NEQ:
711- static const MatchOpInfo info_NEQ = {MATCH_OP_NEQ, 7 };
723+ static const MatchOpInfo info_NEQ = {MATCH_OP_NEQ, 9 };
712724 return &info_NEQ;
713725 case TOKEN_AND:
714726 static const MatchOpInfo info_AND = {MATCH_OP_AND, 11 };
@@ -737,7 +749,7 @@ static MatchExpr *parseMatchExpr(Parser &parser, int prec = 99)
737749 break ;
738750 case ' !' : case TOKEN_NOT:
739751 (void )parser.getToken ();
740- expr = parseMatchExpr (parser, 8 );
752+ expr = parseMatchExpr (parser, 10 );
741753 expr = new MatchExpr (MATCH_OP_NOT, expr);
742754 break ;
743755 case TOKEN_NONE:
@@ -1410,7 +1422,7 @@ static void dumpExpr(const MatchExpr &expr, std::string &str, bool hex = false)
14101422 str += ' ~' ;
14111423 dumpExpr (*expr.lhs , str);
14121424 return ;
1413- case MATCH_OP_BIT_AND: case MATCH_OP_BIT_OR:
1425+ case MATCH_OP_BIT_AND: case MATCH_OP_BIT_OR: case MATCH_OP_BIT_XOR:
14141426 hex = true ;
14151427 // Fallthrough:
14161428 case MATCH_OP_AND: case MATCH_OP_OR:
@@ -1419,6 +1431,7 @@ static void dumpExpr(const MatchExpr &expr, std::string &str, bool hex = false)
14191431 case MATCH_OP_GT: case MATCH_OP_GEQ:
14201432 case MATCH_OP_IN:
14211433 case MATCH_OP_ADD: case MATCH_OP_SUB:
1434+ case MATCH_OP_MUL: case MATCH_OP_DIV: case MATCH_OP_MOD:
14221435 case MATCH_OP_LSHIFT: case MATCH_OP_RSHIFT:
14231436 str += ' (' ;
14241437 dumpExpr (*expr.lhs , str, hex);
@@ -1446,10 +1459,18 @@ static void dumpExpr(const MatchExpr &expr, std::string &str, bool hex = false)
14461459 str += ' +' ; break ;
14471460 case MATCH_OP_SUB:
14481461 str += ' -' ; break ;
1462+ case MATCH_OP_MUL:
1463+ str += ' *' ; break ;
1464+ case MATCH_OP_DIV:
1465+ str += ' /' ; break ;
1466+ case MATCH_OP_MOD:
1467+ str += ' %' ; break ;
14491468 case MATCH_OP_BIT_AND:
14501469 str += ' &' ; break ;
14511470 case MATCH_OP_BIT_OR:
14521471 str += ' |' ; break ;
1472+ case MATCH_OP_BIT_XOR:
1473+ str += ' ^' ; break ;
14531474 case MATCH_OP_LSHIFT:
14541475 str += " <<" ; break ;
14551476 case MATCH_OP_RSHIFT:
@@ -2288,7 +2309,8 @@ static MatchVal matchDoEval(const MatchExpr *expr, const ELF &elf,
22882309 break ;
22892310 }
22902311 case MATCH_OP_ADD: case MATCH_OP_SUB:
2291- case MATCH_OP_BIT_AND: case MATCH_OP_BIT_OR:
2312+ case MATCH_OP_MUL: case MATCH_OP_DIV: case MATCH_OP_MOD:
2313+ case MATCH_OP_BIT_AND: case MATCH_OP_BIT_OR: case MATCH_OP_BIT_XOR:
22922314 case MATCH_OP_LSHIFT: case MATCH_OP_RSHIFT:
22932315 {
22942316 res.type = MATCH_TYPE_UNDEFINED;
@@ -2300,18 +2322,36 @@ static MatchVal matchDoEval(const MatchExpr *expr, const ELF &elf,
23002322 break ;
23012323 res.type = MATCH_TYPE_INTEGER;
23022324 res.i = 0 ;
2325+ typedef __int128 int128_t ;
2326+ int128_t i128 = 0 ;
23032327 switch (expr->op )
23042328 {
23052329 case MATCH_OP_ADD:
2306- res.i = lhs.i + rhs.i ; break ;
2330+ i128 = (int128_t )lhs.i + (int128_t )rhs.i ;
2331+ goto check128;
23072332 case MATCH_OP_SUB:
2308- res.i = lhs.i - rhs.i ; break ;
2333+ i128 = (int128_t )lhs.i - (int128_t )rhs.i ;
2334+ goto check128;
2335+ case MATCH_OP_MUL:
2336+ i128 = (int128_t )lhs.i * (int128_t )rhs.i ;
2337+ goto check128;
2338+ case MATCH_OP_DIV:
2339+ if (rhs.i == 0 ) goto undefined;
2340+ i128 = (int128_t )lhs.i / (int128_t )rhs.i ;
2341+ goto check128;
2342+ case MATCH_OP_MOD:
2343+ if (rhs.i == 0 ) goto undefined;
2344+ i128 = (int128_t )lhs.i % (int128_t )rhs.i ;
2345+ goto check128;
23092346 case MATCH_OP_BIT_AND:
23102347 res.i = (intptr_t )((uint64_t )lhs.i & (uint64_t )rhs.i );
23112348 break ;
23122349 case MATCH_OP_BIT_OR:
23132350 res.i = (intptr_t )((uint64_t )lhs.i | (uint64_t )rhs.i );
23142351 break ;
2352+ case MATCH_OP_BIT_XOR:
2353+ res.i = (intptr_t )((uint64_t )lhs.i ^ (uint64_t )rhs.i );
2354+ break ;
23152355 case MATCH_OP_LSHIFT:
23162356 res.i = (intptr_t )
23172357 (rhs.i <= 0 ? lhs.i :
@@ -2322,7 +2362,12 @@ static MatchVal matchDoEval(const MatchExpr *expr, const ELF &elf,
23222362 (rhs.i <= 0 ? lhs.i :
23232363 rhs.i >= 64 ? 0x0 : (int64_t )lhs.i >> (unsigned )rhs.i );
23242364 break ;
2365+ check128:
2366+ if (i128 < INTPTR_MIN || i128 > INTPTR_MAX) goto undefined;
2367+ res.i = (intptr_t )i128 ; break ;
23252368 default :
2369+ undefined:
2370+ res.type = MATCH_TYPE_UNDEFINED;
23262371 break ;
23272372 }
23282373 break ;
0 commit comments