# HG changeset patch # User Paul Boddie # Date 1652565144 -7200 # Node ID 3bc0f7f438bd7bfe88eab62d14070224f6d2a5ec # Parent 82357f1fa1f42e30439d9d3bfde3f83720047487 Changed mapped regions to employ sizes as opposed to log2sizes. Fixed region allocation to employ the expanded region size incorporating any leading space required for alignment. Introduced file opening measures that would in principle help with the direct use of file dataspaces with the pager, although the need to filter file contents via other dataspaces makes such measures superfluous. diff -r 82357f1fa1f4 -r 3bc0f7f438bd libexec/include/exec/mapped_region.h --- a/libexec/include/exec/mapped_region.h Thu May 12 22:13:22 2022 +0200 +++ b/libexec/include/exec/mapped_region.h Sat May 14 23:52:24 2022 +0200 @@ -23,6 +23,8 @@ #include +#include + /* A mapped region abstraction. */ @@ -31,18 +33,18 @@ { public: l4_addr_t start; - unsigned int log2size; + offset_t size; l4_umword_t flags; l4_addr_t map_start; explicit MappedRegion() - : start(0), log2size(0), flags(0), map_start(0) + : start(0), size(0), flags(0), map_start(0) { } - explicit MappedRegion(l4_addr_t start, unsigned int log2size, + explicit MappedRegion(l4_addr_t start, l4_addr_t size, l4_umword_t flags, l4_addr_t map_start) - : start(start), log2size(log2size), flags(flags), map_start(map_start) + : start(start), size(size), flags(flags), map_start(map_start) { } }; diff -r 82357f1fa1f4 -r 3bc0f7f438bd libexec/include/exec/segment.h --- a/libexec/include/exec/segment.h Thu May 12 22:13:22 2022 +0200 +++ b/libexec/include/exec/segment.h Sat May 14 23:52:24 2022 +0200 @@ -83,6 +83,12 @@ l4_addr_t region_address(char *address); l4_addr_t region_address(l4_addr_t address); + + /* Generic property access. */ + + offset_t file_contents(); + + l4re_rm_flags_t region_flags(); }; /* vim: tabstop=2 expandtab shiftwidth=2 diff -r 82357f1fa1f4 -r 3bc0f7f438bd libexec/lib/src/segment.cc --- a/libexec/lib/src/segment.cc Thu May 12 22:13:22 2022 +0200 +++ b/libexec/lib/src/segment.cc Sat May 14 23:52:24 2022 +0200 @@ -41,7 +41,10 @@ { _region_base = trunc(_base, L4_PAGESIZE); _region_offset = _base - _region_base; - _region_size = round(_size, L4_PAGESIZE); + + /* Expand the region size. */ + + _region_size = round(_size + _region_offset, L4_PAGESIZE); } /* Return the address of allocated memory. */ @@ -58,18 +61,11 @@ return _size; } -/* Allocate a region for the segment. */ +/* Allocate a writable region for the segment. */ long Segment::allocate() { - /* Make regions writable if they need to be filled. */ - - l4re_rm_flags_t allocation_flags = _flags; - - if (_file_contents) - allocation_flags |= L4RE_RM_F_W; - - return ipc_allocate_align(_size, L4RE_RM_F_SEARCH_ADDR | allocation_flags, + return ipc_allocate_align(_region_size, L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_RW, L4_PAGESHIFT, (void **) &_buf, &_ds); } @@ -77,10 +73,21 @@ long Segment::fill(file_t *file) { - if (!_file_contents) - return L4_EOK; + /* Allocate writable memory to populate. */ + + long err = ipc_allocate_align(_region_size, + L4RE_RM_F_SEARCH_ADDR | _flags | L4RE_RM_F_W, + L4_PAGESHIFT, (void **) &_buf, &_ds); + + if (err) + return err; + + /* Align the exposed file contents to the memory mapped region. + Since the region is page-aligned, the region offset is introduced to map + from an earlier part of the file, if appropriate. */ memset(_buf, 0, _region_size); + client_seek(file, _file_offset, SEEK_SET); offset_t nread = client_read(file, _buf + _region_offset, _file_contents); @@ -94,7 +101,7 @@ MappedRegion &Segment::region() { - _region = MappedRegion((l4_addr_t) _buf, page_order(_region_size), _flags, _region_base); + _region = MappedRegion((l4_addr_t) _buf, _region_size, _flags, _region_base); return _region; } @@ -110,5 +117,19 @@ return (address - (l4_addr_t) _buf) + _region_base; } +/* Return the amount of file content loaded into the segment. */ + +offset_t Segment::file_contents() +{ + return _file_contents; +} + +/* Return the region flags for the segment. */ + +l4re_rm_flags_t Segment::region_flags() +{ + return _flags; +} + /* vim: tabstop=2 expandtab shiftwidth=2 */ diff -r 82357f1fa1f4 -r 3bc0f7f438bd tests/dstest_exec.cc --- a/tests/dstest_exec.cc Thu May 12 22:13:22 2022 +0200 +++ b/tests/dstest_exec.cc Sat May 14 23:52:24 2022 +0200 @@ -137,7 +137,7 @@ MappedRegion &r = it->second; - if ((addr >= r.map_start) && (addr < r.map_start + (1UL << r.log2size))) + if ((addr >= r.map_start) && (addr < r.map_start + r.size)) { l4_addr_t page_addr = trunc(addr, L4_PAGESIZE); @@ -145,9 +145,10 @@ region->snd_base = page_addr; #if DEBUG - printf("%lx...%lx from %lx...%lx size %d rights %x\n", + printf("%lx...%lx from %lx...%lx offset %lx size %d rights %x\n", r.map_start, region->snd_base, r.start, l4_fpage_memaddr(region->fpage), + addr - r.map_start, l4_fpage_size(region->fpage), l4_fpage_rights(region->fpage)); printf("%lx -> ", addr); @@ -158,6 +159,11 @@ printf("\n"); #endif + if (r.flags & L4RE_RM_F_W) + l4_touch_rw((const void *) (r.start + (page_addr - r.map_start)), L4_PAGESIZE); + else + l4_touch_ro((const void *) (r.start + (page_addr - r.map_start)), L4_PAGESIZE); + return L4_EOK; } @@ -218,7 +224,7 @@ { it--; MappedRegion &pr = it->second; - start_limit = pr.map_start + (1UL << pr.log2size); + start_limit = pr.map_start + pr.size; it = next; } @@ -258,7 +264,7 @@ printf("-> added region for %lx size %ld (%d)\n", region_start, region_size, page_order(region_size)); #endif - add(MappedRegion(ds_start, page_order(region_size), flags & L4RE_DS_F_RIGHTS_MASK, region_start)); + add(MappedRegion(ds_start, region_size, flags & L4RE_DS_F_RIGHTS_MASK, region_start)); *start = region_start; return L4_EOK; @@ -397,20 +403,42 @@ if (segment == NULL) continue; - err = segment->allocate(); + if (segment->file_contents()) + { + flags_t flags; + + if ((segment->region_flags() & L4RE_RM_F_RW) == L4RE_RM_F_RW) + flags = O_RDWR; + else if (segment->region_flags() & L4RE_RM_F_W) + flags = O_WRONLY; + else + flags = O_RDONLY; + + file_t *file = client_open(argv[1], flags); - if (err) - { - printf("Could not reserve memory.\n"); - return 1; + if (file == NULL) + { + printf("Could not open file for segment.\n"); + return 1; + } + + err = segment->fill(file); + + if (err) + { + printf("Could not fill segment from file.\n"); + return 1; + } } - - err = segment->fill(file); + else + { + err = segment->allocate(); - if (err) - { - printf("Could not fill segment from file.\n"); - return 1; + if (err) + { + printf("Could not allocate segment.\n"); + return 1; + } } }