blob: c796b0915e452616e12299b968d33d52819f1ab1 [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.swiecki3bb518c2010-10-14 00:48:24 +000025#include <math.h>
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000026#include <stdarg.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000027#include <stdint.h>
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000028#include <stdio.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000029#include <stdlib.h>
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +000030#include <string.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000031#include <sys/stat.h>
32#include <sys/time.h>
33#include <sys/types.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000034#include <time.h>
robert.swiecki@gmail.comba85c3e2015-02-02 14:55:16 +000035#include <unistd.h>
robert.swiecki3bb518c2010-10-14 00:48:24 +000036
37#include "common.h"
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000038#include "files.h"
robert.swiecki3bb518c2010-10-14 00:48:24 +000039#include "log.h"
40
Anestis Bechtsoudis4f9bfd02015-09-10 17:31:58 +030041#if defined(__builtin_bswap16)
42#define SWAP16(x) __builtin_bswap16(x)
43#else
44#define SWAP16(x) ((x & 0xff) << 8) | ((x & 0xff00) >> 8)
45#endif
46
47#if defined(__builtin_bswap32)
48#define SWAP32(x) __builtin_bswap32(x)
49#else
50#define SWAP32(x) ((x & 0xff) << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | ((x & 0xff000000) >> 24)
51#endif
52
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000053static int util_urandomFd = -1;
robert.swiecki@gmail.com180263f2015-02-13 13:57:15 +000054
robert.swiecki@gmail.com90e99112015-02-15 02:05:14 +000055uint64_t util_rndGet(uint64_t min, uint64_t max)
robert.swiecki3bb518c2010-10-14 00:48:24 +000056{
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000057 if (util_urandomFd == -1) {
58 if ((util_urandomFd = open("/dev/urandom", O_RDONLY)) == -1) {
59 LOGMSG_P(l_FATAL, "Couldn't open /dev/urandom for writing");
60 }
robert.swiecki@gmail.com180263f2015-02-13 13:57:15 +000061 }
robert.swiecki3bb518c2010-10-14 00:48:24 +000062
robert.swiecki@gmail.com90e99112015-02-15 02:05:14 +000063 uint64_t rnd;
robert.swiecki@gmail.com26a9ab72015-02-22 13:41:18 +000064 if (files_readFromFd(util_urandomFd, (uint8_t *) & rnd, sizeof(rnd)) == false) {
65 LOGMSG_P(l_FATAL, "Failed reading from /dev/urandom");
robert.swiecki@gmail.com4be12dc2015-02-13 14:03:53 +000066 }
robert.swiecki@gmail.com180263f2015-02-13 13:57:15 +000067
robert.swiecki@gmail.combce825a2015-02-13 23:26:07 +000068 if (min > max) {
69 LOGMSG(l_FATAL, "min:%d > max:%d", min, max);
70 }
71
robert.swiecki@gmail.comb0383372015-02-13 14:17:27 +000072 return ((rnd % (max - min + 1)) + min);
robert.swiecki3bb518c2010-10-14 00:48:24 +000073}
74
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +000075void util_rndBuf(uint8_t * buf, size_t sz)
76{
robert.swiecki@gmail.comace40862015-03-08 07:09:56 +000077 /* MMIX LCG PRNG */
78 uint64_t a = 6364136223846793005ULL;
79 uint64_t c = 1442695040888963407ULL;
robert.swiecki@gmail.come6b15522015-03-27 00:33:42 +000080 uint64_t x = util_rndGet(0, 1ULL << 60);
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +000081
robert.swiecki@gmail.com08174c72015-02-28 14:38:06 +000082 for (size_t i = 0; i < sz; i++) {
robert.swiecki@gmail.comace40862015-03-08 07:09:56 +000083 x = (a * x + c);
84 buf[i] = (uint8_t) ((x >> 32) & 0xFF);
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +000085 }
86
87 return;
88}
89
robert.swiecki@gmail.com9e2d43d2015-02-16 12:17:39 +000090int util_vssnprintf(char *str, size_t size, const char *format, va_list ap)
91{
92 char buf1[size];
93 char buf2[size];
94
95 strncpy(buf1, str, size);
96
97 vsnprintf(buf2, size, format, ap);
98
99 return snprintf(str, size, "%s%s", buf1, buf2);
100}
101
102int util_ssnprintf(char *str, size_t size, const char *format, ...)
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +0000103{
104 char buf1[size];
105 char buf2[size];
106
107 strncpy(buf1, str, size);
108
109 va_list args;
110 va_start(args, format);
111 vsnprintf(buf2, size, format, args);
112 va_end(args);
113
robert.swiecki@gmail.com9e2d43d2015-02-16 12:17:39 +0000114 return snprintf(str, size, "%s%s", buf1, buf2);
robert.swiecki@gmail.come7190b92015-02-14 23:05:42 +0000115}
116
Robert Swiecki81c6a0d2015-09-08 15:43:20 +0200117void util_getLocalTime(const char *fmt, char *buf, size_t len, time_t tm)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000118{
119 struct tm ltime;
Robert Swiecki81c6a0d2015-09-08 15:43:20 +0200120 localtime_r(&tm, &ltime);
121 if (strftime(buf, len, fmt, &ltime) < 1) {
122 snprintf(buf, len, "[date fetch error]");
123 }
robert.swiecki3bb518c2010-10-14 00:48:24 +0000124}
125
robert.swiecki40499ff2010-12-13 19:47:08 +0000126void util_nullifyStdio(void)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000127{
128 int fd = open("/dev/null", O_RDWR);
129
130 if (fd == -1) {
131 LOGMSG_P(l_ERROR, "Couldn't open '/dev/null'");
132 return;
133 }
134
135 dup2(fd, 0);
136 dup2(fd, 1);
137 dup2(fd, 2);
138
139 if (fd > 2) {
140 close(fd);
141 }
142
143 return;
144}
145
146bool util_redirectStdin(char *inputFile)
147{
148 int fd = open(inputFile, O_RDONLY);
149
150 if (fd == -1) {
151 LOGMSG_P(l_ERROR, "Couldn't open '%s'", inputFile);
152 return false;
153 }
154
155 dup2(fd, 0);
156 if (fd != 0) {
157 close(fd);
158 }
159
160 return true;
161}
162
robert.swiecki40499ff2010-12-13 19:47:08 +0000163void util_recoverStdio(void)
robert.swiecki3bb518c2010-10-14 00:48:24 +0000164{
165 int fd = open("/dev/tty", O_RDWR);
166
167 if (fd == -1) {
168 LOGMSG_P(l_ERROR, "Couldn't open '/dev/tty'");
169 return;
170 }
171
172 dup2(fd, 0);
173 dup2(fd, 1);
174 dup2(fd, 2);
175
robert.swiecki@gmail.comdf286942015-04-15 21:45:25 +0000176 if (tcsetpgrp(fd, getpid()) == -1) {
177 LOGMSG_P(l_WARN, "tcsetpgrp(%d) failed", getpid());
178 }
179
robert.swiecki3bb518c2010-10-14 00:48:24 +0000180 if (fd > 2) {
181 close(fd);
182 }
robert.swiecki3bb518c2010-10-14 00:48:24 +0000183 return;
184}
groebert@google.com1bd4c212013-06-19 11:13:56 +0000185
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000186/*
robert.swiecki@gmail.com3b630b42015-02-16 10:53:53 +0000187 * This is not a cryptographically secure hash
robert.swiecki@gmail.com772b33d2015-02-14 20:35:00 +0000188 */
groebert@google.com1bd4c212013-06-19 11:13:56 +0000189extern uint64_t util_hash(const char *buf, size_t len)
190{
191 uint64_t ret = 0;
192
193 for (size_t i = 0; i < len; i++) {
194 ret += buf[i];
195 ret += (ret << 10);
196 ret ^= (ret >> 6);
197 }
198
199 return ret;
200}
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000201
robert.swiecki@gmail.com3213a112015-03-12 01:42:02 +0000202extern int64_t util_timeNowMillis(void)
203{
204 struct timeval tv;
205 if (gettimeofday(&tv, NULL) == -1) {
206 LOGMSG_P(l_FATAL, "gettimeofday()");
207 }
208
209 return (((int64_t) tv.tv_sec * 1000LL) + ((int64_t) tv.tv_usec / 1000LL));
210}
211
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000212extern uint16_t util_ToFromBE16(uint16_t val)
213{
214#if __BYTE_ORDER == __BIG_ENDIAN
215 return val;
216#elif __BYTE_ORDER == __LITTLE_ENDIAN
Anestis Bechtsoudis4f9bfd02015-09-10 17:31:58 +0300217 return SWAP16(val);
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000218#else
219#error "Unknown ENDIANESS"
220#endif
221}
222
223extern uint16_t util_ToFromLE16(uint16_t val)
224{
225#if __BYTE_ORDER == __BIG_ENDIAN
Anestis Bechtsoudis4f9bfd02015-09-10 17:31:58 +0300226 return SWAP16(val);
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000227#elif __BYTE_ORDER == __LITTLE_ENDIAN
228 return val;
229#else
230#error "Unknown ENDIANESS"
231#endif
232}
233
234extern uint32_t util_ToFromBE32(uint32_t val)
235{
236#if __BYTE_ORDER == __BIG_ENDIAN
237 return val;
238#elif __BYTE_ORDER == __LITTLE_ENDIAN
Anestis Bechtsoudis4f9bfd02015-09-10 17:31:58 +0300239 return SWAP32(val);
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000240#else
241#error "Unknown ENDIANESS"
242#endif
243}
244
245extern uint32_t util_ToFromLE32(uint32_t val)
246{
247#if __BYTE_ORDER == __BIG_ENDIAN
Anestis Bechtsoudis4f9bfd02015-09-10 17:31:58 +0300248 return SWAP32(val);
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000249#elif __BYTE_ORDER == __LITTLE_ENDIAN
250 return val;
251#else
252#error "Unknown ENDIANESS"
253#endif
254}
Jagger421aca82015-09-05 14:09:47 +0200255
256extern void MX_LOCK(pthread_mutex_t * mutex)
257{
258 if (pthread_mutex_lock(mutex)) {
259 LOGMSG_P(l_FATAL, "pthread_mutex_lock(%p)", mutex);
260 }
261}
262
263extern void MX_UNLOCK(pthread_mutex_t * mutex)
264{
265 if (pthread_mutex_unlock(mutex)) {
266 LOGMSG_P(l_FATAL, "pthread_mutex_unlock(%p)", mutex);
267 }
268}
Anestis Bechtsoudisd59af692015-09-21 15:15:05 +0300269
270extern int64_t fastArray64Search(uint64_t * array, size_t arraySz, uint64_t key)
271{
272 size_t low = 0;
273 size_t high = arraySz - 1;
274 size_t mid;
275
276 while (array[high] != array[low] && key >= array[low] && key <= array[high]) {
277 mid = low + (key - array[low]) * ((high - low) / (array[high] - array[low]));
278
279 if (array[mid] < key) {
280 low = mid + 1;
281 } else if (key < array[mid]) {
282 high = mid - 1;
283 } else {
284 return mid;
285 }
286 }
287
288 if (key == array[low]) {
289 return low;
290 } else {
291 return -1;
292 }
293}