1 /*
2 * Copyright (C) 2012 Oracle.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16 */
17
18 /*
19 * Basically the point of sval is that it can hold both ULLONG_MAX and
20 * LLONG_MIN. If it is an unsigned type then we use sval.uvalue or if it is
21 * signed we use sval.value.
22 *
23 * I considered just using one bit to store whether the value was signed vs
24 * unsigned but I think it might help to have the type information so we know
25 * how to do type promotion.
26 *
27 */
28
29 #include "smatch.h"
30 #include "smatch_slist.h"
31 #include "smatch_extra.h"
32
33 __ALLOCATOR(sval_t, "svals", sval);
34
sval_alloc(sval_t sval)35 sval_t *sval_alloc(sval_t sval)
36 {
37 sval_t *ret;
38
39 ret = __alloc_sval(0);
40 *ret = sval;
41 return ret;
42 }
43
sval_alloc_permanent(sval_t sval)44 sval_t *sval_alloc_permanent(sval_t sval)
45 {
46 sval_t *ret;
47
48 ret = malloc(sizeof(*ret));
49 *ret = sval;
50 return ret;
51 }
52
sval_blank(struct expression * expr)53 sval_t sval_blank(struct expression *expr)
54 {
55 sval_t ret;
56
57 ret.type = get_type(expr);
58 if (!ret.type)
59 ret.type = &int_ctype;
60 ret.value = 123456789;
61
62 return ret;
63 }
64
sval_type_val(struct symbol * type,long long val)65 sval_t sval_type_val(struct symbol *type, long long val)
66 {
67 sval_t ret;
68
69 if (!type)
70 type = &llong_ctype;
71
72 ret.type = type;
73 ret.value = val;
74 return ret;
75 }
76
sval_type_fval(struct symbol * type,long double fval)77 sval_t sval_type_fval(struct symbol *type, long double fval)
78 {
79 sval_t ret;
80
81 ret.type = &ldouble_ctype;
82 ret.ldvalue = fval;
83 return sval_cast(type, ret);
84 }
85
sval_from_val(struct expression * expr,long long val)86 sval_t sval_from_val(struct expression *expr, long long val)
87 {
88 sval_t ret;
89
90 ret = sval_blank(expr);
91 ret.value = val;
92 ret = sval_cast(get_type(expr), ret);
93
94 return ret;
95 }
96
sval_from_fval(struct expression * expr,long double fval)97 sval_t sval_from_fval(struct expression *expr, long double fval)
98 {
99 sval_t ret;
100
101 ret.type = &ldouble_ctype;
102 ret.ldvalue = fval;
103 ret = sval_cast(get_type(expr), ret);
104
105 return ret;
106 }
107
sval_is_ptr(sval_t sval)108 int sval_is_ptr(sval_t sval)
109 {
110 if (!sval.type)
111 return 0;
112 return (sval.type->type == SYM_PTR || sval.type->type == SYM_ARRAY);
113 }
114
sval_is_fp(sval_t sval)115 bool sval_is_fp(sval_t sval)
116 {
117 return type_is_fp(sval.type);
118 }
119
sval_unsigned(sval_t sval)120 int sval_unsigned(sval_t sval)
121 {
122 if (is_ptr_type(sval.type))
123 return true;
124 return type_unsigned(sval.type);
125 }
126
sval_signed(sval_t sval)127 int sval_signed(sval_t sval)
128 {
129 return !type_unsigned(sval.type);
130 }
131
sval_bits(sval_t sval)132 int sval_bits(sval_t sval)
133 {
134 return type_bits(sval.type);
135 }
136
sval_bits_used(sval_t sval)137 int sval_bits_used(sval_t sval)
138 {
139 int i;
140
141 for (i = 64; i >= 1; i--) {
142 if (sval.uvalue & (1ULL << (i - 1)))
143 return i;
144 }
145 return 0;
146 }
147
sval_is_negative(sval_t sval)148 int sval_is_negative(sval_t sval)
149 {
150 if (type_unsigned(sval.type))
151 return 0;
152 if (sval.value < 0)
153 return 1;
154 return 0;
155 }
156
sval_is_positive(sval_t sval)157 int sval_is_positive(sval_t sval)
158 {
159 return !sval_is_negative(sval);
160 }
161
fp_is_min(sval_t sval)162 static bool fp_is_min(sval_t sval)
163 {
164 if (sval.type == &float_ctype)
165 return sval.fvalue == -FLT_MAX;
166 if (sval.type == &double_ctype)
167 return sval.dvalue == -DBL_MAX;
168 if (sval.type == &ldouble_ctype)
169 return sval.ldvalue == -LDBL_MAX;
170 sm_perror("%s: bad type: '%s'", __func__, type_to_str(sval.type));
171 return false;
172 }
173
sval_is_min(sval_t sval)174 int sval_is_min(sval_t sval)
175 {
176 sval_t min = sval_type_min(sval.type);
177
178 if (sval_is_fp(sval))
179 return fp_is_min(sval);
180
181 if (sval_unsigned(sval)) {
182 if (sval.uvalue == 0)
183 return 1;
184 return 0;
185 }
186 /* return true for less than min as well */
187 return (sval.value <= min.value);
188 }
189
fp_is_max(sval_t sval)190 static bool fp_is_max(sval_t sval)
191 {
192 if (sval.type == &float_ctype)
193 return sval.fvalue == FLT_MAX;
194 if (sval.type == &double_ctype)
195 return sval.dvalue == DBL_MAX;
196 if (sval.type == &ldouble_ctype)
197 return sval.ldvalue == LDBL_MAX;
198 sm_perror("%s: bad type: '%s'", __func__, type_to_str(sval.type));
199 return false;
200 }
201
sval_is_max(sval_t sval)202 int sval_is_max(sval_t sval)
203 {
204 sval_t max = sval_type_max(sval.type);
205
206 if (sval_is_fp(sval))
207 return fp_is_max(sval);
208
209 if (sval_unsigned(sval))
210 return (sval.uvalue >= max.value);
211 return (sval.value >= max.value);
212 }
213
sval_is_a_min(sval_t sval)214 int sval_is_a_min(sval_t sval)
215 {
216 if (sval_is_min(sval))
217 return 1;
218
219 if (sval_is_fp(sval))
220 return 0;
221
222 if (sval_signed(sval) && sval.value == SHRT_MIN)
223 return 1;
224 if (sval_signed(sval) && sval.value == INT_MIN)
225 return 1;
226 if (sval_signed(sval) && sval.value == LLONG_MIN)
227 return 1;
228 return 0;
229 }
230
sval_is_a_max(sval_t sval)231 int sval_is_a_max(sval_t sval)
232 {
233 if (sval_is_max(sval))
234 return 1;
235
236 if (sval_is_fp(sval))
237 return 0;
238
239 if (sval.uvalue == SHRT_MAX)
240 return 1;
241 if (sval.uvalue == INT_MAX)
242 return 1;
243 if (sval.uvalue == LLONG_MAX)
244 return 1;
245 if (sval.uvalue == USHRT_MAX)
246 return 1;
247 if (sval.uvalue == UINT_MAX)
248 return 1;
249 if (sval_unsigned(sval) && sval.uvalue == ULLONG_MAX)
250 return 1;
251 if (sval.value > valid_ptr_max - 1000 &&
252 sval.value < valid_ptr_max + 1000)
253 return 1;
254 return 0;
255 }
256
sval_is_negative_min(sval_t sval)257 int sval_is_negative_min(sval_t sval)
258 {
259 if (sval_is_fp(sval))
260 return 0;
261
262 if (!sval_is_negative(sval))
263 return 0;
264 return sval_is_min(sval);
265 }
266
sval_cmp_t(struct symbol * type,sval_t one,sval_t two)267 int sval_cmp_t(struct symbol *type, sval_t one, sval_t two)
268 {
269 sval_t one_cast, two_cast;
270
271 one_cast = sval_cast(type, one);
272 two_cast = sval_cast(type, two);
273 return sval_cmp(one_cast, two_cast);
274 }
275
sval_cmp_val(sval_t one,long long val)276 int sval_cmp_val(sval_t one, long long val)
277 {
278 sval_t sval;
279
280 sval = sval_type_val(&llong_ctype, val);
281 return sval_cmp(one, sval);
282 }
283
sval_min(sval_t one,sval_t two)284 sval_t sval_min(sval_t one, sval_t two)
285 {
286 if (sval_cmp(one, two) > 0)
287 return two;
288 return one;
289 }
290
sval_max(sval_t one,sval_t two)291 sval_t sval_max(sval_t one, sval_t two)
292 {
293 if (sval_cmp(one, two) < 0)
294 return two;
295 return one;
296 }
297
sval_too_low(struct symbol * type,sval_t sval)298 int sval_too_low(struct symbol *type, sval_t sval)
299 {
300 if (sval_is_negative(sval) && type_unsigned(type))
301 return 1;
302 if (type_signed(type) && sval_unsigned(sval))
303 return 0;
304 if (type_signed(sval.type) &&
305 sval.value < sval_type_min(type).value)
306 return 1;
307 if (sval_cmp(sval, sval_type_min(type)) < 0)
308 return 1;
309 return 0;
310 }
311
sval_too_high(struct symbol * type,sval_t sval)312 int sval_too_high(struct symbol *type, sval_t sval)
313 {
314 if (sval_is_negative(sval))
315 return 0;
316 if (sval.uvalue > sval_type_max(type).uvalue)
317 return 1;
318 return 0;
319 }
320
sval_fits(struct symbol * type,sval_t sval)321 int sval_fits(struct symbol *type, sval_t sval)
322 {
323 /* everything fits into floating point */
324 if (type_is_fp(type))
325 return 1;
326 /* floating points don't fit into int */
327 if (type_is_fp(sval.type))
328 return 0;
329
330 if (sval_too_low(type, sval))
331 return 0;
332 if (sval_too_high(type, sval))
333 return 0;
334 return 1;
335 }
336
cast_to_fp(struct symbol * type,sval_t sval)337 static sval_t cast_to_fp(struct symbol *type, sval_t sval)
338 {
339 sval_t ret = {};
340
341 ret.type = type;
342 if (type == &float_ctype) {
343 if (!sval_is_fp(sval)) {
344 if (sval_unsigned(sval))
345 ret.fvalue = sval.uvalue;
346 else
347 ret.fvalue = sval.value;
348 } else if (sval.type == &float_ctype)
349 ret.fvalue = sval.fvalue;
350 else if (sval.type == &double_ctype)
351 ret.fvalue = sval.dvalue;
352 else
353 ret.fvalue = sval.ldvalue;
354 } else if (type == &double_ctype) {
355 if (!sval_is_fp(sval)) {
356 if (sval_unsigned(sval))
357 ret.dvalue = sval.uvalue;
358 else
359 ret.dvalue = sval.value;
360 } else if (sval.type == &float_ctype)
361 ret.dvalue = sval.fvalue;
362 else if (sval.type == &double_ctype)
363 ret.dvalue = sval.dvalue;
364 else
365 ret.dvalue = sval.ldvalue;
366 } else if (type == &ldouble_ctype) {
367 if (!sval_is_fp(sval)) {
368 if (sval_unsigned(sval))
369 ret.ldvalue = (long double)sval.uvalue;
370 else
371 ret.ldvalue = (long double)sval.value;
372 } else if (sval.type == &float_ctype)
373 ret.ldvalue = sval.fvalue;
374 else if (sval.type == &double_ctype)
375 ret.ldvalue = sval.dvalue;
376 else
377 ret.ldvalue = sval.ldvalue;
378 } else {
379 sm_perror("%s: bad type: %s", __func__, type_to_str(type));
380 }
381
382 return ret;
383 }
384
cast_from_fp(struct symbol * type,sval_t sval)385 static sval_t cast_from_fp(struct symbol *type, sval_t sval)
386 {
387 sval_t ret = {};
388
389 ret.type = &llong_ctype;
390 if (sval.type == &float_ctype)
391 ret.value = sval.fvalue;
392 else if (sval.type == &double_ctype)
393 ret.value = sval.dvalue;
394 else if (sval.type == &ldouble_ctype)
395 ret.value = sval.ldvalue;
396 else
397 sm_perror("%s: bad type: %s", __func__, type_to_str(type));
398
399 return sval_cast(type, ret);
400 }
401
sval_cast(struct symbol * type,sval_t sval)402 sval_t sval_cast(struct symbol *type, sval_t sval)
403 {
404 sval_t ret;
405
406 if (!type)
407 type = &int_ctype;
408
409 if (type_is_fp(type))
410 return cast_to_fp(type, sval);
411 if (type_is_fp(sval.type))
412 return cast_from_fp(type, sval);
413
414 ret.type = type;
415 switch (sval_bits(ret)) {
416 case 1:
417 ret.value = !!sval.value;
418 break;
419 case 8:
420 if (sval_unsigned(ret))
421 ret.value = (long long)(unsigned char)sval.value;
422 else
423 ret.value = (long long)(char)sval.value;
424 break;
425 case 16:
426 if (sval_unsigned(ret))
427 ret.value = (long long)(unsigned short)sval.value;
428 else
429 ret.value = (long long)(short)sval.value;
430 break;
431 case 32:
432 if (sval_unsigned(ret))
433 ret.value = (long long)(unsigned int)sval.value;
434 else
435 ret.value = (long long)(int)sval.value;
436 break;
437 default:
438 ret.value = sval.value;
439 }
440 return ret;
441
442 }
443
sval_preop(sval_t sval,int op)444 sval_t sval_preop(sval_t sval, int op)
445 {
446 switch (op) {
447 case '!':
448 sval.value = !sval.value;
449 break;
450 case '~':
451 sval.value = ~sval.value;
452 sval = sval_cast(sval.type, sval);
453 break;
454 case '-':
455 sval.value = -sval.value;
456 sval = sval_cast(sval.type, sval);
457 break;
458 }
459 return sval;
460 }
461
sval_binop_unsigned(struct symbol * type,sval_t left,int op,sval_t right)462 static sval_t sval_binop_unsigned(struct symbol *type, sval_t left, int op, sval_t right)
463 {
464 sval_t ret;
465
466 ret.type = type;
467 switch (op) {
468 case '*':
469 ret.uvalue = left.uvalue * right.uvalue;
470 break;
471 case '/':
472 if (right.uvalue == 0) {
473 sm_debug("%s: divide by zero", __func__);
474 ret.uvalue = 123456789;
475 } else {
476 ret.uvalue = left.uvalue / right.uvalue;
477 }
478 break;
479 case '+':
480 ret.uvalue = left.uvalue + right.uvalue;
481 break;
482 case '-':
483 ret.uvalue = left.uvalue - right.uvalue;
484 break;
485 case '%':
486 if (right.uvalue == 0) {
487 sm_perror(" %s: MOD by zero", __func__);
488 ret.uvalue = 123456789;
489 } else {
490 ret.uvalue = left.uvalue % right.uvalue;
491 }
492 break;
493 case '|':
494 ret.uvalue = left.uvalue | right.uvalue;
495 break;
496 case '&':
497 ret.uvalue = left.uvalue & right.uvalue;
498 break;
499 case SPECIAL_RIGHTSHIFT:
500 ret.uvalue = left.uvalue >> right.uvalue;
501 break;
502 case SPECIAL_LEFTSHIFT:
503 ret.uvalue = left.uvalue << right.uvalue;
504 break;
505 case '^':
506 ret.uvalue = left.uvalue ^ right.uvalue;
507 break;
508 default:
509 sm_perror(" %s: unhandled binop %s", __func__,
510 show_special(op));
511 ret.uvalue = 1234567;
512 }
513 return ret;
514 }
515
516
sval_binop_signed(struct symbol * type,sval_t left,int op,sval_t right)517 static sval_t sval_binop_signed(struct symbol *type, sval_t left, int op, sval_t right)
518 {
519 sval_t ret;
520
521 ret.type = type;
522 switch (op) {
523 case '*':
524 ret.value = left.value * right.value;
525 break;
526 case '/':
527 if (right.value == 0) {
528 sm_debug("%s: divide by zero", __func__);
529 ret.value = 123456789;
530 } else if (left.value == LLONG_MIN && right.value == -1) {
531 sm_debug("%s: invalid divide LLONG_MIN/-1", __func__);
532 ret.value = 12345678;
533 } else {
534 ret.value = left.value / right.value;
535 }
536 break;
537 case '+':
538 ret.value = left.value + right.value;
539 break;
540 case '-':
541 ret.value = left.value - right.value;
542 break;
543 case '%':
544 if (right.value == 0) {
545 sm_perror(" %s: MOD by zero", __func__);
546 ret.value = 123456789;
547 } else {
548 ret.value = left.value % right.value;
549 }
550 break;
551 case '|':
552 ret.value = left.value | right.value;
553 break;
554 case '&':
555 ret.value = left.value & right.value;
556 break;
557 case SPECIAL_RIGHTSHIFT:
558 ret.value = left.value >> right.value;
559 break;
560 case SPECIAL_LEFTSHIFT:
561 ret.value = left.value << right.value;
562 break;
563 case '^':
564 ret.value = left.value ^ right.value;
565 break;
566 default:
567 sm_perror(" %s: unhandled binop %s", __func__,
568 show_special(op));
569 ret.value = 1234567;
570 }
571 return ret;
572 }
573
ptr_binop(struct symbol * type,sval_t left,int op,sval_t right)574 static sval_t ptr_binop(struct symbol *type, sval_t left, int op, sval_t right)
575 {
576 sval_t ret;
577 int align;
578
579 if (op != '+' && op != '-')
580 return sval_binop_unsigned(type, left, op, right);
581
582 ret.type = type;
583 if (type->type == SYM_PTR)
584 type = get_real_base_type(type);
585 align = type->ctype.alignment;
586 if (align <= 0)
587 align = 1;
588
589 if (op == '+') {
590 if (type_is_ptr(left.type))
591 ret.value = left.value + right.value * align;
592 else
593 ret.value = left.value * align + right.value;
594 } else {
595 if (!type_is_ptr(left.type)) {
596 left.value = -left.value;
597 ret = ptr_binop(type, left, '+', right);
598 } else if (!type_is_ptr(right.type)) {
599 right.value = -right.value;
600 ret = ptr_binop(type, left, '+', right);
601 } else {
602 ret.value = (left.value - right.value) / align;
603 }
604 }
605
606 if (op == '-')
607 ret.type = ssize_t_ctype;
608 return ret;
609 }
610
sval_binop(sval_t left,int op,sval_t right)611 sval_t sval_binop(sval_t left, int op, sval_t right)
612 {
613 struct symbol *type;
614 sval_t ret;
615
616 type = get_promoted_type(left.type, right.type);
617
618 if (type_is_ptr(type))
619 ret = ptr_binop(type, left, op, right);
620 else if (type_unsigned(type))
621 ret = sval_binop_unsigned(type, left, op, right);
622 else
623 ret = sval_binop_signed(type, left, op, right);
624 return sval_cast(type, ret);
625 }
626
sval_unop_overflows(sval_t sval,int op)627 int sval_unop_overflows(sval_t sval, int op)
628 {
629 if (op != '-')
630 return 0;
631 if (sval_positive_bits(sval) == 32 && sval.value == INT_MIN)
632 return 1;
633 if (sval_positive_bits(sval) == 64 && sval.value == LLONG_MIN)
634 return 1;
635 if (sval_is_negative(sval))
636 return 0;
637 if (sval_signed(sval))
638 return 0;
639 if (sval_bits(sval) == 32 && sval.uvalue > INT_MAX)
640 return 1;
641 if (sval_bits(sval) == 64 && sval.uvalue > LLONG_MAX)
642 return 1;
643 return 0;
644 }
645
sval_binop_overflows(sval_t left,int op,sval_t right)646 int sval_binop_overflows(sval_t left, int op, sval_t right)
647 {
648 struct symbol *type;
649 sval_t max, min;
650
651 type = left.type;
652 if (type_positive_bits(right.type) > type_positive_bits(left.type))
653 type = right.type;
654 if (type_positive_bits(type) < 31)
655 type = &int_ctype;
656
657 max = sval_type_max(type);
658 min = sval_type_min(type);
659
660 switch (op) {
661 case '+':
662 if (sval_is_negative(left) && sval_is_negative(right)) {
663 if (left.value < min.value + right.value)
664 return 1;
665 return 0;
666 }
667 if (sval_is_negative(left) || sval_is_negative(right))
668 return 0;
669 if (left.uvalue > max.uvalue - right.uvalue)
670 return 1;
671 return 0;
672 case '*':
673 if (type_signed(type)) {
674 if (left.value == 0 || right.value == 0)
675 return 0;
676 if (left.value > max.value / right.value)
677 return 1;
678 if (left.value == -1 || right.value == -1)
679 return 0;
680 return left.value != left.value * right.value / right.value;
681
682 }
683 return right.uvalue != 0 && left.uvalue > max.uvalue / right.uvalue;
684 case '-':
685 if (type_unsigned(type)) {
686 if (sval_cmp(left, right) < 0)
687 return 1;
688 return 0;
689 }
690 if (sval_is_negative(left) && sval_is_negative(right))
691 return 0;
692
693 if (sval_is_negative(left)) {
694 if (left.value < min.value + right.value)
695 return 1;
696 return 0;
697 }
698 if (sval_is_negative(right)) {
699 if (right.value == min.value)
700 return 1;
701 right = sval_preop(right, '-');
702 if (sval_binop_overflows(left, '+', right))
703 return 1;
704 return 0;
705 }
706 return 0;
707 case SPECIAL_LEFTSHIFT:
708 if (sval_cmp(left, sval_binop(max, invert_op(op), right)) > 0)
709 return 1;
710 return 0;
711 }
712 return 0;
713 }
714
sval_binop_overflows_no_sign(sval_t left,int op,sval_t right)715 int sval_binop_overflows_no_sign(sval_t left, int op, sval_t right)
716 {
717
718 struct symbol *type;
719
720 type = left.type;
721 if (type_positive_bits(right.type) > type_positive_bits(left.type))
722 type = right.type;
723 if (type_positive_bits(type) <= 31)
724 type = &uint_ctype;
725 else
726 type = &ullong_ctype;
727
728 left = sval_cast(type, left);
729 right = sval_cast(type, right);
730 return sval_binop_overflows(left, op, right);
731 }
732
find_first_zero_bit(unsigned long long uvalue)733 int find_first_zero_bit(unsigned long long uvalue)
734 {
735 int i;
736
737 for (i = 0; i < 64; i++) {
738 if (!(uvalue & (1ULL << i)))
739 return i;
740 }
741 return i;
742 }
743
sm_fls64(unsigned long long uvalue)744 int sm_fls64(unsigned long long uvalue)
745 {
746 int high_bit = 0;
747
748 while (uvalue) {
749 uvalue >>= 1;
750 high_bit++;
751 }
752
753 return high_bit;
754 }
755
fls_mask(unsigned long long uvalue)756 unsigned long long fls_mask(unsigned long long uvalue)
757 {
758 int high_bit = 0;
759
760 high_bit = sm_fls64(uvalue);
761 if (high_bit == 0)
762 return 0;
763
764 return ((unsigned long long)-1) >> (64 - high_bit);
765 }
766
sval_fls_mask(sval_t sval)767 unsigned long long sval_fls_mask(sval_t sval)
768 {
769 return fls_mask(sval.uvalue);
770 }
771
fp_to_str(sval_t sval)772 static char *fp_to_str(sval_t sval)
773 {
774 char buf[32];
775
776 if (sval.type == &float_ctype)
777 snprintf(buf, sizeof(buf), "%f", sval.fvalue);
778 else if (sval.type == &double_ctype)
779 snprintf(buf, sizeof(buf), "%e", sval.dvalue);
780 else if (sval.type == &ldouble_ctype) {
781 snprintf(buf, sizeof(buf), "%Lf", sval.ldvalue);
782 } else
783 snprintf(buf, sizeof(buf), "nan");
784
785 return alloc_sname(buf);
786 }
787
sval_to_str(sval_t sval)788 const char *sval_to_str(sval_t sval)
789 {
790 char buf[32];
791
792 if (sval_is_fp(sval))
793 return fp_to_str(sval);
794
795 if (sval_is_ptr(sval) && sval.value == valid_ptr_max)
796 return "ptr_max";
797 if (sval_unsigned(sval) && sval.value == ULLONG_MAX)
798 return "u64max";
799 if (sval_unsigned(sval) && sval.value == UINT_MAX)
800 return "u32max";
801 if (sval.value == USHRT_MAX)
802 return "u16max";
803
804 if (sval_signed(sval) && sval.value == LLONG_MAX)
805 return "s64max";
806 if (sval.value == INT_MAX)
807 return "s32max";
808 if (sval.value == SHRT_MAX)
809 return "s16max";
810
811 if (sval_signed(sval) && sval.value == SHRT_MIN)
812 return "s16min";
813 if (sval_signed(sval) && sval.value == INT_MIN)
814 return "s32min";
815 if (sval_signed(sval) && sval.value == LLONG_MIN)
816 return "s64min";
817
818 if (sval_unsigned(sval))
819 snprintf(buf, sizeof(buf), "%llu", sval.value);
820 else if (sval.value < 0)
821 snprintf(buf, sizeof(buf), "(%lld)", sval.value);
822 else
823 snprintf(buf, sizeof(buf), "%lld", sval.value);
824
825 return alloc_sname(buf);
826 }
827
sval_to_str_or_err_ptr(sval_t sval)828 const char *sval_to_str_or_err_ptr(sval_t sval)
829 {
830 char buf[12];
831
832 if (option_project != PROJ_KERNEL ||
833 !is_ptr_type(sval.type))
834 return sval_to_str(sval);
835
836 if (!sval_is_fp(sval) && sval.uvalue >= -4905ULL) {
837 snprintf(buf, sizeof(buf), "(%lld)", sval.value);
838 return alloc_sname(buf);
839 }
840
841 return sval_to_str(sval);
842 }
843
sval_to_numstr(sval_t sval)844 const char *sval_to_numstr(sval_t sval)
845 {
846 char buf[30];
847
848 if (type_is_fp(sval.type))
849 return fp_to_str(sval);
850
851 if (sval_unsigned(sval))
852 snprintf(buf, sizeof(buf), "%llu", sval.value);
853 else if (sval.value < 0)
854 snprintf(buf, sizeof(buf), "(%lld)", sval.value);
855 else
856 snprintf(buf, sizeof(buf), "%lld", sval.value);
857
858 return alloc_sname(buf);
859 }
860
ll_to_sval(long long val)861 sval_t ll_to_sval(long long val)
862 {
863 sval_t ret;
864
865 ret.type = &llong_ctype;
866 ret.value = val;
867 return ret;
868 }
869
free_svals(struct symbol * sym)870 static void free_svals(struct symbol *sym)
871 {
872 if (__inline_fn)
873 return;
874 clear_sval_alloc();
875 }
876
register_sval(int my_id)877 void register_sval(int my_id)
878 {
879 add_hook(&free_svals, AFTER_FUNC_HOOK);
880 }
881