1 /* $OpenBSD: bcode.c,v 1.40 2009/10/27 23:59:37 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 2003, Otto Moerbeek <[email protected]> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/cdefs.h> 20 __FBSDID("$FreeBSD$"); 21 22 #include <err.h> 23 #include <limits.h> 24 #include <openssl/ssl.h> 25 #include <signal.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 30 #include "extern.h" 31 32 BIGNUM zero; 33 34 #define __inline 35 36 #define MAX_ARRAY_INDEX 2048 37 #define READSTACK_SIZE 8 38 39 #define NO_ELSE -2 /* -1 is EOF */ 40 #define REG_ARRAY_SIZE_SMALL (UCHAR_MAX + 1) 41 #define REG_ARRAY_SIZE_BIG (UCHAR_MAX + 1 + USHRT_MAX + 1) 42 43 struct bmachine { 44 struct source *readstack; 45 struct stack *reg; 46 struct stack stack; 47 volatile sig_atomic_t interrupted; 48 u_int scale; 49 u_int obase; 50 u_int ibase; 51 size_t readsp; 52 size_t reg_array_size; 53 size_t readstack_sz; 54 bool extended_regs; 55 }; 56 57 static struct bmachine bmachine; 58 static void sighandler(int); 59 60 static __inline int readch(void); 61 static __inline void unreadch(void); 62 static __inline char *readline(void); 63 static __inline void src_free(void); 64 65 static __inline u_int max(u_int, u_int); 66 static u_long get_ulong(struct number *); 67 68 static __inline void push_number(struct number *); 69 static __inline void push_string(char *); 70 static __inline void push(struct value *); 71 static __inline struct value *tos(void); 72 static __inline struct number *pop_number(void); 73 static __inline char *pop_string(void); 74 static __inline void clear_stack(void); 75 static __inline void print_tos(void); 76 static void pop_print(void); 77 static void pop_printn(void); 78 static __inline void print_stack(void); 79 static __inline void dup(void); 80 static void swap(void); 81 static void drop(void); 82 83 static void get_scale(void); 84 static void set_scale(void); 85 static void get_obase(void); 86 static void set_obase(void); 87 static void get_ibase(void); 88 static void set_ibase(void); 89 static void stackdepth(void); 90 static void push_scale(void); 91 static u_int count_digits(const struct number *); 92 static void num_digits(void); 93 static void to_ascii(void); 94 static void push_line(void); 95 static void comment(void); 96 static void bexec(char *); 97 static void badd(void); 98 static void bsub(void); 99 static void bmul(void); 100 static void bdiv(void); 101 static void bmod(void); 102 static void bdivmod(void); 103 static void bexp(void); 104 static bool bsqrt_stop(const BIGNUM *, const BIGNUM *, u_int *); 105 static void bsqrt(void); 106 static void not(void); 107 static void equal_numbers(void); 108 static void less_numbers(void); 109 static void lesseq_numbers(void); 110 static void equal(void); 111 static void not_equal(void); 112 static void less(void); 113 static void not_less(void); 114 static void greater(void); 115 static void not_greater(void); 116 static void not_compare(void); 117 static bool compare_numbers(enum bcode_compare, struct number *, 118 struct number *); 119 static void compare(enum bcode_compare); 120 static int readreg(void); 121 static void load(void); 122 static void store(void); 123 static void load_stack(void); 124 static void store_stack(void); 125 static void load_array(void); 126 static void store_array(void); 127 static void nop(void); 128 static void quit(void); 129 static void quitN(void); 130 static void skipN(void); 131 static void skip_until_mark(void); 132 static void parse_number(void); 133 static void unknown(void); 134 static void eval_string(char *); 135 static void eval_line(void); 136 static void eval_tos(void); 137 138 139 typedef void (*opcode_function)(void); 140 141 struct jump_entry { 142 u_char ch; 143 opcode_function f; 144 }; 145 146 static opcode_function jump_table[UCHAR_MAX]; 147 148 static const struct jump_entry jump_table_data[] = { 149 { ' ', nop }, 150 { '!', not_compare }, 151 { '#', comment }, 152 { '%', bmod }, 153 { '(', less_numbers }, 154 { '*', bmul }, 155 { '+', badd }, 156 { '-', bsub }, 157 { '.', parse_number }, 158 { '/', bdiv }, 159 { '0', parse_number }, 160 { '1', parse_number }, 161 { '2', parse_number }, 162 { '3', parse_number }, 163 { '4', parse_number }, 164 { '5', parse_number }, 165 { '6', parse_number }, 166 { '7', parse_number }, 167 { '8', parse_number }, 168 { '9', parse_number }, 169 { ':', store_array }, 170 { ';', load_array }, 171 { '<', less }, 172 { '=', equal }, 173 { '>', greater }, 174 { '?', eval_line }, 175 { 'A', parse_number }, 176 { 'B', parse_number }, 177 { 'C', parse_number }, 178 { 'D', parse_number }, 179 { 'E', parse_number }, 180 { 'F', parse_number }, 181 { 'G', equal_numbers }, 182 { 'I', get_ibase }, 183 { 'J', skipN }, 184 { 'K', get_scale }, 185 { 'L', load_stack }, 186 { 'M', nop }, 187 { 'N', not }, 188 { 'O', get_obase }, 189 { 'P', pop_print }, 190 { 'Q', quitN }, 191 { 'R', drop }, 192 { 'S', store_stack }, 193 { 'X', push_scale }, 194 { 'Z', num_digits }, 195 { '[', push_line }, 196 { '\f', nop }, 197 { '\n', nop }, 198 { '\r', nop }, 199 { '\t', nop }, 200 { '^', bexp }, 201 { '_', parse_number }, 202 { 'a', to_ascii }, 203 { 'c', clear_stack }, 204 { 'd', dup }, 205 { 'f', print_stack }, 206 { 'i', set_ibase }, 207 { 'k', set_scale }, 208 { 'l', load }, 209 { 'n', pop_printn }, 210 { 'o', set_obase }, 211 { 'p', print_tos }, 212 { 'q', quit }, 213 { 'r', swap }, 214 { 's', store }, 215 { 'v', bsqrt }, 216 { 'x', eval_tos }, 217 { 'z', stackdepth }, 218 { '{', lesseq_numbers }, 219 { '~', bdivmod } 220 }; 221 222 #define JUMP_TABLE_DATA_SIZE \ 223 (sizeof(jump_table_data)/sizeof(jump_table_data[0])) 224 225 static void 226 sighandler(int ignored) 227 { 228 229 switch (ignored) 230 { 231 default: 232 bmachine.interrupted = true; 233 } 234 } 235 236 void 237 init_bmachine(bool extended_registers) 238 { 239 unsigned int i; 240 241 bmachine.extended_regs = extended_registers; 242 bmachine.reg_array_size = bmachine.extended_regs ? 243 REG_ARRAY_SIZE_BIG : REG_ARRAY_SIZE_SMALL; 244 245 bmachine.reg = calloc(bmachine.reg_array_size, 246 sizeof(bmachine.reg[0])); 247 if (bmachine.reg == NULL) 248 err(1, NULL); 249 250 for (i = 0; i < UCHAR_MAX; i++) 251 jump_table[i] = unknown; 252 for (i = 0; i < JUMP_TABLE_DATA_SIZE; i++) 253 jump_table[jump_table_data[i].ch] = jump_table_data[i].f; 254 255 stack_init(&bmachine.stack); 256 257 for (i = 0; i < bmachine.reg_array_size; i++) 258 stack_init(&bmachine.reg[i]); 259 260 bmachine.readstack_sz = READSTACK_SIZE; 261 bmachine.readstack = calloc(sizeof(struct source), 262 bmachine.readstack_sz); 263 if (bmachine.readstack == NULL) 264 err(1, NULL); 265 bmachine.obase = bmachine.ibase = 10; 266 BN_init(&zero); 267 bn_check(BN_zero(&zero)); 268 signal(SIGINT, sighandler); 269 } 270 271 /* Reset the things needed before processing a (new) file */ 272 void 273 reset_bmachine(struct source *src) 274 { 275 276 bmachine.readsp = 0; 277 bmachine.readstack[0] = *src; 278 } 279 280 static __inline int 281 readch(void) 282 { 283 struct source *src = &bmachine.readstack[bmachine.readsp]; 284 285 return (src->vtable->readchar(src)); 286 } 287 288 static __inline void 289 unreadch(void) 290 { 291 struct source *src = &bmachine.readstack[bmachine.readsp]; 292 293 src->vtable->unreadchar(src); 294 } 295 296 static __inline char * 297 readline(void) 298 { 299 struct source *src = &bmachine.readstack[bmachine.readsp]; 300 301 return (src->vtable->readline(src)); 302 } 303 304 static __inline void 305 src_free(void) 306 { 307 struct source *src = &bmachine.readstack[bmachine.readsp]; 308 309 src->vtable->free(src); 310 } 311 312 #ifdef DEBUGGING 313 void 314 pn(const char *str, const struct number *n) 315 { 316 char *p = BN_bn2dec(n->number); 317 318 if (p == NULL) 319 err(1, "BN_bn2dec failed"); 320 fputs(str, stderr); 321 fprintf(stderr, " %s (%u)\n" , p, n->scale); 322 OPENSSL_free(p); 323 } 324 325 void 326 pbn(const char *str, const BIGNUM *n) 327 { 328 char *p = BN_bn2dec(n); 329 330 if (p == NULL) 331 err(1, "BN_bn2dec failed"); 332 fputs(str, stderr); 333 fprintf(stderr, " %s\n", p); 334 OPENSSL_free(p); 335 } 336 337 #endif 338 339 static __inline u_int 340 max(u_int a, u_int b) 341 { 342 343 return (a > b ? a : b); 344 } 345 346 static unsigned long factors[] = { 347 0, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 348 100000000, 1000000000 349 }; 350 351 void 352 scale_number(BIGNUM *n, int s) 353 { 354 unsigned int abs_scale; 355 356 if (s == 0) 357 return; 358 359 abs_scale = s > 0 ? s : -s; 360 361 if (abs_scale < sizeof(factors)/sizeof(factors[0])) { 362 if (s > 0) 363 bn_check(BN_mul_word(n, factors[abs_scale])); 364 else 365 BN_div_word(n, factors[abs_scale]); 366 } else { 367 BIGNUM *a, *p; 368 BN_CTX *ctx; 369 370 a = BN_new(); 371 bn_checkp(a); 372 p = BN_new(); 373 bn_checkp(p); 374 ctx = BN_CTX_new(); 375 bn_checkp(ctx); 376 377 bn_check(BN_set_word(a, 10)); 378 bn_check(BN_set_word(p, abs_scale)); 379 bn_check(BN_exp(a, a, p, ctx)); 380 if (s > 0) 381 bn_check(BN_mul(n, n, a, ctx)); 382 else 383 bn_check(BN_div(n, NULL, n, a, ctx)); 384 BN_CTX_free(ctx); 385 BN_free(a); 386 BN_free(p); 387 } 388 } 389 390 void 391 split_number(const struct number *n, BIGNUM *i, BIGNUM *f) 392 { 393 u_long rem; 394 395 bn_checkp(BN_copy(i, n->number)); 396 397 if (n->scale == 0 && f != NULL) 398 bn_check(BN_zero(f)); 399 else if (n->scale < sizeof(factors)/sizeof(factors[0])) { 400 rem = BN_div_word(i, factors[n->scale]); 401 if (f != NULL) 402 bn_check(BN_set_word(f, rem)); 403 } else { 404 BIGNUM *a, *p; 405 BN_CTX *ctx; 406 407 a = BN_new(); 408 bn_checkp(a); 409 p = BN_new(); 410 bn_checkp(p); 411 ctx = BN_CTX_new(); 412 bn_checkp(ctx); 413 414 bn_check(BN_set_word(a, 10)); 415 bn_check(BN_set_word(p, n->scale)); 416 bn_check(BN_exp(a, a, p, ctx)); 417 bn_check(BN_div(i, f, n->number, a, ctx)); 418 BN_CTX_free(ctx); 419 BN_free(a); 420 BN_free(p); 421 } 422 } 423 424 __inline void 425 normalize(struct number *n, u_int s) 426 { 427 428 scale_number(n->number, s - n->scale); 429 n->scale = s; 430 } 431 432 static u_long 433 get_ulong(struct number *n) 434 { 435 436 normalize(n, 0); 437 return (BN_get_word(n->number)); 438 } 439 440 void 441 negate(struct number *n) 442 { 443 444 bn_check(BN_sub(n->number, &zero, n->number)); 445 } 446 447 static __inline void 448 push_number(struct number *n) 449 { 450 451 stack_pushnumber(&bmachine.stack, n); 452 } 453 454 static __inline void 455 push_string(char *string) 456 { 457 458 stack_pushstring(&bmachine.stack, string); 459 } 460 461 static __inline void 462 push(struct value *v) 463 { 464 465 stack_push(&bmachine.stack, v); 466 } 467 468 static __inline struct value * 469 tos(void) 470 { 471 472 return (stack_tos(&bmachine.stack)); 473 } 474 475 static __inline struct value * 476 pop(void) 477 { 478 479 return (stack_pop(&bmachine.stack)); 480 } 481 482 static __inline struct number * 483 pop_number(void) 484 { 485 486 return (stack_popnumber(&bmachine.stack)); 487 } 488 489 static __inline char * 490 pop_string(void) 491 { 492 493 return (stack_popstring(&bmachine.stack)); 494 } 495 496 static __inline void 497 clear_stack(void) 498 { 499 500 stack_clear(&bmachine.stack); 501 } 502 503 static __inline void 504 print_stack(void) 505 { 506 507 stack_print(stdout, &bmachine.stack, "", bmachine.obase); 508 } 509 510 static __inline void 511 print_tos(void) 512 { 513 struct value *value = tos(); 514 515 if (value != NULL) { 516 print_value(stdout, value, "", bmachine.obase); 517 putchar('\n'); 518 } 519 else 520 warnx("stack empty"); 521 } 522 523 static void 524 pop_print(void) 525 { 526 struct value *value = pop(); 527 528 if (value != NULL) { 529 switch (value->type) { 530 case BCODE_NONE: 531 break; 532 case BCODE_NUMBER: 533 normalize(value->u.num, 0); 534 print_ascii(stdout, value->u.num); 535 fflush(stdout); 536 break; 537 case BCODE_STRING: 538 fputs(value->u.string, stdout); 539 fflush(stdout); 540 break; 541 } 542 stack_free_value(value); 543 } 544 } 545 546 static void 547 pop_printn(void) 548 { 549 struct value *value = pop(); 550 551 if (value != NULL) { 552 print_value(stdout, value, "", bmachine.obase); 553 fflush(stdout); 554 stack_free_value(value); 555 } 556 } 557 558 static __inline void 559 dup(void) 560 { 561 562 stack_dup(&bmachine.stack); 563 } 564 565 static void 566 swap(void) 567 { 568 569 stack_swap(&bmachine.stack); 570 } 571 572 static void 573 drop(void) 574 { 575 struct value *v = pop(); 576 if (v != NULL) 577 stack_free_value(v); 578 } 579 580 static void 581 get_scale(void) 582 { 583 struct number *n; 584 585 n = new_number(); 586 bn_check(BN_set_word(n->number, bmachine.scale)); 587 push_number(n); 588 } 589 590 static void 591 set_scale(void) 592 { 593 struct number *n; 594 u_long scale; 595 596 n = pop_number(); 597 if (n != NULL) { 598 if (BN_cmp(n->number, &zero) < 0) 599 warnx("scale must be a nonnegative number"); 600 else { 601 scale = get_ulong(n); 602 if (scale != BN_MASK2 && scale <= UINT_MAX) 603 bmachine.scale = (u_int)scale; 604 else 605 warnx("scale too large"); 606 } 607 free_number(n); 608 } 609 } 610 611 static void 612 get_obase(void) 613 { 614 struct number *n; 615 616 n = new_number(); 617 bn_check(BN_set_word(n->number, bmachine.obase)); 618 push_number(n); 619 } 620 621 static void 622 set_obase(void) 623 { 624 struct number *n; 625 u_long base; 626 627 n = pop_number(); 628 if (n != NULL) { 629 base = get_ulong(n); 630 if (base != BN_MASK2 && base > 1 && base <= UINT_MAX) 631 bmachine.obase = (u_int)base; 632 else 633 warnx("output base must be a number greater than 1"); 634 free_number(n); 635 } 636 } 637 638 static void 639 get_ibase(void) 640 { 641 struct number *n; 642 643 n = new_number(); 644 bn_check(BN_set_word(n->number, bmachine.ibase)); 645 push_number(n); 646 } 647 648 static void 649 set_ibase(void) 650 { 651 struct number *n; 652 u_long base; 653 654 n = pop_number(); 655 if (n != NULL) { 656 base = get_ulong(n); 657 if (base != BN_MASK2 && 2 <= base && base <= 16) 658 bmachine.ibase = (u_int)base; 659 else 660 warnx("input base must be a number between 2 and 16 " 661 "(inclusive)"); 662 free_number(n); 663 } 664 } 665 666 static void 667 stackdepth(void) 668 { 669 struct number *n; 670 size_t i; 671 672 i = stack_size(&bmachine.stack); 673 n = new_number(); 674 bn_check(BN_set_word(n->number, i)); 675 push_number(n); 676 } 677 678 static void 679 push_scale(void) 680 { 681 struct number *n; 682 struct value *value; 683 u_int scale = 0; 684 685 value = pop(); 686 if (value != NULL) { 687 switch (value->type) { 688 case BCODE_NONE: 689 return; 690 case BCODE_NUMBER: 691 scale = value->u.num->scale; 692 break; 693 case BCODE_STRING: 694 break; 695 } 696 stack_free_value(value); 697 n = new_number(); 698 bn_check(BN_set_word(n->number, scale)); 699 push_number(n); 700 } 701 } 702 703 static u_int 704 count_digits(const struct number *n) 705 { 706 struct number *int_part, *fract_part; 707 u_int i; 708 709 if (BN_is_zero(n->number)) 710 return (1); 711 712 int_part = new_number(); 713 fract_part = new_number(); 714 fract_part->scale = n->scale; 715 split_number(n, int_part->number, fract_part->number); 716 717 i = 0; 718 while (!BN_is_zero(int_part->number)) { 719 BN_div_word(int_part->number, 10); 720 i++; 721 } 722 free_number(int_part); 723 free_number(fract_part); 724 return (i + n->scale); 725 } 726 727 static void 728 num_digits(void) 729 { 730 struct number *n = NULL; 731 struct value *value; 732 size_t digits; 733 734 value = pop(); 735 if (value != NULL) { 736 switch (value->type) { 737 case BCODE_NONE: 738 return; 739 case BCODE_NUMBER: 740 digits = count_digits(value->u.num); 741 n = new_number(); 742 bn_check(BN_set_word(n->number, digits)); 743 break; 744 case BCODE_STRING: 745 digits = strlen(value->u.string); 746 n = new_number(); 747 bn_check(BN_set_word(n->number, digits)); 748 break; 749 } 750 stack_free_value(value); 751 push_number(n); 752 } 753 } 754 755 static void 756 to_ascii(void) 757 { 758 struct number *n; 759 struct value *value; 760 char str[2]; 761 762 value = pop(); 763 if (value != NULL) { 764 str[1] = '\0'; 765 switch (value->type) { 766 case BCODE_NONE: 767 return; 768 case BCODE_NUMBER: 769 n = value->u.num; 770 normalize(n, 0); 771 if (BN_num_bits(n->number) > 8) 772 bn_check(BN_mask_bits(n->number, 8)); 773 str[0] = (char)BN_get_word(n->number); 774 break; 775 case BCODE_STRING: 776 str[0] = value->u.string[0]; 777 break; 778 } 779 stack_free_value(value); 780 push_string(bstrdup(str)); 781 } 782 } 783 784 static int 785 readreg(void) 786 { 787 int ch1, ch2, idx; 788 789 idx = readch(); 790 if (idx == 0xff && bmachine.extended_regs) { 791 ch1 = readch(); 792 ch2 = readch(); 793 if (ch1 == EOF || ch2 == EOF) { 794 warnx("unexpected eof"); 795 idx = -1; 796 } else 797 idx = (ch1 << 8) + ch2 + UCHAR_MAX + 1; 798 } 799 if (idx < 0 || (unsigned)idx >= bmachine.reg_array_size) { 800 warnx("internal error: reg num = %d", idx); 801 idx = -1; 802 } 803 return (idx); 804 } 805 806 static void 807 load(void) 808 { 809 struct number *n; 810 struct value *v; 811 struct value copy; 812 int idx; 813 814 idx = readreg(); 815 if (idx >= 0) { 816 v = stack_tos(&bmachine.reg[idx]); 817 if (v == NULL) { 818 n = new_number(); 819 bn_check(BN_zero(n->number)); 820 push_number(n); 821 } else 822 push(stack_dup_value(v, ©)); 823 } 824 } 825 826 static void 827 store(void) 828 { 829 struct value *val; 830 int idx; 831 832 idx = readreg(); 833 if (idx >= 0) { 834 val = pop(); 835 if (val == NULL) { 836 return; 837 } 838 stack_set_tos(&bmachine.reg[idx], val); 839 } 840 } 841 842 static void 843 load_stack(void) 844 { 845 struct stack *stack; 846 struct value *value; 847 int idx; 848 849 idx = readreg(); 850 if (idx >= 0) { 851 stack = &bmachine.reg[idx]; 852 value = NULL; 853 if (stack_size(stack) > 0) { 854 value = stack_pop(stack); 855 } 856 if (value != NULL) 857 push(value); 858 else 859 warnx("stack register '%c' (0%o) is empty", 860 idx, idx); 861 } 862 } 863 864 static void 865 store_stack(void) 866 { 867 struct value *value; 868 int idx; 869 870 idx = readreg(); 871 if (idx >= 0) { 872 value = pop(); 873 if (value == NULL) 874 return; 875 stack_push(&bmachine.reg[idx], value); 876 } 877 } 878 879 static void 880 load_array(void) 881 { 882 struct number *inumber, *n; 883 struct stack *stack; 884 struct value *v; 885 struct value copy; 886 u_long idx; 887 int reg; 888 889 reg = readreg(); 890 if (reg >= 0) { 891 inumber = pop_number(); 892 if (inumber == NULL) 893 return; 894 idx = get_ulong(inumber); 895 if (BN_cmp(inumber->number, &zero) < 0) 896 warnx("negative idx"); 897 else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX) 898 warnx("idx too big"); 899 else { 900 stack = &bmachine.reg[reg]; 901 v = frame_retrieve(stack, idx); 902 if (v == NULL || v->type == BCODE_NONE) { 903 n = new_number(); 904 bn_check(BN_zero(n->number)); 905 push_number(n); 906 } 907 else 908 push(stack_dup_value(v, ©)); 909 } 910 free_number(inumber); 911 } 912 } 913 914 static void 915 store_array(void) 916 { 917 struct number *inumber; 918 struct value *value; 919 struct stack *stack; 920 u_long idx; 921 int reg; 922 923 reg = readreg(); 924 if (reg >= 0) { 925 inumber = pop_number(); 926 if (inumber == NULL) 927 return; 928 value = pop(); 929 if (value == NULL) { 930 free_number(inumber); 931 return; 932 } 933 idx = get_ulong(inumber); 934 if (BN_cmp(inumber->number, &zero) < 0) { 935 warnx("negative idx"); 936 stack_free_value(value); 937 } else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX) { 938 warnx("idx too big"); 939 stack_free_value(value); 940 } else { 941 stack = &bmachine.reg[reg]; 942 frame_assign(stack, idx, value); 943 } 944 free_number(inumber); 945 } 946 } 947 948 static void 949 push_line(void) 950 { 951 952 push_string(read_string(&bmachine.readstack[bmachine.readsp])); 953 } 954 955 static void 956 comment(void) 957 { 958 959 free(readline()); 960 } 961 962 static void 963 bexec(char *line) 964 { 965 966 system(line); 967 free(line); 968 } 969 970 static void 971 badd(void) 972 { 973 struct number *a, *b, *r; 974 975 a = pop_number(); 976 if (a == NULL) { 977 return; 978 } 979 b = pop_number(); 980 if (b == NULL) { 981 push_number(a); 982 return; 983 } 984 985 r = new_number(); 986 r->scale = max(a->scale, b->scale); 987 if (r->scale > a->scale) 988 normalize(a, r->scale); 989 else if (r->scale > b->scale) 990 normalize(b, r->scale); 991 bn_check(BN_add(r->number, a->number, b->number)); 992 push_number(r); 993 free_number(a); 994 free_number(b); 995 } 996 997 static void 998 bsub(void) 999 { 1000 struct number *a, *b, *r; 1001 1002 a = pop_number(); 1003 if (a == NULL) { 1004 return; 1005 } 1006 b = pop_number(); 1007 if (b == NULL) { 1008 push_number(a); 1009 return; 1010 } 1011 1012 r = new_number(); 1013 1014 r->scale = max(a->scale, b->scale); 1015 if (r->scale > a->scale) 1016 normalize(a, r->scale); 1017 else if (r->scale > b->scale) 1018 normalize(b, r->scale); 1019 bn_check(BN_sub(r->number, b->number, a->number)); 1020 push_number(r); 1021 free_number(a); 1022 free_number(b); 1023 } 1024 1025 void 1026 bmul_number(struct number *r, struct number *a, struct number *b) 1027 { 1028 BN_CTX *ctx; 1029 1030 /* Create copies of the scales, since r might be equal to a or b */ 1031 u_int ascale = a->scale; 1032 u_int bscale = b->scale; 1033 u_int rscale = ascale + bscale; 1034 1035 ctx = BN_CTX_new(); 1036 bn_checkp(ctx); 1037 bn_check(BN_mul(r->number, a->number, b->number, ctx)); 1038 BN_CTX_free(ctx); 1039 1040 if (rscale > bmachine.scale && rscale > ascale && rscale > bscale) { 1041 r->scale = rscale; 1042 normalize(r, max(bmachine.scale, max(ascale, bscale))); 1043 } else 1044 r->scale = rscale; 1045 } 1046 1047 static void 1048 bmul(void) 1049 { 1050 struct number *a, *b, *r; 1051 1052 a = pop_number(); 1053 if (a == NULL) { 1054 return; 1055 } 1056 b = pop_number(); 1057 if (b == NULL) { 1058 push_number(a); 1059 return; 1060 } 1061 1062 r = new_number(); 1063 bmul_number(r, a, b); 1064 1065 push_number(r); 1066 free_number(a); 1067 free_number(b); 1068 } 1069 1070 static void 1071 bdiv(void) 1072 { 1073 struct number *a, *b, *r; 1074 BN_CTX *ctx; 1075 u_int scale; 1076 1077 a = pop_number(); 1078 if (a == NULL) { 1079 return; 1080 } 1081 b = pop_number(); 1082 if (b == NULL) { 1083 push_number(a); 1084 return; 1085 } 1086 1087 r = new_number(); 1088 r->scale = bmachine.scale; 1089 scale = max(a->scale, b->scale); 1090 1091 if (BN_is_zero(a->number)) 1092 warnx("divide by zero"); 1093 else { 1094 normalize(a, scale); 1095 normalize(b, scale + r->scale); 1096 1097 ctx = BN_CTX_new(); 1098 bn_checkp(ctx); 1099 bn_check(BN_div(r->number, NULL, b->number, a->number, ctx)); 1100 BN_CTX_free(ctx); 1101 } 1102 push_number(r); 1103 free_number(a); 1104 free_number(b); 1105 } 1106 1107 static void 1108 bmod(void) 1109 { 1110 struct number *a, *b, *r; 1111 BN_CTX *ctx; 1112 u_int scale; 1113 1114 a = pop_number(); 1115 if (a == NULL) { 1116 return; 1117 } 1118 b = pop_number(); 1119 if (b == NULL) { 1120 push_number(a); 1121 return; 1122 } 1123 1124 r = new_number(); 1125 scale = max(a->scale, b->scale); 1126 r->scale = max(b->scale, a->scale + bmachine.scale); 1127 1128 if (BN_is_zero(a->number)) 1129 warnx("remainder by zero"); 1130 else { 1131 normalize(a, scale); 1132 normalize(b, scale + bmachine.scale); 1133 1134 ctx = BN_CTX_new(); 1135 bn_checkp(ctx); 1136 bn_check(BN_mod(r->number, b->number, a->number, ctx)); 1137 BN_CTX_free(ctx); 1138 } 1139 push_number(r); 1140 free_number(a); 1141 free_number(b); 1142 } 1143 1144 static void 1145 bdivmod(void) 1146 { 1147 struct number *a, *b, *rdiv, *rmod; 1148 BN_CTX *ctx; 1149 u_int scale; 1150 1151 a = pop_number(); 1152 if (a == NULL) { 1153 return; 1154 } 1155 b = pop_number(); 1156 if (b == NULL) { 1157 push_number(a); 1158 return; 1159 } 1160 1161 rdiv = new_number(); 1162 rmod = new_number(); 1163 rdiv->scale = bmachine.scale; 1164 rmod->scale = max(b->scale, a->scale + bmachine.scale); 1165 scale = max(a->scale, b->scale); 1166 1167 if (BN_is_zero(a->number)) 1168 warnx("divide by zero"); 1169 else { 1170 normalize(a, scale); 1171 normalize(b, scale + bmachine.scale); 1172 1173 ctx = BN_CTX_new(); 1174 bn_checkp(ctx); 1175 bn_check(BN_div(rdiv->number, rmod->number, 1176 b->number, a->number, ctx)); 1177 BN_CTX_free(ctx); 1178 } 1179 push_number(rdiv); 1180 push_number(rmod); 1181 free_number(a); 1182 free_number(b); 1183 } 1184 1185 static void 1186 bexp(void) 1187 { 1188 struct number *a, *p, *r; 1189 u_int scale; 1190 bool neg; 1191 1192 p = pop_number(); 1193 if (p == NULL) { 1194 return; 1195 } 1196 a = pop_number(); 1197 if (a == NULL) { 1198 push_number(p); 1199 return; 1200 } 1201 1202 if (p->scale != 0) 1203 warnx("Runtime warning: non-zero scale in exponent"); 1204 normalize(p, 0); 1205 1206 neg = false; 1207 if (BN_cmp(p->number, &zero) < 0) { 1208 neg = true; 1209 negate(p); 1210 scale = bmachine.scale; 1211 } else { 1212 /* Posix bc says min(a.scale * b, max(a.scale, scale) */ 1213 u_long b; 1214 u_int m; 1215 1216 b = BN_get_word(p->number); 1217 m = max(a->scale, bmachine.scale); 1218 scale = a->scale * (u_int)b; 1219 if (scale > m || (a->scale > 0 && (b == BN_MASK2 || 1220 b > UINT_MAX))) 1221 scale = m; 1222 } 1223 1224 if (BN_is_zero(p->number)) { 1225 r = new_number(); 1226 bn_check(BN_one(r->number)); 1227 normalize(r, scale); 1228 } else { 1229 while (!BN_is_bit_set(p->number, 0)) { 1230 bmul_number(a, a, a); 1231 bn_check(BN_rshift1(p->number, p->number)); 1232 } 1233 1234 r = dup_number(a); 1235 normalize(r, scale); 1236 bn_check(BN_rshift1(p->number, p->number)); 1237 1238 while (!BN_is_zero(p->number)) { 1239 bmul_number(a, a, a); 1240 if (BN_is_bit_set(p->number, 0)) 1241 bmul_number(r, r, a); 1242 bn_check(BN_rshift1(p->number, p->number)); 1243 } 1244 1245 if (neg) { 1246 BN_CTX *ctx; 1247 BIGNUM *one; 1248 1249 one = BN_new(); 1250 bn_checkp(one); 1251 bn_check(BN_one(one)); 1252 ctx = BN_CTX_new(); 1253 bn_checkp(ctx); 1254 scale_number(one, r->scale + scale); 1255 normalize(r, scale); 1256 bn_check(BN_div(r->number, NULL, one, r->number, ctx)); 1257 BN_free(one); 1258 BN_CTX_free(ctx); 1259 } else 1260 normalize(r, scale); 1261 } 1262 push_number(r); 1263 free_number(a); 1264 free_number(p); 1265 } 1266 1267 static bool 1268 bsqrt_stop(const BIGNUM *x, const BIGNUM *y, u_int *onecount) 1269 { 1270 BIGNUM *r; 1271 bool ret; 1272 1273 r = BN_new(); 1274 bn_checkp(r); 1275 bn_check(BN_sub(r, x, y)); 1276 if (BN_is_one(r)) 1277 (*onecount)++; 1278 ret = BN_is_zero(r); 1279 BN_free(r); 1280 return (ret || *onecount > 1); 1281 } 1282 1283 static void 1284 bsqrt(void) 1285 { 1286 struct number *n, *r; 1287 BIGNUM *x, *y; 1288 BN_CTX *ctx; 1289 u_int onecount, scale; 1290 1291 onecount = 0; 1292 n = pop_number(); 1293 if (n == NULL) { 1294 return; 1295 } 1296 if (BN_is_zero(n->number)) { 1297 r = new_number(); 1298 push_number(r); 1299 } else if (BN_cmp(n->number, &zero) < 0) 1300 warnx("square root of negative number"); 1301 else { 1302 scale = max(bmachine.scale, n->scale); 1303 normalize(n, 2*scale); 1304 x = BN_dup(n->number); 1305 bn_checkp(x); 1306 bn_check(BN_rshift(x, x, BN_num_bits(x)/2)); 1307 y = BN_new(); 1308 bn_checkp(y); 1309 ctx = BN_CTX_new(); 1310 bn_checkp(ctx); 1311 for (;;) { 1312 bn_checkp(BN_copy(y, x)); 1313 bn_check(BN_div(x, NULL, n->number, x, ctx)); 1314 bn_check(BN_add(x, x, y)); 1315 bn_check(BN_rshift1(x, x)); 1316 if (bsqrt_stop(x, y, &onecount)) 1317 break; 1318 } 1319 r = bmalloc(sizeof(*r)); 1320 r->scale = scale; 1321 r->number = y; 1322 BN_free(x); 1323 BN_CTX_free(ctx); 1324 push_number(r); 1325 } 1326 1327 free_number(n); 1328 } 1329 1330 static void 1331 not(void) 1332 { 1333 struct number *a; 1334 1335 a = pop_number(); 1336 if (a == NULL) { 1337 return; 1338 } 1339 a->scale = 0; 1340 bn_check(BN_set_word(a->number, BN_get_word(a->number) ? 0 : 1)); 1341 push_number(a); 1342 } 1343 1344 static void 1345 equal(void) 1346 { 1347 1348 compare(BCODE_EQUAL); 1349 } 1350 1351 static void 1352 equal_numbers(void) 1353 { 1354 struct number *a, *b, *r; 1355 1356 a = pop_number(); 1357 if (a == NULL) { 1358 return; 1359 } 1360 b = pop_number(); 1361 if (b == NULL) { 1362 push_number(a); 1363 return; 1364 } 1365 r = new_number(); 1366 bn_check(BN_set_word(r->number, 1367 compare_numbers(BCODE_EQUAL, a, b) ? 1 : 0)); 1368 push_number(r); 1369 } 1370 1371 static void 1372 less_numbers(void) 1373 { 1374 struct number *a, *b, *r; 1375 1376 a = pop_number(); 1377 if (a == NULL) { 1378 return; 1379 } 1380 b = pop_number(); 1381 if (b == NULL) { 1382 push_number(a); 1383 return; 1384 } 1385 r = new_number(); 1386 bn_check(BN_set_word(r->number, 1387 compare_numbers(BCODE_LESS, a, b) ? 1 : 0)); 1388 push_number(r); 1389 } 1390 1391 static void 1392 lesseq_numbers(void) 1393 { 1394 struct number *a, *b, *r; 1395 1396 a = pop_number(); 1397 if (a == NULL) { 1398 return; 1399 } 1400 b = pop_number(); 1401 if (b == NULL) { 1402 push_number(a); 1403 return; 1404 } 1405 r = new_number(); 1406 bn_check(BN_set_word(r->number, 1407 compare_numbers(BCODE_NOT_GREATER, a, b) ? 1 : 0)); 1408 push_number(r); 1409 } 1410 1411 static void 1412 not_equal(void) 1413 { 1414 1415 compare(BCODE_NOT_EQUAL); 1416 } 1417 1418 static void 1419 less(void) 1420 { 1421 1422 compare(BCODE_LESS); 1423 } 1424 1425 static void 1426 not_compare(void) 1427 { 1428 1429 switch (readch()) { 1430 case '<': 1431 not_less(); 1432 break; 1433 case '>': 1434 not_greater(); 1435 break; 1436 case '=': 1437 not_equal(); 1438 break; 1439 default: 1440 unreadch(); 1441 bexec(readline()); 1442 break; 1443 } 1444 } 1445 1446 static void 1447 not_less(void) 1448 { 1449 1450 compare(BCODE_NOT_LESS); 1451 } 1452 1453 static void 1454 greater(void) 1455 { 1456 1457 compare(BCODE_GREATER); 1458 } 1459 1460 static void 1461 not_greater(void) 1462 { 1463 1464 compare(BCODE_NOT_GREATER); 1465 } 1466 1467 static bool 1468 compare_numbers(enum bcode_compare type, struct number *a, struct number *b) 1469 { 1470 u_int scale; 1471 int cmp; 1472 1473 scale = max(a->scale, b->scale); 1474 1475 if (scale > a->scale) 1476 normalize(a, scale); 1477 else if (scale > b->scale) 1478 normalize(b, scale); 1479 1480 cmp = BN_cmp(a->number, b->number); 1481 1482 free_number(a); 1483 free_number(b); 1484 1485 switch (type) { 1486 case BCODE_EQUAL: 1487 return (cmp == 0); 1488 case BCODE_NOT_EQUAL: 1489 return (cmp != 0); 1490 case BCODE_LESS: 1491 return (cmp < 0); 1492 case BCODE_NOT_LESS: 1493 return (cmp >= 0); 1494 case BCODE_GREATER: 1495 return (cmp > 0); 1496 case BCODE_NOT_GREATER: 1497 return (cmp <= 0); 1498 } 1499 return (false); 1500 } 1501 1502 static void 1503 compare(enum bcode_compare type) 1504 { 1505 struct number *a, *b; 1506 struct value *v; 1507 int idx, elseidx; 1508 bool ok; 1509 1510 elseidx = NO_ELSE; 1511 idx = readreg(); 1512 if (readch() == 'e') 1513 elseidx = readreg(); 1514 else 1515 unreadch(); 1516 1517 a = pop_number(); 1518 if (a == NULL) 1519 return; 1520 b = pop_number(); 1521 if (b == NULL) { 1522 push_number(a); 1523 return; 1524 } 1525 1526 ok = compare_numbers(type, a, b); 1527 1528 if (!ok && elseidx != NO_ELSE) 1529 idx = elseidx; 1530 1531 if (idx >= 0 && (ok || (!ok && elseidx != NO_ELSE))) { 1532 v = stack_tos(&bmachine.reg[idx]); 1533 if (v == NULL) 1534 warnx("register '%c' (0%o) is empty", idx, idx); 1535 else { 1536 switch(v->type) { 1537 case BCODE_NONE: 1538 warnx("register '%c' (0%o) is empty", idx, idx); 1539 break; 1540 case BCODE_NUMBER: 1541 warn("eval called with non-string argument"); 1542 break; 1543 case BCODE_STRING: 1544 eval_string(bstrdup(v->u.string)); 1545 break; 1546 } 1547 } 1548 } 1549 } 1550 1551 1552 static void 1553 nop(void) 1554 { 1555 1556 } 1557 1558 static void 1559 quit(void) 1560 { 1561 1562 if (bmachine.readsp < 2) 1563 exit(0); 1564 src_free(); 1565 bmachine.readsp--; 1566 src_free(); 1567 bmachine.readsp--; 1568 } 1569 1570 static void 1571 quitN(void) 1572 { 1573 struct number *n; 1574 u_long i; 1575 1576 n = pop_number(); 1577 if (n == NULL) 1578 return; 1579 i = get_ulong(n); 1580 free_number(n); 1581 if (i == BN_MASK2 || i == 0) 1582 warnx("Q command requires a number >= 1"); 1583 else if (bmachine.readsp < i) 1584 warnx("Q command argument exceeded string execution depth"); 1585 else { 1586 while (i-- > 0) { 1587 src_free(); 1588 bmachine.readsp--; 1589 } 1590 } 1591 } 1592 1593 static void 1594 skipN(void) 1595 { 1596 struct number *n; 1597 u_long i; 1598 1599 n = pop_number(); 1600 if (n == NULL) 1601 return; 1602 i = get_ulong(n); 1603 if (i == BN_MASK2) 1604 warnx("J command requires a number >= 0"); 1605 else if (i > 0 && bmachine.readsp < i) 1606 warnx("J command argument exceeded string execution depth"); 1607 else { 1608 while (i-- > 0) { 1609 src_free(); 1610 bmachine.readsp--; 1611 } 1612 skip_until_mark(); 1613 } 1614 } 1615 1616 static void 1617 skip_until_mark(void) 1618 { 1619 1620 for (;;) { 1621 switch (readch()) { 1622 case 'M': 1623 return; 1624 case EOF: 1625 errx(1, "mark not found"); 1626 return; 1627 case 'l': 1628 case 'L': 1629 case 's': 1630 case 'S': 1631 case ':': 1632 case ';': 1633 case '<': 1634 case '>': 1635 case '=': 1636 readreg(); 1637 if (readch() == 'e') 1638 readreg(); 1639 else 1640 unreadch(); 1641 break; 1642 case '[': 1643 free(read_string(&bmachine.readstack[bmachine.readsp])); 1644 break; 1645 case '!': 1646 switch (readch()) { 1647 case '<': 1648 case '>': 1649 case '=': 1650 readreg(); 1651 if (readch() == 'e') 1652 readreg(); 1653 else 1654 unreadch(); 1655 break; 1656 default: 1657 free(readline()); 1658 break; 1659 } 1660 break; 1661 default: 1662 break; 1663 } 1664 } 1665 } 1666 1667 static void 1668 parse_number(void) 1669 { 1670 1671 unreadch(); 1672 push_number(readnumber(&bmachine.readstack[bmachine.readsp], 1673 bmachine.ibase)); 1674 } 1675 1676 static void 1677 unknown(void) 1678 { 1679 int ch = bmachine.readstack[bmachine.readsp].lastchar; 1680 warnx("%c (0%o) is unimplemented", ch, ch); 1681 } 1682 1683 static void 1684 eval_string(char *p) 1685 { 1686 int ch; 1687 1688 if (bmachine.readsp > 0) { 1689 /* Check for tail call. Do not recurse in that case. */ 1690 ch = readch(); 1691 if (ch == EOF) { 1692 src_free(); 1693 src_setstring(&bmachine.readstack[bmachine.readsp], p); 1694 return; 1695 } else 1696 unreadch(); 1697 } 1698 if (bmachine.readsp == bmachine.readstack_sz - 1) { 1699 size_t newsz = bmachine.readstack_sz * 2; 1700 struct source *stack; 1701 stack = realloc(bmachine.readstack, newsz * 1702 sizeof(struct source)); 1703 if (stack == NULL) 1704 err(1, "recursion too deep"); 1705 bmachine.readstack_sz = newsz; 1706 bmachine.readstack = stack; 1707 } 1708 src_setstring(&bmachine.readstack[++bmachine.readsp], p); 1709 } 1710 1711 static void 1712 eval_line(void) 1713 { 1714 /* Always read from stdin */ 1715 struct source in; 1716 char *p; 1717 1718 clearerr(stdin); 1719 src_setstream(&in, stdin); 1720 p = (*in.vtable->readline)(&in); 1721 eval_string(p); 1722 } 1723 1724 static void 1725 eval_tos(void) 1726 { 1727 char *p; 1728 1729 p = pop_string(); 1730 if (p == NULL) 1731 return; 1732 eval_string(p); 1733 } 1734 1735 void 1736 eval(void) 1737 { 1738 int ch; 1739 1740 for (;;) { 1741 ch = readch(); 1742 if (ch == EOF) { 1743 if (bmachine.readsp == 0) 1744 return; 1745 src_free(); 1746 bmachine.readsp--; 1747 continue; 1748 } 1749 if (bmachine.interrupted) { 1750 if (bmachine.readsp > 0) { 1751 src_free(); 1752 bmachine.readsp--; 1753 continue; 1754 } else 1755 bmachine.interrupted = false; 1756 } 1757 #ifdef DEBUGGING 1758 fprintf(stderr, "# %c\n", ch); 1759 stack_print(stderr, &bmachine.stack, "* ", 1760 bmachine.obase); 1761 fprintf(stderr, "%zd =>\n", bmachine.readsp); 1762 #endif 1763 1764 if (0 <= ch && ch < (signed)UCHAR_MAX) 1765 (*jump_table[ch])(); 1766 else 1767 warnx("internal error: opcode %d", ch); 1768 1769 #ifdef DEBUGGING 1770 stack_print(stderr, &bmachine.stack, "* ", 1771 bmachine.obase); 1772 fprintf(stderr, "%zd ==\n", bmachine.readsp); 1773 #endif 1774 } 1775 } 1776