• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 #include <mm/mm.h>
13 #include <common/util.h>
14 
15 #include "thread_env.h"
16 
17 /*
18  * Setup the initial environment for a user process (main thread).
19  *
20  * According to Libc convention, we current set the environment
21  * on the user stack.
22  *
23  */
24 
25 #define AT_NULL     0 /* end of vector */
26 #define AT_IGNORE   1 /* entry should be ignored */
27 #define AT_EXECFD   2 /* file descriptor of program */
28 #define AT_PHDR     3 /* program headers for program */
29 #define AT_PHENT    4 /* size of program header entry */
30 #define AT_PHNUM    5 /* number of program headers */
31 #define AT_PAGESZ   6 /* system page size */
32 #define AT_BASE     7 /* base address of interpreter */
33 #define AT_FLAGS    8 /* flags */
34 #define AT_ENTRY    9 /* entry point of program */
35 #define AT_NOTELF   10 /* program is not ELF */
36 #define AT_UID      11 /* real uid */
37 #define AT_EUID     12 /* effective uid */
38 #define AT_GID      13 /* real gid */
39 #define AT_EGID     14 /* effective gid */
40 #define AT_PLATFORM 15 /* string identifying CPU for optimizations */
41 #define AT_HWCAP    16 /* arch dependent hints at CPU capabilities */
42 #define AT_CLKTCK   17 /* frequency at which times() increments */
43 /* AT_* values 18 through 22 are reserved */
44 #define AT_SECURE 23 /* secure mode boolean */
45 /* string identifying real platform, may differ from AT_PLATFORM. */
46 #define AT_BASE_PLATFORM 24
47 #define AT_RANDOM        25 /* address of 16 random bytes */
48 #define AT_HWCAP2        26 /* extension of AT_HWCAP */
49 #define AT_EXECFN        31 /* filename of program */
50 
51 #if defined(CHCORE_ARCH_X86_64)
52 const char PLAT[] = "x86_64";
53 #elif defined(CHCORE_ARCH_AARCH64)
54 const char PLAT[] = "aarch64";
55 #else
56 const char PLAT[] = "unknown";
57 #endif
58 
59 struct env_buf {
60     unsigned long *entries_tail;
61     unsigned long *entries_end;
62     char *strings_tail;
63     char *strings_end;
64     unsigned long strings_offset;
65 };
66 
env_buf_append_int(struct env_buf * env_buf,unsigned long val)67 static void env_buf_append_int(struct env_buf *env_buf, unsigned long val)
68 {
69     BUG_ON(env_buf->entries_tail >= env_buf->entries_end);
70     *(env_buf->entries_tail++) = val;
71 }
72 
env_buf_append_str(struct env_buf * env_buf,const char * val)73 static void env_buf_append_str(struct env_buf *env_buf, const char *val)
74 {
75     int i = 0;
76     int val_size = strlen(val) + 1;
77 
78     BUG_ON(env_buf->strings_tail + val_size > env_buf->strings_end);
79     while (val[i] != '\0') {
80         env_buf->strings_tail[i] = val[i];
81         i++;
82     }
83     env_buf_append_int(env_buf,
84                        (unsigned long)env_buf->strings_tail
85                            + env_buf->strings_offset);
86     env_buf->strings_tail += val_size;
87 }
88 
env_buf_append_int_auxv(struct env_buf * env_buf,unsigned long type,unsigned long val)89 static void env_buf_append_int_auxv(struct env_buf *env_buf, unsigned long type,
90                                     unsigned long val)
91 {
92     env_buf_append_int(env_buf, type);
93     env_buf_append_int(env_buf, val);
94 }
95 
env_buf_append_str_auxv(struct env_buf * env_buf,unsigned long type,const char * val)96 static void env_buf_append_str_auxv(struct env_buf *env_buf, unsigned long type,
97                                     const char *val)
98 {
99     env_buf_append_int(env_buf, type);
100     env_buf_append_str(env_buf, val);
101 }
102 
103 #define FAKE_UGID       1000
104 #define FAKE_CLKTLK     100
105 #define FAKE_RANDOM_OFF 64
106 
107 /*
108  * For setting up the stack (env) of some process.
109  *
110  * env: stack top address used by kernel
111  * top_vaddr: stack top address mapped to user
112  */
prepare_env(char * env,vaddr_t top_vaddr,char * name,struct process_metadata * meta)113 void prepare_env(char *env, vaddr_t top_vaddr, char *name,
114                  struct process_metadata *meta)
115 {
116     struct env_buf env_buf;
117     /* clear env */
118     memset(env, 0, ENV_SIZE_ON_STACK);
119 
120     env_buf.entries_tail = (unsigned long *)env;
121     env_buf.entries_end = (unsigned long *)(env + ENV_SIZE_ON_STACK / 2);
122     env_buf.strings_tail = (char *)env_buf.entries_end;
123     env_buf.strings_end = env + ENV_SIZE_ON_STACK;
124     env_buf.strings_offset = top_vaddr - ENV_SIZE_ON_STACK - (long)env;
125 
126     /** argc */
127     env_buf_append_int(&env_buf, 1);
128     /** argv(only program cmd) */
129     env_buf_append_str(&env_buf, name);
130 
131     /** end of argv */
132     env_buf_append_int(&env_buf, 0);
133 
134     /** end of envp(empty envp) */
135     env_buf_append_int(&env_buf, 0);
136 
137     env_buf_append_int_auxv(&env_buf, AT_SECURE, 0);
138     env_buf_append_int_auxv(&env_buf, AT_PAGESZ, PAGE_SIZE);
139     env_buf_append_int_auxv(&env_buf, AT_PHDR, meta->phdr_addr);
140     env_buf_append_int_auxv(&env_buf, AT_PHENT, meta->phentsize);
141     env_buf_append_int_auxv(&env_buf, AT_PHNUM, meta->phnum);
142     env_buf_append_int_auxv(&env_buf, AT_FLAGS, meta->flags);
143     env_buf_append_int_auxv(&env_buf, AT_ENTRY, meta->entry);
144     env_buf_append_int_auxv(&env_buf, AT_UID, FAKE_UGID);
145     env_buf_append_int_auxv(&env_buf, AT_EUID, FAKE_UGID);
146     env_buf_append_int_auxv(&env_buf, AT_GID, FAKE_UGID);
147     env_buf_append_int_auxv(&env_buf, AT_EGID, FAKE_UGID);
148     env_buf_append_int_auxv(&env_buf, AT_CLKTCK, FAKE_CLKTLK);
149     env_buf_append_int_auxv(&env_buf, AT_HWCAP, 0);
150     env_buf_append_str_auxv(&env_buf, AT_PLATFORM, PLAT);
151     env_buf_append_int_auxv(&env_buf, AT_RANDOM, top_vaddr - FAKE_RANDOM_OFF);
152     env_buf_append_int_auxv(&env_buf, AT_NULL, 0);
153 
154     /* add more auxv here */
155 }
156