1 /* $OpenBSD: bcode.c,v 1.40 2009/10/27 23:59:37 deraadt Exp $ */
4 * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
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.
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.
19 #include <sys/cdefs.h>
20 __FBSDID("$FreeBSD$");
24 #include <openssl/ssl.h>
36 #define MAX_ARRAY_INDEX 2048
37 #define READSTACK_SIZE 8
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)
44 struct source *readstack;
47 volatile sig_atomic_t interrupted;
52 size_t reg_array_size;
57 static struct bmachine bmachine;
58 static void sighandler(int);
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);
65 static __inline u_int max(u_int, u_int);
66 static u_long get_ulong(struct number *);
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);
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 *,
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);
139 typedef void (*opcode_function)(void);
146 static opcode_function jump_table[UCHAR_MAX];
148 static const struct jump_entry jump_table_data[] = {
150 { '!', not_compare },
153 { '(', less_numbers },
157 { '.', parse_number },
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 },
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 },
192 { 'S', store_stack },
201 { '_', parse_number },
203 { 'c', clear_stack },
205 { 'f', print_stack },
218 { '{', lesseq_numbers },
222 #define JUMP_TABLE_DATA_SIZE \
223 (sizeof(jump_table_data)/sizeof(jump_table_data[0]))
226 sighandler(int ignored)
232 bmachine.interrupted = true;
237 init_bmachine(bool extended_registers)
241 bmachine.extended_regs = extended_registers;
242 bmachine.reg_array_size = bmachine.extended_regs ?
243 REG_ARRAY_SIZE_BIG : REG_ARRAY_SIZE_SMALL;
245 bmachine.reg = calloc(bmachine.reg_array_size,
246 sizeof(bmachine.reg[0]));
247 if (bmachine.reg == NULL)
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;
255 stack_init(&bmachine.stack);
257 for (i = 0; i < bmachine.reg_array_size; i++)
258 stack_init(&bmachine.reg[i]);
260 bmachine.readstack_sz = READSTACK_SIZE;
261 bmachine.readstack = calloc(sizeof(struct source),
262 bmachine.readstack_sz);
263 if (bmachine.readstack == NULL)
265 bmachine.obase = bmachine.ibase = 10;
267 bn_check(BN_zero(&zero));
268 signal(SIGINT, sighandler);
271 /* Reset the things needed before processing a (new) file */
273 reset_bmachine(struct source *src)
277 bmachine.readstack[0] = *src;
283 struct source *src = &bmachine.readstack[bmachine.readsp];
285 return (src->vtable->readchar(src));
291 struct source *src = &bmachine.readstack[bmachine.readsp];
293 src->vtable->unreadchar(src);
296 static __inline char *
299 struct source *src = &bmachine.readstack[bmachine.readsp];
301 return (src->vtable->readline(src));
307 struct source *src = &bmachine.readstack[bmachine.readsp];
309 src->vtable->free(src);
314 pn(const char *str, const struct number *n)
316 char *p = BN_bn2dec(n->number);
319 err(1, "BN_bn2dec failed");
321 fprintf(stderr, " %s (%u)\n" , p, n->scale);
326 pbn(const char *str, const BIGNUM *n)
328 char *p = BN_bn2dec(n);
331 err(1, "BN_bn2dec failed");
333 fprintf(stderr, " %s\n", p);
339 static __inline u_int
340 max(u_int a, u_int b)
343 return (a > b ? a : b);
346 static unsigned long factors[] = {
347 0, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
348 100000000, 1000000000
352 scale_number(BIGNUM *n, int s)
354 unsigned int abs_scale;
359 abs_scale = s > 0 ? s : -s;
361 if (abs_scale < sizeof(factors)/sizeof(factors[0])) {
363 bn_check(BN_mul_word(n, factors[abs_scale]));
365 BN_div_word(n, factors[abs_scale]);
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));
381 bn_check(BN_mul(n, n, a, ctx));
383 bn_check(BN_div(n, NULL, n, a, ctx));
391 split_number(const struct number *n, BIGNUM *i, BIGNUM *f)
395 bn_checkp(BN_copy(i, n->number));
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]);
402 bn_check(BN_set_word(f, rem));
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));
425 normalize(struct number *n, u_int s)
428 scale_number(n->number, s - n->scale);
433 get_ulong(struct number *n)
437 return (BN_get_word(n->number));
441 negate(struct number *n)
444 bn_check(BN_sub(n->number, &zero, n->number));
448 push_number(struct number *n)
451 stack_pushnumber(&bmachine.stack, n);
455 push_string(char *string)
458 stack_pushstring(&bmachine.stack, string);
462 push(struct value *v)
465 stack_push(&bmachine.stack, v);
468 static __inline struct value *
472 return (stack_tos(&bmachine.stack));
475 static __inline struct value *
479 return (stack_pop(&bmachine.stack));
482 static __inline struct number *
486 return (stack_popnumber(&bmachine.stack));
489 static __inline char *
493 return (stack_popstring(&bmachine.stack));
500 stack_clear(&bmachine.stack);
507 stack_print(stdout, &bmachine.stack, "", bmachine.obase);
513 struct value *value = tos();
516 print_value(stdout, value, "", bmachine.obase);
520 warnx("stack empty");
526 struct value *value = pop();
529 switch (value->type) {
533 normalize(value->u.num, 0);
534 print_ascii(stdout, value->u.num);
538 fputs(value->u.string, stdout);
542 stack_free_value(value);
549 struct value *value = pop();
552 print_value(stdout, value, "", bmachine.obase);
554 stack_free_value(value);
562 stack_dup(&bmachine.stack);
569 stack_swap(&bmachine.stack);
575 struct value *v = pop();
586 bn_check(BN_set_word(n->number, bmachine.scale));
598 if (BN_cmp(n->number, &zero) < 0)
599 warnx("scale must be a nonnegative number");
601 scale = get_ulong(n);
602 if (scale != BN_MASK2 && scale <= UINT_MAX)
603 bmachine.scale = (u_int)scale;
605 warnx("scale too large");
617 bn_check(BN_set_word(n->number, bmachine.obase));
630 if (base != BN_MASK2 && base > 1 && base <= UINT_MAX)
631 bmachine.obase = (u_int)base;
633 warnx("output base must be a number greater than 1");
644 bn_check(BN_set_word(n->number, bmachine.ibase));
657 if (base != BN_MASK2 && 2 <= base && base <= 16)
658 bmachine.ibase = (u_int)base;
660 warnx("input base must be a number between 2 and 16 "
672 i = stack_size(&bmachine.stack);
674 bn_check(BN_set_word(n->number, i));
687 switch (value->type) {
691 scale = value->u.num->scale;
696 stack_free_value(value);
698 bn_check(BN_set_word(n->number, scale));
704 count_digits(const struct number *n)
706 struct number *int_part, *fract_part;
709 if (BN_is_zero(n->number))
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);
718 while (!BN_is_zero(int_part->number)) {
719 BN_div_word(int_part->number, 10);
722 free_number(int_part);
723 free_number(fract_part);
724 return (i + n->scale);
730 struct number *n = NULL;
736 switch (value->type) {
740 digits = count_digits(value->u.num);
742 bn_check(BN_set_word(n->number, digits));
745 digits = strlen(value->u.string);
747 bn_check(BN_set_word(n->number, digits));
750 stack_free_value(value);
765 switch (value->type) {
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);
776 str[0] = value->u.string[0];
779 stack_free_value(value);
780 push_string(bstrdup(str));
790 if (idx == 0xff && bmachine.extended_regs) {
793 if (ch1 == EOF || ch2 == EOF) {
794 warnx("unexpected eof");
797 idx = (ch1 << 8) + ch2 + UCHAR_MAX + 1;
799 if (idx < 0 || (unsigned)idx >= bmachine.reg_array_size) {
800 warnx("internal error: reg num = %d", idx);
816 v = stack_tos(&bmachine.reg[idx]);
819 bn_check(BN_zero(n->number));
822 push(stack_dup_value(v, ©));
838 stack_set_tos(&bmachine.reg[idx], val);
851 stack = &bmachine.reg[idx];
853 if (stack_size(stack) > 0) {
854 value = stack_pop(stack);
859 warnx("stack register '%c' (0%o) is empty",
875 stack_push(&bmachine.reg[idx], value);
882 struct number *inumber, *n;
891 inumber = pop_number();
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");
900 stack = &bmachine.reg[reg];
901 v = frame_retrieve(stack, idx);
902 if (v == NULL || v->type == BCODE_NONE) {
904 bn_check(BN_zero(n->number));
908 push(stack_dup_value(v, ©));
910 free_number(inumber);
917 struct number *inumber;
925 inumber = pop_number();
930 free_number(inumber);
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);
941 stack = &bmachine.reg[reg];
942 frame_assign(stack, idx, value);
944 free_number(inumber);
952 push_string(read_string(&bmachine.readstack[bmachine.readsp]));
973 struct number *a, *b, *r;
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));
1000 struct number *a, *b, *r;
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));
1026 bmul_number(struct number *r, struct number *a, struct number *b)
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;
1037 bn_check(BN_mul(r->number, a->number, b->number, ctx));
1040 if (rscale > bmachine.scale && rscale > ascale && rscale > bscale) {
1042 normalize(r, max(bmachine.scale, max(ascale, bscale)));
1050 struct number *a, *b, *r;
1063 bmul_number(r, a, b);
1073 struct number *a, *b, *r;
1088 r->scale = bmachine.scale;
1089 scale = max(a->scale, b->scale);
1091 if (BN_is_zero(a->number))
1092 warnx("divide by zero");
1094 normalize(a, scale);
1095 normalize(b, scale + r->scale);
1099 bn_check(BN_div(r->number, NULL, b->number, a->number, ctx));
1110 struct number *a, *b, *r;
1125 scale = max(a->scale, b->scale);
1126 r->scale = max(b->scale, a->scale + bmachine.scale);
1128 if (BN_is_zero(a->number))
1129 warnx("remainder by zero");
1131 normalize(a, scale);
1132 normalize(b, scale + bmachine.scale);
1136 bn_check(BN_mod(r->number, b->number, a->number, ctx));
1147 struct number *a, *b, *rdiv, *rmod;
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);
1167 if (BN_is_zero(a->number))
1168 warnx("divide by zero");
1170 normalize(a, scale);
1171 normalize(b, scale + bmachine.scale);
1175 bn_check(BN_div(rdiv->number, rmod->number,
1176 b->number, a->number, ctx));
1188 struct number *a, *p, *r;
1203 warnx("Runtime warning: non-zero scale in exponent");
1207 if (BN_cmp(p->number, &zero) < 0) {
1210 scale = bmachine.scale;
1212 /* Posix bc says min(a.scale * b, max(a.scale, scale) */
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 ||
1224 if (BN_is_zero(p->number)) {
1226 bn_check(BN_one(r->number));
1227 normalize(r, scale);
1229 while (!BN_is_bit_set(p->number, 0)) {
1230 bmul_number(a, a, a);
1231 bn_check(BN_rshift1(p->number, p->number));
1235 normalize(r, scale);
1236 bn_check(BN_rshift1(p->number, p->number));
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));
1251 bn_check(BN_one(one));
1254 scale_number(one, r->scale + scale);
1255 normalize(r, scale);
1256 bn_check(BN_div(r->number, NULL, one, r->number, ctx));
1260 normalize(r, scale);
1268 bsqrt_stop(const BIGNUM *x, const BIGNUM *y, u_int *onecount)
1275 bn_check(BN_sub(r, x, y));
1278 ret = BN_is_zero(r);
1280 return (ret || *onecount > 1);
1286 struct number *n, *r;
1289 u_int onecount, scale;
1296 if (BN_is_zero(n->number)) {
1299 } else if (BN_cmp(n->number, &zero) < 0)
1300 warnx("square root of negative number");
1302 scale = max(bmachine.scale, n->scale);
1303 normalize(n, 2*scale);
1304 x = BN_dup(n->number);
1306 bn_check(BN_rshift(x, x, BN_num_bits(x)/2));
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))
1319 r = bmalloc(sizeof(*r));
1340 bn_check(BN_set_word(a->number, BN_get_word(a->number) ? 0 : 1));
1348 compare(BCODE_EQUAL);
1354 struct number *a, *b, *r;
1366 bn_check(BN_set_word(r->number,
1367 compare_numbers(BCODE_EQUAL, a, b) ? 1 : 0));
1374 struct number *a, *b, *r;
1386 bn_check(BN_set_word(r->number,
1387 compare_numbers(BCODE_LESS, a, b) ? 1 : 0));
1392 lesseq_numbers(void)
1394 struct number *a, *b, *r;
1406 bn_check(BN_set_word(r->number,
1407 compare_numbers(BCODE_NOT_GREATER, a, b) ? 1 : 0));
1415 compare(BCODE_NOT_EQUAL);
1422 compare(BCODE_LESS);
1450 compare(BCODE_NOT_LESS);
1457 compare(BCODE_GREATER);
1464 compare(BCODE_NOT_GREATER);
1468 compare_numbers(enum bcode_compare type, struct number *a, struct number *b)
1473 scale = max(a->scale, b->scale);
1475 if (scale > a->scale)
1476 normalize(a, scale);
1477 else if (scale > b->scale)
1478 normalize(b, scale);
1480 cmp = BN_cmp(a->number, b->number);
1488 case BCODE_NOT_EQUAL:
1492 case BCODE_NOT_LESS:
1496 case BCODE_NOT_GREATER:
1503 compare(enum bcode_compare type)
1505 struct number *a, *b;
1512 if (readch() == 'e')
1513 elseidx = readreg();
1526 ok = compare_numbers(type, a, b);
1528 if (!ok && elseidx != NO_ELSE)
1531 if (idx >= 0 && (ok || (!ok && elseidx != NO_ELSE))) {
1532 v = stack_tos(&bmachine.reg[idx]);
1534 warnx("register '%c' (0%o) is empty", idx, idx);
1538 warnx("register '%c' (0%o) is empty", idx, idx);
1541 warn("eval called with non-string argument");
1544 eval_string(bstrdup(v->u.string));
1562 if (bmachine.readsp < 2)
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");
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");
1617 skip_until_mark(void)
1625 errx(1, "mark not found");
1637 if (readch() == 'e')
1643 free(read_string(&bmachine.readstack[bmachine.readsp]));
1651 if (readch() == 'e')
1672 push_number(readnumber(&bmachine.readstack[bmachine.readsp],
1679 int ch = bmachine.readstack[bmachine.readsp].lastchar;
1680 warnx("%c (0%o) is unimplemented", ch, ch);
1684 eval_string(char *p)
1688 if (bmachine.readsp > 0) {
1689 /* Check for tail call. Do not recurse in that case. */
1693 src_setstring(&bmachine.readstack[bmachine.readsp], p);
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));
1704 err(1, "recursion too deep");
1705 bmachine.readstack_sz = newsz;
1706 bmachine.readstack = stack;
1708 src_setstring(&bmachine.readstack[++bmachine.readsp], p);
1714 /* Always read from stdin */
1719 src_setstream(&in, stdin);
1720 p = (*in.vtable->readline)(&in);
1743 if (bmachine.readsp == 0)
1749 if (bmachine.interrupted) {
1750 if (bmachine.readsp > 0) {
1755 bmachine.interrupted = false;
1758 fprintf(stderr, "# %c\n", ch);
1759 stack_print(stderr, &bmachine.stack, "* ",
1761 fprintf(stderr, "%zd =>\n", bmachine.readsp);
1764 if (0 <= ch && ch < (signed)UCHAR_MAX)
1765 (*jump_table[ch])();
1767 warnx("internal error: opcode %d", ch);
1770 stack_print(stderr, &bmachine.stack, "* ",
1772 fprintf(stderr, "%zd ==\n", bmachine.readsp);