diff options
Diffstat (limited to '')
-rw-r--r-- | include/libbb.h | 228 |
1 files changed, 185 insertions, 43 deletions
diff --git a/include/libbb.h b/include/libbb.h index bc1453e12..8dc4e4992 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -281,6 +281,26 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN | |||
281 | # endif | 281 | # endif |
282 | #endif | 282 | #endif |
283 | 283 | ||
284 | #if ENABLE_FEATURE_TLS_SCHANNEL || ENABLE_FEATURE_USE_CNG_API | ||
285 | # define SECURITY_WIN32 | ||
286 | # include <windows.h> | ||
287 | # include <security.h> | ||
288 | #endif | ||
289 | |||
290 | #if ENABLE_FEATURE_USE_CNG_API | ||
291 | # include <bcrypt.h> | ||
292 | |||
293 | // these work on Windows >= 10 | ||
294 | # define BCRYPT_HMAC_SHA1_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x000000a1) | ||
295 | # define BCRYPT_HMAC_SHA256_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x000000b1) | ||
296 | # define sha1_begin_hmac BCRYPT_HMAC_SHA1_ALG_HANDLE | ||
297 | # define sha256_begin_hmac BCRYPT_HMAC_SHA256_ALG_HANDLE | ||
298 | #else | ||
299 | # define sha1_begin_hmac sha1_begin | ||
300 | # define sha256_begin_hmac sha256_begin | ||
301 | # define hmac_uninit(...) ((void)0) | ||
302 | #endif | ||
303 | |||
284 | /* Tested to work correctly with all int types (IIRC :]) */ | 304 | /* Tested to work correctly with all int types (IIRC :]) */ |
285 | #define MAXINT(T) (T)( \ | 305 | #define MAXINT(T) (T)( \ |
286 | ((T)-1) > 0 \ | 306 | ((T)-1) > 0 \ |
@@ -899,7 +919,36 @@ struct hostent *xgethostbyname(const char *name) FAST_FUNC; | |||
899 | // Also mount.c and inetd.c are using gethostbyname(), | 919 | // Also mount.c and inetd.c are using gethostbyname(), |
900 | // + inet_common.c has additional IPv4-only stuff | 920 | // + inet_common.c has additional IPv4-only stuff |
901 | 921 | ||
922 | #if defined CONFIG_FEATURE_TLS_SCHANNEL | ||
923 | typedef struct tls_state { | ||
924 | int ofd; | ||
925 | int ifd; | ||
926 | |||
927 | // handles | ||
928 | CredHandle cred_handle; | ||
929 | CtxtHandle ctx_handle; | ||
930 | |||
931 | // buffers | ||
932 | char in_buffer[16384 + 256]; // input buffer (to read from server) | ||
933 | unsigned long in_buffer_size; // amount of data currently in input buffer | ||
934 | |||
935 | char *out_buffer; // output buffer (for decrypted data), this is essentially the same as input buffer as data is decrypted in place | ||
936 | unsigned long out_buffer_size; // amount of data currently in output buffer | ||
937 | unsigned long out_buffer_used; // amount of extra data currently in output buffer | ||
938 | |||
939 | // data | ||
940 | char *hostname; | ||
941 | SecPkgContext_StreamSizes stream_sizes; | ||
942 | |||
943 | // booleans | ||
902 | 944 | ||
945 | // context initialized | ||
946 | int initialized; | ||
947 | |||
948 | // closed by remote peer | ||
949 | int closed; | ||
950 | } tls_state_t; | ||
951 | #else | ||
903 | struct tls_aes { | 952 | struct tls_aes { |
904 | uint32_t key[60]; | 953 | uint32_t key[60]; |
905 | unsigned rounds; | 954 | unsigned rounds; |
@@ -956,12 +1005,14 @@ typedef struct tls_state { | |||
956 | struct tls_aes aes_decrypt; | 1005 | struct tls_aes aes_decrypt; |
957 | uint8_t H[16]; //used by AES_GCM | 1006 | uint8_t H[16]; //used by AES_GCM |
958 | } tls_state_t; | 1007 | } tls_state_t; |
1008 | #endif | ||
959 | 1009 | ||
960 | static inline tls_state_t *new_tls_state(void) | 1010 | static inline tls_state_t *new_tls_state(void) |
961 | { | 1011 | { |
962 | tls_state_t *tls = xzalloc(sizeof(*tls)); | 1012 | tls_state_t *tls = xzalloc(sizeof(*tls)); |
963 | return tls; | 1013 | return tls; |
964 | } | 1014 | } |
1015 | |||
965 | void tls_handshake(tls_state_t *tls, const char *sni) FAST_FUNC; | 1016 | void tls_handshake(tls_state_t *tls, const char *sni) FAST_FUNC; |
966 | #define TLSLOOP_EXIT_ON_LOCAL_EOF (1 << 0) | 1017 | #define TLSLOOP_EXIT_ON_LOCAL_EOF (1 << 0) |
967 | void tls_run_copy_loop(tls_state_t *tls, unsigned flags) FAST_FUNC; | 1018 | void tls_run_copy_loop(tls_state_t *tls, unsigned flags) FAST_FUNC; |
@@ -1071,13 +1122,13 @@ unsigned bb_clk_tck(void) FAST_FUNC; | |||
1071 | 1122 | ||
1072 | #if SEAMLESS_COMPRESSION | 1123 | #if SEAMLESS_COMPRESSION |
1073 | /* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */ | 1124 | /* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */ |
1074 | int setup_unzip_on_fd(int fd, int fail_if_not_compressed) FAST_FUNC; | 1125 | int setup_unzip_on_fd(int fd, int die_if_not_compressed) FAST_FUNC; |
1075 | /* Autodetects .gz etc */ | 1126 | /* Autodetects .gz etc */ |
1076 | extern int open_zipped(const char *fname, int fail_if_not_compressed) FAST_FUNC; | 1127 | extern int open_zipped(const char *fname, int die_if_not_compressed) FAST_FUNC; |
1077 | extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; | 1128 | extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; |
1078 | #else | 1129 | #else |
1079 | # define setup_unzip_on_fd(...) (0) | 1130 | # define setup_unzip_on_fd(...) (0) |
1080 | # define open_zipped(fname, fail_if_not_compressed) open((fname), O_RDONLY); | 1131 | # define open_zipped(fname, die_if_not_compressed) open((fname), O_RDONLY); |
1081 | # define xmalloc_open_zipped_read_close(fname, maxsz_p) xmalloc_open_read_close((fname), (maxsz_p)) | 1132 | # define xmalloc_open_zipped_read_close(fname, maxsz_p) xmalloc_open_read_close((fname), (maxsz_p)) |
1082 | #endif | 1133 | #endif |
1083 | /* lzma has no signature, need a little helper. NB: exist only for ENABLE_FEATURE_SEAMLESS_LZMA=y */ | 1134 | /* lzma has no signature, need a little helper. NB: exist only for ENABLE_FEATURE_SEAMLESS_LZMA=y */ |
@@ -1173,6 +1224,16 @@ char *bin2hex(char *dst, const char *src, int count) FAST_FUNC; | |||
1173 | /* Reverse */ | 1224 | /* Reverse */ |
1174 | char* hex2bin(char *dst, const char *src, int count) FAST_FUNC; | 1225 | char* hex2bin(char *dst, const char *src, int count) FAST_FUNC; |
1175 | 1226 | ||
1227 | void FAST_FUNC xorbuf_3(void *dst, const void *src1, const void *src2, unsigned count); | ||
1228 | void FAST_FUNC xorbuf(void* buf, const void* mask, unsigned count); | ||
1229 | void FAST_FUNC xorbuf16_aligned_long(void* buf, const void* mask); | ||
1230 | void FAST_FUNC xorbuf64_3_aligned64(void *dst, const void *src1, const void *src2); | ||
1231 | #if BB_UNALIGNED_MEMACCESS_OK | ||
1232 | # define xorbuf16(buf,mask) xorbuf16_aligned_long(buf,mask) | ||
1233 | #else | ||
1234 | void FAST_FUNC xorbuf16(void* buf, const void* mask); | ||
1235 | #endif | ||
1236 | |||
1176 | /* Generate a UUID */ | 1237 | /* Generate a UUID */ |
1177 | void generate_uuid(uint8_t *buf) FAST_FUNC; | 1238 | void generate_uuid(uint8_t *buf) FAST_FUNC; |
1178 | 1239 | ||
@@ -1887,18 +1948,25 @@ extern char *pw_encrypt(const char *clear, const char *salt, int cleanup) FAST_F | |||
1887 | extern int obscure(const char *old, const char *newval, const struct passwd *pwdp) FAST_FUNC; | 1948 | extern int obscure(const char *old, const char *newval, const struct passwd *pwdp) FAST_FUNC; |
1888 | /* | 1949 | /* |
1889 | * rnd is additional random input. New one is returned. | 1950 | * rnd is additional random input. New one is returned. |
1890 | * Useful if you call crypt_make_salt many times in a row: | 1951 | * Useful if you call crypt_make_rand64encoded many times in a row: |
1891 | * rnd = crypt_make_salt(buf1, 4, 0); | 1952 | * rnd = crypt_make_rand64encoded(buf1, 4, 0); |
1892 | * rnd = crypt_make_salt(buf2, 4, rnd); | 1953 | * rnd = crypt_make_rand64encoded(buf2, 4, rnd); |
1893 | * rnd = crypt_make_salt(buf3, 4, rnd); | 1954 | * rnd = crypt_make_rand64encoded(buf3, 4, rnd); |
1894 | * (otherwise we risk having same salt generated) | 1955 | * (otherwise we risk having same salt generated) |
1895 | */ | 1956 | */ |
1896 | extern int crypt_make_salt(char *p, int cnt /*, int rnd*/) FAST_FUNC; | 1957 | extern int crypt_make_rand64encoded(char *p, int cnt /*, int rnd*/) FAST_FUNC; |
1897 | /* "$N$" + sha_salt_16_bytes + NUL */ | 1958 | /* Size of char salt[] to hold randomly-generated salt string |
1898 | #define MAX_PW_SALT_LEN (3 + 16 + 1) | 1959 | * sha256/512: |
1960 | * "$5$" ["rounds=999999999$"] "<sha_salt_16_chars><NUL>" | ||
1961 | * "$6$" ["rounds=999999999$"] "<sha_salt_16_chars><NUL>" | ||
1962 | * #define MAX_PW_SALT_LEN (3 + sizeof("rounds=999999999$")-1 + 16 + 1) | ||
1963 | * yescrypt: | ||
1964 | * "$y$" <up to 8 params of up to 6 chars each> "$" <up to 86 chars salt><NUL> | ||
1965 | * (86 chars are ascii64-encoded 64 binary bytes) | ||
1966 | */ | ||
1967 | #define MAX_PW_SALT_LEN (3 + 8*6 + 1 + 86 + 1) | ||
1899 | extern char* crypt_make_pw_salt(char p[MAX_PW_SALT_LEN], const char *algo) FAST_FUNC; | 1968 | extern char* crypt_make_pw_salt(char p[MAX_PW_SALT_LEN], const char *algo) FAST_FUNC; |
1900 | 1969 | ||
1901 | |||
1902 | /* Returns number of lines changed, or -1 on error */ | 1970 | /* Returns number of lines changed, or -1 on error */ |
1903 | #if !(ENABLE_FEATURE_ADDUSER_TO_GROUP || ENABLE_FEATURE_DEL_USER_FROM_GROUP) | 1971 | #if !(ENABLE_FEATURE_ADDUSER_TO_GROUP || ENABLE_FEATURE_DEL_USER_FROM_GROUP) |
1904 | #define update_passwd(filename, username, data, member) \ | 1972 | #define update_passwd(filename, username, data, member) \ |
@@ -2041,6 +2109,10 @@ int64_t windows_read_key(int fd, char *buffer, int timeout) FAST_FUNC; | |||
2041 | int64_t safe_read_key(int fd, char *buffer, int timeout) FAST_FUNC; | 2109 | int64_t safe_read_key(int fd, char *buffer, int timeout) FAST_FUNC; |
2042 | void read_key_ungets(char *buffer, const char *str, unsigned len) FAST_FUNC; | 2110 | void read_key_ungets(char *buffer, const char *str, unsigned len) FAST_FUNC; |
2043 | 2111 | ||
2112 | int check_got_signal_and_poll(struct pollfd pfd[1], int timeout) FAST_FUNC; | ||
2113 | #if ENABLE_PLATFORM_MINGW32 | ||
2114 | # define check_got_signal_and_poll(p, t) poll(p, 1, t) | ||
2115 | #endif | ||
2044 | 2116 | ||
2045 | #if ENABLE_FEATURE_EDITING | 2117 | #if ENABLE_FEATURE_EDITING |
2046 | /* It's NOT just ENABLEd or disabled. It's a number: */ | 2118 | /* It's NOT just ENABLEd or disabled. It's a number: */ |
@@ -2087,7 +2159,7 @@ typedef struct line_input_t { | |||
2087 | # if MAX_HISTORY | 2159 | # if MAX_HISTORY |
2088 | int cnt_history; | 2160 | int cnt_history; |
2089 | int cur_history; | 2161 | int cur_history; |
2090 | int max_history; /* must never be <= 0 */ | 2162 | int max_history; /* must never be < 0 */ |
2091 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY | 2163 | # if ENABLE_FEATURE_EDITING_SAVEHISTORY |
2092 | /* meaning of this field depends on FEATURE_EDITING_SAVE_ON_EXIT: | 2164 | /* meaning of this field depends on FEATURE_EDITING_SAVE_ON_EXIT: |
2093 | * if !FEATURE_EDITING_SAVE_ON_EXIT: "how many lines are | 2165 | * if !FEATURE_EDITING_SAVE_ON_EXIT: "how many lines are |
@@ -2294,6 +2366,51 @@ char *decode_base64(char *dst, const char **pp_src) FAST_FUNC; | |||
2294 | char *decode_base32(char *dst, const char **pp_src) FAST_FUNC; | 2366 | char *decode_base32(char *dst, const char **pp_src) FAST_FUNC; |
2295 | void read_base64(FILE *src_stream, FILE *dst_stream, int flags) FAST_FUNC; | 2367 | void read_base64(FILE *src_stream, FILE *dst_stream, int flags) FAST_FUNC; |
2296 | 2368 | ||
2369 | int FAST_FUNC i2a64(int i); | ||
2370 | int FAST_FUNC a2i64(char c); | ||
2371 | char* FAST_FUNC num2str64_lsb_first(char *s, unsigned v, int n); | ||
2372 | |||
2373 | enum { | ||
2374 | /* how many bytes XYZ_end() fills */ | ||
2375 | MD5_OUTSIZE = 16, | ||
2376 | SHA1_OUTSIZE = 20, | ||
2377 | SHA256_OUTSIZE = 32, | ||
2378 | SHA512_OUTSIZE = 64, | ||
2379 | SHA3_OUTSIZE = 28, | ||
2380 | /* size of input block */ | ||
2381 | SHA2_INSIZE = 64, | ||
2382 | }; | ||
2383 | |||
2384 | #if defined CONFIG_FEATURE_USE_CNG_API | ||
2385 | struct bcrypt_hash_ctx_t { | ||
2386 | void *handle; | ||
2387 | void *hash_obj; | ||
2388 | unsigned int output_size; | ||
2389 | }; | ||
2390 | typedef struct bcrypt_hash_ctx_t md5_ctx_t; | ||
2391 | typedef struct bcrypt_hash_ctx_t sha1_ctx_t; | ||
2392 | typedef struct bcrypt_hash_ctx_t sha256_ctx_t; | ||
2393 | typedef struct bcrypt_hash_ctx_t sha512_ctx_t; | ||
2394 | typedef struct sha3_ctx_t { | ||
2395 | uint64_t state[25]; | ||
2396 | unsigned bytes_queued; | ||
2397 | unsigned input_block_bytes; | ||
2398 | } sha3_ctx_t; | ||
2399 | void md5_begin(struct bcrypt_hash_ctx_t *ctx) FAST_FUNC; | ||
2400 | void sha1_begin(struct bcrypt_hash_ctx_t *ctx) FAST_FUNC; | ||
2401 | void sha256_begin(struct bcrypt_hash_ctx_t *ctx) FAST_FUNC; | ||
2402 | void sha512_begin(struct bcrypt_hash_ctx_t *ctx) FAST_FUNC; | ||
2403 | void generic_hash(struct bcrypt_hash_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; | ||
2404 | unsigned generic_end(struct bcrypt_hash_ctx_t *ctx, void *resbuf) FAST_FUNC; | ||
2405 | # define md5_hash generic_hash | ||
2406 | # define sha1_hash generic_hash | ||
2407 | # define sha256_hash generic_hash | ||
2408 | # define sha512_hash generic_hash | ||
2409 | # define md5_end generic_end | ||
2410 | # define sha1_end generic_end | ||
2411 | # define sha256_end generic_end | ||
2412 | # define sha512_end generic_end | ||
2413 | #else | ||
2297 | typedef struct md5_ctx_t { | 2414 | typedef struct md5_ctx_t { |
2298 | uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */ | 2415 | uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */ |
2299 | void (*process_block)(struct md5_ctx_t*) FAST_FUNC; | 2416 | void (*process_block)(struct md5_ctx_t*) FAST_FUNC; |
@@ -2324,20 +2441,66 @@ void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; | |||
2324 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; | 2441 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; |
2325 | void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; | 2442 | void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; |
2326 | unsigned sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; | 2443 | unsigned sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; |
2444 | #endif | ||
2327 | void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC; | 2445 | void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC; |
2328 | void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; | 2446 | void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; |
2329 | unsigned sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC; | 2447 | unsigned sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC; |
2448 | void FAST_FUNC sha256_block(const void *in, size_t len, uint8_t hash[32]); | ||
2330 | /* TLS benefits from knowing that sha1 and sha256 share these. Give them "agnostic" names too */ | 2449 | /* TLS benefits from knowing that sha1 and sha256 share these. Give them "agnostic" names too */ |
2450 | #if defined CONFIG_FEATURE_USE_CNG_API | ||
2451 | typedef struct bcrypt_hash_ctx_t md5sha_ctx_t; | ||
2452 | #define md5sha_hash generic_hash | ||
2453 | #define sha_end generic_end | ||
2454 | #else | ||
2331 | typedef struct md5_ctx_t md5sha_ctx_t; | 2455 | typedef struct md5_ctx_t md5sha_ctx_t; |
2332 | #define md5sha_hash md5_hash | 2456 | #define md5sha_hash md5_hash |
2333 | #define sha_end sha1_end | 2457 | #define sha_end sha1_end |
2334 | enum { | 2458 | #endif |
2335 | MD5_OUTSIZE = 16, | 2459 | |
2336 | SHA1_OUTSIZE = 20, | 2460 | /* RFC 2104 HMAC (hash-based message authentication code) */ |
2337 | SHA256_OUTSIZE = 32, | 2461 | #if !ENABLE_FEATURE_USE_CNG_API |
2338 | SHA512_OUTSIZE = 64, | 2462 | typedef struct hmac_ctx { |
2339 | SHA3_OUTSIZE = 28, | 2463 | md5sha_ctx_t hashed_key_xor_ipad; |
2340 | }; | 2464 | md5sha_ctx_t hashed_key_xor_opad; |
2465 | } hmac_ctx_t; | ||
2466 | #else | ||
2467 | typedef struct bcrypt_hash_ctx_t hmac_ctx_t; | ||
2468 | #endif | ||
2469 | #define HMAC_ONLY_SHA256 (!ENABLE_FEATURE_TLS_SHA1) | ||
2470 | typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC; | ||
2471 | #if !ENABLE_FEATURE_USE_CNG_API | ||
2472 | #if HMAC_ONLY_SHA256 | ||
2473 | #define hmac_begin(ctx,key,key_size,begin) \ | ||
2474 | hmac_begin(ctx,key,key_size) | ||
2475 | #endif | ||
2476 | void FAST_FUNC hmac_begin(hmac_ctx_t *ctx, const uint8_t *key, unsigned key_size, md5sha_begin_func *begin); | ||
2477 | static ALWAYS_INLINE void hmac_hash(hmac_ctx_t *ctx, const void *in, size_t len) | ||
2478 | { | ||
2479 | md5sha_hash(&ctx->hashed_key_xor_ipad, in, len); | ||
2480 | } | ||
2481 | #else | ||
2482 | # if HMAC_ONLY_SHA256 | ||
2483 | # define hmac_begin(pre,key,key_size,begin) \ | ||
2484 | _hmac_begin(pre, key, key_size, sha256_begin_hmac) | ||
2485 | # else | ||
2486 | # define hmac_begin _hmac_begin | ||
2487 | # endif | ||
2488 | void _hmac_begin(hmac_ctx_t *pre, uint8_t *key, unsigned key_size, | ||
2489 | BCRYPT_ALG_HANDLE alg_handle); | ||
2490 | void hmac_uninit(hmac_ctx_t *pre); | ||
2491 | #endif | ||
2492 | unsigned FAST_FUNC hmac_end(hmac_ctx_t *ctx, uint8_t *out); | ||
2493 | #if HMAC_ONLY_SHA256 | ||
2494 | #define hmac_block(key,key_size,begin,in,sz,out) \ | ||
2495 | hmac_block(key,key_size,in,sz,out) | ||
2496 | #endif | ||
2497 | unsigned FAST_FUNC hmac_block(const uint8_t *key, unsigned key_size, | ||
2498 | md5sha_begin_func *begin, | ||
2499 | const void *in, unsigned sz, | ||
2500 | uint8_t *out); | ||
2501 | /* HMAC helpers for TLS: */ | ||
2502 | void FAST_FUNC hmac_hash_v(hmac_ctx_t *ctx, va_list va); | ||
2503 | unsigned hmac_peek_hash(hmac_ctx_t *ctx, uint8_t *out, ...); | ||
2341 | 2504 | ||
2342 | extern uint32_t *global_crc32_table; | 2505 | extern uint32_t *global_crc32_table; |
2343 | uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; | 2506 | uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; |
@@ -2473,31 +2636,10 @@ extern struct globals *BB_GLOBAL_CONST ptr_to_globals; | |||
2473 | #define barrier() asm volatile ("":::"memory") | 2636 | #define barrier() asm volatile ("":::"memory") |
2474 | 2637 | ||
2475 | #if defined(__clang_major__) && __clang_major__ >= 9 | 2638 | #if defined(__clang_major__) && __clang_major__ >= 9 |
2476 | /* Clang/llvm drops assignment to "constant" storage. Silently. | 2639 | /* {ASSIGN,XZALLOC}_CONST_PTR() are out-of-line functions |
2477 | * Needs serious convincing to not eliminate the store. | 2640 | * to prevent clang from reading pointer before it is assigned. |
2478 | */ | ||
2479 | static ALWAYS_INLINE void* not_const_pp(const void *p) | ||
2480 | { | ||
2481 | void *pp; | ||
2482 | asm volatile ( | ||
2483 | "# forget that p points to const" | ||
2484 | : /*outputs*/ "=r" (pp) | ||
2485 | : /*inputs*/ "0" (p) | ||
2486 | ); | ||
2487 | return pp; | ||
2488 | } | ||
2489 | # if !ENABLE_PLATFORM_MINGW32 | ||
2490 | # define ASSIGN_CONST_PTR(pptr, v) do { \ | ||
2491 | *(void**)not_const_pp(pptr) = (void*)(v); \ | ||
2492 | barrier(); \ | ||
2493 | } while (0) | ||
2494 | #else | ||
2495 | /* On Windows it seems necessary for this to be a function too. */ | ||
2496 | void ASSIGN_CONST_PTR(const void *pptr, const void *ptr) FAST_FUNC; | ||
2497 | #endif | ||
2498 | /* XZALLOC_CONST_PTR() is an out-of-line function to prevent | ||
2499 | * clang from reading pointer before it is assigned. | ||
2500 | */ | 2641 | */ |
2642 | void ASSIGN_CONST_PTR(const void *pptr, void *v) FAST_FUNC; | ||
2501 | void XZALLOC_CONST_PTR(const void *pptr, size_t size) FAST_FUNC; | 2643 | void XZALLOC_CONST_PTR(const void *pptr, size_t size) FAST_FUNC; |
2502 | #else | 2644 | #else |
2503 | # define ASSIGN_CONST_PTR(pptr, v) do { \ | 2645 | # define ASSIGN_CONST_PTR(pptr, v) do { \ |