1.1 --- a/libexec/include/exec/mapped_region.h Thu May 12 22:13:22 2022 +0200
1.2 +++ b/libexec/include/exec/mapped_region.h Sat May 14 23:52:24 2022 +0200
1.3 @@ -23,6 +23,8 @@
1.4
1.5 #include <l4/sys/types.h>
1.6
1.7 +#include <systypes/base.h>
1.8 +
1.9
1.10
1.11 /* A mapped region abstraction. */
1.12 @@ -31,18 +33,18 @@
1.13 {
1.14 public:
1.15 l4_addr_t start;
1.16 - unsigned int log2size;
1.17 + offset_t size;
1.18 l4_umword_t flags;
1.19 l4_addr_t map_start;
1.20
1.21 explicit MappedRegion()
1.22 - : start(0), log2size(0), flags(0), map_start(0)
1.23 + : start(0), size(0), flags(0), map_start(0)
1.24 {
1.25 }
1.26
1.27 - explicit MappedRegion(l4_addr_t start, unsigned int log2size,
1.28 + explicit MappedRegion(l4_addr_t start, l4_addr_t size,
1.29 l4_umword_t flags, l4_addr_t map_start)
1.30 - : start(start), log2size(log2size), flags(flags), map_start(map_start)
1.31 + : start(start), size(size), flags(flags), map_start(map_start)
1.32 {
1.33 }
1.34 };
2.1 --- a/libexec/include/exec/segment.h Thu May 12 22:13:22 2022 +0200
2.2 +++ b/libexec/include/exec/segment.h Sat May 14 23:52:24 2022 +0200
2.3 @@ -83,6 +83,12 @@
2.4 l4_addr_t region_address(char *address);
2.5
2.6 l4_addr_t region_address(l4_addr_t address);
2.7 +
2.8 + /* Generic property access. */
2.9 +
2.10 + offset_t file_contents();
2.11 +
2.12 + l4re_rm_flags_t region_flags();
2.13 };
2.14
2.15 /* vim: tabstop=2 expandtab shiftwidth=2
3.1 --- a/libexec/lib/src/segment.cc Thu May 12 22:13:22 2022 +0200
3.2 +++ b/libexec/lib/src/segment.cc Sat May 14 23:52:24 2022 +0200
3.3 @@ -41,7 +41,10 @@
3.4 {
3.5 _region_base = trunc(_base, L4_PAGESIZE);
3.6 _region_offset = _base - _region_base;
3.7 - _region_size = round(_size, L4_PAGESIZE);
3.8 +
3.9 + /* Expand the region size. */
3.10 +
3.11 + _region_size = round(_size + _region_offset, L4_PAGESIZE);
3.12 }
3.13
3.14 /* Return the address of allocated memory. */
3.15 @@ -58,18 +61,11 @@
3.16 return _size;
3.17 }
3.18
3.19 -/* Allocate a region for the segment. */
3.20 +/* Allocate a writable region for the segment. */
3.21
3.22 long Segment::allocate()
3.23 {
3.24 - /* Make regions writable if they need to be filled. */
3.25 -
3.26 - l4re_rm_flags_t allocation_flags = _flags;
3.27 -
3.28 - if (_file_contents)
3.29 - allocation_flags |= L4RE_RM_F_W;
3.30 -
3.31 - return ipc_allocate_align(_size, L4RE_RM_F_SEARCH_ADDR | allocation_flags,
3.32 + return ipc_allocate_align(_region_size, L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_RW,
3.33 L4_PAGESHIFT, (void **) &_buf, &_ds);
3.34 }
3.35
3.36 @@ -77,10 +73,21 @@
3.37
3.38 long Segment::fill(file_t *file)
3.39 {
3.40 - if (!_file_contents)
3.41 - return L4_EOK;
3.42 + /* Allocate writable memory to populate. */
3.43 +
3.44 + long err = ipc_allocate_align(_region_size,
3.45 + L4RE_RM_F_SEARCH_ADDR | _flags | L4RE_RM_F_W,
3.46 + L4_PAGESHIFT, (void **) &_buf, &_ds);
3.47 +
3.48 + if (err)
3.49 + return err;
3.50 +
3.51 + /* Align the exposed file contents to the memory mapped region.
3.52 + Since the region is page-aligned, the region offset is introduced to map
3.53 + from an earlier part of the file, if appropriate. */
3.54
3.55 memset(_buf, 0, _region_size);
3.56 +
3.57 client_seek(file, _file_offset, SEEK_SET);
3.58 offset_t nread = client_read(file, _buf + _region_offset, _file_contents);
3.59
3.60 @@ -94,7 +101,7 @@
3.61
3.62 MappedRegion &Segment::region()
3.63 {
3.64 - _region = MappedRegion((l4_addr_t) _buf, page_order(_region_size), _flags, _region_base);
3.65 + _region = MappedRegion((l4_addr_t) _buf, _region_size, _flags, _region_base);
3.66 return _region;
3.67 }
3.68
3.69 @@ -110,5 +117,19 @@
3.70 return (address - (l4_addr_t) _buf) + _region_base;
3.71 }
3.72
3.73 +/* Return the amount of file content loaded into the segment. */
3.74 +
3.75 +offset_t Segment::file_contents()
3.76 +{
3.77 + return _file_contents;
3.78 +}
3.79 +
3.80 +/* Return the region flags for the segment. */
3.81 +
3.82 +l4re_rm_flags_t Segment::region_flags()
3.83 +{
3.84 + return _flags;
3.85 +}
3.86 +
3.87 /* vim: tabstop=2 expandtab shiftwidth=2
3.88 */
4.1 --- a/tests/dstest_exec.cc Thu May 12 22:13:22 2022 +0200
4.2 +++ b/tests/dstest_exec.cc Sat May 14 23:52:24 2022 +0200
4.3 @@ -137,7 +137,7 @@
4.4
4.5 MappedRegion &r = it->second;
4.6
4.7 - if ((addr >= r.map_start) && (addr < r.map_start + (1UL << r.log2size)))
4.8 + if ((addr >= r.map_start) && (addr < r.map_start + r.size))
4.9 {
4.10 l4_addr_t page_addr = trunc(addr, L4_PAGESIZE);
4.11
4.12 @@ -145,9 +145,10 @@
4.13 region->snd_base = page_addr;
4.14
4.15 #if DEBUG
4.16 - printf("%lx...%lx from %lx...%lx size %d rights %x\n",
4.17 + printf("%lx...%lx from %lx...%lx offset %lx size %d rights %x\n",
4.18 r.map_start, region->snd_base,
4.19 r.start, l4_fpage_memaddr(region->fpage),
4.20 + addr - r.map_start,
4.21 l4_fpage_size(region->fpage),
4.22 l4_fpage_rights(region->fpage));
4.23 printf("%lx -> ", addr);
4.24 @@ -158,6 +159,11 @@
4.25 printf("\n");
4.26 #endif
4.27
4.28 + if (r.flags & L4RE_RM_F_W)
4.29 + l4_touch_rw((const void *) (r.start + (page_addr - r.map_start)), L4_PAGESIZE);
4.30 + else
4.31 + l4_touch_ro((const void *) (r.start + (page_addr - r.map_start)), L4_PAGESIZE);
4.32 +
4.33 return L4_EOK;
4.34 }
4.35
4.36 @@ -218,7 +224,7 @@
4.37 {
4.38 it--;
4.39 MappedRegion &pr = it->second;
4.40 - start_limit = pr.map_start + (1UL << pr.log2size);
4.41 + start_limit = pr.map_start + pr.size;
4.42 it = next;
4.43 }
4.44
4.45 @@ -258,7 +264,7 @@
4.46 printf("-> added region for %lx size %ld (%d)\n", region_start, region_size, page_order(region_size));
4.47 #endif
4.48
4.49 - add(MappedRegion(ds_start, page_order(region_size), flags & L4RE_DS_F_RIGHTS_MASK, region_start));
4.50 + add(MappedRegion(ds_start, region_size, flags & L4RE_DS_F_RIGHTS_MASK, region_start));
4.51
4.52 *start = region_start;
4.53 return L4_EOK;
4.54 @@ -397,20 +403,42 @@
4.55 if (segment == NULL)
4.56 continue;
4.57
4.58 - err = segment->allocate();
4.59 + if (segment->file_contents())
4.60 + {
4.61 + flags_t flags;
4.62 +
4.63 + if ((segment->region_flags() & L4RE_RM_F_RW) == L4RE_RM_F_RW)
4.64 + flags = O_RDWR;
4.65 + else if (segment->region_flags() & L4RE_RM_F_W)
4.66 + flags = O_WRONLY;
4.67 + else
4.68 + flags = O_RDONLY;
4.69 +
4.70 + file_t *file = client_open(argv[1], flags);
4.71
4.72 - if (err)
4.73 - {
4.74 - printf("Could not reserve memory.\n");
4.75 - return 1;
4.76 + if (file == NULL)
4.77 + {
4.78 + printf("Could not open file for segment.\n");
4.79 + return 1;
4.80 + }
4.81 +
4.82 + err = segment->fill(file);
4.83 +
4.84 + if (err)
4.85 + {
4.86 + printf("Could not fill segment from file.\n");
4.87 + return 1;
4.88 + }
4.89 }
4.90 -
4.91 - err = segment->fill(file);
4.92 + else
4.93 + {
4.94 + err = segment->allocate();
4.95
4.96 - if (err)
4.97 - {
4.98 - printf("Could not fill segment from file.\n");
4.99 - return 1;
4.100 + if (err)
4.101 + {
4.102 + printf("Could not allocate segment.\n");
4.103 + return 1;
4.104 + }
4.105 }
4.106 }
4.107