aboutsummaryrefslogtreecommitdiffstats
path: root/executor
diff options
context:
space:
mode:
Diffstat (limited to 'executor')
-rw-r--r--executor/executor.cc8
-rw-r--r--executor/executor_bsd.h22
-rw-r--r--executor/executor_darwin.h3
-rw-r--r--executor/executor_linux.h38
-rw-r--r--executor/executor_test.h18
5 files changed, 52 insertions, 37 deletions
diff --git a/executor/executor.cc b/executor/executor.cc
index fb73efc5c..704a284a9 100644
--- a/executor/executor.cc
+++ b/executor/executor.cc
@@ -348,8 +348,16 @@ struct call_t {
struct cover_t {
int fd;
uint32 size;
+ // mmap_alloc_ptr is the internal pointer to KCOV mapping, possibly with guard pages.
+ // It is only used to allocate/deallocate the buffer of mmap_alloc_size.
+ char* mmap_alloc_ptr;
uint32 mmap_alloc_size;
+ // data is the pointer to the kcov buffer containing the recorded PCs.
+ // data may differ from mmap_alloc_ptr.
char* data;
+ // data_size is set by cover_open(). This is the requested kcov buffer size.
+ uint32 data_size;
+ // data_end is simply data + data_size.
char* data_end;
// Currently collecting comparisons.
bool collect_comps;
diff --git a/executor/executor_bsd.h b/executor/executor_bsd.h
index b7cbdd4f5..88e1f46cb 100644
--- a/executor/executor_bsd.h
+++ b/executor/executor_bsd.h
@@ -71,7 +71,7 @@ static void cover_open(cover_t* cov, bool extra)
#if GOOS_freebsd
if (ioctl(cov->fd, KIOSETBUFSIZE, kCoverSize))
fail("ioctl init trace write failed");
- cov->mmap_alloc_size = kCoverSize * KCOV_ENTRY_SIZE;
+ cov->data_size = kCoverSize * KCOV_ENTRY_SIZE;
#elif GOOS_openbsd
unsigned long cover_size = kCoverSize;
if (ioctl(cov->fd, KIOSETBUFSIZE, &cover_size))
@@ -83,7 +83,7 @@ static void cover_open(cover_t* cov, bool extra)
if (ioctl(cov->fd, KIOREMOTEATTACH, &args))
fail("ioctl remote attach failed");
}
- cov->mmap_alloc_size = kCoverSize * (is_kernel_64_bit ? 8 : 4);
+ cov->data_size = kCoverSize * (is_kernel_64_bit ? 8 : 4);
#elif GOOS_netbsd
uint64_t cover_size;
if (extra) {
@@ -100,18 +100,20 @@ static void cover_open(cover_t* cov, bool extra)
if (ioctl(cov->fd, KCOV_IOC_SETBUFSIZE, &cover_size))
fail("ioctl init trace write failed");
}
- cov->mmap_alloc_size = cover_size * KCOV_ENTRY_SIZE;
+ cov->data_size = cover_size * KCOV_ENTRY_SIZE;
#endif
}
static void cover_mmap(cover_t* cov)
{
- if (cov->data != NULL)
+ if (cov->mmap_alloc_ptr != NULL)
fail("cover_mmap invoked on an already mmapped cover_t object");
+ cov->mmap_alloc_size = cov->data_size;
void* mmap_ptr = mmap(NULL, cov->mmap_alloc_size, PROT_READ | PROT_WRITE,
MAP_SHARED, cov->fd, 0);
if (mmap_ptr == MAP_FAILED)
fail("cover mmap failed");
+ cov->mmap_alloc_ptr = (char*)mmap_ptr;
cov->data = (char*)mmap_ptr;
cov->data_end = cov->data + cov->mmap_alloc_size;
cov->data_offset = is_kernel_64_bit ? sizeof(uint64_t) : sizeof(uint32_t);
@@ -120,13 +122,13 @@ static void cover_mmap(cover_t* cov)
static void cover_protect(cover_t* cov)
{
- if (cov->data == NULL)
+ if (cov->mmap_alloc_ptr == NULL)
fail("cover_protect invoked on an unmapped cover_t object");
#if GOOS_freebsd
size_t mmap_alloc_size = kCoverSize * KCOV_ENTRY_SIZE;
long page_size = sysconf(_SC_PAGESIZE);
if (page_size > 0)
- mprotect(cov->data + page_size, mmap_alloc_size - page_size,
+ mprotect(cov->mmap_alloc_ptr + page_size, mmap_alloc_size - page_size,
PROT_READ);
#elif GOOS_openbsd
int mib[2], page_size;
@@ -135,20 +137,20 @@ static void cover_protect(cover_t* cov)
mib[1] = HW_PAGESIZE;
size_t len = sizeof(page_size);
if (sysctl(mib, ARRAY_SIZE(mib), &page_size, &len, NULL, 0) != -1)
- mprotect(cov->data + page_size, mmap_alloc_size - page_size, PROT_READ);
+ mprotect(cov->mmap_alloc_ptr + page_size, mmap_alloc_size - page_size, PROT_READ);
#endif
}
static void cover_unprotect(cover_t* cov)
{
- if (cov->data == NULL)
+ if (cov->mmap_alloc_ptr == NULL)
fail("cover_unprotect invoked on an unmapped cover_t object");
#if GOOS_freebsd
size_t mmap_alloc_size = kCoverSize * KCOV_ENTRY_SIZE;
- mprotect(cov->data, mmap_alloc_size, PROT_READ | PROT_WRITE);
+ mprotect(cov->mmap_alloc_ptr, mmap_alloc_size, PROT_READ | PROT_WRITE);
#elif GOOS_openbsd
size_t mmap_alloc_size = kCoverSize * sizeof(uintptr_t);
- mprotect(cov->data, mmap_alloc_size, PROT_READ | PROT_WRITE);
+ mprotect(cov->mmap_alloc_ptr, mmap_alloc_size, PROT_READ | PROT_WRITE);
#endif
}
diff --git a/executor/executor_darwin.h b/executor/executor_darwin.h
index bb7956c20..d555eeb02 100644
--- a/executor/executor_darwin.h
+++ b/executor/executor_darwin.h
@@ -73,7 +73,7 @@ static void cover_open(cover_t* cov, bool extra)
static void cover_mmap(cover_t* cov)
{
- if (cov->data != NULL)
+ if (cov->mmap_alloc_ptr != NULL)
fail("cover_mmap invoked on an already mmapped cover_t object");
uintptr_t mmap_ptr = 0;
if (ksancov_map(cov->fd, &mmap_ptr, &cov->mmap_alloc_size))
@@ -84,6 +84,7 @@ static void cover_mmap(cover_t* cov)
if (cov->mmap_alloc_size > kCoverSize)
fail("mmap allocation size larger than anticipated");
+ cov->mmap_alloc_ptr = (char*)mmap_ptr;
cov->data = (char*)mmap_ptr;
cov->data_end = cov->data + cov->mmap_alloc_size;
}
diff --git a/executor/executor_linux.h b/executor/executor_linux.h
index f882b9c40..a5a073ba0 100644
--- a/executor/executor_linux.h
+++ b/executor/executor_linux.h
@@ -114,7 +114,7 @@ static void cover_open(cover_t* cov, bool extra)
: kCoverSize;
if (ioctl(cov->fd, kcov_init_trace, cover_size))
fail("cover init trace write failed");
- cov->mmap_alloc_size = cover_size * (is_kernel_64_bit ? 8 : 4);
+ cov->data_size = cover_size * (is_kernel_64_bit ? 8 : 4);
if (pkeys_enabled)
debug("pkey protection enabled\n");
}
@@ -133,35 +133,37 @@ static void cover_unprotect(cover_t* cov)
static void cover_mmap(cover_t* cov)
{
- if (cov->data != NULL)
+ if (cov->mmap_alloc_ptr != NULL)
fail("cover_mmap invoked on an already mmapped cover_t object");
- if (cov->mmap_alloc_size == 0)
+ if (cov->data_size == 0)
fail("cover_t structure is corrupted");
// Allocate kcov buffer plus two guard pages surrounding it.
- char* mapped = (char*)mmap(NULL, cov->mmap_alloc_size + 2 * SYZ_PAGE_SIZE,
- PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0);
- if (mapped == MAP_FAILED)
+ cov->mmap_alloc_size = cov->data_size + 2 * SYZ_PAGE_SIZE;
+ cov->mmap_alloc_ptr = (char*)mmap(NULL, cov->mmap_alloc_size,
+ PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0);
+ if (cov->mmap_alloc_ptr == MAP_FAILED)
exitf("failed to preallocate kcov buffer");
// Now map the kcov buffer to the file, overwriting the existing mapping above.
int prot = flag_read_only_coverage ? PROT_READ : (PROT_READ | PROT_WRITE);
- cov->data = (char*)mmap(mapped + SYZ_PAGE_SIZE, cov->mmap_alloc_size,
- prot, MAP_SHARED | MAP_FIXED, cov->fd, 0);
- if (cov->data == MAP_FAILED)
+ void* data_buf = (char*)mmap(cov->mmap_alloc_ptr + SYZ_PAGE_SIZE, cov->data_size,
+ prot, MAP_SHARED | MAP_FIXED, cov->fd, 0);
+ if (data_buf == MAP_FAILED)
exitf("cover mmap failed");
- if (pkeys_enabled && pkey_mprotect(cov->data, cov->mmap_alloc_size, prot, RESERVED_PKEY))
+ if (pkeys_enabled && pkey_mprotect(data_buf, cov->data_size, prot, RESERVED_PKEY))
exitf("failed to pkey_mprotect kcov buffer");
- cov->data_end = cov->data + cov->mmap_alloc_size;
+ cov->data = (char*)data_buf;
+ cov->data_end = cov->data + cov->data_size;
cov->data_offset = is_kernel_64_bit ? sizeof(uint64_t) : sizeof(uint32_t);
cov->pc_offset = 0;
}
static void cover_munmap(cover_t* cov)
{
- if (cov->data == NULL)
+ if (cov->mmap_alloc_ptr == NULL)
fail("cover_munmap invoked on a non-mmapped cover_t object");
- if (munmap(cov->data - SYZ_PAGE_SIZE, cov->mmap_alloc_size + 2 * SYZ_PAGE_SIZE))
+ if (munmap(cov->mmap_alloc_ptr, cov->mmap_alloc_size))
fail("cover_munmap failed");
- cov->data = NULL;
+ cov->mmap_alloc_ptr = NULL;
}
static void cover_enable(cover_t* cov, bool collect_comps, bool extra)
@@ -303,8 +305,8 @@ static const char* setup_delay_kcov()
cov.fd = kCoverFd;
cover_open(&cov, false);
cover_mmap(&cov);
- char* first = cov.data;
- cov.data = nullptr;
+ char* first = cov.mmap_alloc_ptr;
+ cov.mmap_alloc_ptr = nullptr;
cover_mmap(&cov);
// If delayed kcov mmap is not supported by the kernel,
// accesses to the second mapping will crash.
@@ -316,9 +318,9 @@ static const char* setup_delay_kcov()
fail("clock_gettime failed");
error = "kernel commit b3d7fe86fbd0 is not present";
} else {
- munmap(cov.data - SYZ_PAGE_SIZE, cov.mmap_alloc_size + 2 * SYZ_PAGE_SIZE);
+ munmap(cov.mmap_alloc_ptr, cov.mmap_alloc_size);
}
- munmap(first - SYZ_PAGE_SIZE, cov.mmap_alloc_size + 2 * SYZ_PAGE_SIZE);
+ munmap(first, cov.mmap_alloc_size);
close(cov.fd);
return error;
}
diff --git a/executor/executor_test.h b/executor/executor_test.h
index e2a2002bb..d8471e6b5 100644
--- a/executor/executor_test.h
+++ b/executor/executor_test.h
@@ -75,7 +75,7 @@ static intptr_t execute_syscall(const call_t* c, intptr_t a[kMaxArgs])
static void cover_open(cover_t* cov, bool extra)
{
- cov->mmap_alloc_size = kCoverSize * sizeof(unsigned long);
+ cov->data_size = kCoverSize * sizeof(unsigned long);
}
static void cover_enable(cover_t* cov, bool collect_comps, bool extra)
@@ -102,14 +102,16 @@ static void cover_protect(cover_t* cov)
static void cover_mmap(cover_t* cov)
{
- if (cov->data != NULL)
+ if (cov->mmap_alloc_ptr != NULL)
fail("cover_mmap invoked on an already mmapped cover_t object");
- if (cov->mmap_alloc_size == 0)
+ if (cov->data_size == 0)
fail("cover_t structure is corrupted");
- cov->data = (char*)mmap(NULL, cov->mmap_alloc_size,
- PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
- if (cov->data == MAP_FAILED)
+ cov->mmap_alloc_size = cov->data_size;
+ cov->mmap_alloc_ptr = (char*)mmap(NULL, cov->mmap_alloc_size,
+ PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+ if (cov->mmap_alloc_ptr == MAP_FAILED)
exitf("cover mmap failed");
+ cov->data = cov->mmap_alloc_ptr;
cov->data_end = cov->data + cov->mmap_alloc_size;
cov->data_offset = is_kernel_64_bit ? sizeof(uint64_t) : sizeof(uint32_t);
// We don't care about the specific PC values for now.
@@ -125,9 +127,9 @@ static long inject_cover(cover_t* cov, long a, long b)
{
if (cov->data == nullptr)
return ENOENT;
- uint32 size = std::min((uint32)b, cov->mmap_alloc_size);
+ uint32 size = std::min((uint32)b, cov->data_size);
memcpy(cov->data, (void*)a, size);
- memset(cov->data + size, 0xcd, std::min<uint64>(100, cov->mmap_alloc_size - size));
+ memset(cov->data + size, 0xcd, std::min<uint64>(100, cov->data_size - size));
return 0;
}