Paste number 160204: | Test case for possible TLB bug |
Pasted by: | nyef |
When: | 9 years, 3 months ago |
Share: | Tweet this! | http://paste.lisp.org/+3FM4 |
Channel: | None |
Paste contents: |
#include <stdio.h>
#include <sys/mman.h>
#include <signal.h>
#include <stdlib.h>
#define BINDSTACK_SIZE 0x1000000
#define BINDSTACK_PAGE_SIZE 0x1000
#define BINDSTACK_LOW_GUARD_PAGE 0x0ffe000
#define BINDSTACK_HIGH_GUARD_PAGE 0xfff000
void *bindstack;
struct symdata {
unsigned int pad0;
unsigned int value;
unsigned int pad2;
unsigned int pad3;
unsigned int pad4;
unsigned int pad5;
};
#define SYMDATA_SIZE 0x6000 /* 1024 entries, 6 words/entry, 4 bytes/word */
struct symdata *symdata;
int trap_1_hit;
void protect_low(int protect)
{
mprotect(bindstack + BINDSTACK_LOW_GUARD_PAGE,
BINDSTACK_PAGE_SIZE,
protect? 0: PROT_READ | PROT_WRITE | PROT_EXEC);
}
void protect_high(int protect)
{
mprotect(bindstack + BINDSTACK_HIGH_GUARD_PAGE,
BINDSTACK_PAGE_SIZE,
protect? 0: PROT_READ | PROT_WRITE | PROT_EXEC);
}
void sigsegv_handler(int signal, siginfo_t *info, void *context)
{
void *addr = info->si_addr;
if (addr == (bindstack + BINDSTACK_HIGH_GUARD_PAGE)) {
printf("trap 1\n");
protect_high(0);
protect_low(1);
trap_1_hit = 1;
} else if ((addr > (bindstack + BINDSTACK_LOW_GUARD_PAGE)) &&
(addr < (bindstack + BINDSTACK_HIGH_GUARD_PAGE))) {
printf("trap 2\n");
protect_high(1);
protect_low(0);
} else {
printf("unknown trap address %p\n", addr);
abort();
}
}
void run_bind_test(void)
{
unsigned int *p = bindstack;
unsigned int i = 0;
while (!trap_1_hit) {
p[0] = (unsigned int)&symdata[i];
p[1] = symdata[i].value;
symdata[i].value = 0xf001f001;
p += 2;
i = (i + 1) & 1023;
}
while (p != bindstack) {
p -= 2;
((struct symdata *)p[0])->value = p[1];
p[0] = 0;
p[1] = 0;
}
}
int main(void)
{
struct sigaction sa;
if (sigprocmask(SIG_BLOCK, NULL, &sa.sa_mask)) {
perror("sigprocmask");
return 0;
}
sa.sa_sigaction = sigsegv_handler;
sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_RESTART;
if (sigaction(SIGSEGV, &sa, NULL)) {
perror("sigaction");
return 0;
}
bindstack = mmap(NULL,
BINDSTACK_SIZE,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS,
-1,
0);
if (bindstack == MAP_FAILED) {
perror("mmap bindstack");
return 0;
}
symdata = mmap(NULL,
SYMDATA_SIZE,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS,
-1,
0);
if (symdata == MAP_FAILED) {
perror("mmap symdata");
return 0;
}
protect_high(1);
trap_1_hit = 0;
printf("bindstack: %p, symdata: %p\n", bindstack, symdata);
run_bind_test();
printf("done\n");
return 0;
}
This paste has no annotations.