cmem/mem.c

72 lines
1.4 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <signal.h>
#include <setjmp.h>
// Global flag and jump buffer for recovery
static jmp_buf env_buffer;
static volatile int enable_handler = 0;
void segfault_handler(int signal_num) {
if (enable_handler == 1) {
longjmp(env_buffer, 1);
} else {
printf("Segmentation Fault :(");
exit(signal_num);
}
}
#define IMPL_TRY_DEREF(type) \
int tryDereference(type* pointer, type* output) { \
if(setjmp(env_buffer) == 0) {\
enable_handler = 1;\
*output = *pointer;\
enable_handler = 0;\
return 1;\
} else {\
enable_handler = 0;\
return 0;\
}\
}
IMPL_TRY_DEREF(uint8_t)
void printMem(uint8_t* location) {
uint8_t value;
if(tryDereference(location, &value)) {
printf("%p: 0x%02x\n", location, value);
}
else {
printf("%p: SEGFAULT\n", location);
}
}
uint8_t* flipBit(uint8_t* data, int bit) {
return (uint8_t*)((1<<bit) ^ (uintptr_t)data);
}
uint32_t nBits() {
//NOTE: Just use UINTPTR_MAX
uint32_t n = 0;
for(uintptr_t p = 1;p > 0; p<<=1) ++n;
return n;
}
int main(int argc, char *argv[])
{
signal(SIGSEGV, segfault_handler);
uint32_t nbits = nBits();
printf("Using %u bit addresses\n", nbits);
uint8_t a = 0x55;
uint8_t* var = &a;
printMem(var-1);
printMem(var);
printMem(var+1);
for (uint32_t i = 0; i < nbits; ++i) {
//printf("flipping bit %u\n", i);
printMem(flipBit(var, i));
}
return EXIT_SUCCESS;
}