blob: e073795e43a4a9303199efbeee2bcfb6fdb3028c [file] [log] [blame]
robert.swiecki3bb518c2010-10-14 00:48:24 +00001/*
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00002 *
robert.swiecki@gmail.com97c77332015-02-14 23:06:58 +00003 * honggfuzz - utilities
4 * -----------------------------------------
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00005 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +00006 * Author: Robert Swiecki <swiecki@google.com>
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00007 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +00008 * Copyright 2010-2015 by Google Inc. All Rights Reserved.
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +00009 *
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
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000012 * a copy of the License at
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000013 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000014 * http://www.apache.org/licenses/LICENSE-2.0
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000015 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000016 * 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.
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +000021 *
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +000022 */
robert.swiecki3bb518c2010-10-14 00:48:24 +000023
robert.swiecki3bb518c2010-10-14 00:48:24 +000024#include <fcntl.h>
Robert Swieckic8c32db2015-10-09 18:06:22 +020025#include <inttypes.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000026#include <math.h>
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000027#include <stdarg.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000028#include <stdint.h>
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000029#include <stdio.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000030#include <stdlib.h>
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000031#include <string.h>
Robert Swieckiac56a502016-03-17 18:59:46 +010032#include <sys/mman.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000033#include <sys/stat.h>
34#include <sys/time.h>
35#include <sys/types.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000036#include <time.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000037#include <unistd.h>
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +020038#include <ctype.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000039
40#include "common.h"
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000041#include "files.h"
robert.swiecki3bb518c2010-10-14 00:48:24 +000042#include "log.h"
43
Robert Swiecki3bfc33c2016-03-14 18:12:41 +010044void *util_Malloc(size_t sz)
45{
46 void *p = malloc(sz);
47 if (p == NULL) {
48 LOG_F("malloc(size='%zu')", sz);
49 }
50 return p;
51}
52
Robert Swieckiac56a502016-03-17 18:59:46 +010053void *util_Calloc(size_t sz)
54{
55 void *p = util_Malloc(sz);
56 memset(p, '\0', sz);
57 return p;
58}
59
60void *util_MMap(size_t sz)
61{
62 void *p = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
63 if (p == MAP_FAILED) {
64 LOG_F("mmap(size='%zu')", sz);
65 }
66 return p;
67}
68
Jagger6539b3a2016-04-06 02:32:50 +020069char *util_StrDup(const char *s)
70{
71 char *ret = strdup(s);
72 if (ret == NULL) {
73 LOG_F("strdup(size=%zu)", strlen(s));
74 }
75 return ret;
76}
77
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000078static int util_urandomFd = -1;
Jagger2e518b52015-09-24 04:01:16 +020079static __thread uint64_t rndX;
80static __thread uint64_t rndIni = false;
robert.swiecki@gmail.com180263f2015-02-13 13:57:15 +000081
robert.swiecki@gmail.com90e99112015-02-15 02:05:14 +000082uint64_t util_rndGet(uint64_t min, uint64_t max)
robert.swiecki3bb518c2010-10-14 00:48:24 +000083{
Jagger2e518b52015-09-24 04:01:16 +020084 if (min > max) {
Anestis Bechtsoudis07e14ce2015-12-30 14:15:42 +020085 LOG_F("min:%" PRIu64 " > max:%" PRIu64, min, max);
Jagger2e518b52015-09-24 04:01:16 +020086 }
87
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000088 if (util_urandomFd == -1) {
Jagger5a3c4c32016-04-16 19:27:47 +020089 if ((util_urandomFd = open("/dev/urandom", O_RDONLY | O_CLOEXEC)) == -1) {
Robert Swieckic8c32db2015-10-09 18:06:22 +020090 PLOG_F("Couldn't open /dev/urandom for writing");
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000091 }
robert.swiecki@gmail.com180263f2015-02-13 13:57:15 +000092 }
robert.swiecki3bb518c2010-10-14 00:48:24 +000093
Jagger2e518b52015-09-24 04:01:16 +020094 if (rndIni == false) {
Jagger4d109852016-02-04 02:28:44 +010095 if (files_readFromFd(util_urandomFd, (uint8_t *) & rndX, sizeof(rndX)) != sizeof(rndX)) {
Robert Swieckic8c32db2015-10-09 18:06:22 +020096 PLOG_F("Couldn't read '%zu' bytes from /dev/urandom", sizeof(rndX));
Jagger2e518b52015-09-24 04:01:16 +020097 }
98 rndIni = true;
robert.swiecki@gmail.com4be12dc2015-02-13 14:03:53 +000099 }
robert.swiecki@gmail.com180263f2015-02-13 13:57:15 +0000100
Jagger2e518b52015-09-24 04:01:16 +0200101 /* MMIX LCG PRNG */
102 static const uint64_t a = 6364136223846793005ULL;
103 static const uint64_t c = 1442695040888963407ULL;
robert.swiecki@gmail.combce825a2015-02-13 23:26:07 +0000104
Jagger2e518b52015-09-24 04:01:16 +0200105 rndX = (a * rndX + c);
106
107 return ((rndX % (max - min + 1)) + min);
robert.swiecki3bb518c2010-10-14 00:48:24 +0000108}
109
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +0000110void util_rndBuf(uint8_t * buf, size_t sz)
111{
robert.swiecki@gmail.comace40862015-03-08 07:09:56 +0000112 /* MMIX LCG PRNG */
Jagger89085f92015-09-24 04:45:53 +0200113 static const uint64_t a = 6364136223846793005ULL;
114 static const uint64_t c = 1442695040888963407ULL;
115 uint64_t x = util_rndGet(0, 1ULL << 62);
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +0000116
robert.swiecki@gmail.com08174c72015-02-28 14:38:06 +0000117 for (size_t i = 0; i < sz; i++) {
robert.swiecki@gmail.comace40862015-03-08 07:09:56 +0000118 x = (a * x + c);
Robert Swiecki2ec203d2016-03-17 19:14:04 +0100119 buf[i] = (uint8_t) ((x & 0xFF0000) > 16);
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +0000120 }
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +0000121}
122
Robert Swiecki23ec02a2016-01-19 18:47:45 +0100123/*
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200124 * Function has variable length stack size, although already we know it's invoked
125 * with relatively small sizes (max is _HF_REPORT_SIZE), thus safe to silent warning.
126 */
127#pragma GCC diagnostic push
Anestis Bechtsoudis539dbc52015-12-26 20:11:46 +0200128#pragma GCC diagnostic ignored "-Wframe-larger-than="
robert.swiecki@gmail.com9e2d43d2015-02-16 12:17:39 +0000129int util_vssnprintf(char *str, size_t size, const char *format, va_list ap)
130{
131 char buf1[size];
132 char buf2[size];
133
134 strncpy(buf1, str, size);
135
136 vsnprintf(buf2, size, format, ap);
137
138 return snprintf(str, size, "%s%s", buf1, buf2);
139}
140
141int util_ssnprintf(char *str, size_t size, const char *format, ...)
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +0000142{
143 char buf1[size];
144 char buf2[size];
145
146 strncpy(buf1, str, size);
147
148 va_list args;
149 va_start(args, format);
150 vsnprintf(buf2, size, format, args);
151 va_end(args);
152
robert.swiecki@gmail.com9e2d43d2015-02-16 12:17:39 +0000153 return snprintf(str, size, "%s%s", buf1, buf2);
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +0000154}
155
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200156#pragma GCC diagnostic pop /* EOF diagnostic ignored "-Wstack-usage=" */
157
Robert Swiecki81c6a0d2015-09-08 15:43:20 +0200158void util_getLocalTime(const char *fmt, char *buf, size_t len, time_t tm)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000159{
160 struct tm ltime;
Robert Swiecki81c6a0d2015-09-08 15:43:20 +0200161 localtime_r(&tm, &ltime);
162 if (strftime(buf, len, fmt, &ltime) < 1) {
163 snprintf(buf, len, "[date fetch error]");
164 }
robert.swiecki3bb518c2010-10-14 00:48:24 +0000165}
166
robert.swiecki40499ff2010-12-13 19:47:08 +0000167void util_nullifyStdio(void)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000168{
169 int fd = open("/dev/null", O_RDWR);
170
171 if (fd == -1) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200172 PLOG_E("Couldn't open '/dev/null'");
robert.swiecki3bb518c2010-10-14 00:48:24 +0000173 return;
174 }
175
176 dup2(fd, 0);
177 dup2(fd, 1);
178 dup2(fd, 2);
179
180 if (fd > 2) {
181 close(fd);
182 }
robert.swiecki3bb518c2010-10-14 00:48:24 +0000183}
184
Robert Swiecki1e1b3532016-03-10 18:43:28 +0100185bool util_redirectStdin(const char *inputFile)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000186{
187 int fd = open(inputFile, O_RDONLY);
188
189 if (fd == -1) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200190 PLOG_E("Couldn't open '%s'", inputFile);
robert.swiecki3bb518c2010-10-14 00:48:24 +0000191 return false;
192 }
193
194 dup2(fd, 0);
195 if (fd != 0) {
196 close(fd);
197 }
198
199 return true;
200}
201
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000202/*
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +0000203 * This is not a cryptographically secure hash
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000204 */
Anestis Bechtsoudis38572552016-02-07 12:55:55 +0200205uint64_t util_hash(const char *buf, size_t len)
groebert@google.com1bd4c212013-06-19 11:13:56 +0000206{
207 uint64_t ret = 0;
208
209 for (size_t i = 0; i < len; i++) {
210 ret += buf[i];
211 ret += (ret << 10);
212 ret ^= (ret >> 6);
213 }
214
215 return ret;
216}
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000217
Anestis Bechtsoudis38572552016-02-07 12:55:55 +0200218int64_t util_timeNowMillis(void)
robert.swiecki@gmail.com3213a112015-03-12 01:42:02 +0000219{
220 struct timeval tv;
221 if (gettimeofday(&tv, NULL) == -1) {
Robert Swieckic8c32db2015-10-09 18:06:22 +0200222 PLOG_F("gettimeofday()");
robert.swiecki@gmail.com3213a112015-03-12 01:42:02 +0000223 }
224
225 return (((int64_t) tv.tv_sec * 1000LL) + ((int64_t) tv.tv_usec / 1000LL));
226}
227
Anestis Bechtsoudis38572552016-02-07 12:55:55 +0200228uint64_t util_getUINT32(const uint8_t * buf)
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200229{
Jagger26569d92016-03-17 02:22:15 +0100230 uint32_t r;
Jaggerc54b8932016-03-17 03:12:06 +0100231 memcpy(&r, buf, sizeof(r));
Jagger26569d92016-03-17 02:22:15 +0100232 return (uint64_t) r;
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200233}
234
Anestis Bechtsoudis38572552016-02-07 12:55:55 +0200235uint64_t util_getUINT64(const uint8_t * buf)
Anestis Bechtsoudisbe0ac7b2015-12-26 15:38:47 +0200236{
Jagger26569d92016-03-17 02:22:15 +0100237 uint64_t r;
Jaggerc54b8932016-03-17 03:12:06 +0100238 memcpy(&r, buf, sizeof(r));
Jagger26569d92016-03-17 02:22:15 +0100239 return r;
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000240}
Jagger421aca82015-09-05 14:09:47 +0200241
Jagger6caced32016-03-10 21:42:23 +0100242void util_mutexLock(pthread_mutex_t * mutex, const char *func, int line)
Jagger421aca82015-09-05 14:09:47 +0200243{
244 if (pthread_mutex_lock(mutex)) {
Anestis Bechtsoudis5a401c42016-04-22 07:50:19 +0300245 PLOG_F("%s():%d pthread_mutex_lock(%p)", func, line, (void *)mutex);
Jagger421aca82015-09-05 14:09:47 +0200246 }
247}
248
Jagger6caced32016-03-10 21:42:23 +0100249void util_mutexUnlock(pthread_mutex_t * mutex, const char *func, int line)
Jagger421aca82015-09-05 14:09:47 +0200250{
251 if (pthread_mutex_unlock(mutex)) {
Anestis Bechtsoudis5a401c42016-04-22 07:50:19 +0300252 PLOG_F("%s():%d pthread_mutex_unlock(%p)", func, line, (void *)mutex);
Jagger421aca82015-09-05 14:09:47 +0200253 }
254}
Anestis Bechtsoudisd59af692015-09-21 15:15:05 +0300255
Anestis Bechtsoudis38572552016-02-07 12:55:55 +0200256int64_t fastArray64Search(uint64_t * array, size_t arraySz, uint64_t key)
Anestis Bechtsoudisd59af692015-09-21 15:15:05 +0300257{
258 size_t low = 0;
259 size_t high = arraySz - 1;
260 size_t mid;
261
262 while (array[high] != array[low] && key >= array[low] && key <= array[high]) {
263 mid = low + (key - array[low]) * ((high - low) / (array[high] - array[low]));
264
265 if (array[mid] < key) {
266 low = mid + 1;
267 } else if (key < array[mid]) {
268 high = mid - 1;
269 } else {
270 return mid;
271 }
272 }
273
274 if (key == array[low]) {
275 return low;
276 } else {
277 return -1;
278 }
279}
Anestis Bechtsoudis413cb132016-02-07 12:59:00 +0200280
281bool util_isANumber(const char *s)
282{
283 if (!isdigit(s[0])) {
284 return false;
285 }
286 for (int i = 0; s[i]; s++) {
287 if (!isdigit(s[i]) && s[i] != 'x') {
288 return false;
289 }
290 }
291 return true;
292}