Beispiel #1
0
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 */
}
Beispiel #2
0
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;
}
Beispiel #3
0
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 */
}