void* setup_main_stack(const char* command_line, void* stack_top) { /* Variable "esp" stores an address, and at the memory loaction * pointed out by that address a "struct main_args" is found. * That is: "esp" is a pointer to "struct main_args" */ struct main_args* esp; int argc; int total_size; int line_size; /* "cmd_line_on_stack" and "ptr_save" are variables that each store * one address, and at that address (the first) char (of a possible * sequence) can be found. */ char* cmd_line_on_stack; char* ptr_save; //int i = 0; /* CALCULate the bytes needed to store the command_line */ line_size = strlen(command_line) + 1; STACK_DEBUG("# line_size = %d\n", line_size); char* new_command_line = malloc(line_size); strlcpy(new_command_line, command_line, line_size); char* curr; char** saveptr; argc = 0; line_size = 0; for(curr = strtok_r(new_command_line, " ", &saveptr); curr != NULL; curr = strtok_r(NULL, " ", &saveptr)) { ++argc; for(;*curr != '\0';++curr) { *(new_command_line+line_size) = *curr; ++line_size; } *(new_command_line+line_size) = ' '; ++line_size; } *(new_command_line+line_size) = '\0'; STACK_DEBUG("# new_command_line = '%s'\n# new_line_size = '%d'\n", new_command_line, line_size); /* round up to make it even divisible by 4 */ line_size += 3 - (line_size - 1) % 4; STACK_DEBUG("# line_size (aligned) = %d\n", line_size); /* calculate how many words the command_line contain */ STACK_DEBUG("# argc = %d\n", argc); /* calculate the size needed on our simulated stack */ total_size = (4 + argc)*sizeof(int) + line_size; STACK_DEBUG("# total_size = %d\n", total_size); /* calculate where the final stack top for the program will be located */ esp = stack_top - total_size; /* setup return address and argument count */ esp->ret = NULL; esp->argc = argc; /* calculate where in the memory the argv array starts */ esp->argv = esp + 1; /* calculate where in the memory the words is stored */ cmd_line_on_stack = stack_top - line_size; /* copy the command_line to where it should be in the stack */ strlcpy(cmd_line_on_stack, new_command_line, line_size); /* build argv array and insert null-characters after each word */ esp->argv[0] = cmd_line_on_stack; int i = 1; for(curr = cmd_line_on_stack; *curr != '\0'; ++curr) { if(*curr == ' ') { *curr = '\0'; esp->argv[i] = curr+1; ++i; } } esp->argv[argc] = NULL; return esp; /* the new stack top */ }
static int GetStackSize( size_t *stackSizePtr) { size_t rawStackSize; struct rlimit rLimit; /* The result from getrlimit(). */ #ifdef TCL_THREADS rawStackSize = TclpThreadGetStackSize(); if (rawStackSize == (size_t) -1) { /* * Some kind of confirmed error in TclpThreadGetStackSize?! Fall back * to whatever getrlimit can determine. */ STACK_DEBUG(("stack checks: TclpThreadGetStackSize failed in \n")); } if (rawStackSize > 0) { goto finalSanityCheck; } /* * If we have zero or an error, try the system limits instead. After all, * the pthread documentation states that threads should always be bound by * the system stack size limit in any case. */ #endif /* TCL_THREADS */ if (getrlimit(RLIMIT_STACK, &rLimit) != 0) { /* * getrlimit() failed, just fail the whole thing. */ STACK_DEBUG(("skipping stack checks with failure: getrlimit failed\n")); return TCL_BREAK; } if (rLimit.rlim_cur == RLIM_INFINITY) { /* * Limit is "infinite"; there is no stack limit. */ STACK_DEBUG(("skipping stack checks with success: infinite limit\n")); return TCL_CONTINUE; } rawStackSize = rLimit.rlim_cur; /* * Final sanity check on the determined stack size. If we fail this, * assume there are bogus values about and that we can't actually figure * out what the stack size really is. */ #ifdef TCL_THREADS /* Stop warning... */ finalSanityCheck: #endif if (rawStackSize <= 0) { STACK_DEBUG(("skipping stack checks with success\n")); return TCL_CONTINUE; } /* * Calculate a stack size with a safety margin. */ *stackSizePtr = (rawStackSize / TCL_MAGIC_STACK_DIVISOR) - (getpagesize() * TCL_RESERVED_STACK_PAGES); return TCL_OK; }
void* setup_main_stack(const char* command_line, void* stack_top) { /* Variable "esp" stores an address, and at the memory loaction * pointed out by that address a "struct main_args" is found. * That is: "esp" is a pointer to "struct main_args" */ struct main_args* esp; int argc; int total_size; int line_size; /* "cmd_line_on_stack" and "ptr_save" are variables that each store * one address, and at that address (the first) char (of a possible * sequence) can be found. */ char* cmd_line_on_stack; char* ptr_save; int i = 0; /* calculate the bytes needed to store the command_line */ line_size = strlen(command_line) + 1; STACK_DEBUG("# line_size = %d\n", line_size); /* round up to make it even divisible by 4 */ line_size = line_size + (4 - line_size%4); STACK_DEBUG("# line_size (aligned) = %d\n", line_size); /* calculate how many words the command_line contain */ argc = count_args(command_line," ") ; STACK_DEBUG("# argc = %d\n", argc); /* calculate the size needed on our simulated stack */ total_size = line_size + (argc * 4) + (4 * 4) ; STACK_DEBUG("# total_size = %d\n", total_size); /* calculate where the final stack top will be located */ esp = stack_top - total_size; /* setup return address and argument count */ esp->ret = NULL ; esp->argc = argc ; /* calculate where in the memory the argv array starts */ esp->argv = (char**)((unsigned)esp + 3*4); /* calculate where in the memory the words is stored */ cmd_line_on_stack = (char*)((unsigned)esp + 4*4 + argc*4) ; /* copy the command_line to where it should be in the stack */ bool new_word_flag = false; int argv_c = 0; for(i; i < line_size && argv_c <= argc; ++i) { if(new_word_flag || (i == 0 && command_line[i] != ' ')){ esp->argv[argv_c] = (char*) cmd_line_on_stack + i; ++argv_c; } if(command_line[i] != ' '){ cmd_line_on_stack[i] = command_line[i]; new_word_flag = false; } else{ cmd_line_on_stack[i] = '\0'; new_word_flag = true; } } /* build argv array and insert null-characters after each word */ return esp; /* the new stack top */ }