1.1 --- a/tests/dstest_exec.cc Sun May 01 23:25:09 2022 +0200
1.2 +++ b/tests/dstest_exec.cc Mon May 02 23:45:37 2022 +0200
1.3 @@ -72,12 +72,104 @@
1.4 }
1.5 };
1.6
1.7 -typedef std::map<l4_addr_t, Region> Regions;
1.8 +
1.9 +
1.10 +/* Program segment abstraction. */
1.11 +
1.12 +class Segment
1.13 +{
1.14 +protected:
1.15 + Region _region;
1.16 +
1.17 +public:
1.18 + /* Allocated memory. */
1.19 +
1.20 + char *buf;
1.21 + l4re_ds_t ds;
1.22 +
1.23 + /* Segment base and corresponding region base. */
1.24 +
1.25 + l4_addr_t base, region_base;
1.26 +
1.27 + /* Segment size and corresponding region size. */
1.28 +
1.29 + offset_t size, region_size;
1.30 +
1.31 + /* Offset of segment content within the region. */
1.32 +
1.33 + offset_t region_offset;
1.34 +
1.35 + /* Access flags. */
1.36 +
1.37 + l4re_rm_flags_t flags;
1.38 +
1.39 + /* File access details. */
1.40 +
1.41 + offset_t file_offset, file_contents;
1.42 +
1.43 + explicit Segment(offset_t base, offset_t size, l4re_rm_flags_t flags,
1.44 + offset_t file_offset = 0, offset_t file_contents = 0)
1.45 + : base(base), size(size), flags(flags), file_offset(file_offset), file_contents(file_contents)
1.46 + {
1.47 + region_base = trunc(base, L4_PAGESIZE);
1.48 + region_offset = base - region_base;
1.49 + region_size = round(size, L4_PAGESIZE);
1.50 + }
1.51 +
1.52 + long allocate();
1.53 +
1.54 + long fill(file_t *file);
1.55 +
1.56 + Region ®ion();
1.57 +
1.58 + l4_addr_t region_address(char *address);
1.59 +
1.60 + l4_addr_t region_address(l4_addr_t address);
1.61 +};
1.62 +
1.63 +long Segment::allocate()
1.64 +{
1.65 + return ipc_allocate_align(size, L4RE_RM_F_SEARCH_ADDR | flags,
1.66 + L4_PAGESHIFT, (void **) &buf, &ds);
1.67 +}
1.68 +
1.69 +long Segment::fill(file_t *file)
1.70 +{
1.71 + if (!file_contents)
1.72 + return L4_EOK;
1.73 +
1.74 + memset(buf, 0, region_size);
1.75 + client_seek(file, file_offset, SEEK_SET);
1.76 + offset_t nread = client_read(file, buf + region_offset, file_contents);
1.77 +
1.78 + if (nread < file_contents)
1.79 + return -L4_EIO;
1.80 + else
1.81 + return L4_EOK;
1.82 +}
1.83 +
1.84 +Region &Segment::region()
1.85 +{
1.86 + _region = Region((l4_addr_t) buf, page_order(region_size), flags, region_base);
1.87 + return _region;
1.88 +}
1.89 +
1.90 +l4_addr_t Segment::region_address(char *address)
1.91 +{
1.92 + return (l4_addr_t) ((address - buf) + (char *) region_base);
1.93 +}
1.94 +
1.95 +l4_addr_t Segment::region_address(l4_addr_t address)
1.96 +{
1.97 + return (address - (l4_addr_t) buf) + region_base;
1.98 +}
1.99
1.100
1.101
1.102 /* A simple system pager also acting as a region mapper. */
1.103
1.104 +typedef std::map<l4_addr_t, Region> Regions;
1.105 +
1.106 class ExecPager : public PagerObject
1.107 {
1.108 protected:
1.109 @@ -405,61 +497,39 @@
1.110 /* Copy the payload regions to new dataspaces.
1.111 NOTE: This should be directed by the ELF metadata. */
1.112
1.113 - address_t program_region_base = 0x1000000;
1.114 address_t program_start = 0x1000af3;
1.115
1.116 - char *program_buf;
1.117 - offset_t nread;
1.118 - offset_t program_region_contents = 0x282ae;
1.119 - offset_t program_region_size = round(program_region_contents, L4_PAGESIZE);
1.120 - l4re_ds_t program_region_ds;
1.121 + Segment program(0x1000000, 0x282ae, L4_FPAGE_RWX, 0, 0x282ae);
1.122 + Segment data(0x1029360, 0x8068, L4_FPAGE_RW, 0x28360, 0x2058);
1.123 + Segment stack(0x80000000, 16 * L4_PAGESIZE, L4_FPAGE_RW);
1.124 + Segment *segments[] = {&program, &data, &stack, NULL};
1.125 + Segment **segment;
1.126 +
1.127 + for (segment = segments; *segment != NULL; segment++)
1.128 + {
1.129 + err = (*segment)->allocate();
1.130
1.131 - err = ipc_allocate_align(program_region_size, L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_RWX,
1.132 - L4_PAGESHIFT, (void **) &program_buf, &program_region_ds);
1.133 + if (err)
1.134 + {
1.135 + printf("Could not reserve memory.\n");
1.136 + return 1;
1.137 + }
1.138
1.139 - if (err)
1.140 - {
1.141 - printf("Could not reserve program memory.\n");
1.142 - return 1;
1.143 + err = (*segment)->fill(file);
1.144 +
1.145 + if (err)
1.146 + {
1.147 + printf("Could not fill segment from file.\n");
1.148 + return 1;
1.149 + }
1.150 }
1.151
1.152 - nread = client_read(file, program_buf, program_region_contents);
1.153 -
1.154 - printf("Read %ld from file into %p.\n", nread, program_buf);
1.155 -
1.156 - if (memcmp(program_buf + program_start - program_region_base, "\x31\xed", 2))
1.157 + if (memcmp(program.buf + program_start - program.region_base, "\x31\xed", 2))
1.158 {
1.159 printf("Did not find expected instructions at start.\n");
1.160 return 1;
1.161 }
1.162
1.163 - offset_t data_region_start = 0x1029360;
1.164 - offset_t data_region_size = round(0x8068, L4_PAGESIZE);
1.165 - offset_t data_region_base = trunc(data_region_start, L4_PAGESIZE);
1.166 - offset_t data_region_offset = data_region_start - data_region_base;
1.167 -
1.168 - char *data_buf;
1.169 - offset_t data_file_offset = 0x28360;
1.170 - offset_t data_region_contents = 0x2058;
1.171 - l4re_ds_t data_region_ds;
1.172 -
1.173 - err = ipc_allocate_align(data_region_size, L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_RW,
1.174 - L4_PAGESHIFT, (void **) &data_buf, &data_region_ds);
1.175 -
1.176 - if (err)
1.177 - {
1.178 - printf("Could not reserve data memory.\n");
1.179 - return 1;
1.180 - }
1.181 -
1.182 - memset(data_buf, 0, data_region_size);
1.183 -
1.184 - client_seek(file, data_file_offset, SEEK_SET);
1.185 - nread = client_read(file, data_buf + data_region_offset, data_region_contents);
1.186 -
1.187 - printf("Read %ld from file into %p in region %p with size %ld for %lx.\n",
1.188 - nread, data_buf + data_region_offset, data_buf, data_region_size, data_region_base);
1.189 -
1.190 /* UTCB location and size. */
1.191
1.192 l4_addr_t utcb_start = Utcb_area_start;
1.193 @@ -478,25 +548,9 @@
1.194
1.195 printf("KIP at %lx.\n", kip_start);
1.196
1.197 - /* Stack allocation. */
1.198 -
1.199 - l4_addr_t stack_buf;
1.200 - offset_t stack_size = 16 * L4_PAGESIZE;
1.201 - l4_addr_t stack_region_base = 0x8000000 - stack_size;
1.202 - l4re_ds_t stack_ds;
1.203 -
1.204 - err = ipc_allocate_align(stack_size, L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_RW,
1.205 - L4_PAGESHIFT, (void **) &stack_buf, &stack_ds);
1.206 -
1.207 - if (err)
1.208 - {
1.209 - printf("Could not reserve stack.\n");
1.210 - return 1;
1.211 - }
1.212 -
1.213 /* Populate stack with additional capabilities. */
1.214
1.215 - l4re_env_cap_entry_t *stack_env_cap = (l4re_env_cap_entry_t *) (stack_buf + stack_size);
1.216 + l4re_env_cap_entry_t *stack_env_cap = (l4re_env_cap_entry_t *) (stack.buf + stack.size);
1.217
1.218 /* Special invalid/terminating environment capability entry. */
1.219
1.220 @@ -516,7 +570,7 @@
1.221 memset(stack_arg, 0, (char *) stack_element - stack_arg);
1.222 memcpy(stack_arg, argv[1], strlen(argv[1]));
1.223
1.224 - printf("Stack L4 program argument: %p / %lx\n", stack_arg, ((l4_addr_t) stack_arg - stack_buf) + stack_region_base);
1.225 + printf("Stack L4 program argument: %p / %lx\n", stack_arg, stack.region_address(stack_arg));
1.226
1.227 stack_element = (l4_umword_t *) stack_arg;
1.228
1.229 @@ -527,7 +581,7 @@
1.230 *(--stack_element) = 0;
1.231 *(--stack_element) = 0x14 << L4_CAP_SHIFT;
1.232
1.233 - printf("Stack L4 aux elements: %p / %lx\n", stack_element, ((l4_addr_t) stack_element - stack_buf) + stack_region_base);
1.234 + printf("Stack L4 aux elements: %p / %lx\n", stack_element, stack.region_address((char *) stack_element));
1.235
1.236 /* Populate stack with standard capabilities. */
1.237
1.238 @@ -541,7 +595,7 @@
1.239 env->rm = 0x11 << L4_CAP_SHIFT;
1.240 env->mem_alloc = 0x12 << L4_CAP_SHIFT;
1.241 env->first_free_cap = 0x15;
1.242 - env->caps = (l4re_env_cap_entry_t *) (caps_start - stack_buf) + stack_region_base;
1.243 + env->caps = (l4re_env_cap_entry_t *) (stack.region_address(caps_start));
1.244 env->utcb_area = utcb_fpage;
1.245 env->first_free_utcb = utcb_start + L4_UTCB_OFFSET;
1.246
1.247 @@ -556,7 +610,7 @@
1.248
1.249 /* L4Re global environment pointer. */
1.250
1.251 - *(--stack_element) = ((l4_addr_t) env - stack_buf) + stack_region_base;
1.252 + *(--stack_element) = stack.region_address((char *) env);
1.253 *(--stack_element) = 0xf1;
1.254
1.255 /* Apparently required entries. */
1.256 @@ -578,7 +632,7 @@
1.257
1.258 l4_addr_t stack_data_end = (l4_addr_t) stack_element;
1.259
1.260 - printf("Stack L4 data: %lx / %lx\n", stack_data_end, (stack_data_end - stack_buf) + stack_region_base);
1.261 + printf("Stack L4 data: %lx / %lx\n", stack_data_end, stack.region_address(stack_data_end));
1.262
1.263 /* No environment pointers. */
1.264
1.265 @@ -588,7 +642,7 @@
1.266 /* NOTE: Just one argument currently. */
1.267
1.268 *(--stack_element) = 0;
1.269 - *(--stack_element) = (l4_umword_t) ((l4_addr_t) stack_arg - stack_buf) + stack_region_base;
1.270 + *(--stack_element) = (l4_umword_t) (stack.region_address(stack_arg));
1.271 *(--stack_element) = 1;
1.272
1.273 char *stack_adjusted = Ldr::adjust_sp((char *) stack_element, NULL);
1.274 @@ -602,9 +656,9 @@
1.275
1.276 printf("%ld %lx %lx\n", stack_adjusted_element[0], stack_adjusted_element[1], stack_adjusted_element[2]);
1.277
1.278 - l4_addr_t stack_start = ((l4_addr_t) stack_adjusted - stack_buf) + stack_region_base;
1.279 + l4_addr_t stack_start = stack.region_address(stack_adjusted);
1.280
1.281 - printf("Stack L4 start: %p / %lx\n", stack_adjusted, ((l4_addr_t) stack_adjusted - stack_buf) + stack_region_base);
1.282 + printf("Stack L4 start: %p / %lx\n", stack_adjusted, stack.region_address(stack_adjusted));
1.283
1.284 /* Create a new task and thread. */
1.285
1.286 @@ -635,9 +689,8 @@
1.287
1.288 init_pager(&config);
1.289
1.290 - exec_pager.add(Region((l4_addr_t) program_buf, page_order(program_region_size), L4_FPAGE_RX, program_region_base));
1.291 - exec_pager.add(Region((l4_addr_t) data_buf, page_order(data_region_size), L4_FPAGE_RW, data_region_base));
1.292 - exec_pager.add(Region((l4_addr_t) stack_buf, page_order(stack_size), L4_FPAGE_RW, stack_region_base));
1.293 + for (segment = segments; *segment != NULL; segment++)
1.294 + exec_pager.add((*segment)->region());
1.295
1.296 err = pthread_create(&pager_thread, &attr, ipc_server_start_mainloop, &config);
1.297
1.298 @@ -711,7 +764,7 @@
1.299
1.300 printf("Schedule thread...\n");
1.301
1.302 - printf("Stack at 0x%lx mapped to region at 0x%lx.\n", stack_start, stack_region_base);
1.303 + printf("Stack at 0x%lx mapped to region at 0x%lx.\n", stack_start, stack.region_base);
1.304
1.305 err = l4_error(l4_thread_ex_regs(thread, program_start, stack_start, 0));
1.306