#include #include #include #include #include #include #include jmp_buf jb; typedef struct _bitfield { unsigned char msb:1; unsigned char pad:6; unsigned char lsb:1; } bitfield_t; static int sigbus_caught = 0; void sigbus_handler(int signum) { sigbus_caught = 1; longjmp(jb, signum); } int * foo1_origin; int * foo2_origin; int * foo3_origin; int * foo4_origin; void foo2(void) { volatile int dummy2; dummy2 = 0; foo2_origin = &dummy2; } void foo1(void) { volatile int dummy1; dummy1 = 0; foo1_origin = &dummy1; foo2(); } void foo4(void) { volatile int dummy4; dummy4 = 0; foo4_origin = &dummy4; } void foo3(void) { volatile int dummy3; dummy3 = 0; foo3_origin = &dummy3; foo4(); } int main(void) { int i; bitfield_t bf; char ducks[8]; char dummies[2]; char * heap; unsigned char cage; int canary = 0x11223344; printf("Pointer size : %u bits\n", sizeof(void *) * 8); printf("Int size : %u bits\n", sizeof(int) * 8); /* This probably gives the wrong results since %x means integer... */ printf("Address of main : 0x%x\n", &main); printf("User stack begins at : 0x%x\n", &i); heap = malloc(1); printf("Address of heap object: 0x%x\n", heap); cage = *((char *) &canary); printf("Scalar type endianness: "); if(cage == 0x44) { printf("Little endian"); } else if(cage == 0x11) { printf("Big endian"); } else { printf("??? endian: %x", cage); } printf("\n"); printf("Bitfield endianness : "); memset(&bf, 0, sizeof(bf)); bf.lsb = 1; cage = *((unsigned char *) &bf); if(cage == 0x80) { printf("Little endian"); } else if(cage == 0x01) { printf("Big endian"); } else { printf("??? endian: %x", cage); } printf("\n"); /* Idea stolen from http://www.sandia.gov/ASCI/Red/usage/tutorial/dbmalloc/example/testmem.c */ printf("Char signedness : "); dummies[0] = 0x1; dummies[1] = 0xf6; if(sizeof(char) != 1) { printf("char is not 8 bits on this platform.\n"); } if(dummies[0] < dummies[1]) printf("unsigned"); else printf("signed"); printf("\n"); if(signal(SIGBUS, &sigbus_handler) == SIG_ERR) { printf("signal(SIGBUS) returned error %s\n", strerror(errno)); return -1; } else { int signum; printf("Unaligned accesses : "); for(i = 0; i < sizeof(ducks); ++i) ducks[i] = i; signum = setjmp(jb); if(signum == 0) canary = *((int *) &ducks[2]); /* do an unaligned access */ if(sigbus_caught == 1) printf("caught (signal %u)", signum); else printf("not caught"); printf("\n"); } foo1(); foo3(); { int delta1; int delta2; if(foo1_origin < foo2_origin) delta1 = foo2_origin - foo1_origin; else delta1 = foo1_origin - foo2_origin; if(foo3_origin < foo4_origin) delta2 = foo4_origin - foo3_origin; else delta2 = foo3_origin - foo4_origin; printf("function call overhead: %i\n", delta2 - delta1); } return 0; }