Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory layout of argc, argv, envp

Tags:

c

linux

From what I understand, the values of the environment variables are in memory directly after the NULL-terminated argv values. Beyond the env variables, auxv is present.

How exactly are the environment variables laid out – where is this layout specified / documented? And what systems does it apply to?

like image 246
djd Avatar asked May 12 '14 01:05

djd


1 Answers

A simple answer will be: the layout of the stack on program invocation is defined by the binary format definitions (such as ELF spec: http://refspecs.linuxbase.org/elf/abi386-4.pdf, check out figure 3-31 for the initial stack layout on exec).

As Linux is not limited to the ELF executables and can support multiple binary formats using its binfmt interpreter framework, the actual handling of argv/envp data happens in 2 stages.

First, when sys_execve system call is invoked, the kernel will create a virtual memory mapping for the new process stack. Then it will use a page or few (up to the 32 pages arbitrary limit) from the bottom of the stack to store a copy of the argv/envp parameters supplied:

bprm->exec = bprm->p;
retval = copy_strings(bprm->envc, envp, bprm);
if (retval < 0)
    goto out;

retval = copy_strings(bprm->argc, argv, bprm);
if (retval < 0)
    goto out;

(http://code.metager.de/source/xref/linux/stable/fs/exec.c#1502)

During the second stage, bprm object is passed to the binfmt interpreter (together with associated memory mappings). The interpreter, beside other things, will push additional info to the stack, including the argument/environment entry counts and pointers. For elf executables it will happen in create_elf_tables:

/* Now, let's put argc (and argv, envp if appropriate) on the stack */
if (__put_user(argc, sp++))
    return -EFAULT;
argv = sp;
envp = argv + argc + 1;

/* Populate argv and envp */
p = current->mm->arg_end = current->mm->arg_start;
while (argc-- > 0) {...

(http://code.metager.de/source/xref/linux/stable/fs/binfmt_elf.c#293)

The interpreter here is actually building the structure outlined in figure 3-31 in the spec linked above.

like image 184
oakad Avatar answered Sep 23 '22 10:09

oakad