int TclpGetCStackParams( int **stackBoundPtr) { int result = TCL_OK; size_t stackSize = 0; /* The size of the current stack. */ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); /* Most variables are actually in a * thread-specific data block to minimise the * impact on the stack. */ #ifdef TCL_CROSS_COMPILE if (stackGrowsDown == -1) { /* * Not initialised! */ stackGrowsDown = StackGrowsDown(&result); } #endif /* * The first time through in a thread: record the "outermost" stack * frame and inquire with the OS about the stack size. */ if (tsdPtr->outerVarPtr == NULL) { tsdPtr->outerVarPtr = &result; result = GetStackSize(&stackSize); if (result != TCL_OK) { /* Can't check, assume it always succeeds */ #ifdef TCL_CROSS_COMPILE stackGrowsDown = 1; #endif tsdPtr->stackBound = NULL; goto done; } } if (stackSize || (tsdPtr->stackBound && ((stackGrowsDown && (&result < tsdPtr->stackBound)) || (!stackGrowsDown && (&result > tsdPtr->stackBound))))) { /* * Either the thread's first pass or stack failure: set the params */ if (!stackSize) { /* * Stack failure: if we didn't already blow up, we are within the * safety area. Recheck with the OS in case the stack was grown. */ result = GetStackSize(&stackSize); if (result != TCL_OK) { /* Can't check, assume it always succeeds */ #ifdef TCL_CROSS_COMPILE stackGrowsDown = 1; #endif tsdPtr->stackBound = NULL; goto done; } } if (stackGrowsDown) { tsdPtr->stackBound = (int *) ((char *)tsdPtr->outerVarPtr - stackSize); } else { tsdPtr->stackBound = (int *) ((char *)tsdPtr->outerVarPtr + stackSize); } } done: *stackBoundPtr = tsdPtr->stackBound; return stackGrowsDown; }
int num_segments() { FILE *pfs; char proc[128]; char rperm, wperm, xperm, priv; int scm; int num_seg=0; int major, minor, inode; int mem_start, mem_end; int offset; char e, f; scm=SetSyscalls(SYS_LOCAL | SYS_UNMAPPED); sprintf(proc, "/proc/%d/maps", syscall(SYS_getpid)); pfs=safe_fopen_wrapper(proc, "r"); if(!pfs) { SetSyscalls(scm); return -1; } // Count the numer of mmapped files in use by the executable while(1) { int result = fscanf(pfs, "%x-%x %c%c%c%c %x %d:%d %d\n", &mem_start, &mem_end, &rperm, &wperm, &xperm, &priv, &offset, &major, &minor, &inode); if(result!=10) break; /*fprintf(stderr, "0x%x 0x%x %c%c%c%c 0x%x %d:%d %d\n", mem_start, mem_end, rperm, wperm, xperm, priv, offset, major, minor, inode);*/ my_map[num_seg].mem_start=mem_start; my_map[num_seg].mem_end=mem_end-1; /* FIXME - Greger */ if(my_map[num_seg].mem_end-my_map[num_seg].mem_start==0x34000-1) my_map[num_seg].mem_end=my_map[num_seg].mem_start+0x320ff; my_map[num_seg].offset=offset; my_map[num_seg].prot=(rperm=='r'?PROT_READ:0) | (wperm=='w'?PROT_WRITE:0) | (xperm=='x'?PROT_EXEC:0); my_map[num_seg].flags=(priv=='p'?:0); my_map[num_seg].inode=inode; my_map[num_seg].r=rperm; my_map[num_seg].w=wperm; my_map[num_seg].x=xperm; my_map[num_seg].p=priv; num_seg++; } fclose(pfs); map_count=num_seg; text_loc=find_map_for_addr((long)num_segments); if(StackGrowsDown()) stack_loc=find_map_for_addr((long)stack_end_addr()); else stack_loc=find_map_for_addr((long)stack_start_addr()); heap_loc=find_map_for_addr((long)data_start_addr()); /*fprintf(stderr, "%d segments\n", num_seg);*/ SetSyscalls(scm); return num_seg; }