1 /* 2 * Copyright (c) 2016-2020, Intel Corporation 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * * Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * * Neither the name of Intel Corporation nor the names of its contributors 13 * may be used to endorse or promote products derived from this software 14 * without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "config.h" 30 #include "hs_common.h" 31 #include "hs_runtime.h" 32 #include "ue2common.h" 33 #include "util/cpuid_inline.h" 34 #include "util/join.h" 35 36 #if defined(DISABLE_AVX512_DISPATCH) 37 #define avx512_ disabled_ 38 #define check_avx512() (0) 39 #endif 40 41 #if defined(DISABLE_AVX512VBMI_DISPATCH) 42 #define avx512vbmi_ disabled_ 43 #define check_avx512vbmi() (0) 44 #endif 45 46 #define CREATE_DISPATCH(RTYPE, NAME, ...) \ 47 /* create defns */ \ 48 RTYPE JOIN(avx512vbmi_, NAME)(__VA_ARGS__); \ 49 RTYPE JOIN(avx512_, NAME)(__VA_ARGS__); \ 50 RTYPE JOIN(avx2_, NAME)(__VA_ARGS__); \ 51 RTYPE JOIN(corei7_, NAME)(__VA_ARGS__); \ 52 RTYPE JOIN(core2_, NAME)(__VA_ARGS__); \ 53 \ 54 /* error func */ \ 55 static inline RTYPE JOIN(error_, NAME)(__VA_ARGS__) { \ 56 return (RTYPE)HS_ARCH_ERROR; \ 57 } \ 58 \ 59 /* resolver */ \ 60 static RTYPE (*JOIN(resolve_, NAME)(void))(__VA_ARGS__) { \ 61 if (check_avx512vbmi()) { \ 62 return JOIN(avx512vbmi_, NAME); \ 63 } \ 64 if (check_avx512()) { \ 65 return JOIN(avx512_, NAME); \ 66 } \ 67 if (check_avx2()) { \ 68 return JOIN(avx2_, NAME); \ 69 } \ 70 if (check_sse42() && check_popcnt()) { \ 71 return JOIN(corei7_, NAME); \ 72 } \ 73 if (check_ssse3()) { \ 74 return JOIN(core2_, NAME); \ 75 } \ 76 /* anything else is fail */ \ 77 return JOIN(error_, NAME); \ 78 } \ 79 \ 80 /* function */ \ 81 HS_PUBLIC_API \ 82 RTYPE NAME(__VA_ARGS__) __attribute__((ifunc("resolve_" #NAME))) 83 84 CREATE_DISPATCH(hs_error_t, hs_scan, const hs_database_t *db, const char *data, 85 unsigned length, unsigned flags, hs_scratch_t *scratch, 86 match_event_handler onEvent, void *userCtx); 87 88 CREATE_DISPATCH(hs_error_t, hs_stream_size, const hs_database_t *database, 89 size_t *stream_size); 90 91 CREATE_DISPATCH(hs_error_t, hs_database_size, const hs_database_t *db, 92 size_t *size); 93 CREATE_DISPATCH(hs_error_t, dbIsValid, const hs_database_t *db); 94 CREATE_DISPATCH(hs_error_t, hs_free_database, hs_database_t *db); 95 96 CREATE_DISPATCH(hs_error_t, hs_open_stream, const hs_database_t *db, 97 unsigned int flags, hs_stream_t **stream); 98 99 CREATE_DISPATCH(hs_error_t, hs_scan_stream, hs_stream_t *id, const char *data, 100 unsigned int length, unsigned int flags, hs_scratch_t *scratch, 101 match_event_handler onEvent, void *ctxt); 102 103 CREATE_DISPATCH(hs_error_t, hs_close_stream, hs_stream_t *id, 104 hs_scratch_t *scratch, match_event_handler onEvent, void *ctxt); 105 106 CREATE_DISPATCH(hs_error_t, hs_scan_vector, const hs_database_t *db, 107 const char *const *data, const unsigned int *length, 108 unsigned int count, unsigned int flags, hs_scratch_t *scratch, 109 match_event_handler onevent, void *context); 110 111 CREATE_DISPATCH(hs_error_t, hs_database_info, const hs_database_t *db, char **info); 112 113 CREATE_DISPATCH(hs_error_t, hs_copy_stream, hs_stream_t **to_id, 114 const hs_stream_t *from_id); 115 116 CREATE_DISPATCH(hs_error_t, hs_reset_stream, hs_stream_t *id, 117 unsigned int flags, hs_scratch_t *scratch, 118 match_event_handler onEvent, void *context); 119 120 CREATE_DISPATCH(hs_error_t, hs_reset_and_copy_stream, hs_stream_t *to_id, 121 const hs_stream_t *from_id, hs_scratch_t *scratch, 122 match_event_handler onEvent, void *context); 123 124 CREATE_DISPATCH(hs_error_t, hs_serialize_database, const hs_database_t *db, 125 char **bytes, size_t *length); 126 127 CREATE_DISPATCH(hs_error_t, hs_deserialize_database, const char *bytes, 128 const size_t length, hs_database_t **db); 129 130 CREATE_DISPATCH(hs_error_t, hs_deserialize_database_at, const char *bytes, 131 const size_t length, hs_database_t *db); 132 133 CREATE_DISPATCH(hs_error_t, hs_serialized_database_info, const char *bytes, 134 size_t length, char **info); 135 136 CREATE_DISPATCH(hs_error_t, hs_serialized_database_size, const char *bytes, 137 const size_t length, size_t *deserialized_size); 138 139 CREATE_DISPATCH(hs_error_t, hs_compress_stream, const hs_stream_t *stream, 140 char *buf, size_t buf_space, size_t *used_space); 141 142 CREATE_DISPATCH(hs_error_t, hs_expand_stream, const hs_database_t *db, 143 hs_stream_t **stream, const char *buf,size_t buf_size); 144 145 CREATE_DISPATCH(hs_error_t, hs_reset_and_expand_stream, hs_stream_t *to_stream, 146 const char *buf, size_t buf_size, hs_scratch_t *scratch, 147 match_event_handler onEvent, void *context); 148 149 /** INTERNALS **/ 150 151 CREATE_DISPATCH(u32, Crc32c_ComputeBuf, u32 inCrc32, const void *buf, size_t bufLen); 152