xref: /illumos-gate/usr/src/tools/smatch/src/smatch_sval.c (revision 5a0e240f87295cfc13c53236f30ccace0d5412c7)
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