* Huge performance improvement by caching the bit array. Yay.

This commit is contained in:
Sam Hocevar
2006-12-17 23:58:23 +00:00
committed by sam
parent d81d47bbe0
commit b7370e4aba
5 changed files with 50 additions and 24 deletions
+35 -23
View File
@@ -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
View File
@@ -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. */
}
}
+7
View File
@@ -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;
};
+3
View File
@@ -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;
+3
View File
@@ -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;
}