1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <errno.h>
21: #include <stdlib.h>
22: #include <stdio.h>
23: #include <string.h>
24: #include <hurd.h>
25: #include <hurd/exec_startup.h>
26: #include <sysdep.h>
27: #include <hurd/threadvar.h>
28: #include <unistd.h>
29: #include <elf.h>
30: #include <set-hooks.h>
31: #include "hurdstartup.h"
32: #include <argz.h>
33:
34: mach_port_t *_hurd_init_dtable;
35: mach_msg_type_number_t _hurd_init_dtablesize;
36:
37: extern void __mach_init (void);
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57: void
58: _hurd_startup (void **argptr, void (*main) (intptr_t *data))
59: {
60: error_t err;
61: mach_port_t in_bootstrap;
62: char *args, *env;
63: mach_msg_type_number_t argslen, envlen;
64: struct hurd_startup_data data;
65: char **argv, **envp;
66: int argc, envc;
67: intptr_t *argcptr;
68: vm_address_t addr;
69:
70:
71:
72: addr = 0;
73: __vm_map (__mach_task_self (),
74: &addr, __vm_page_size, 0, 0, MACH_PORT_NULL, 0, 1,
75: VM_PROT_NONE, VM_PROT_NONE, VM_INHERIT_COPY);
76:
77: if (err = __task_get_special_port (__mach_task_self (), TASK_BOOTSTRAP_PORT,
78: &in_bootstrap))
79: LOSE;
80:
81: if (in_bootstrap != MACH_PORT_NULL)
82: {
83:
84:
85:
86: argslen = envlen = 0;
87: data.dtablesize = data.portarraysize = data.intarraysize = 0;
88:
89: err = __exec_startup_get_info (in_bootstrap,
90: &data.user_entry,
91: &data.phdr, &data.phdrsz,
92: &data.stack_base, &data.stack_size,
93: &data.flags,
94: &args, &argslen,
95: &env, &envlen,
96: &data.dtable, &data.dtablesize,
97: &data.portarray, &data.portarraysize,
98: &data.intarray, &data.intarraysize);
99: __mach_port_deallocate (__mach_task_self (), in_bootstrap);
100: }
101:
102: if (err || in_bootstrap == MACH_PORT_NULL || (data.flags & EXEC_STACK_ARGS))
103: {
104:
105:
106:
107:
108:
109:
110: argcptr = (intptr_t *) argptr;
111: argc = argcptr[0];
112: argv = (char **) &argcptr[1];
113: envp = &argv[argc + 1];
114: envc = 0;
115: while (envp[envc])
116: ++envc;
117: }
118: else
119: {
120:
121:
122:
123:
124: argc = __argz_count (args, argslen);
125:
126: envc = __argz_count (env, envlen);
127:
128:
129:
130:
131:
132: argcptr = __alloca (sizeof (intptr_t) +
133: (argc + 1 + envc + 1) * sizeof (char *) +
134: sizeof (struct hurd_startup_data));
135: *argcptr = argc;
136: argv = (void *) (argcptr + 1);
137: __argz_extract (args, argslen, argv);
138:
139:
140: envp = &argv[argc + 1];
141: __argz_extract (env, envlen, envp);
142: }
143:
144: if (err || in_bootstrap == MACH_PORT_NULL)
145: {
146:
147:
148:
149: data.flags = 0;
150: args = env = NULL;
151: argslen = envlen = 0;
152: data.dtable = NULL;
153: data.dtablesize = 0;
154: data.portarray = NULL;
155: data.portarraysize = 0;
156: data.intarray = NULL;
157: data.intarraysize = 0;
158: }
159: else if ((void *) &envp[envc + 1] == argv[0])
160: {
161:
162:
163:
164: struct
165: {
166: intptr_t count;
167: char *argv[argc + 1];
168: char *envp[envc + 1];
169: struct hurd_startup_data data;
170: } *args = alloca (sizeof *args);
171: if ((void *) &args[1] == (void *) argcptr)
172: args = alloca (-((char *) &args->data - (char *) args));
173: memmove (args, argcptr, (char *) &args->data - (char *) args);
174: argcptr = (void *) args;
175: argv = args->argv;
176: envp = args->envp;
177: }
178:
179: {
180: struct hurd_startup_data *d = (void *) &envp[envc + 1];
181:
182: if ((void *) d != argv[0])
183: {
184: *d = data;
185: _hurd_init_dtable = d->dtable;
186: _hurd_init_dtablesize = d->dtablesize;
187: }
188:
189: (*main) (argcptr);
190: }
191:
192:
193: LOSE;
194: abort ();
195: }