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