/* Create a stack with a barrier page at the end to guard against stack overflow. */ static void *CreateStack( int size ) { const long PageSize = getpagesize(); /* Round size up to the nearest PageSize. */ size += PageSize-1; size -= (size%PageSize); /* mmap always returns page-aligned data. * * mmap entries always show up individually in /proc/#/maps. We could use posix_memalign as * a fallback, but we'd have to put a barrier page on both sides to guarantee that. */ char *p = NULL; p = (char *) mmap( NULL, size+PageSize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 ); if( p == (void *) -1 ) return NULL; // if( posix_memalign( (void**) &p, PageSize, RealSize ) != 0 ) // return NULL; if( find_stack_direction() < 0 ) { /* The stack grows towards smaller addresses. Protect the first page. */ mprotect( p, PageSize, PROT_NONE ); p += PageSize; } else { /* The stack grows towards larger addresses. Protect the last page. */ mprotect( p+size, PageSize, PROT_NONE ); } return p; }
int main(void) { find_stack_direction(); if(stack_dir==1) puts("stack grew upward"); else puts("stack grew downward"); return 0; }
static int find_stack_direction (int *addr, int depth) { int dir, dummy = 0; if (! addr) addr = &dummy; *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; dir = depth ? find_stack_direction (addr, depth - 1) : 0; return dir + dummy; }
int find_stack_direction() { static char *addr = 0; auto char dummy; if (addr == 0) { addr = &dummy; return find_stack_direction(); } else return (&dummy > addr) ? 1 : -1; }
void * alloca (unsigned size) { auto char probe; /* Probes stack depth: */ register char *depth = ADDRESS_FUNCTION (probe); #if STACK_DIRECTION == 0 if (STACK_DIR == 0) /* Unknown growth direction. */ find_stack_direction (); #endif /* Reclaim garbage, defined as all alloca'd storage that was allocated from deeper in the stack than currently. */ { register header *hp; /* Traverses linked list. */ for (hp = last_alloca_header; hp != NULL;) if ((STACK_DIR > 0 && hp->h.deep > depth) || (STACK_DIR < 0 && hp->h.deep < depth)) { register header *np = hp->h.next; free ((void *) hp); /* Collect garbage. */ hp = np; /* -> next header. */ } else break; /* Rest are not deeper. */ last_alloca_header = hp; /* -> last valid storage. */ } if (size == 0) return NULL; /* No allocation required. */ /* Allocate combined header + user data storage. */ { register void * newptr = malloc (sizeof (header) + size); /* Address of header. */ ((header *) newptr)->h.next = last_alloca_header; ((header *) newptr)->h.deep = depth; last_alloca_header = (header *) newptr; /* User storage begins just after header. */ return (void *) ((char *) newptr + sizeof (header)); } }
static void find_stack_direction() { static char *addr = NULL; /* Address of first `dummy', once known. */ auto char dummy; /* To get stack address. */ if (addr == NULL) { /* Initial entry. */ addr = ADDRESS_FUNCTION(dummy); find_stack_direction(); /* Recurse once. */ } else { /* Second entry. */ if (ADDRESS_FUNCTION(dummy) > addr) stack_dir = 1; /* Stack grew upward. */ else stack_dir = -1; /* Stack grew downward. */ } }
static void find_stack_direction (/* void */) { static char *addr = NULL; /* address of first `dummy', once known */ auto char dummy; /* to get stack address */ if (addr == NULL) { /* initial entry */ addr = &dummy; find_stack_direction (); /* recurse once */ } else /* second entry */ if (&dummy > addr) stack_dir = 1; /* stack grew upward */ else stack_dir = -1; /* stack grew downward */ }
static void find_stack_direction (char **ptr) { auto char dummy; /* To get stack address. */ if (*ptr == NULL) { /* Initial entry. */ *ptr = ADDRESS_FUNCTION (dummy); find_stack_direction (ptr); /* Recurse once. */ } else { /* Second entry. */ if (ADDRESS_FUNCTION (dummy) > *ptr) stack_dir = 1; /* Stack grew upward. */ else stack_dir = -1; /* Stack grew downward. */ } }
static void segv_handler (int signo, siginfo_t *info, void *context) { /* Clear SIGNO if it seems to have been a stack overflow. */ if (0 < info->si_code) { /* If the faulting address is within the stack, or within one page of the stack end, assume that it is a stack overflow. */ ucontext_t const *user_context = context; char const *stack_min = user_context->uc_stack.ss_sp; size_t stack_size = user_context->uc_stack.ss_size; char const *faulting_address = info->si_addr; size_t s = faulting_address - stack_min; size_t page_size = sysconf (_SC_PAGESIZE); if (find_stack_direction (0) < 0) s += page_size; if (s < stack_size + page_size) signo = 0; } segv_action (signo, info, context); }
static void find_stack_direction (void) { static char *addr = NULL; /* address of first `dummy', once known */ char dummy; /* to get stack address */ if (addr == NULL) { /* initial entry */ // printf("1. addr \t%d\n", sizeof addr); printf("1. addr \t%lx\n", addr); printf("1. dummy \t%0lx\n", &dummy); addr = &dummy; find_stack_direction (); /* recurse once */ } else /* second entry */ { printf("2. addr \t%ld\n", (long)addr); printf("2. dummy \t%ld\n", (long)&dummy); if (&dummy > addr) stack_dir = 1; /* stack grew upward */ else stack_dir = -1; /* stack grew downward */ } }
static int find_stack_direction (char const *addr) { char dummy; return ! addr ? find_stack_direction (&dummy) : addr < &dummy ? 1 : -1; }
main () { exit (find_stack_direction() < 0); }
static int get_stack_location (char * const *argv) { # if ! (defined RLIMIT_STACK && defined _SC_PAGESIZE) errno = ENOTSUP; return -1; # else struct rlimit rlimit; int r = getrlimit (RLIMIT_STACK, &rlimit); if (r == 0) { char const *base; size_t size = rlimit.rlim_cur; extern char **environ; size_t page_size = sysconf (_SC_PAGESIZE); int stack_direction = find_stack_direction (0); # if HAVE_GETCONTEXT && HAVE_DECL_GETCONTEXT ucontext_t context; if (getcontext (&context) == 0) { base = context.uc_stack.ss_sp; if (stack_direction < 0) base -= size - context.uc_stack.ss_size; } else # endif { if (stack_direction < 0) { char const *a = max_address_from_argv (argv); char const *b = max_address_from_argv (environ); base = (a < b ? b : a) - size; base += - (size_t) base % page_size; } else { char const *a = min_address_from_argv (argv); char const *b = min_address_from_argv (environ); base = a < b ? a : b; base -= (size_t) base % page_size; } } if (size != rlimit.rlim_cur || rlimit.rlim_cur < 0 || base + size < base # ifdef RLIM_SAVED_CUR || rlimit.rlim_cur == RLIM_SAVED_CUR # endif # ifdef RLIM_SAVED_MAX || rlimit.rlim_cur == RLIM_SAVED_MAX # endif # ifdef RLIM_INFINITY || rlimit.rlim_cur == RLIM_INFINITY # endif ) { errno = EOVERFLOW; return -1; } stack_base = base; stack_size = size; # if DEBUG fprintf (stderr, "get_stack_location base=%p size=%lx\n", base, (unsigned long) size); # endif } return r; # endif }
int main(int argc, char** argv) { printf("sizeof(__int16_t)=%d\n", sizeof(__int16_t)); printf("sizeof(__int32_t)=%d\n", sizeof(__int32_t)); printf("sizeof(__int64_t)=%d\n", sizeof(__int64_t)); //printf("sizeof(cell_t)=%d\n", sizeof(cell_t)); printf("sizeof(char)=%d\n", sizeof(char)); printf("sizeof(char_p)=%d\n", sizeof(char*)); printf("sizeof(dev_t)=%d\n", sizeof(dev_t)); printf("sizeof(double)=%d\n", sizeof(double)); printf("sizeof(float)=%d\n", sizeof(float)); printf("sizeof(fpos_t)=%d\n", sizeof(fpos_t)); printf("sizeof(int16_t)=%d\n", sizeof(int16_t)); printf("sizeof(int32_t)=%d\n", sizeof(int32_t)); printf("sizeof(int64_t)=%d\n", sizeof(int64_t)); printf("sizeof(int8_t)=%d\n", sizeof(int8_t)); printf("sizeof(int)=%d\n", sizeof(int)); printf("sizeof(intmax_t)=%d\n", sizeof(intmax_t)); printf("sizeof(intptr_t)=%d\n", sizeof(intptr_t)); printf("sizeof(long)=%d\n", sizeof(long)); printf("sizeof(long double)=%d\n", sizeof(long double)); printf("sizeof(long long)=%d\n", sizeof(long long)); printf("sizeof(long long int)=%d\n", sizeof(long long int)); printf("sizeof(mode_t)=%d\n", sizeof(mode_t)); #ifdef INCLUDE_LFS_ONLY_TYPES printf("sizeof(off64_t)=%d\n", sizeof(off64_t)); #endif printf("sizeof(off_t)=%d\n", sizeof(off_t)); printf("sizeof(pid_t)=%d\n", sizeof(pid_t)); printf("sizeof(ptrdiff_t)=%d\n", sizeof(ptrdiff_t)); printf("sizeof(short)=%d\n", sizeof(short)); printf("sizeof(signed char)=%d\n", sizeof(signed char)); printf("sizeof(size_t)=%d\n", sizeof(size_t)); printf("sizeof(socklen_t)=%d\n", sizeof(socklen_t)); printf("sizeof(ssize_t)=%d\n", sizeof(ssize_t)); { struct stat x; FILE *fp; fp = fopen("/dev/null", "w"); if (fp != NULL) { printf("sizeof(stat_st_size)=%d\n", sizeof(x.st_size)); fclose(fp); } } //printf("sizeof(struct_iovec)=%d\n", sizeof(struct_iovec)); printf("sizeof(time_t)=%d\n", sizeof(time_t)); printf("sizeof(uint16_t)=%d\n", sizeof(uint16_t)); printf("sizeof(uint32_t)=%d\n", sizeof(uint32_t)); printf("sizeof(uint64_t)=%d\n", sizeof(uint64_t)); printf("sizeof(uint8_t)=%d\n", sizeof(uint8_t)); printf("sizeof(uintmax_t)=%d\n", sizeof(uintmax_t)); printf("sizeof(uintptr_t)=%d\n", sizeof(uintptr_t)); printf("sizeof(unsigned char)=%d\n", sizeof(unsigned char)); printf("sizeof(unsigned int)=%d\n", sizeof(unsigned int)); printf("sizeof(unsigned long)=%d\n", sizeof(unsigned long)); printf("sizeof(unsigned short)=%d\n", sizeof(unsigned short)); printf("sizeof(void_p)=%d\n", sizeof(void*)); printf("sizeof(voidp)=%d\n", sizeof(void*)); printf("sizeof(mbstate_t)=%d\n", sizeof(mbstate_t)); printf("sizeof(__off64_t)=%d\n", sizeof(__off64_t)); #ifdef __cplusplus { printf("cv_type_of_bool="); bool x = true; if ((bool)(-x) >= 0) printf("unsigned "); if (sizeof(x) == sizeof(int)) printf("int\n"); else if (sizeof(x) == sizeof(char)) printf("char\n"); else if (sizeof(x) == sizeof(short)) printf("short\n"); else if (sizeof(x) == sizeof(long)) printf("long\n"); } #endif { struct pollfd myfds; int code; myfds.fd = 0; myfds.events = POLLIN; code = poll(&myfds, 1, 100); printf("cf_cv_working_poll=%s\n", (code>=0) ? "yes" : "no"); } { struct timespec ts1, ts2; int code; ts1.tv_sec = 0; ts1.tv_nsec = 750000000; ts2.tv_sec = 0; ts2.tv_nsec = 0; errno = 0; code = nanosleep(&ts1, &ts2); /* on failure errno is ENOSYS. */ printf("cf_cv_func_nanosleep=%s\n", (code==0) ? "yes" : "no"); } { int n = write(1, TEXT, sizeof(TEXT)-1); printf("\nac_cv_write_stdout=%s\n", (n == sizeof(TEXT)-1) ? "yes" : "no"); } #ifdef __cplusplus { cookie_io_functions_t funcs = {reader, writer, seeker, closer}; struct cookiedata g = { 0 }; FILE *fp = fopencookie(&g, "r", funcs); printf("cookie_io_functions_use_off64_t=%s\n", (fp && fseek(fp, 8192, SEEK_SET) == 0 && g.pos == 8192) ? "yes" : "no"); } #endif { struct stat s, t; int code = #if 1 0; #else // doesn't compile so no ( stat ("conftestdata", &s) == 0 && utime("conftestdata", (long *)0) == 0 && stat("conftestdata", &t) == 0 && t.st_mtime >= s.st_mtime && t.st_mtime - s.st_mtime < 120 ); #endif printf("ac_cv_func_utime_null=%s\n", code ? "yes" : "no"); } printf("ac_cv_c_stack_direction=%d\n", find_stack_direction()); { DIR *dir; char entry[sizeof(struct dirent)+PATH_MAX]; struct dirent *pentry = (struct dirent *) &entry; int code; dir = opendir("/"); code = dir && (readdir_r(dir, (struct dirent *) entry, &pentry) == 0); printf("ac_cv_what_readdir_r=%s\n", code ? "POSIX" : "none"); } #if 0 { char c0 = 0x40, c1 = 0x80, c2 = 0x81; int code = memcmp(&c0, &c2, 1) < 0 && memcmp(&c1, &c2, 1) < 0; printf("ac_cv_func_memcmp_clean=%s\n", code ? "yes" : "no"); } #endif #if 0 // doesn't compile so no int foo = res_ninit(NULL); #endif { int code = getgroups(0, 0) != -1; printf("ac_cv_func_getgroups_works=%s\n", code ? "yes" : "no"); } { struct stat sbuf; int code = (stat("", &sbuf) == 0); printf("ac_cv_func_stat_empty_string_bug=%s\n", code ? "yes" : "no"); } { struct stat sbuf; int code = (lstat("", &sbuf) == 0); printf("ac_cv_func_lstat_empty_string_bug=%s\n", code ? "yes" : "no"); } { struct stat sbuf; int code = (lstat("conftest.sym/", &sbuf) == 0); printf("ac_cv_func_lstat_dereferences_slashed_symlink=%s (you should do 'echo > conftest.file && ln -s conftest.file conftest.sym' before running this test)\n", code ? "yes" : "no"); } { char buffer[10000]; struct passwd pwd; struct passwd* pwdp = &pwd; int error = getpwuid_r(0, &pwd, (char*)&buffer, sizeof(buffer), &pwdp); int code = (errno != ENOSYS); printf("ac_cv_func_getpwuid_r=%s\n", code ? "yes" : "no"); } { int sfd = socket(AF_UNIX, SOCK_STREAM, 0); int code = (sfd >= 0); if (code) close(sfd); printf("wi_cv_unix_domain_sockets=%s\n", code ? "yes" : "no"); } { struct hostent *hp1, *hp2; int code = 0; hp1 = gethostbyname("ftp.ncftp.com"); if (hp1 == (struct hostent *)0) { hp2 = gethostbyname("www.ibm.com"); if (hp2 == (struct hostent *)0) code = 1; } printf("wi_cv_look_for_resolv=%s\n", code ? "yes" : "no"); } { char s[16]; int i, result, code; for (i=0; i<(int)(sizeof(s)/sizeof(char)); i++) s[i] = 'x'; result = (int)snprintf(s + 1, 10, "%s %s!", "hello", "world"); if (s[10] != '\0') code = 1; /* did not force termination! */ else if (s[11] != 'x') code = 2; /* overflow! */ else if (s[0] != 'x') code = 3; /* underflow! */ else code = 0; printf("wi_cv_snprintf_terminates=%s\n", (code==0) ? "yes" : "no"); } { char s[8]; int result = (int)snprintf(s, sizeof(s) - 1, "%d", 22); printf("wi_cv_snprintf_returns_ptr=%s\n", (result == 2) ? "no" : "yes"); } #if 0 { //doesn't compile -> no int test_SYS = SYS_ioprio_set; int test_NR = _NR_ioprio_set; } #endif { /* The string "%2$d %1$d", with dollar characters protected from the shell's dollar expansion (possibly an autoconf bug). */ static char format[] = { '%', '2', '$', 'd', ' ', '%', '1', '$', 'd', '\0' }; static char buf[100]; int code; sprintf(buf, format, 33, 55); code = (strcmp (buf, "55 33") == 0); printf("gt_cv_func_printf_posix=%s\n", code ? "yes" : "no"); } { int code = ac_cv_c_c99_format(); printf("ac_cv_c_c99_format=%s\n", code==0 ? "yes" : "no"); } { int code = ac_cv_fread_reads_directories(); printf("ac_cv_fread_reads_directories=%s\n", code ? "yes" : "no"); } { int code = ac_cv_snprintf_returns_bogus(); printf("ac_cv_snprintf_returns_bogus=%s\n", code ? "yes" : "no"); } { uint64_t i0; uint64_t i1; uint8_t c[8]; double d; d = 8.642135e130; memcpy ((void *) &i0, (void *) &d, 8); i1 = i0; memcpy ((void *) c, (void *) &i1, 8); int code = ( (c[0] == 0x2f) && (c[1] == 0x25) && (c[2] == 0xc0) && (c[3] == 0xc7) && (c[4] == 0x43) && (c[5] == 0x2b) && (c[6] == 0x1f) && (c[7] == 0x5b) ); printf("c_cv_fp_layout_need_nothing=%s\n", code ? "yes" : "no"); } }