Process initialization

This section describes the machine state that exec creates for "infant" processes, including argument passing, register usage, and stack frame layout. Programming language systems use this initial program state to establish a standard environment for their application programs. For example, a C program begins executing at a function named main, conventionally declared in the way described in Figure 21:

   extern int main (int argc, char

*argv[ ], char *envp[ ]);

Figure 21. Declaration for main

Briefly, argc is a non-negative argument count; argv is an array of argument strings, with argv[argc] == 0, and envp is an array of environment strings, also terminated by a NULL pointer.

Although this section does not describe C program initialization, it gives the information necessary to implement the call to main or to the entry point for a program in any other language.

Registers

When a process is first entered (from an exec system call), the contents of registers other than those listed below are unspecified. Consequently, a program that requires registers to have specific values must set them explicitly during process initialization. It should not rely on the operating system to set all registers to 0. Following are the registers whose contents are specified:

Table 13.

r15

The initial stack pointer, aligned to a 8-byte boundary and pointing to a stack location that contains the argument count (see the Section called Process stack for further information about the initial stack layout)

fpc

The floating point control register contains 0, specifying "round to nearest" mode and the disabling of floating-point exceptions

Process stack

Every process has a stack, but the system defines no fixed stack address. Furthermore, a program's stack address can change from one system to another – even from one process invocation to another. Thus the process initialization code must use the stack address in general purpose register r15. Data in the stack segment at addresses below the stack pointer contain undefined values.

Whereas the argument and environment vectors transmit information from one application program to another, the auxiliary vector conveys information from the operating system to the program. This vector is an array of structures, which are defined in Figure 22.

typedef struct {

                long a_type;

                union {

                       long a_val;

                       void *a_ptr;

                       void (*a_fcn)();

               } a_un;

} auxv_t;

Figure 22. Auxiliary vector structure

The structures are interpreted according to the a_type member, as shown in Table 14.

Table 14. Auxiliary Vector Types, a_type

Name

Value

a_un

AT_NULL

0

ignored

AT_IGNORE

1

ignored

AT_EXECFD

2

a_val

AT_PHDR

3

a_ptr

AT_PHENT

4

a_val

AT_PHNUM

5

a_val

AT_PAGESZ

6

a_val

AT_BASE

7

a_ptr

AT_FLAGS

8

a_val

AT_ENTRY

9

a_ptr

AT_NOTELF

10

a_val

AT_UID

11

a_val

AT_EUID

12

a_val

AT_GID

13

a_val

AT_EGID

14

a_val

a_type auxiliary vector types are described in 'Auxiliary Vector Types Description' below.

Auxiliary Vector Types Description

AT_NULL

The auxiliary vector has no fixed length; so an entry of this type is used to denote the end of the vector. The corresponding value of a_un is undefined.

AT_IGNORE

This type indicates the entry has no meaning. The corresponding value of a_un is undefined.

AT_EXECFD

exec may pass control to an interpreter program. When this happens, the system places either an entry of type AT_EXECFD or one of type AT_PHDR in the auxiliary vector. The a_val field in the AT_EXECFD entry contains a file descriptor for the application program's object file.

AT_PHDR

Under some conditions, the system creates the memory image of the application program before passing control to an interpreter program. When this happens, the a_ptr field of the AT_PHDR entry tells the interpreter where to find the program header table in the memory image. If the AT_PHDR entry is present, entries of types AT_PHENT, AT_PHNUM and AT_ENTRY must also be present. See the section the Chapter called Program loading and dynamic linking for more information about the program header table.

AT_PHENT

The a_val field of this entry holds the size, in bytes, of one entry in the program header table at which the AT_PHDR entry points.

AT_PHNUM

The a_val field of this entry holds the number of entries in the program header table at which the AT_PHDR entry points.

AT_PAGESZ

If present this entry's a_val field gives the system page size in bytes. The same information is also available through sysconf.

AT_BASE

The a_ptr member of this entry holds the base address at which the interpreter program was loaded into memory.

AT_FLAGS

If present, the a_val field of this entry holds 1-bit flags. Undefined bits are set to zero.

AT_ENTRY

The a_ptr field of this entry holds the entry point of the application program to which the interpreter program should transfer control.

AT_NOTELF

The a_val field of this entry is non-zero if the program is in another format than ELF, for example in the old COFF format.

AT_UID

The a_ptr field of this entry holds the real user id of the process.

AT_EUID

The a_ptr field of this entry holds the effective user id of the process.

AT_GID

The a_ptr field of this entry holds the real group id of the process.

AT_EGID

The a_ptr field of this entry holds the effective group id of the process.

Other auxiliary vector types are reserved. No flags are currently defined for AT_FLAGS on the zSeries architecture.

When a process receives control, its stack holds the arguments, environment, and auxiliary vector from exec. Argument strings, environment strings, and the auxiliary information appear in no specific order within the information block; the system makes no guarantees about their relative arrangement. The system may also leave an unspecified amount of memory between the null auxiliary vector entry and the beginning of the information block. A sample initial stack is shown in Figure 23.

Figure 23. Initial Process Stack