"Fossies" - the Fresh Open Source Software Archive

Member "honggfuzz-2.2/libhfcommon/util.c" (23 Apr 2020, 23647 Bytes) of package /linux/privat/honggfuzz-2.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "util.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.1_vs_2.2.

    1 /*
    2  *
    3  * honggfuzz - utilities
    4  * -----------------------------------------
    5  *
    6  * Author: Robert Swiecki <swiecki@google.com>
    7  *
    8  * Copyright 2010-2018 by Google Inc. All Rights Reserved.
    9  *
   10  * Licensed under the Apache License, Version 2.0 (the "License"); you may
   11  * not use this file except in compliance with the License. You may obtain
   12  * a copy of the License at
   13  *
   14  * http://www.apache.org/licenses/LICENSE-2.0
   15  *
   16  * Unless required by applicable law or agreed to in writing, software
   17  * distributed under the License is distributed on an "AS IS" BASIS,
   18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
   19  * implied. See the License for the specific language governing
   20  * permissions and limitations under the License.
   21  *
   22  */
   23 
   24 #include "libhfcommon/util.h"
   25 
   26 #include <ctype.h>
   27 #include <errno.h>
   28 #include <fcntl.h>
   29 #include <inttypes.h>
   30 #if !defined(_HF_ARCH_DARWIN) && !defined(__CYGWIN__)
   31 #include <link.h>
   32 #endif /* !defined(_HF_ARCH_DARWIN) && !defined(__CYGWIN__) */
   33 #include <math.h>
   34 #include <pthread.h>
   35 #include <signal.h>
   36 #include <stdarg.h>
   37 #include <stdint.h>
   38 #include <stdio.h>
   39 #include <stdlib.h>
   40 #include <string.h>
   41 #include <sys/mman.h>
   42 #include <sys/stat.h>
   43 #include <sys/time.h>
   44 #include <sys/types.h>
   45 #include <time.h>
   46 #include <unistd.h>
   47 
   48 #include "libhfcommon/common.h"
   49 #include "libhfcommon/files.h"
   50 #include "libhfcommon/log.h"
   51 
   52 void* util_Malloc(size_t sz) {
   53     void* p = malloc(sz);
   54     if (p == NULL) {
   55         LOG_F("malloc(size='%zu')", sz);
   56     }
   57     return p;
   58 }
   59 
   60 void* util_Calloc(size_t sz) {
   61     void* p = util_Malloc(sz);
   62     memset(p, '\0', sz);
   63     return p;
   64 }
   65 
   66 void* util_AllocCopy(const uint8_t* ptr, size_t sz) {
   67     void* p = util_Malloc(sz);
   68     memcpy(p, ptr, sz);
   69     return p;
   70 }
   71 
   72 void* util_Realloc(void* ptr, size_t sz) {
   73     void* ret = realloc(ptr, sz);
   74     if (ret == NULL) {
   75         PLOG_W("realloc(%p, %zu)", ptr, sz);
   76         free(ptr);
   77         return NULL;
   78     }
   79     return ret;
   80 }
   81 
   82 void* util_MMap(size_t sz) {
   83     void* p = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
   84     if (p == MAP_FAILED) {
   85         LOG_F("mmap(size='%zu')", sz);
   86     }
   87     return p;
   88 }
   89 
   90 char* util_StrDup(const char* s) {
   91     char* ret = strdup(s);
   92     if (ret == NULL) {
   93         LOG_F("strdup(size=%zu)", strlen(s));
   94     }
   95     return ret;
   96 }
   97 
   98 static __thread pthread_once_t rndThreadOnce = PTHREAD_ONCE_INIT;
   99 static __thread uint64_t rndState[2];
  100 
  101 static void util_rndInitThread(void) {
  102     int fd = TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY | O_CLOEXEC));
  103     if (fd == -1) {
  104         PLOG_F("Couldn't open /dev/urandom for reading");
  105     }
  106     if (files_readFromFd(fd, (uint8_t*)rndState, sizeof(rndState)) != sizeof(rndState)) {
  107         PLOG_F("Couldn't read '%zu' bytes from /dev/urandom", sizeof(rndState));
  108     }
  109     close(fd);
  110 }
  111 
  112 /*
  113  * xoroshiro128plus by David Blackman and Sebastiano Vigna
  114  */
  115 static inline uint64_t util_RotL(const uint64_t x, int k) {
  116     return (x << k) | (x >> (64 - k));
  117 }
  118 
  119 static inline uint64_t util_InternalRnd64(void) {
  120     const uint64_t s0 = rndState[0];
  121     uint64_t s1 = rndState[1];
  122     const uint64_t result = s0 + s1;
  123     s1 ^= s0;
  124     rndState[0] = util_RotL(s0, 55) ^ s1 ^ (s1 << 14);
  125     rndState[1] = util_RotL(s1, 36);
  126 
  127     return result;
  128 }
  129 
  130 uint64_t util_rnd64(void) {
  131     pthread_once(&rndThreadOnce, util_rndInitThread);
  132     return util_InternalRnd64();
  133 }
  134 
  135 uint64_t util_rndGet(uint64_t min, uint64_t max) {
  136     if (min > max) {
  137         LOG_F("min:%" PRIu64 " > max:%" PRIu64, min, max);
  138     }
  139 
  140     if (max == UINT64_MAX) {
  141         return util_rnd64();
  142     }
  143 
  144     return ((util_rnd64() % (max - min + 1)) + min);
  145 }
  146 
  147 /* Generate random printable ASCII */
  148 uint8_t util_rndPrintable(void) {
  149     return util_rndGet(32, 126);
  150 }
  151 
  152 /* Turn one byte to a printable ASCII */
  153 void util_turnToPrintable(uint8_t* buf, size_t sz) {
  154     for (size_t i = 0; i < sz; i++) {
  155         buf[i] = buf[i] % 95 + 32;
  156     }
  157 }
  158 
  159 void util_rndBufPrintable(uint8_t* buf, size_t sz) {
  160     for (size_t i = 0; i < sz; i++) {
  161         buf[i] = util_rndPrintable();
  162     }
  163 }
  164 
  165 void util_rndBuf(uint8_t* buf, size_t sz) {
  166     pthread_once(&rndThreadOnce, util_rndInitThread);
  167     if (sz == 0) {
  168         return;
  169     }
  170     for (size_t i = 0; i < sz; i++) {
  171         buf[i] = (uint8_t)(util_InternalRnd64() >> 40);
  172     }
  173 }
  174 
  175 int util_vssnprintf(char* str, size_t size, const char* format, va_list ap) {
  176     size_t len = strlen(str);
  177     if (len >= size) {
  178         return len;
  179     }
  180 
  181     size_t left = size - len;
  182     return vsnprintf(&str[len], left, format, ap);
  183 }
  184 
  185 int util_ssnprintf(char* str, size_t size, const char* format, ...) {
  186     va_list args;
  187     va_start(args, format);
  188     int ret = util_vssnprintf(str, size, format, args);
  189     va_end(args);
  190 
  191     return ret;
  192 }
  193 
  194 bool util_strStartsWith(const char* str, const char* tofind) {
  195     if (strncmp(str, tofind, strlen(tofind)) == 0) {
  196         return true;
  197     }
  198     return false;
  199 }
  200 
  201 void util_getLocalTime(const char* fmt, char* buf, size_t len, time_t tm) {
  202     struct tm ltime;
  203     localtime_r(&tm, &ltime);
  204     if (strftime(buf, len, fmt, &ltime) < 1) {
  205         snprintf(buf, len, "[date fetch error]");
  206     }
  207 }
  208 
  209 void util_closeStdio(bool close_stdin, bool close_stdout, bool close_stderr) {
  210     int fd = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR));
  211     if (fd == -1) {
  212         PLOG_E("Couldn't open '/dev/null'");
  213         return;
  214     }
  215 
  216     if (close_stdin) {
  217         TEMP_FAILURE_RETRY(dup2(fd, STDIN_FILENO));
  218     }
  219     if (close_stdout) {
  220         TEMP_FAILURE_RETRY(dup2(fd, STDOUT_FILENO));
  221     }
  222     if (close_stderr) {
  223         TEMP_FAILURE_RETRY(dup2(fd, STDERR_FILENO));
  224     }
  225 
  226     if (fd > STDERR_FILENO) {
  227         close(fd);
  228     }
  229 }
  230 
  231 /*
  232  * This is not a cryptographically secure hash
  233  */
  234 uint64_t util_hash(const char* buf, size_t len) {
  235     uint64_t ret = 0;
  236 
  237     for (size_t i = 0; i < len; i++) {
  238         ret += buf[i];
  239         ret += (ret << 10);
  240         ret ^= (ret >> 6);
  241     }
  242 
  243     return ret;
  244 }
  245 
  246 int64_t util_timeNowUSecs(void) {
  247     struct timeval tv;
  248     if (gettimeofday(&tv, NULL) == -1) {
  249         PLOG_F("gettimeofday()");
  250     }
  251 
  252     return (((int64_t)tv.tv_sec * 1000000) + (int64_t)tv.tv_usec);
  253 }
  254 
  255 void util_sleepForMSec(uint64_t msec) {
  256     if (msec == 0) {
  257         return;
  258     }
  259     struct timespec ts = {
  260         .tv_sec = msec / 1000U,
  261         .tv_nsec = (msec % 1000U) * 1000000U,
  262     };
  263     TEMP_FAILURE_RETRY(nanosleep(&ts, &ts));
  264 }
  265 
  266 uint64_t util_getUINT32(const uint8_t* buf) {
  267     uint32_t r;
  268     memcpy(&r, buf, sizeof(r));
  269     return (uint64_t)r;
  270 }
  271 
  272 uint64_t util_getUINT64(const uint8_t* buf) {
  273     uint64_t r;
  274     memcpy(&r, buf, sizeof(r));
  275     return r;
  276 }
  277 
  278 void util_mutexLock(pthread_mutex_t* mutex, const char* func, int line) {
  279     if (pthread_mutex_lock(mutex)) {
  280         PLOG_F("%s():%d pthread_mutex_lock(%p)", func, line, (void*)mutex);
  281     }
  282 }
  283 
  284 void util_mutexUnlock(pthread_mutex_t* mutex, const char* func, int line) {
  285     if (pthread_mutex_unlock(mutex)) {
  286         PLOG_F("%s():%d pthread_mutex_unlock(%p)", func, line, (void*)mutex);
  287     }
  288 }
  289 
  290 void util_mutexRWLockRead(pthread_rwlock_t* mutex, const char* func, int line) {
  291     if (pthread_rwlock_rdlock(mutex)) {
  292         PLOG_F("%s():%d pthread_rwlock_rdlock(%p)", func, line, (void*)mutex);
  293     }
  294 }
  295 
  296 void util_mutexRWLockWrite(pthread_rwlock_t* mutex, const char* func, int line) {
  297     if (pthread_rwlock_wrlock(mutex)) {
  298         PLOG_F("%s():%d pthread_rwlock_wrlock(%p)", func, line, (void*)mutex);
  299     }
  300 }
  301 
  302 void util_mutexRWUnlock(pthread_rwlock_t* mutex, const char* func, int line) {
  303     if (pthread_rwlock_unlock(mutex)) {
  304         PLOG_F("%s():%d pthread_rwlock_unlock(%p)", func, line, (void*)mutex);
  305     }
  306 }
  307 
  308 int64_t fastArray64Search(uint64_t* array, size_t arraySz, uint64_t key) {
  309     size_t low = 0;
  310     size_t high = arraySz - 1;
  311     size_t mid;
  312 
  313     while (array[high] != array[low] && key >= array[low] && key <= array[high]) {
  314         mid = low + (key - array[low]) * ((high - low) / (array[high] - array[low]));
  315 
  316         if (array[mid] < key) {
  317             low = mid + 1;
  318         } else if (key < array[mid]) {
  319             high = mid - 1;
  320         } else {
  321             return mid;
  322         }
  323     }
  324 
  325     if (key == array[low]) {
  326         return low;
  327     } else {
  328         return -1;
  329     }
  330 }
  331 
  332 bool util_isANumber(const char* s) {
  333     if (!isdigit((unsigned char)s[0])) {
  334         return false;
  335     }
  336     for (int i = 0; s[i]; s++) {
  337         if (!isdigit((unsigned char)s[i]) && s[i] != 'x') {
  338             return false;
  339         }
  340     }
  341     return true;
  342 }
  343 
  344 size_t util_decodeCString(char* s) {
  345     size_t o = 0;
  346     for (size_t i = 0; s[i] != '\0' && s[i] != '"'; i++, o++) {
  347         switch (s[i]) {
  348             case '\\': {
  349                 i++;
  350                 if (!s[i]) {
  351                     continue;
  352                 }
  353                 switch (s[i]) {
  354                     case 'a':
  355                         s[o] = '\a';
  356                         break;
  357                     case 'r':
  358                         s[o] = '\r';
  359                         break;
  360                     case 'n':
  361                         s[o] = '\n';
  362                         break;
  363                     case 't':
  364                         s[o] = '\t';
  365                         break;
  366                     case '0':
  367                         s[o] = '\0';
  368                         break;
  369                     case 'x': {
  370                         if (s[i + 1] && s[i + 2]) {
  371                             char hex[] = {s[i + 1], s[i + 2], 0};
  372                             s[o] = strtoul(hex, NULL, 16);
  373                             i += 2;
  374                         } else {
  375                             s[o] = s[i];
  376                         }
  377                         break;
  378                     }
  379                     default:
  380                         s[o] = s[i];
  381                         break;
  382                 }
  383                 break;
  384             }
  385             default: {
  386                 s[o] = s[i];
  387                 break;
  388             }
  389         }
  390     }
  391     s[o] = '\0';
  392     return o;
  393 }
  394 
  395 /* ISO 3309 CRC-64 Poly table */
  396 static const uint64_t util_CRC64ISOPoly[] = {
  397     0x0000000000000000ULL,
  398     0x01B0000000000000ULL,
  399     0x0360000000000000ULL,
  400     0x02D0000000000000ULL,
  401     0x06C0000000000000ULL,
  402     0x0770000000000000ULL,
  403     0x05A0000000000000ULL,
  404     0x0410000000000000ULL,
  405     0x0D80000000000000ULL,
  406     0x0C30000000000000ULL,
  407     0x0EE0000000000000ULL,
  408     0x0F50000000000000ULL,
  409     0x0B40000000000000ULL,
  410     0x0AF0000000000000ULL,
  411     0x0820000000000000ULL,
  412     0x0990000000000000ULL,
  413     0x1B00000000000000ULL,
  414     0x1AB0000000000000ULL,
  415     0x1860000000000000ULL,
  416     0x19D0000000000000ULL,
  417     0x1DC0000000000000ULL,
  418     0x1C70000000000000ULL,
  419     0x1EA0000000000000ULL,
  420     0x1F10000000000000ULL,
  421     0x1680000000000000ULL,
  422     0x1730000000000000ULL,
  423     0x15E0000000000000ULL,
  424     0x1450000000000000ULL,
  425     0x1040000000000000ULL,
  426     0x11F0000000000000ULL,
  427     0x1320000000000000ULL,
  428     0x1290000000000000ULL,
  429     0x3600000000000000ULL,
  430     0x37B0000000000000ULL,
  431     0x3560000000000000ULL,
  432     0x34D0000000000000ULL,
  433     0x30C0000000000000ULL,
  434     0x3170000000000000ULL,
  435     0x33A0000000000000ULL,
  436     0x3210000000000000ULL,
  437     0x3B80000000000000ULL,
  438     0x3A30000000000000ULL,
  439     0x38E0000000000000ULL,
  440     0x3950000000000000ULL,
  441     0x3D40000000000000ULL,
  442     0x3CF0000000000000ULL,
  443     0x3E20000000000000ULL,
  444     0x3F90000000000000ULL,
  445     0x2D00000000000000ULL,
  446     0x2CB0000000000000ULL,
  447     0x2E60000000000000ULL,
  448     0x2FD0000000000000ULL,
  449     0x2BC0000000000000ULL,
  450     0x2A70000000000000ULL,
  451     0x28A0000000000000ULL,
  452     0x2910000000000000ULL,
  453     0x2080000000000000ULL,
  454     0x2130000000000000ULL,
  455     0x23E0000000000000ULL,
  456     0x2250000000000000ULL,
  457     0x2640000000000000ULL,
  458     0x27F0000000000000ULL,
  459     0x2520000000000000ULL,
  460     0x2490000000000000ULL,
  461     0x6C00000000000000ULL,
  462     0x6DB0000000000000ULL,
  463     0x6F60000000000000ULL,
  464     0x6ED0000000000000ULL,
  465     0x6AC0000000000000ULL,
  466     0x6B70000000000000ULL,
  467     0x69A0000000000000ULL,
  468     0x6810000000000000ULL,
  469     0x6180000000000000ULL,
  470     0x6030000000000000ULL,
  471     0x62E0000000000000ULL,
  472     0x6350000000000000ULL,
  473     0x6740000000000000ULL,
  474     0x66F0000000000000ULL,
  475     0x6420000000000000ULL,
  476     0x6590000000000000ULL,
  477     0x7700000000000000ULL,
  478     0x76B0000000000000ULL,
  479     0x7460000000000000ULL,
  480     0x75D0000000000000ULL,
  481     0x71C0000000000000ULL,
  482     0x7070000000000000ULL,
  483     0x72A0000000000000ULL,
  484     0x7310000000000000ULL,
  485     0x7A80000000000000ULL,
  486     0x7B30000000000000ULL,
  487     0x79E0000000000000ULL,
  488     0x7850000000000000ULL,
  489     0x7C40000000000000ULL,
  490     0x7DF0000000000000ULL,
  491     0x7F20000000000000ULL,
  492     0x7E90000000000000ULL,
  493     0x5A00000000000000ULL,
  494     0x5BB0000000000000ULL,
  495     0x5960000000000000ULL,
  496     0x58D0000000000000ULL,
  497     0x5CC0000000000000ULL,
  498     0x5D70000000000000ULL,
  499     0x5FA0000000000000ULL,
  500     0x5E10000000000000ULL,
  501     0x5780000000000000ULL,
  502     0x5630000000000000ULL,
  503     0x54E0000000000000ULL,
  504     0x5550000000000000ULL,
  505     0x5140000000000000ULL,
  506     0x50F0000000000000ULL,
  507     0x5220000000000000ULL,
  508     0x5390000000000000ULL,
  509     0x4100000000000000ULL,
  510     0x40B0000000000000ULL,
  511     0x4260000000000000ULL,
  512     0x43D0000000000000ULL,
  513     0x47C0000000000000ULL,
  514     0x4670000000000000ULL,
  515     0x44A0000000000000ULL,
  516     0x4510000000000000ULL,
  517     0x4C80000000000000ULL,
  518     0x4D30000000000000ULL,
  519     0x4FE0000000000000ULL,
  520     0x4E50000000000000ULL,
  521     0x4A40000000000000ULL,
  522     0x4BF0000000000000ULL,
  523     0x4920000000000000ULL,
  524     0x4890000000000000ULL,
  525     0xD800000000000000ULL,
  526     0xD9B0000000000000ULL,
  527     0xDB60000000000000ULL,
  528     0xDAD0000000000000ULL,
  529     0xDEC0000000000000ULL,
  530     0xDF70000000000000ULL,
  531     0xDDA0000000000000ULL,
  532     0xDC10000000000000ULL,
  533     0xD580000000000000ULL,
  534     0xD430000000000000ULL,
  535     0xD6E0000000000000ULL,
  536     0xD750000000000000ULL,
  537     0xD340000000000000ULL,
  538     0xD2F0000000000000ULL,
  539     0xD020000000000000ULL,
  540     0xD190000000000000ULL,
  541     0xC300000000000000ULL,
  542     0xC2B0000000000000ULL,
  543     0xC060000000000000ULL,
  544     0xC1D0000000000000ULL,
  545     0xC5C0000000000000ULL,
  546     0xC470000000000000ULL,
  547     0xC6A0000000000000ULL,
  548     0xC710000000000000ULL,
  549     0xCE80000000000000ULL,
  550     0xCF30000000000000ULL,
  551     0xCDE0000000000000ULL,
  552     0xCC50000000000000ULL,
  553     0xC840000000000000ULL,
  554     0xC9F0000000000000ULL,
  555     0xCB20000000000000ULL,
  556     0xCA90000000000000ULL,
  557     0xEE00000000000000ULL,
  558     0xEFB0000000000000ULL,
  559     0xED60000000000000ULL,
  560     0xECD0000000000000ULL,
  561     0xE8C0000000000000ULL,
  562     0xE970000000000000ULL,
  563     0xEBA0000000000000ULL,
  564     0xEA10000000000000ULL,
  565     0xE380000000000000ULL,
  566     0xE230000000000000ULL,
  567     0xE0E0000000000000ULL,
  568     0xE150000000000000ULL,
  569     0xE540000000000000ULL,
  570     0xE4F0000000000000ULL,
  571     0xE620000000000000ULL,
  572     0xE790000000000000ULL,
  573     0xF500000000000000ULL,
  574     0xF4B0000000000000ULL,
  575     0xF660000000000000ULL,
  576     0xF7D0000000000000ULL,
  577     0xF3C0000000000000ULL,
  578     0xF270000000000000ULL,
  579     0xF0A0000000000000ULL,
  580     0xF110000000000000ULL,
  581     0xF880000000000000ULL,
  582     0xF930000000000000ULL,
  583     0xFBE0000000000000ULL,
  584     0xFA50000000000000ULL,
  585     0xFE40000000000000ULL,
  586     0xFFF0000000000000ULL,
  587     0xFD20000000000000ULL,
  588     0xFC90000000000000ULL,
  589     0xB400000000000000ULL,
  590     0xB5B0000000000000ULL,
  591     0xB760000000000000ULL,
  592     0xB6D0000000000000ULL,
  593     0xB2C0000000000000ULL,
  594     0xB370000000000000ULL,
  595     0xB1A0000000000000ULL,
  596     0xB010000000000000ULL,
  597     0xB980000000000000ULL,
  598     0xB830000000000000ULL,
  599     0xBAE0000000000000ULL,
  600     0xBB50000000000000ULL,
  601     0xBF40000000000000ULL,
  602     0xBEF0000000000000ULL,
  603     0xBC20000000000000ULL,
  604     0xBD90000000000000ULL,
  605     0xAF00000000000000ULL,
  606     0xAEB0000000000000ULL,
  607     0xAC60000000000000ULL,
  608     0xADD0000000000000ULL,
  609     0xA9C0000000000000ULL,
  610     0xA870000000000000ULL,
  611     0xAAA0000000000000ULL,
  612     0xAB10000000000000ULL,
  613     0xA280000000000000ULL,
  614     0xA330000000000000ULL,
  615     0xA1E0000000000000ULL,
  616     0xA050000000000000ULL,
  617     0xA440000000000000ULL,
  618     0xA5F0000000000000ULL,
  619     0xA720000000000000ULL,
  620     0xA690000000000000ULL,
  621     0x8200000000000000ULL,
  622     0x83B0000000000000ULL,
  623     0x8160000000000000ULL,
  624     0x80D0000000000000ULL,
  625     0x84C0000000000000ULL,
  626     0x8570000000000000ULL,
  627     0x87A0000000000000ULL,
  628     0x8610000000000000ULL,
  629     0x8F80000000000000ULL,
  630     0x8E30000000000000ULL,
  631     0x8CE0000000000000ULL,
  632     0x8D50000000000000ULL,
  633     0x8940000000000000ULL,
  634     0x88F0000000000000ULL,
  635     0x8A20000000000000ULL,
  636     0x8B90000000000000ULL,
  637     0x9900000000000000ULL,
  638     0x98B0000000000000ULL,
  639     0x9A60000000000000ULL,
  640     0x9BD0000000000000ULL,
  641     0x9FC0000000000000ULL,
  642     0x9E70000000000000ULL,
  643     0x9CA0000000000000ULL,
  644     0x9D10000000000000ULL,
  645     0x9480000000000000ULL,
  646     0x9530000000000000ULL,
  647     0x97E0000000000000ULL,
  648     0x9650000000000000ULL,
  649     0x9240000000000000ULL,
  650     0x93F0000000000000ULL,
  651     0x9120000000000000ULL,
  652     0x9090000000000000ULL,
  653 };
  654 
  655 uint64_t util_CRC64(const uint8_t* buf, size_t len) {
  656     uint64_t res = 0ULL;
  657 
  658     for (size_t i = 0; i < len; i++) {
  659         res = util_CRC64ISOPoly[(uint8_t)res ^ buf[i]] ^ (res >> 8);
  660     }
  661 
  662     return res;
  663 }
  664 
  665 uint64_t util_CRC64Rev(const uint8_t* buf, size_t len) {
  666     uint64_t res = 0ULL;
  667 
  668     for (ssize_t i = (ssize_t)len - 1; i >= 0; i--) {
  669         res = util_CRC64ISOPoly[(uint8_t)res ^ buf[i]] ^ (res >> 8);
  670     }
  671 
  672     return res;
  673 }
  674 
  675 static const struct {
  676     const int signo;
  677     const char* const signame;
  678 } sigNames[] = {
  679 #if defined(SIGHUP)
  680     {SIGHUP, "SIGHUP"},
  681 #endif
  682 #if defined(SIGINT)
  683     {SIGINT, "SIGINT"},
  684 #endif
  685 #if defined(SIGQUIT)
  686     {SIGQUIT, "SIGQUIT"},
  687 #endif
  688 #if defined(SIGILL)
  689     {SIGILL, "SIGILL"},
  690 #endif
  691 #if defined(SIGTRAP)
  692     {SIGTRAP, "SIGTRAP"},
  693 #endif
  694 #if defined(SIGABRT)
  695     {SIGABRT, "SIGABRT"},
  696 #endif
  697 #if defined(SIGIOT)
  698     {SIGIOT, "SIGIOT"},
  699 #endif
  700 #if defined(SIGBUS)
  701     {SIGBUS, "SIGBUS"},
  702 #endif
  703 #if defined(SIGFPE)
  704     {SIGFPE, "SIGFPE"},
  705 #endif
  706 #if defined(SIGKILL)
  707     {SIGKILL, "SIGKILL"},
  708 #endif
  709 #if defined(SIGUSR1)
  710     {SIGUSR1, "SIGUSR1"},
  711 #endif
  712 #if defined(SIGSEGV)
  713     {SIGSEGV, "SIGSEGV"},
  714 #endif
  715 #if defined(SIGUSR2)
  716     {SIGUSR2, "SIGUSR2"},
  717 #endif
  718 #if defined(SIGPIPE)
  719     {SIGPIPE, "SIGPIPE"},
  720 #endif
  721 #if defined(SIGALRM)
  722     {SIGALRM, "SIGALRM"},
  723 #endif
  724 #if defined(SIGTERM)
  725     {SIGTERM, "SIGTERM"},
  726 #endif
  727 #if defined(SIGSTKFLT)
  728     {SIGSTKFLT, "SIGSTKFLT"},
  729 #endif
  730 #if defined(SIGCHLD)
  731     {SIGCHLD, "SIGCHLD"},
  732 #endif
  733 #if defined(SIGCONT)
  734     {SIGCONT, "SIGCONT"},
  735 #endif
  736 #if defined(SIGSTOP)
  737     {SIGSTOP, "SIGSTOP"},
  738 #endif
  739 #if defined(SIGTSTP)
  740     {SIGTSTP, "SIGTSTP"},
  741 #endif
  742 #if defined(SIGTTIN)
  743     {SIGTTIN, "SIGTTIN"},
  744 #endif
  745 #if defined(SIGTTOU)
  746     {SIGTTOU, "SIGTTOU"},
  747 #endif
  748 #if defined(SIGURG)
  749     {SIGURG, "SIGURG"},
  750 #endif
  751 #if defined(SIGXCPU)
  752     {SIGXCPU, "SIGXCPU"},
  753 #endif
  754 #if defined(SIGXFSZ)
  755     {SIGXFSZ, "SIGXFSZ"},
  756 #endif
  757 #if defined(SIGVTALRM)
  758     {SIGVTALRM, "SIGVTALRM"},
  759 #endif
  760 #if defined(SIGPROF)
  761     {SIGPROF, "SIGPROF"},
  762 #endif
  763 #if defined(SIGWINCH)
  764     {SIGWINCH, "SIGWINCH"},
  765 #endif
  766 #if defined(SIGIO)
  767     {SIGIO, "SIGIO"},
  768 #endif
  769 #if defined(SIGPOLL)
  770     {SIGPOLL, "SIGPOLL"},
  771 #endif
  772 #if defined(SIGLOST)
  773     {SIGLOST, "SIGLOST"},
  774 #endif
  775 #if defined(SIGPWR)
  776     {SIGPWR, "SIGPWR"},
  777 #endif
  778 #if defined(SIGSYS)
  779     {SIGSYS, "SIGSYS"},
  780 #endif
  781 #if defined(SIGTHR)
  782     {SIGTHR, "SIGTHR"},
  783 #endif
  784 #if defined(SIGEMT)
  785     {SIGEMT, "SIGEMT"},
  786 #endif
  787 #if defined(SIGINFO)
  788     {SIGINFO, "SIGINFO"},
  789 #endif
  790 #if defined(SIGLIBRT)
  791     {SIGLIBRT, "SIGLIBRT"},
  792 #endif
  793 };
  794 
  795 const char* util_sigName(int signo) {
  796     static __thread char signame[32];
  797     for (size_t i = 0; i < ARRAYSIZE(sigNames); i++) {
  798         if (signo == sigNames[i].signo) {
  799             return sigNames[i].signame;
  800         }
  801     }
  802 #if defined(SIGRTMIN) && defined(SIGRTMAX)
  803     if (signo >= SIGRTMIN && signo <= SIGRTMAX) {
  804         snprintf(signame, sizeof(signame), "SIG%d-RTMIN+%d", signo, signo - SIGRTMIN);
  805         return signame;
  806     }
  807 #endif /* defined(SIGRTMIN) && defined(SIGRTMAX) */
  808     snprintf(signame, sizeof(signame), "UNKNOWN-%d", signo);
  809     return signame;
  810 }
  811 
  812 #if !defined(_HF_ARCH_DARWIN) && !defined(__CYGWIN__)
  813 static int addrStatic_cb(struct dl_phdr_info* info, size_t size HF_ATTR_UNUSED, void* data) {
  814     for (size_t i = 0; i < info->dlpi_phnum; i++) {
  815         if (info->dlpi_phdr[i].p_type != PT_LOAD) {
  816             continue;
  817         }
  818         uintptr_t addr_start = info->dlpi_addr + info->dlpi_phdr[i].p_vaddr;
  819         uintptr_t addr_end =
  820             addr_start + HF_MIN(info->dlpi_phdr[i].p_memsz, info->dlpi_phdr[i].p_filesz);
  821         if (((uintptr_t)data >= addr_start) && ((uintptr_t)data < addr_end)) {
  822             if ((info->dlpi_phdr[i].p_flags & PF_W) == 0) {
  823                 return LHFC_ADDR_RO;
  824             } else {
  825                 return LHFC_ADDR_RW;
  826             }
  827         }
  828     }
  829     return LHFC_ADDR_NOTFOUND;
  830 }
  831 
  832 lhfc_addr_t util_getProgAddr(const void* addr) {
  833     return (lhfc_addr_t)dl_iterate_phdr(addrStatic_cb, (void*)addr);
  834 }
  835 
  836 static int check32_cb(struct dl_phdr_info* info, size_t size HF_ATTR_UNUSED, void* data) {
  837     uint32_t v = *(uint32_t*)data;
  838 
  839     for (size_t i = 0; i < info->dlpi_phnum; i++) {
  840         /* Look only in the actual binary, and not in libraries */
  841         if (info->dlpi_name[0] != '\0') {
  842             continue;
  843         }
  844         if (info->dlpi_phdr[i].p_type != PT_LOAD) {
  845             continue;
  846         }
  847         if (!(info->dlpi_phdr[i].p_flags & PF_R)) {
  848             continue;
  849         }
  850         uint32_t* start = (uint32_t*)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
  851         uint32_t* end =
  852             (uint32_t*)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr +
  853                         HF_MIN(info->dlpi_phdr[i].p_memsz, info->dlpi_phdr[i].p_filesz));
  854         /* Assume that the 32bit value looked for is also 32bit aligned */
  855         for (; start < end; start++) {
  856             if (*start == v) {
  857                 return 1;
  858             }
  859         }
  860     }
  861     return 0;
  862 }
  863 
  864 bool util_32bitValInBinary(uint32_t v) {
  865     return (dl_iterate_phdr(check32_cb, &v) == 1);
  866 }
  867 
  868 static int check64_cb(struct dl_phdr_info* info, size_t size HF_ATTR_UNUSED, void* data) {
  869     uint64_t v = *(uint64_t*)data;
  870 
  871     for (size_t i = 0; i < info->dlpi_phnum; i++) {
  872         /* Look only in the actual binary, and not in libraries */
  873         if (info->dlpi_name[0] != '\0') {
  874             continue;
  875         }
  876         if (info->dlpi_phdr[i].p_type != PT_LOAD) {
  877             continue;
  878         }
  879         if (!(info->dlpi_phdr[i].p_flags & PF_R)) {
  880             continue;
  881         }
  882         uint64_t* start = (uint64_t*)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
  883         uint64_t* end =
  884             (uint64_t*)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr +
  885                         HF_MIN(info->dlpi_phdr[i].p_memsz, info->dlpi_phdr[i].p_filesz));
  886         /* Assume that the 64bit value looked for is also 64bit aligned */
  887         for (; start < end; start++) {
  888             if (*start == v) {
  889                 return 1;
  890             }
  891         }
  892     }
  893     return 0;
  894 }
  895 
  896 bool util_64bitValInBinary(uint32_t v) {
  897     return (dl_iterate_phdr(check64_cb, &v) == 1);
  898 }
  899 #else  /* !defined(_HF_ARCH_DARWIN) && !defined(__CYGWIN__) */
  900 /* Darwin doesn't use ELF file format for binaries, so dl_iterate_phdr() cannot be used there */
  901 lhfc_addr_t util_getProgAddr(const void* addr HF_ATTR_UNUSED) {
  902     return LHFC_ADDR_NOTFOUND;
  903 }
  904 bool util_32bitValInBinary(uint32_t v HF_ATTR_UNUSED) {
  905     return false;
  906 }
  907 bool util_64bitValInBinary(uint32_t v HF_ATTR_UNUSED) {
  908     return false;
  909 }
  910 #endif /* !defined(_HF_ARCH_DARWIN) && !defined(__CYGWIN__) */