1 /* 2 * Copyright (c) 2015-2019, 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 #ifndef HS_COMMON_H_ 30 #define HS_COMMON_H_ 31 32 #if defined(_WIN32) 33 #define HS_CDECL __cdecl 34 #else 35 #define HS_CDECL 36 #endif 37 #include <stdlib.h> 38 39 /** 40 * @file 41 * @brief The Hyperscan common API definition. 42 * 43 * Hyperscan is a high speed regular expression engine. 44 * 45 * This header contains functions available to both the Hyperscan compiler and 46 * runtime. 47 */ 48 49 #ifdef __cplusplus 50 extern "C" 51 { 52 #endif 53 54 struct hs_database; 55 56 /** 57 * A Hyperscan pattern database. 58 * 59 * Generated by one of the Hyperscan compiler functions: 60 * - @ref hs_compile() 61 * - @ref hs_compile_multi() 62 * - @ref hs_compile_ext_multi() 63 */ 64 typedef struct hs_database hs_database_t; 65 66 /** 67 * A type for errors returned by Hyperscan functions. 68 */ 69 typedef int hs_error_t; 70 71 /** 72 * Free a compiled pattern database. 73 * 74 * The free callback set by @ref hs_set_database_allocator() (or @ref 75 * hs_set_allocator()) will be used by this function. 76 * 77 * @param db 78 * A compiled pattern database. NULL may also be safely provided, in which 79 * case the function does nothing. 80 * 81 * @return 82 * @ref HS_SUCCESS on success, other values on failure. 83 */ 84 hs_error_t HS_CDECL hs_free_database(hs_database_t *db); 85 86 /** 87 * Serialize a pattern database to a stream of bytes. 88 * 89 * The allocator callback set by @ref hs_set_misc_allocator() (or @ref 90 * hs_set_allocator()) will be used by this function. 91 * 92 * @param db 93 * A compiled pattern database. 94 * 95 * @param bytes 96 * On success, a pointer to an array of bytes will be returned here. 97 * These bytes can be subsequently relocated or written to disk. The 98 * caller is responsible for freeing this block. 99 * 100 * @param length 101 * On success, the number of bytes in the generated byte array will be 102 * returned here. 103 * 104 * @return 105 * @ref HS_SUCCESS on success, @ref HS_NOMEM if the byte array cannot be 106 * allocated, other values may be returned if errors are detected. 107 */ 108 hs_error_t HS_CDECL hs_serialize_database(const hs_database_t *db, char **bytes, 109 size_t *length); 110 111 /** 112 * Reconstruct a pattern database from a stream of bytes previously generated 113 * by @ref hs_serialize_database(). 114 * 115 * This function will allocate sufficient space for the database using the 116 * allocator set with @ref hs_set_database_allocator() (or @ref 117 * hs_set_allocator()); to use a pre-allocated region of memory, use the @ref 118 * hs_deserialize_database_at() function. 119 * 120 * @param bytes 121 * A byte array generated by @ref hs_serialize_database() representing a 122 * compiled pattern database. 123 * 124 * @param length 125 * The length of the byte array generated by @ref hs_serialize_database(). 126 * This should be the same value as that returned by @ref 127 * hs_serialize_database(). 128 * 129 * @param db 130 * On success, a pointer to a newly allocated @ref hs_database_t will be 131 * returned here. This database can then be used for scanning, and 132 * eventually freed by the caller using @ref hs_free_database(). 133 * 134 * @return 135 * @ref HS_SUCCESS on success, other values on failure. 136 */ 137 hs_error_t HS_CDECL hs_deserialize_database(const char *bytes, 138 const size_t length, 139 hs_database_t **db); 140 141 /** 142 * Reconstruct a pattern database from a stream of bytes previously generated 143 * by @ref hs_serialize_database() at a given memory location. 144 * 145 * This function (unlike @ref hs_deserialize_database()) will write the 146 * reconstructed database to the memory location given in the @p db parameter. 147 * The amount of space required at this location can be determined with the 148 * @ref hs_serialized_database_size() function. 149 * 150 * @param bytes 151 * A byte array generated by @ref hs_serialize_database() representing a 152 * compiled pattern database. 153 * 154 * @param length 155 * The length of the byte array generated by @ref hs_serialize_database(). 156 * This should be the same value as that returned by @ref 157 * hs_serialize_database(). 158 * 159 * @param db 160 * Pointer to an 8-byte aligned block of memory of sufficient size to hold 161 * the deserialized database. On success, the reconstructed database will 162 * be written to this location. This database can then be used for pattern 163 * matching. The user is responsible for freeing this memory; the @ref 164 * hs_free_database() call should not be used. 165 * 166 * @return 167 * @ref HS_SUCCESS on success, other values on failure. 168 */ 169 hs_error_t HS_CDECL hs_deserialize_database_at(const char *bytes, 170 const size_t length, 171 hs_database_t *db); 172 173 /** 174 * Provides the size of the stream state allocated by a single stream opened 175 * against the given database. 176 * 177 * @param database 178 * Pointer to a compiled (streaming mode) pattern database. 179 * 180 * @param stream_size 181 * On success, the size in bytes of an individual stream opened against the 182 * given database is placed in this parameter. 183 * 184 * @return 185 * @ref HS_SUCCESS on success, other values on failure. 186 */ 187 hs_error_t HS_CDECL hs_stream_size(const hs_database_t *database, 188 size_t *stream_size); 189 190 /** 191 * Provides the size of the given database in bytes. 192 * 193 * @param database 194 * Pointer to compiled pattern database. 195 * 196 * @param database_size 197 * On success, the size of the compiled database in bytes is placed in this 198 * parameter. 199 * 200 * @return 201 * @ref HS_SUCCESS on success, other values on failure. 202 */ 203 hs_error_t HS_CDECL hs_database_size(const hs_database_t *database, 204 size_t *database_size); 205 206 /** 207 * Utility function for reporting the size that would be required by a 208 * database if it were deserialized. 209 * 210 * This can be used to allocate a shared memory region or other "special" 211 * allocation prior to deserializing with the @ref hs_deserialize_database_at() 212 * function. 213 * 214 * @param bytes 215 * Pointer to a byte array generated by @ref hs_serialize_database() 216 * representing a compiled pattern database. 217 * 218 * @param length 219 * The length of the byte array generated by @ref hs_serialize_database(). 220 * This should be the same value as that returned by @ref 221 * hs_serialize_database(). 222 * 223 * @param deserialized_size 224 * On success, the size of the compiled database that would be generated 225 * by @ref hs_deserialize_database_at() is returned here. 226 * 227 * @return 228 * @ref HS_SUCCESS on success, other values on failure. 229 */ 230 hs_error_t HS_CDECL hs_serialized_database_size(const char *bytes, 231 const size_t length, 232 size_t *deserialized_size); 233 234 /** 235 * Utility function providing information about a database. 236 * 237 * @param database 238 * Pointer to a compiled database. 239 * 240 * @param info 241 * On success, a string containing the version and platform information for 242 * the supplied database is placed in the parameter. The string is 243 * allocated using the allocator supplied in @ref hs_set_misc_allocator() 244 * (or malloc() if no allocator was set) and should be freed by the caller. 245 * 246 * @return 247 * @ref HS_SUCCESS on success, other values on failure. 248 */ 249 hs_error_t HS_CDECL hs_database_info(const hs_database_t *database, 250 char **info); 251 252 /** 253 * Utility function providing information about a serialized database. 254 * 255 * @param bytes 256 * Pointer to a serialized database. 257 * 258 * @param length 259 * Length in bytes of the serialized database. 260 * 261 * @param info 262 * On success, a string containing the version and platform information 263 * for the supplied serialized database is placed in the parameter. The 264 * string is allocated using the allocator supplied in @ref 265 * hs_set_misc_allocator() (or malloc() if no allocator was set) and 266 * should be freed by the caller. 267 * 268 * @return 269 * @ref HS_SUCCESS on success, other values on failure. 270 */ 271 hs_error_t HS_CDECL hs_serialized_database_info(const char *bytes, 272 size_t length, char **info); 273 274 /** 275 * The type of the callback function that will be used by Hyperscan to allocate 276 * more memory at runtime as required, for example in @ref hs_open_stream() to 277 * allocate stream state. 278 * 279 * If Hyperscan is to be used in a multi-threaded, or similarly concurrent 280 * environment, the allocation function will need to be re-entrant, or 281 * similarly safe for concurrent use. 282 * 283 * @param size 284 * The number of bytes to allocate. 285 * @return 286 * A pointer to the region of memory allocated, or NULL on error. 287 */ 288 typedef void *(HS_CDECL *hs_alloc_t)(size_t size); 289 290 /** 291 * The type of the callback function that will be used by Hyperscan to free 292 * memory regions previously allocated using the @ref hs_alloc_t function. 293 * 294 * @param ptr 295 * The region of memory to be freed. 296 */ 297 typedef void (HS_CDECL *hs_free_t)(void *ptr); 298 299 /** 300 * Set the allocate and free functions used by Hyperscan for allocating 301 * memory at runtime for stream state, scratch space, database bytecode, 302 * and various other data structure returned by the Hyperscan API. 303 * 304 * The function is equivalent to calling @ref hs_set_stream_allocator(), 305 * @ref hs_set_scratch_allocator(), @ref hs_set_database_allocator() and 306 * @ref hs_set_misc_allocator() with the provided parameters. 307 * 308 * This call will override any previous allocators that have been set. 309 * 310 * Note: there is no way to change the allocator used for temporary objects 311 * created during the various compile calls (@ref hs_compile(), @ref 312 * hs_compile_multi(), @ref hs_compile_ext_multi()). 313 * 314 * @param alloc_func 315 * A callback function pointer that allocates memory. This function must 316 * return memory suitably aligned for the largest representable data type 317 * on this platform. 318 * 319 * @param free_func 320 * A callback function pointer that frees allocated memory. 321 * 322 * @return 323 * @ref HS_SUCCESS on success, other values on failure. 324 */ 325 hs_error_t HS_CDECL hs_set_allocator(hs_alloc_t alloc_func, 326 hs_free_t free_func); 327 328 /** 329 * Set the allocate and free functions used by Hyperscan for allocating memory 330 * for database bytecode produced by the compile calls (@ref hs_compile(), @ref 331 * hs_compile_multi(), @ref hs_compile_ext_multi()) and by database 332 * deserialization (@ref hs_deserialize_database()). 333 * 334 * If no database allocation functions are set, or if NULL is used in place of 335 * both parameters, then memory allocation will default to standard methods 336 * (such as the system malloc() and free() calls). 337 * 338 * This call will override any previous database allocators that have been set. 339 * 340 * Note: the database allocator may also be set by calling @ref 341 * hs_set_allocator(). 342 * 343 * Note: there is no way to change how temporary objects created during the 344 * various compile calls (@ref hs_compile(), @ref hs_compile_multi(), @ref 345 * hs_compile_ext_multi()) are allocated. 346 * 347 * @param alloc_func 348 * A callback function pointer that allocates memory. This function must 349 * return memory suitably aligned for the largest representable data type 350 * on this platform. 351 * 352 * @param free_func 353 * A callback function pointer that frees allocated memory. 354 * 355 * @return 356 * @ref HS_SUCCESS on success, other values on failure. 357 */ 358 hs_error_t HS_CDECL hs_set_database_allocator(hs_alloc_t alloc_func, 359 hs_free_t free_func); 360 361 /** 362 * Set the allocate and free functions used by Hyperscan for allocating memory 363 * for items returned by the Hyperscan API such as @ref hs_compile_error_t, @ref 364 * hs_expr_info_t and serialized databases. 365 * 366 * If no misc allocation functions are set, or if NULL is used in place of both 367 * parameters, then memory allocation will default to standard methods (such as 368 * the system malloc() and free() calls). 369 * 370 * This call will override any previous misc allocators that have been set. 371 * 372 * Note: the misc allocator may also be set by calling @ref hs_set_allocator(). 373 * 374 * @param alloc_func 375 * A callback function pointer that allocates memory. This function must 376 * return memory suitably aligned for the largest representable data type 377 * on this platform. 378 * 379 * @param free_func 380 * A callback function pointer that frees allocated memory. 381 * 382 * @return 383 * @ref HS_SUCCESS on success, other values on failure. 384 */ 385 hs_error_t HS_CDECL hs_set_misc_allocator(hs_alloc_t alloc_func, 386 hs_free_t free_func); 387 388 /** 389 * Set the allocate and free functions used by Hyperscan for allocating memory 390 * for scratch space by @ref hs_alloc_scratch() and @ref hs_clone_scratch(). 391 * 392 * If no scratch allocation functions are set, or if NULL is used in place of 393 * both parameters, then memory allocation will default to standard methods 394 * (such as the system malloc() and free() calls). 395 * 396 * This call will override any previous scratch allocators that have been set. 397 * 398 * Note: the scratch allocator may also be set by calling @ref 399 * hs_set_allocator(). 400 * 401 * @param alloc_func 402 * A callback function pointer that allocates memory. This function must 403 * return memory suitably aligned for the largest representable data type 404 * on this platform. 405 * 406 * @param free_func 407 * A callback function pointer that frees allocated memory. 408 * 409 * @return 410 * @ref HS_SUCCESS on success, other values on failure. 411 */ 412 hs_error_t HS_CDECL hs_set_scratch_allocator(hs_alloc_t alloc_func, 413 hs_free_t free_func); 414 415 /** 416 * Set the allocate and free functions used by Hyperscan for allocating memory 417 * for stream state by @ref hs_open_stream(). 418 * 419 * If no stream allocation functions are set, or if NULL is used in place of 420 * both parameters, then memory allocation will default to standard methods 421 * (such as the system malloc() and free() calls). 422 * 423 * This call will override any previous stream allocators that have been set. 424 * 425 * Note: the stream allocator may also be set by calling @ref 426 * hs_set_allocator(). 427 * 428 * @param alloc_func 429 * A callback function pointer that allocates memory. This function must 430 * return memory suitably aligned for the largest representable data type 431 * on this platform. 432 * 433 * @param free_func 434 * A callback function pointer that frees allocated memory. 435 * 436 * @return 437 * @ref HS_SUCCESS on success, other values on failure. 438 */ 439 hs_error_t HS_CDECL hs_set_stream_allocator(hs_alloc_t alloc_func, 440 hs_free_t free_func); 441 442 /** 443 * Utility function for identifying this release version. 444 * 445 * @return 446 * A string containing the version number of this release build and the 447 * date of the build. It is allocated statically, so it does not need to 448 * be freed by the caller. 449 */ 450 const char * HS_CDECL hs_version(void); 451 452 /** 453 * Utility function to test the current system architecture. 454 * 455 * Hyperscan requires the Supplemental Streaming SIMD Extensions 3 instruction 456 * set. This function can be called on any x86 platform to determine if the 457 * system provides the required instruction set. 458 * 459 * This function does not test for more advanced features if Hyperscan has 460 * been built for a more specific architecture, for example the AVX2 461 * instruction set. 462 * 463 * @return 464 * @ref HS_SUCCESS on success, @ref HS_ARCH_ERROR if system does not 465 * support Hyperscan. 466 */ 467 hs_error_t HS_CDECL hs_valid_platform(void); 468 469 /** 470 * @defgroup HS_ERROR hs_error_t values 471 * 472 * @{ 473 */ 474 475 /** 476 * The engine completed normally. 477 */ 478 #define HS_SUCCESS 0 479 480 /** 481 * A parameter passed to this function was invalid. 482 * 483 * This error is only returned in cases where the function can detect an 484 * invalid parameter -- it cannot be relied upon to detect (for example) 485 * pointers to freed memory or other invalid data. 486 */ 487 #define HS_INVALID (-1) 488 489 /** 490 * A memory allocation failed. 491 */ 492 #define HS_NOMEM (-2) 493 494 /** 495 * The engine was terminated by callback. 496 * 497 * This return value indicates that the target buffer was partially scanned, 498 * but that the callback function requested that scanning cease after a match 499 * was located. 500 */ 501 #define HS_SCAN_TERMINATED (-3) 502 503 /** 504 * The pattern compiler failed, and the @ref hs_compile_error_t should be 505 * inspected for more detail. 506 */ 507 #define HS_COMPILER_ERROR (-4) 508 509 /** 510 * The given database was built for a different version of Hyperscan. 511 */ 512 #define HS_DB_VERSION_ERROR (-5) 513 514 /** 515 * The given database was built for a different platform (i.e., CPU type). 516 */ 517 #define HS_DB_PLATFORM_ERROR (-6) 518 519 /** 520 * The given database was built for a different mode of operation. This error 521 * is returned when streaming calls are used with a block or vectored database 522 * and vice versa. 523 */ 524 #define HS_DB_MODE_ERROR (-7) 525 526 /** 527 * A parameter passed to this function was not correctly aligned. 528 */ 529 #define HS_BAD_ALIGN (-8) 530 531 /** 532 * The memory allocator (either malloc() or the allocator set with @ref 533 * hs_set_allocator()) did not correctly return memory suitably aligned for the 534 * largest representable data type on this platform. 535 */ 536 #define HS_BAD_ALLOC (-9) 537 538 /** 539 * The scratch region was already in use. 540 * 541 * This error is returned when Hyperscan is able to detect that the scratch 542 * region given is already in use by another Hyperscan API call. 543 * 544 * A separate scratch region, allocated with @ref hs_alloc_scratch() or @ref 545 * hs_clone_scratch(), is required for every concurrent caller of the Hyperscan 546 * API. 547 * 548 * For example, this error might be returned when @ref hs_scan() has been 549 * called inside a callback delivered by a currently-executing @ref hs_scan() 550 * call using the same scratch region. 551 * 552 * Note: Not all concurrent uses of scratch regions may be detected. This error 553 * is intended as a best-effort debugging tool, not a guarantee. 554 */ 555 #define HS_SCRATCH_IN_USE (-10) 556 557 /** 558 * Unsupported CPU architecture. 559 * 560 * This error is returned when Hyperscan is able to detect that the current 561 * system does not support the required instruction set. 562 * 563 * At a minimum, Hyperscan requires Supplemental Streaming SIMD Extensions 3 564 * (SSSE3). 565 */ 566 #define HS_ARCH_ERROR (-11) 567 568 /** 569 * Provided buffer was too small. 570 * 571 * This error indicates that there was insufficient space in the buffer. The 572 * call should be repeated with a larger provided buffer. 573 * 574 * Note: in this situation, it is normal for the amount of space required to be 575 * returned in the same manner as the used space would have been returned if the 576 * call was successful. 577 */ 578 #define HS_INSUFFICIENT_SPACE (-12) 579 580 /** 581 * Unexpected internal error. 582 * 583 * This error indicates that there was unexpected matching behaviors. This 584 * could be related to invalid usage of stream and scratch space or invalid memory 585 * operations by users. 586 * 587 */ 588 #define HS_UNKNOWN_ERROR (-13) 589 590 /** @} */ 591 592 #ifdef __cplusplus 593 } /* extern "C" */ 594 #endif 595 596 #endif /* HS_COMMON_H_ */ 597