1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2017 Jason King
14 * Copyright 2019 Joyent, Inc.
15 */
16 #ifndef _DEMANGLE_INT_H
17 #define _DEMANGLE_INT_H
18
19 #include <inttypes.h>
20 #include <stdio.h>
21 #include <sys/byteorder.h>
22 #include <sys/ctype.h> /* Use ASCII ISXXXX() macros */
23 #include <sys/debug.h>
24 #include <sys/sysmacros.h>
25 #include <sys/isa_defs.h>
26 #include "demangle-sys.h"
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31
32 #ifdef __CHECKER__
33 /*
34 * smatch seems to have a bug which chokes on the builtins, so
35 * we just have it fallback to the non-builtin definitions
36 */
37 #elif __GNUC__ >= 5 && __GNUC_MINOR__ > 1
38 #define USE_BUILTIN_OVERFLOW
39 #elif defined(__clang__)
40 #define USE_BUILTIN_OVERFLOW
41 #endif
42
43 #ifdef USE_BUILTIN_OVERFLOW
44 static inline boolean_t
mul_overflow(uint64_t a,uint64_t b,uint64_t * v)45 mul_overflow(uint64_t a, uint64_t b, uint64_t *v)
46 {
47 return (__builtin_mul_overflow(a, b, v));
48 }
49
50 static inline boolean_t
add_overflow(uint64_t a,uint64_t b,uint64_t * v)51 add_overflow(uint64_t a, uint64_t b, uint64_t *v)
52 {
53 return (__builtin_add_overflow(a, b, v));
54 }
55
56 static inline boolean_t
sub_overflow(uint64_t a,uint64_t b,uint64_t * v)57 sub_overflow(uint64_t a, uint64_t b, uint64_t *v)
58 {
59 return (__builtin_sub_overflow(a, b, v));
60 }
61 #else
62 static inline boolean_t
63 mul_overflow(uint64_t a, uint64_t b, uint64_t *v)
64 {
65 uint64_t val = a * b;
66
67 if (a != 0 && val / a != b)
68 return (B_TRUE);
69 *v = val;
70 return (B_FALSE);
71 }
72
73 static inline boolean_t
74 add_overflow(uint64_t a, uint64_t b, uint64_t *v)
75 {
76 uint64_t val = a + b;
77
78 if (val < a || val < b)
79 return (B_TRUE);
80 *v = val;
81 return (B_FALSE);
82 }
83
84 static inline boolean_t
85 sub_overflow(uint64_t a, uint64_t b, uint64_t *v)
86 {
87 uint64_t val = a - b;
88
89 if (val > a)
90 return (B_TRUE);
91 *v = val;
92 return (B_FALSE);
93 }
94 #endif
95
96 extern sysdem_ops_t *sysdem_ops_default;
97
98 char *cpp_demangle(const char *, size_t, sysdem_ops_t *);
99 char *rust_demangle(const char *, size_t, sysdem_ops_t *);
100
101 struct custr_alloc;
102
103 void *zalloc(sysdem_ops_t *, size_t);
104 void *xcalloc(sysdem_ops_t *, size_t, size_t);
105 void *xrealloc(sysdem_ops_t *, void *, size_t, size_t);
106 void xfree(sysdem_ops_t *, void *, size_t);
107 char *xstrdup(sysdem_ops_t *, const char *);
108
109 extern volatile boolean_t demangle_debug;
110
111 /*
112 * gcc seems to get unhappy with the ASSERT() style definition (also borrowed
113 * for the DEMDEBUG macro unless demdebug() is returns a non-void value
114 * (despite the return value never being used).
115 */
116 int demdebug(const char *, ...);
117
118 #define DEMDEBUG(s, ...) \
119 ((void)(demangle_debug && demdebug(s, ## __VA_ARGS__)))
120
121 #ifdef __cplusplus
122 }
123 #endif
124
125 #endif /* _DEMANGLE_INT_H */
126