* Huge performance improvement by caching the bit array. Yay.
This commit is contained in:
+35
-23
@@ -34,40 +34,52 @@
|
||||
|
||||
#define MAGIC1 0x33ea84f7
|
||||
#define MAGIC2 0x783bc31f
|
||||
/* We arbitrarily split files into 1024-byte chunks. Each chunk has an
|
||||
* associated seed that can be computed from the zzuf seed, the chunk
|
||||
* index and the fuzziness density. This allows us to predictably fuzz
|
||||
* any part of the file without reading the whole file. */
|
||||
#define CHUNKBYTES 1024
|
||||
|
||||
void zzuf_fuzz(int fd, uint8_t *buf, uint64_t len)
|
||||
{
|
||||
uint64_t start, stop;
|
||||
unsigned int i, todo;
|
||||
uint8_t *aligned_buf;
|
||||
unsigned int i, j, todo;
|
||||
|
||||
start = files[fd].pos;
|
||||
stop = start + len;
|
||||
aligned_buf = buf - files[fd].pos;
|
||||
|
||||
for(i = start / CHUNKBYTES; i < (stop + CHUNKBYTES - 1) / CHUNKBYTES; i++)
|
||||
for(i = files[fd].pos / CHUNKBYTES;
|
||||
i < (files[fd].pos + len + CHUNKBYTES - 1) / CHUNKBYTES;
|
||||
i++)
|
||||
{
|
||||
uint32_t chunkseed = i * MAGIC1;
|
||||
|
||||
/* Add some random dithering to handle ratio < 1.0/CHUNKBYTES */
|
||||
zzuf_srand(_zzuf_seed ^ chunkseed);
|
||||
todo = (int)((_zzuf_ratio * (8 * CHUNKBYTES * 1000) + zzuf_rand(1000))
|
||||
/ 1000.0);
|
||||
zzuf_srand(_zzuf_seed ^ chunkseed ^ (todo * MAGIC2));
|
||||
|
||||
while(todo--)
|
||||
/* Cache bitmask array */
|
||||
if(files[fd].cur != (int)i)
|
||||
{
|
||||
uint64_t idx = i * CHUNKBYTES + zzuf_rand(CHUNKBYTES);
|
||||
uint8_t byte = (1 << zzuf_rand(8));
|
||||
uint32_t chunkseed = i * MAGIC1;
|
||||
|
||||
if(idx < start || idx >= stop)
|
||||
continue;
|
||||
memset(files[fd].data, 0, CHUNKBYTES);
|
||||
|
||||
buf[idx - start] ^= byte;
|
||||
/* Add some random dithering to handle ratio < 1.0/CHUNKBYTES */
|
||||
zzuf_srand(_zzuf_seed ^ chunkseed);
|
||||
todo = (int)((_zzuf_ratio * (8 * CHUNKBYTES * 1000)
|
||||
+ zzuf_rand(1000)) / 1000.0);
|
||||
zzuf_srand(_zzuf_seed ^ chunkseed ^ (todo * MAGIC2));
|
||||
|
||||
while(todo--)
|
||||
{
|
||||
unsigned int idx = zzuf_rand(CHUNKBYTES);
|
||||
uint8_t byte = (1 << zzuf_rand(8));
|
||||
|
||||
files[fd].data[idx] ^= byte;
|
||||
}
|
||||
|
||||
files[fd].cur = i;
|
||||
}
|
||||
|
||||
/* Apply our bitmask array to the buffer */
|
||||
start = (i * CHUNKBYTES > files[fd].pos)
|
||||
? i * CHUNKBYTES : files[fd].pos;
|
||||
|
||||
stop = ((i + 1) * CHUNKBYTES < files[fd].pos + len)
|
||||
? (i + 1) * CHUNKBYTES : files[fd].pos + len;
|
||||
|
||||
for(j = start; j < stop; j++)
|
||||
aligned_buf[j] ^= files[fd].data[j % CHUNKBYTES];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -105,7 +105,8 @@ void zzuf_fini(void)
|
||||
if(!files[i].managed)
|
||||
continue;
|
||||
|
||||
/* TODO */
|
||||
/* XXX: What are we supposed to do? If filedescriptors weren't
|
||||
* closed properly, there's a leak, but it's not our problem. */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,11 +16,18 @@
|
||||
* libzzuf.h: preloaded wrapper library
|
||||
*/
|
||||
|
||||
/* We arbitrarily split files into 1024-byte chunks. Each chunk has an
|
||||
* associated seed that can be computed from the zzuf seed, the chunk
|
||||
* index and the fuzziness density. This allows us to predictably fuzz
|
||||
* any part of the file without reading the whole file. */
|
||||
#define CHUNKBYTES 1024
|
||||
|
||||
struct zzuf
|
||||
{
|
||||
int managed;
|
||||
uint64_t seed;
|
||||
uint64_t pos;
|
||||
int cur;
|
||||
char *data;
|
||||
};
|
||||
|
||||
|
||||
@@ -97,6 +97,8 @@ void zzuf_load_fd(void)
|
||||
else \
|
||||
debug(STR(fn) "(\"%s\", %i) = %i", file, oflag, ret); \
|
||||
files[ret].managed = 1; \
|
||||
files[ret].cur = -1; \
|
||||
files[ret].data = malloc(CHUNKBYTES); \
|
||||
files[ret].pos = 0; \
|
||||
} \
|
||||
} \
|
||||
@@ -182,6 +184,7 @@ int close(int fd)
|
||||
return ret;
|
||||
|
||||
debug("close(%i) = %i", fd, ret);
|
||||
free(files[fd].data);
|
||||
files[fd].managed = 0;
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -95,6 +95,8 @@ void zzuf_load_stream(void)
|
||||
int fd = fileno(ret); \
|
||||
files[fd].managed = 1; \
|
||||
files[fd].pos = 0; \
|
||||
files[fd].cur = -1; \
|
||||
files[fd].data = malloc(CHUNKBYTES); \
|
||||
debug(STR(fn) "(\"%s\", \"%s\") = %p", path, mode, ret); \
|
||||
} \
|
||||
} \
|
||||
@@ -265,6 +267,7 @@ int fclose(FILE *fp)
|
||||
ret = fclose_orig(fp);
|
||||
debug("fclose(%p) = %i", fp, ret);
|
||||
files[fd].managed = 0;
|
||||
free(files[fd].data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user