14226f635SJason King /*
24226f635SJason King  * This file and its contents are supplied under the terms of the
34226f635SJason King  * Common Development and Distribution License ("CDDL"), version 1.0.
44226f635SJason King  * You may only use this file in accordance with the terms of version
54226f635SJason King  * 1.0 of the CDDL.
64226f635SJason King  *
74226f635SJason King  * A full copy of the text of the CDDL should have accompanied this
84226f635SJason King  * source.  A copy of the CDDL is also available via the Internet at
94226f635SJason King  * http://www.illumos.org/license/CDDL.
104226f635SJason King  */
114226f635SJason King 
124226f635SJason King /*
134226f635SJason King  * Copyright 2017 Jason King
14*1cd08393SJason King  * Copyright 2019 Joyent, Inc.
154226f635SJason King  */
164226f635SJason King #ifndef _DEMANGLE_INT_H
174226f635SJason King #define	_DEMANGLE_INT_H
184226f635SJason King 
19*1cd08393SJason King #include <inttypes.h>
204226f635SJason King #include <stdio.h>
21*1cd08393SJason King #include <sys/byteorder.h>
22*1cd08393SJason King #include <sys/ctype.h> /* Use ASCII ISXXXX() macros */
23*1cd08393SJason King #include <sys/debug.h>
24*1cd08393SJason King #include <sys/sysmacros.h>
25*1cd08393SJason King #include <sys/isa_defs.h>
264226f635SJason King #include "demangle-sys.h"
274226f635SJason King 
284226f635SJason King #ifdef __cplusplus
294226f635SJason King extern "C" {
304226f635SJason King #endif
314226f635SJason King 
32*1cd08393SJason King #ifdef __CHECKER__
33*1cd08393SJason King /*
34*1cd08393SJason King  * smatch seems to have a bug which chokes on the builtins, so
35*1cd08393SJason King  * we just have it fallback to the non-builtin definitions
36*1cd08393SJason King  */
37*1cd08393SJason King #elif __GNUC__ >= 5 && __GNUC_MINOR__ > 1
38*1cd08393SJason King #define	USE_BUILTIN_OVERFLOW
39*1cd08393SJason King #elif defined(__clang__)
40*1cd08393SJason King #define	USE_BUILTIN_OVERFLOW
41*1cd08393SJason King #endif
42*1cd08393SJason King 
43*1cd08393SJason King #ifdef USE_BUILTIN_OVERFLOW
44*1cd08393SJason King static inline boolean_t
mul_overflow(uint64_t a,uint64_t b,uint64_t * v)45*1cd08393SJason King mul_overflow(uint64_t a, uint64_t b, uint64_t *v)
46*1cd08393SJason King {
47*1cd08393SJason King 	return (__builtin_mul_overflow(a, b, v));
48*1cd08393SJason King }
49*1cd08393SJason King 
50*1cd08393SJason King static inline boolean_t
add_overflow(uint64_t a,uint64_t b,uint64_t * v)51*1cd08393SJason King add_overflow(uint64_t a, uint64_t b, uint64_t *v)
52*1cd08393SJason King {
53*1cd08393SJason King 	return (__builtin_add_overflow(a, b, v));
54*1cd08393SJason King }
55*1cd08393SJason King 
56*1cd08393SJason King static inline boolean_t
sub_overflow(uint64_t a,uint64_t b,uint64_t * v)57*1cd08393SJason King sub_overflow(uint64_t a, uint64_t b, uint64_t *v)
58*1cd08393SJason King {
59*1cd08393SJason King 	return (__builtin_sub_overflow(a, b, v));
60*1cd08393SJason King }
61*1cd08393SJason King #else
62*1cd08393SJason King static inline boolean_t
63*1cd08393SJason King mul_overflow(uint64_t a, uint64_t b, uint64_t *v)
64*1cd08393SJason King {
65*1cd08393SJason King 	uint64_t val = a * b;
66*1cd08393SJason King 
67*1cd08393SJason King 	if (a != 0 && val / a != b)
68*1cd08393SJason King 		return (B_TRUE);
69*1cd08393SJason King 	*v = val;
70*1cd08393SJason King 	return (B_FALSE);
71*1cd08393SJason King }
72*1cd08393SJason King 
73*1cd08393SJason King static inline boolean_t
74*1cd08393SJason King add_overflow(uint64_t a, uint64_t b, uint64_t *v)
75*1cd08393SJason King {
76*1cd08393SJason King 	uint64_t val = a + b;
77*1cd08393SJason King 
78*1cd08393SJason King 	if (val < a || val < b)
79*1cd08393SJason King 		return (B_TRUE);
80*1cd08393SJason King 	*v = val;
81*1cd08393SJason King 	return (B_FALSE);
82*1cd08393SJason King }
83*1cd08393SJason King 
84*1cd08393SJason King static inline boolean_t
85*1cd08393SJason King sub_overflow(uint64_t a, uint64_t b, uint64_t *v)
86*1cd08393SJason King {
87*1cd08393SJason King 	uint64_t val = a - b;
88*1cd08393SJason King 
89*1cd08393SJason King 	if (val > a)
90*1cd08393SJason King 		return (B_TRUE);
91*1cd08393SJason King 	*v = val;
92*1cd08393SJason King 	return (B_FALSE);
93*1cd08393SJason King }
94*1cd08393SJason King #endif
95*1cd08393SJason King 
964226f635SJason King extern sysdem_ops_t *sysdem_ops_default;
974226f635SJason King 
986a6cfa5dSJason King char *cpp_demangle(const char *, size_t, sysdem_ops_t *);
996a6cfa5dSJason King char *rust_demangle(const char *, size_t, sysdem_ops_t *);
1004226f635SJason King 
101*1cd08393SJason King struct custr_alloc;
102*1cd08393SJason King 
1034226f635SJason King void *zalloc(sysdem_ops_t *, size_t);
104*1cd08393SJason King void *xcalloc(sysdem_ops_t *, size_t, size_t);
1054226f635SJason King void *xrealloc(sysdem_ops_t *, void *, size_t, size_t);
1064226f635SJason King void xfree(sysdem_ops_t *, void *, size_t);
1076a6cfa5dSJason King char *xstrdup(sysdem_ops_t *, const char *);
1084226f635SJason King 
1094226f635SJason King extern volatile boolean_t demangle_debug;
1104226f635SJason King 
1116a6cfa5dSJason King /*
1126a6cfa5dSJason King  * gcc seems to get unhappy with the ASSERT() style definition (also borrowed
1136a6cfa5dSJason King  * for the DEMDEBUG macro unless demdebug() is returns a non-void value
1146a6cfa5dSJason King  * (despite the return value never being used).
1156a6cfa5dSJason King  */
1166a6cfa5dSJason King int demdebug(const char *, ...);
1176a6cfa5dSJason King 
1186a6cfa5dSJason King #define	DEMDEBUG(s, ...) \
1196a6cfa5dSJason King 	((void)(demangle_debug && demdebug(s, ## __VA_ARGS__)))
1206a6cfa5dSJason King 
1214226f635SJason King #ifdef __cplusplus
1224226f635SJason King }
1234226f635SJason King #endif
1244226f635SJason King 
1254226f635SJason King #endif /* _DEMANGLE_INT_H */
126