1.1 --- a/libexec/include/exec/elf.h Thu Jun 02 01:09:30 2022 +0200
1.2 +++ b/libexec/include/exec/elf.h Fri Jun 03 00:21:10 2022 +0200
1.3 @@ -19,27 +19,16 @@
1.4 * Boston, MA 02110-1301, USA
1.5 */
1.6
1.7 +#pragma once
1.8 +
1.9 #include <exec/segment.h>
1.10
1.11
1.12
1.13 /* Generic program segment interface. */
1.14
1.15 -class ProgramSegment
1.16 -{
1.17 -public:
1.18 - virtual bool loadable() = 0;
1.19 - virtual offset_t file_contents() = 0;
1.20 - virtual offset_t file_offset() = 0;
1.21 - virtual l4_addr_t region_address() = 0;
1.22 - virtual offset_t region_size() = 0;
1.23 - virtual l4re_rm_flags_t region_flags() = 0;
1.24 -
1.25 - Segment *segment();
1.26 -};
1.27 -
1.28 template <typename PROGRAM_HEADER>
1.29 -class ProgramSegmentVariant : public ProgramSegment
1.30 +class ProgramSegmentVariant : public Segment
1.31 {
1.32 protected:
1.33 PROGRAM_HEADER *_header;
1.34 @@ -55,18 +44,23 @@
1.35 l4re_rm_flags_t region_flags();
1.36 };
1.37
1.38 -
1.39 +
1.40
1.41 /* Generic interface for an ELF payload. */
1.42
1.43 class Payload
1.44 {
1.45 +protected:
1.46 + Segment **_segments = NULL;
1.47 +
1.48 public:
1.49 + virtual ~Payload();
1.50 +
1.51 virtual l4_addr_t entry_point() = 0;
1.52 virtual offset_t header_extent() = 0;
1.53 virtual offset_t program_header_extent() = 0;
1.54 - virtual unsigned int segments() = 0;
1.55 - virtual ProgramSegment *segment(unsigned int i) = 0;
1.56 + virtual unsigned int segments();
1.57 + virtual Segment *segment(unsigned int i) = 0;
1.58 };
1.59
1.60 template <typename HEADER, typename PROGRAM_HEADER>
1.61 @@ -82,7 +76,7 @@
1.62 offset_t header_extent();
1.63 offset_t program_header_extent();
1.64 unsigned int segments();
1.65 - ProgramSegment *segment(unsigned int i);
1.66 + Segment *segment(unsigned int i);
1.67 };
1.68
1.69
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/libexec/include/exec/memory.h Fri Jun 03 00:21:10 2022 +0200
2.3 @@ -0,0 +1,32 @@
2.4 +/*
2.5 + * Program memory initialisation support.
2.6 + *
2.7 + * Copyright (C) 2022 Paul Boddie <paul@boddie.org.uk>
2.8 + *
2.9 + * This program is free software; you can redistribute it and/or
2.10 + * modify it under the terms of the GNU General Public License as
2.11 + * published by the Free Software Foundation; either version 2 of
2.12 + * the License, or (at your option) any later version.
2.13 + *
2.14 + * This program is distributed in the hope that it will be useful,
2.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.17 + * GNU General Public License for more details.
2.18 + *
2.19 + * You should have received a copy of the GNU General Public License
2.20 + * along with this program; if not, write to the Free Software
2.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
2.22 + * Boston, MA 02110-1301, USA
2.23 + */
2.24 +
2.25 +#pragma once
2.26 +
2.27 +#include <exec/elf.h>
2.28 +#include <exec/segment.h>
2.29 +
2.30 +
2.31 +
2.32 +long exec_get_payload(const char *filename, Payload **payload);
2.33 +
2.34 +/* vim: tabstop=2 expandtab shiftwidth=2
2.35 +*/
3.1 --- a/libexec/include/exec/segment.h Thu Jun 02 01:09:30 2022 +0200
3.2 +++ b/libexec/include/exec/segment.h Fri Jun 03 00:21:10 2022 +0200
3.3 @@ -30,7 +30,7 @@
3.4
3.5
3.6
3.7 -/* Program segment abstraction. */
3.8 +/* Program segment abstractions. */
3.9
3.10 class Segment
3.11 {
3.12 @@ -42,29 +42,24 @@
3.13 char *_buf;
3.14 l4re_ds_t _ds;
3.15
3.16 - /* Segment base and corresponding region base. */
3.17 + /* Segment region base. */
3.18
3.19 - l4_addr_t _base, _region_base;
3.20 + l4_addr_t _region_base;
3.21
3.22 - /* Segment size and corresponding region size. */
3.23 + /* Segment region size. */
3.24
3.25 - offset_t _size, _region_size;
3.26 + offset_t _region_allocated_size;
3.27
3.28 /* Offset of segment content within the region. */
3.29
3.30 - offset_t _region_offset;
3.31 -
3.32 - /* Access flags. */
3.33 + offset_t _region_content_offset;
3.34
3.35 - l4re_rm_flags_t _flags;
3.36 + /* Common initialisation. */
3.37
3.38 - /* File access details. */
3.39 -
3.40 - offset_t _file_offset, _file_contents;
3.41 + void init();
3.42
3.43 public:
3.44 - explicit Segment(l4_addr_t base, offset_t size, l4re_rm_flags_t flags,
3.45 - offset_t file_offset = 0, offset_t file_contents = 0);
3.46 + virtual ~Segment();
3.47
3.48 char *address();
3.49
3.50 @@ -86,8 +81,46 @@
3.51
3.52 /* Generic property access. */
3.53
3.54 + virtual bool loadable() = 0;
3.55 + virtual offset_t file_contents() = 0;
3.56 + virtual offset_t file_offset() = 0;
3.57 + virtual l4_addr_t region_address() = 0;
3.58 + virtual offset_t region_size() = 0;
3.59 + virtual l4re_rm_flags_t region_flags() = 0;
3.60 +};
3.61 +
3.62 +
3.63 +
3.64 +class ExplicitSegment : public Segment
3.65 +{
3.66 +protected:
3.67 + /* Segment base. */
3.68 +
3.69 + l4_addr_t _base;
3.70 +
3.71 + /* Segment size. */
3.72 +
3.73 + offset_t _size;
3.74 +
3.75 + /* Access flags. */
3.76 +
3.77 + l4re_rm_flags_t _flags;
3.78 +
3.79 + /* File access details. */
3.80 +
3.81 + offset_t _file_offset, _file_contents;
3.82 +
3.83 +public:
3.84 + explicit ExplicitSegment(l4_addr_t base, offset_t size, l4re_rm_flags_t flags,
3.85 + offset_t file_offset = 0, offset_t file_contents = 0);
3.86 +
3.87 + /* Generic property access. */
3.88 +
3.89 + bool loadable();
3.90 offset_t file_contents();
3.91 -
3.92 + offset_t file_offset();
3.93 + l4_addr_t region_address();
3.94 + offset_t region_size();
3.95 l4re_rm_flags_t region_flags();
3.96 };
3.97
4.1 --- a/libexec/lib/src/Makefile Thu Jun 02 01:09:30 2022 +0200
4.2 +++ b/libexec/lib/src/Makefile Fri Jun 03 00:21:10 2022 +0200
4.3 @@ -3,7 +3,7 @@
4.4
4.5 TARGET = libexec.a libexec.so
4.6 PC_FILENAME = libexec
4.7 -SRC_CC = elf.cc process.cc segment.cc stack.cc
4.8 +SRC_CC = elf.cc memory.cc process.cc segment.cc stack.cc
4.9 REQUIRES_LIBS = l4re_c-util libmem libipc libstdc++ libsystypes libfsclient
4.10
4.11 PRIVATE_INCDIR += $(PKGDIR)/include/exec
5.1 --- a/libexec/lib/src/elf.cc Thu Jun 02 01:09:30 2022 +0200
5.2 +++ b/libexec/lib/src/elf.cc Fri Jun 03 00:21:10 2022 +0200
5.3 @@ -25,26 +25,13 @@
5.4
5.5
5.6
5.7 -/* Generic segment creation from program segments. */
5.8 -
5.9 -Segment *ProgramSegment::segment()
5.10 -{
5.11 - return new Segment(
5.12 - region_address(),
5.13 - region_size(),
5.14 - region_flags(),
5.15 - file_offset(),
5.16 - file_contents());
5.17 -}
5.18 -
5.19 -
5.20 -
5.21 /* Program segment construction for 32- or 64-bit variants. */
5.22
5.23 template <typename PROGRAM_HEADER>
5.24 ProgramSegmentVariant<PROGRAM_HEADER>::ProgramSegmentVariant(PROGRAM_HEADER *header)
5.25 : _header(header)
5.26 {
5.27 + init();
5.28 }
5.29
5.30 template <typename PROGRAM_HEADER>
5.31 @@ -94,6 +81,24 @@
5.32
5.33
5.34
5.35 +/* Generic payload destruction. */
5.36 +
5.37 +Payload::~Payload()
5.38 +{
5.39 + if (_segments != NULL)
5.40 + {
5.41 + for (unsigned int i = 0; i < segments(); i++)
5.42 + delete _segments[i];
5.43 + }
5.44 +}
5.45 +
5.46 +unsigned int Payload::segments()
5.47 +{
5.48 + return 0;
5.49 +}
5.50 +
5.51 +
5.52 +
5.53 /* ELF payload construction for 32- or 64-bit variants. */
5.54
5.55 template <typename HEADER, typename PROGRAM_HEADER>
5.56 @@ -127,14 +132,30 @@
5.57 }
5.58
5.59 template <typename HEADER, typename PROGRAM_HEADER>
5.60 -ProgramSegment *PayloadVariant<HEADER, PROGRAM_HEADER>::segment(unsigned int i)
5.61 +Segment *PayloadVariant<HEADER, PROGRAM_HEADER>::segment(unsigned int i)
5.62 {
5.63 if (i >= segments())
5.64 return NULL;
5.65
5.66 - return new ProgramSegmentVariant<PROGRAM_HEADER>(
5.67 - (PROGRAM_HEADER *) ((char *) _header + _header->e_phoff +
5.68 - _header->e_phentsize * i));
5.69 + if (_segments == NULL)
5.70 + {
5.71 + _segments = new Segment *[segments()];
5.72 +
5.73 + for (unsigned int j = 0; j < segments(); j++)
5.74 + _segments[j] = NULL;
5.75 + }
5.76 +
5.77 + Segment *segment = _segments[i];
5.78 +
5.79 + if (segment == NULL)
5.80 + {
5.81 + segment = new ProgramSegmentVariant<PROGRAM_HEADER>(
5.82 + (PROGRAM_HEADER *) ((char *) _header + _header->e_phoff +
5.83 + _header->e_phentsize * i));
5.84 + _segments[i] = segment;
5.85 + }
5.86 +
5.87 + return segment;
5.88 }
5.89
5.90
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/libexec/lib/src/memory.cc Fri Jun 03 00:21:10 2022 +0200
6.3 @@ -0,0 +1,92 @@
6.4 +/*
6.5 + * Support for initialising program memory regions in new tasks.
6.6 + *
6.7 + * Copyright (C) 2022 Paul Boddie <paul@boddie.org.uk>
6.8 + *
6.9 + * This program is free software; you can redistribute it and/or
6.10 + * modify it under the terms of the GNU General Public License as
6.11 + * published by the Free Software Foundation; either version 2 of
6.12 + * the License, or (at your option) any later version.
6.13 + *
6.14 + * This program is distributed in the hope that it will be useful,
6.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.17 + * GNU General Public License for more details.
6.18 + *
6.19 + * You should have received a copy of the GNU General Public License
6.20 + * along with this program; if not, write to the Free Software
6.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
6.22 + * Boston, MA 02110-1301, USA
6.23 + */
6.24 +
6.25 +#include <l4/sys/err.h>
6.26 +#include <l4/util/elf.h>
6.27 +
6.28 +#include <fsclient/client.h>
6.29 +#include <systypes/fcntl.h>
6.30 +
6.31 +#include <string.h>
6.32 +
6.33 +#include "memory.h"
6.34 +
6.35 +
6.36 +
6.37 +/* Obtain the payload as a dataspace. */
6.38 +
6.39 +long exec_get_payload(const char *filename, Payload **payload)
6.40 +{
6.41 + file_t *file = client_open(filename, O_RDONLY);
6.42 +
6.43 + if (file == NULL)
6.44 + return -L4_EIO;
6.45 +
6.46 + /* Obtain metadata from the file. */
6.47 +
6.48 + char *buf = (char *) client_mmap(file, 0, file->size, 0, 0, L4RE_DS_F_R);
6.49 +
6.50 + /* Test the file type indicator. */
6.51 +
6.52 + if ((file->size < EI_NIDENT) || memcmp(buf, "\x7f" "ELF", 4))
6.53 + return -L4_EINVAL;
6.54 +
6.55 + /* Attempt to get a payload object appropriate for a particular object size
6.56 + variant. */
6.57 +
6.58 + *payload = get_payload(buf);
6.59 +
6.60 + if ((*payload == NULL) ||
6.61 + (file->size < (*payload)->header_extent()) ||
6.62 + (file->size < (*payload)->program_header_extent()))
6.63 + return -L4_ERANGE;
6.64 +
6.65 + /* Obtain all loadable segments. */
6.66 +
6.67 + for (unsigned int i = 0; i < (*payload)->segments(); i++)
6.68 + {
6.69 + Segment *segment = (*payload)->segment(i);
6.70 + long err;
6.71 +
6.72 + if (!segment->loadable())
6.73 + continue;
6.74 +
6.75 + if (segment->file_contents())
6.76 + {
6.77 + file_t *rfile = client_open(filename, file_opening_flags(segment->region_flags()));
6.78 +
6.79 + if (rfile == NULL)
6.80 + return -L4_EIO;
6.81 +
6.82 + err = segment->fill(rfile);
6.83 + }
6.84 + else
6.85 + err = segment->allocate();
6.86 +
6.87 + if (err)
6.88 + return err;
6.89 + }
6.90 +
6.91 + return L4_EOK;
6.92 +}
6.93 +
6.94 +/* vim: tabstop=2 expandtab shiftwidth=2
6.95 +*/
7.1 --- a/libexec/lib/src/segment.cc Thu Jun 02 01:09:30 2022 +0200
7.2 +++ b/libexec/lib/src/segment.cc Fri Jun 03 00:21:10 2022 +0200
7.3 @@ -31,20 +31,22 @@
7.4
7.5
7.6
7.7 -/* Initialise a memory segment. */
7.8 +/* Obligatory destructor. */
7.9
7.10 -Segment::Segment(l4_addr_t base, offset_t size, l4re_rm_flags_t flags,
7.11 - offset_t file_offset, offset_t file_contents)
7.12 +Segment::~Segment()
7.13 +{
7.14 +}
7.15
7.16 -: _base(base), _size(size), _flags(flags), _file_offset(file_offset),
7.17 - _file_contents(file_contents)
7.18 +/* Common initialisation. */
7.19 +
7.20 +void Segment::init()
7.21 {
7.22 - _region_base = trunc(_base, L4_PAGESIZE);
7.23 - _region_offset = _base - _region_base;
7.24 + _region_base = trunc(region_address(), L4_PAGESIZE);
7.25 + _region_content_offset = region_address() - _region_base;
7.26
7.27 /* Expand the region size. */
7.28
7.29 - _region_size = round(_size + _region_offset, L4_PAGESIZE);
7.30 + _region_allocated_size = round(region_size() + _region_content_offset, L4_PAGESIZE);
7.31 }
7.32
7.33 /* Return the address of allocated memory. */
7.34 @@ -58,14 +60,14 @@
7.35
7.36 offset_t Segment::size()
7.37 {
7.38 - return _region_size;
7.39 + return _region_allocated_size;
7.40 }
7.41
7.42 /* Allocate a writable region for the segment. */
7.43
7.44 long Segment::allocate()
7.45 {
7.46 - return ipc_allocate_align(_region_size, L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_RW,
7.47 + return ipc_allocate_align(_region_allocated_size, L4RE_RM_F_SEARCH_ADDR | L4RE_RM_F_RW,
7.48 L4_PAGESHIFT, (void **) &_buf, &_ds);
7.49 }
7.50
7.51 @@ -76,11 +78,11 @@
7.52 /* Provide the exposed file contents in a masked memory mapped region. */
7.53
7.54 _buf = (char *) client_mmap(file,
7.55 - _file_offset - _region_offset,
7.56 - _region_size,
7.57 - _file_offset,
7.58 - _file_offset + _file_contents,
7.59 - _flags);
7.60 + file_offset() - _region_content_offset,
7.61 + _region_allocated_size,
7.62 + file_offset(),
7.63 + file_offset() + file_contents(),
7.64 + region_flags());
7.65
7.66 if (_buf == NULL)
7.67 return -L4_EIO;
7.68 @@ -92,7 +94,7 @@
7.69
7.70 MappedRegion &Segment::region()
7.71 {
7.72 - _region = MappedRegion((l4_addr_t) _buf, _region_size, _flags, _region_base);
7.73 + _region = MappedRegion((l4_addr_t) _buf, _region_allocated_size, region_flags(), _region_base);
7.74 return _region;
7.75 }
7.76
7.77 @@ -108,16 +110,49 @@
7.78 return (address - (l4_addr_t) _buf) + _region_base;
7.79 }
7.80
7.81 +
7.82 +
7.83 +/* Initialise a memory segment using explicit parameters. */
7.84 +
7.85 +ExplicitSegment::ExplicitSegment(l4_addr_t base, offset_t size,
7.86 + l4re_rm_flags_t flags, offset_t file_offset,
7.87 + offset_t file_contents)
7.88 +: _base(base), _size(size), _flags(flags), _file_offset(file_offset),
7.89 + _file_contents(file_contents)
7.90 +{
7.91 + init();
7.92 +}
7.93 +
7.94 /* Return the amount of file content loaded into the segment. */
7.95
7.96 -offset_t Segment::file_contents()
7.97 +bool ExplicitSegment::loadable()
7.98 +{
7.99 + return false;
7.100 +}
7.101 +
7.102 +offset_t ExplicitSegment::file_contents()
7.103 {
7.104 return _file_contents;
7.105 }
7.106
7.107 +offset_t ExplicitSegment::file_offset()
7.108 +{
7.109 + return _file_offset;
7.110 +}
7.111 +
7.112 +l4_addr_t ExplicitSegment::region_address()
7.113 +{
7.114 + return _base;
7.115 +}
7.116 +
7.117 +offset_t ExplicitSegment::region_size()
7.118 +{
7.119 + return _size;
7.120 +}
7.121 +
7.122 /* Return the region flags for the segment. */
7.123
7.124 -l4re_rm_flags_t Segment::region_flags()
7.125 +l4re_rm_flags_t ExplicitSegment::region_flags()
7.126 {
7.127 return _flags;
7.128 }
8.1 --- a/tests/dstest_exec.cc Thu Jun 02 01:09:30 2022 +0200
8.2 +++ b/tests/dstest_exec.cc Fri Jun 03 00:21:10 2022 +0200
8.3 @@ -20,18 +20,15 @@
8.4 */
8.5
8.6 #include <l4/re/env.h>
8.7 -#include <l4/re/l4aux.h>
8.8 #include <l4/sys/err.h>
8.9 -#include <l4/util/elf.h>
8.10 #include <l4/util/util.h>
8.11
8.12 #include <exec/elf.h>
8.13 +#include <exec/memory.h>
8.14 #include <exec/process.h>
8.15 -#include <fsclient/client.h>
8.16 #include <ipc/mem_ipc.h>
8.17 #include <ipc/server.h>
8.18 #include <mem/memory_utils.h>
8.19 -#include <systypes/fcntl.h>
8.20
8.21 #include <map>
8.22
8.23 @@ -319,115 +316,22 @@
8.24 return 1;
8.25 }
8.26
8.27 - /* Obtain the payload as a dataspace. */
8.28 -
8.29 - file_t *file = client_open(argv[1], O_RDONLY);
8.30 -
8.31 - if (file == NULL)
8.32 - {
8.33 - printf("Could not read file: %s\n", argv[1]);
8.34 - return 1;
8.35 - }
8.36 -
8.37 - /* Obtain metadata from the file. */
8.38 -
8.39 - char *buf = (char *) client_mmap(file, 0, file->size, 0, 0, L4RE_DS_F_R);
8.40 -
8.41 - if ((file->size < EI_NIDENT) || memcmp(buf, "\x7f" "ELF", 4))
8.42 - {
8.43 - printf("Not an ELF payload: %s\n", argv[1]);
8.44 - return 1;
8.45 - }
8.46 + /* Initialise the memory of the new task. */
8.47
8.48 - Payload *payload = get_payload(buf);
8.49 + offset_t initial_stack_size = 16 * L4_PAGESIZE;
8.50 + ExplicitSegment stack(Utcb_area_start - initial_stack_size, initial_stack_size, L4_FPAGE_RW);
8.51 + Payload *payload;
8.52
8.53 - if (payload == NULL)
8.54 - {
8.55 - printf("Unrecognised object size.\n");
8.56 - return 1;
8.57 - }
8.58 -
8.59 - if (file->size < payload->header_extent())
8.60 + if (exec_get_payload(argv[1], &payload))
8.61 {
8.62 - printf("Header incomplete.\n");
8.63 - return 1;
8.64 - }
8.65 -
8.66 - printf("Program start: %lx\n", payload->entry_point());
8.67 -
8.68 - if (file->size < payload->program_header_extent())
8.69 - {
8.70 - printf("Program headers incomplete.\n");
8.71 + printf("Could not initialise program.\n");
8.72 return 1;
8.73 }
8.74
8.75 - /* Make appropriate segments, although program segments could be made
8.76 - interoperable with these. */
8.77 -
8.78 - Segment *segments[payload->segments() + 1];
8.79 -
8.80 - for (unsigned int i = 0; i < payload->segments(); i++)
8.81 - {
8.82 - ProgramSegment *ps = payload->segment(i);
8.83 -
8.84 - printf("Segment(0x%lx, 0x%lx, 0x%x, 0x%lx, 0x%lx): %s\n",
8.85 - ps->region_address(),
8.86 - ps->region_size(),
8.87 - ps->region_flags(),
8.88 - ps->file_offset(),
8.89 - ps->file_contents(),
8.90 - ps->loadable() ? "loadable" : "other");
8.91 -
8.92 - if (ps->loadable())
8.93 - segments[i] = ps->segment();
8.94 - else
8.95 - segments[i] = NULL;
8.96 - }
8.97 -
8.98 - /* Copy the payload regions to new dataspaces. */
8.99 -
8.100 - address_t program_start = payload->entry_point();
8.101 - offset_t initial_stack_size = 16 * L4_PAGESIZE;
8.102 -
8.103 - Segment stack(Utcb_area_start - initial_stack_size, initial_stack_size, L4_FPAGE_RW);
8.104 -
8.105 - segments[payload->segments()] = &stack;
8.106 -
8.107 - for (unsigned int i = 0; i < payload->segments() + 1; i++)
8.108 + if (stack.allocate())
8.109 {
8.110 - Segment *segment = segments[i];
8.111 -
8.112 - if (segment == NULL)
8.113 - continue;
8.114 -
8.115 - if (segment->file_contents())
8.116 - {
8.117 - file_t *file = client_open(argv[1], file_opening_flags(segment->region_flags()));
8.118 -
8.119 - if (file == NULL)
8.120 - {
8.121 - printf("Could not open file for segment.\n");
8.122 - return 1;
8.123 - }
8.124 -
8.125 - err = segment->fill(file);
8.126 -
8.127 - if (err)
8.128 - {
8.129 - printf("Could not fill segment from file.\n");
8.130 - return 1;
8.131 - }
8.132 - }
8.133 - else
8.134 - {
8.135 - err = segment->allocate();
8.136 -
8.137 - if (err)
8.138 - {
8.139 - printf("Could not allocate segment.\n");
8.140 - return 1;
8.141 - }
8.142 - }
8.143 + printf("Could not allocate stack.\n");
8.144 + return 1;
8.145 }
8.146
8.147 /* Start the pager. */
8.148 @@ -441,15 +345,13 @@
8.149
8.150 init_pager(&config);
8.151
8.152 - for (unsigned int i = 0; i < payload->segments() + 1; i++)
8.153 + for (unsigned int i = 0; i < payload->segments(); i++)
8.154 {
8.155 - Segment *segment = segments[i];
8.156 + if (payload->segment(i)->loadable())
8.157 + exec_pager.add(payload->segment(i)->region());
8.158 + }
8.159
8.160 - if (segment == NULL)
8.161 - continue;
8.162 -
8.163 - exec_pager.add(segment->region());
8.164 - }
8.165 + exec_pager.add(stack.region());
8.166
8.167 err = pthread_create(&pager_thread, &attr, ipc_server_start_mainloop, &config);
8.168
8.169 @@ -494,7 +396,7 @@
8.170
8.171 printf("Run thread...\n");
8.172
8.173 - err = process.thread_start(program_start, st);
8.174 + err = process.thread_start(payload->entry_point(), st);
8.175
8.176 if (err)
8.177 {