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 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 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 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