diff --git a/repos/base-linux/run/lx_fs.run b/repos/base-linux/run/lx_fs.run
index 5e8f6c653..8162b567f 100644
--- a/repos/base-linux/run/lx_fs.run
+++ b/repos/base-linux/run/lx_fs.run
@@ -32,7 +32,7 @@ install_config {
-
+
diff --git a/repos/base-linux/run/lx_hybrid_ctors.run b/repos/base-linux/run/lx_hybrid_ctors.run
index f5064a40c..6fa4e07ec 100644
--- a/repos/base-linux/run/lx_hybrid_ctors.run
+++ b/repos/base-linux/run/lx_hybrid_ctors.run
@@ -32,7 +32,7 @@ install_config {
-
+
diff --git a/repos/base-linux/run/lx_hybrid_errno.run b/repos/base-linux/run/lx_hybrid_errno.run
index 8f9548f76..2a47c87b8 100644
--- a/repos/base-linux/run/lx_hybrid_errno.run
+++ b/repos/base-linux/run/lx_hybrid_errno.run
@@ -25,7 +25,7 @@ install_config {
-
+
diff --git a/repos/base-linux/run/lx_hybrid_exception.run b/repos/base-linux/run/lx_hybrid_exception.run
index 29ef601f5..18bc0d228 100644
--- a/repos/base-linux/run/lx_hybrid_exception.run
+++ b/repos/base-linux/run/lx_hybrid_exception.run
@@ -31,7 +31,7 @@ install_config {
-
+
diff --git a/repos/base-linux/run/lx_hybrid_pthread_ipc.run b/repos/base-linux/run/lx_hybrid_pthread_ipc.run
index d151fd5dd..1468b210a 100644
--- a/repos/base-linux/run/lx_hybrid_pthread_ipc.run
+++ b/repos/base-linux/run/lx_hybrid_pthread_ipc.run
@@ -28,7 +28,7 @@ install_config {
-
+
diff --git a/repos/base-linux/src/lib/base/child_process.cc b/repos/base-linux/src/lib/base/child_process.cc
index 9427d8b37..48fd021c3 100644
--- a/repos/base-linux/src/lib/base/child_process.cc
+++ b/repos/base-linux/src/lib/base/child_process.cc
@@ -50,7 +50,7 @@ void Child::Initial_thread::start(addr_t) { }
/*
* On Linux, the ELF loading is performed by the kernel
*/
-Child::Process::Loaded_executable::Loaded_executable(Dataspace_capability,
+Child::Process::Loaded_executable::Loaded_executable(Type,
Dataspace_capability,
Ram_session &,
Region_map &,
@@ -58,51 +58,27 @@ Child::Process::Loaded_executable::Loaded_executable(Dataspace_capability,
Parent_capability) { }
-Child::Process::Process(Dataspace_capability elf_ds,
+Child::Process::Process(Type type,
Dataspace_capability ldso_ds,
- Pd_session_capability,
Pd_session &pd,
- Ram_session &ram,
Initial_thread_base &,
Region_map &local_rm,
Region_map &remote_rm,
Parent_capability parent_cap)
:
- loaded_executable(elf_ds, ldso_ds, ram, local_rm, remote_rm, parent_cap)
+ loaded_executable(type, ldso_ds, pd, local_rm, remote_rm, parent_cap)
{
/* skip loading when called during fork */
- if (!elf_ds.valid())
+ if (type == TYPE_FORKED)
return;
- /* attach ELF locally */
- addr_t elf_addr;
- try { elf_addr = local_rm.attach(elf_ds); }
- catch (Region_map::Invalid_dataspace) {
- error("local attach of ELF executable failed (Invalid_dataspace)"); throw; }
- catch (Region_map::Region_conflict) {
- error("local attach of ELF executable failed (Region_conflict)"); throw; }
-
- /* setup ELF object and read program entry pointer */
- Elf_binary elf(elf_addr);
- if (!elf.valid())
- throw Invalid_executable();
-
- bool const dynamically_linked = elf.dynamically_linked();
-
- local_rm.detach(elf_addr);
-
/*
* If the specified executable is a dynamically linked program, we load
* the dynamic linker instead.
*/
- if (dynamically_linked) {
-
- if (!ldso_ds.valid()) {
- error("attempt to start dynamic executable without dynamic linker");
- throw Missing_dynamic_linker();
- }
-
- elf_ds = ldso_ds;
+ if (!ldso_ds.valid()) {
+ error("attempt to start dynamic executable without dynamic linker");
+ throw Missing_dynamic_linker();
}
pd.assign_parent(parent_cap);
@@ -110,7 +86,7 @@ Child::Process::Process(Dataspace_capability elf_ds,
Linux_native_pd_client
lx_pd(static_cap_cast(pd.native_pd()));
- lx_pd.start(elf_ds);
+ lx_pd.start(ldso_ds);
}
diff --git a/repos/base-nova/run/platform.run b/repos/base-nova/run/platform.run
index a674eb9cb..0adfbcd62 100644
--- a/repos/base-nova/run/platform.run
+++ b/repos/base-nova/run/platform.run
@@ -24,7 +24,7 @@ set config {
-
+
}
append config "
diff --git a/repos/base/include/base/child.h b/repos/base/include/base/child.h
index ffab7cc50..ea001a4ea 100644
--- a/repos/base/include/base/child.h
+++ b/repos/base/include/base/child.h
@@ -222,6 +222,11 @@ struct Genode::Child_policy
* would otherwise produce a deadlock.
*/
virtual Region_map *address_space(Pd_session &) { return nullptr; }
+
+ /**
+ * Return true if ELF loading should be inhibited
+ */
+ virtual bool forked() const { return false; }
};
@@ -344,6 +349,8 @@ class Genode::Child : protected Rpc_object,
class Missing_dynamic_linker : Exception { };
class Invalid_executable : Exception { };
+ enum Type { TYPE_LOADED, TYPE_FORKED };
+
struct Loaded_executable
{
/**
@@ -368,7 +375,7 @@ class Genode::Child : protected Rpc_object,
* \throw Out_of_ram
* \throw Out_of_caps
*/
- Loaded_executable(Dataspace_capability elf_ds,
+ Loaded_executable(Type type,
Dataspace_capability ldso_ds,
Ram_session &ram,
Region_map &local_rm,
@@ -379,11 +386,6 @@ class Genode::Child : protected Rpc_object,
/**
* Constructor
*
- * \param ram RAM session used to allocate the BSS and
- * DATA segments for the new process
- * \param parent parent of the new protection domain
- * \param name name of protection domain
- *
* \throw Missing_dynamic_linker
* \throw Invalid_executable
* \throw Region_map::Region_conflict
@@ -391,25 +393,21 @@ class Genode::Child : protected Rpc_object,
* \throw Out_of_ram
* \throw Out_of_caps
*
- * The other arguments correspond to those of 'Child::Child'.
- *
* On construction of a protection domain, the initial thread is
* started immediately.
*
- * The argument 'elf_ds' may be invalid to create an empty process.
- * In this case, all process initialization steps except for the
- * creation of the initial thread must be done manually, i.e., as
- * done for implementing fork.
+ * The 'type' 'TYPE_FORKED' creates an empty process. In this case,
+ * all process initialization steps except for the creation of the
+ * initial thread must be done manually, i.e., as done for
+ * implementing fork.
*/
- Process(Dataspace_capability elf_ds,
- Dataspace_capability ldso_ds,
- Pd_session_capability pd_cap,
- Pd_session &pd,
- Ram_session &ram,
- Initial_thread_base &initial_thread,
- Region_map &local_rm,
- Region_map &remote_rm,
- Parent_capability parent);
+ Process(Type type,
+ Dataspace_capability ldso_ds,
+ Pd_session &pd,
+ Initial_thread_base &initial_thread,
+ Region_map &local_rm,
+ Region_map &remote_rm,
+ Parent_capability parent);
~Process();
};
diff --git a/repos/base/src/lib/base/child.cc b/repos/base/src/lib/base/child.cc
index 99b74f604..b2132f1e3 100644
--- a/repos/base/src/lib/base/child.cc
+++ b/repos/base/src/lib/base/child.cc
@@ -771,10 +771,11 @@ void Child::_try_construct_env_dependent_members()
_policy.init(_cpu.session(), _cpu.cap());
+ Process::Type const type = _policy.forked()
+ ? Process::TYPE_FORKED : Process::TYPE_LOADED;
try {
_initial_thread.construct(_cpu.session(), _pd.cap(), _policy.name());
- _process.construct(_binary.session().dataspace(), _linker_dataspace(),
- _pd.cap(), _pd.session(), _pd.session(),
+ _process.construct(type, _linker_dataspace(), _pd.session(),
*_initial_thread, _local_rm,
Child_address_space(_pd.session(), _policy).region_map(),
cap());
diff --git a/repos/base/src/lib/base/child_process.cc b/repos/base/src/lib/base/child_process.cc
index 420005854..63d4c9945 100644
--- a/repos/base/src/lib/base/child_process.cc
+++ b/repos/base/src/lib/base/child_process.cc
@@ -24,53 +24,32 @@
using namespace Genode;
-Child::Process::Loaded_executable::Loaded_executable(Dataspace_capability elf_ds,
+Child::Process::Loaded_executable::Loaded_executable(Type type,
Dataspace_capability ldso_ds,
- Ram_session &ram,
+ Pd_session &pd,
Region_map &local_rm,
Region_map &remote_rm,
Parent_capability parent_cap)
{
/* skip loading when called during fork */
- if (!elf_ds.valid())
+ if (type == TYPE_FORKED)
return;
- /* attach ELF locally */
- addr_t elf_addr;
- try { elf_addr = local_rm.attach(elf_ds); }
- catch (Region_map::Invalid_dataspace) {
- error("local attach of ELF executable failed (invalid dataspace)"); throw; }
- catch (Region_map::Region_conflict) {
- error("local attach of ELF executable failed (region conflict)"); throw; }
-
- /* setup ELF object and read program entry pointer */
- Elf_binary elf(elf_addr);
- if (!elf.valid())
- throw Invalid_executable();
-
- /*
- * If the specified executable is a dynamically linked program, we load
- * the dynamic linker instead.
- */
- if (elf.dynamically_linked()) {
-
- local_rm.detach(elf_addr);
-
- if (!ldso_ds.valid()) {
- error("attempt to start dynamic executable without dynamic linker");
- throw Missing_dynamic_linker();
- }
-
- try { elf_addr = local_rm.attach(ldso_ds); }
- catch (Region_map::Invalid_dataspace) {
- error("dynamic linker is an invalid dataspace"); throw; }
- catch (Region_map::Region_conflict) {
- error("region conflict while attaching dynamic linker"); throw; }
-
- elf_ds = ldso_ds;
- elf = Elf_binary(elf_addr);
+ /* locally attach ELF binary of the dynamic linker */
+ if (!ldso_ds.valid()) {
+ error("attempt to start dynamic executable without dynamic linker");
+ throw Missing_dynamic_linker();
}
+ addr_t elf_addr = 0;
+ try { elf_addr = local_rm.attach(ldso_ds); }
+ catch (Region_map::Invalid_dataspace) {
+ error("dynamic linker is an invalid dataspace"); throw; }
+ catch (Region_map::Region_conflict) {
+ error("region conflict while attaching dynamic linker"); throw; }
+
+ Elf_binary elf(elf_addr);
+
entry = elf.entry();
/* setup region map for the new pd */
@@ -105,7 +84,7 @@ Child::Process::Loaded_executable::Loaded_executable(Dataspace_capability elf_ds
/* alloc dataspace */
Dataspace_capability ds_cap;
- try { ds_cap = ram.alloc(size); }
+ try { ds_cap = pd.alloc(size); }
catch (Out_of_ram) {
error("allocation of read-write segment failed"); throw; };
@@ -141,7 +120,9 @@ Child::Process::Loaded_executable::Loaded_executable(Dataspace_capability elf_ds
off_t const offset = 0;
try { remote_rm.attach_at(ds_cap, addr, size, offset); }
catch (Region_map::Region_conflict) {
- error("region conflict while remotely attaching ELF segment"); throw; }
+ error("region conflict while remotely attaching ELF segment");
+ error("addr=", (void *)addr, " size=", (void *)size, " offset=", (void *)offset);
+ throw; }
} else {
@@ -153,12 +134,13 @@ Child::Process::Loaded_executable::Loaded_executable(Dataspace_capability elf_ds
off_t const offset = seg.file_offset();
try {
if (exec)
- remote_rm.attach_executable(elf_ds, addr, size, offset);
+ remote_rm.attach_executable(ldso_ds, addr, size, offset);
else
- remote_rm.attach_at(elf_ds, addr, size, offset);
+ remote_rm.attach_at(ldso_ds, addr, size, offset);
}
catch (Region_map::Region_conflict) {
error("region conflict while remotely attaching read-only ELF segment");
+ error("addr=", (void *)addr, " size=", (void *)size, " offset=", (void *)offset);
throw;
}
catch (Region_map::Invalid_dataspace) {
@@ -194,17 +176,15 @@ void Child::Initial_thread::start(addr_t ip)
}
-Child::Process::Process(Dataspace_capability elf_ds,
+Child::Process::Process(Type type,
Dataspace_capability ldso_ds,
- Pd_session_capability,
Pd_session &pd,
- Ram_session &ram,
Initial_thread_base &initial_thread,
Region_map &local_rm,
Region_map &remote_rm,
Parent_capability parent_cap)
:
- loaded_executable(elf_ds, ldso_ds, ram, local_rm, remote_rm, parent_cap)
+ loaded_executable(type, ldso_ds, pd, local_rm, remote_rm, parent_cap)
{
/* register parent interface for new protection domain */
pd.assign_parent(parent_cap);
@@ -214,7 +194,7 @@ Child::Process::Process(Dataspace_capability elf_ds,
* from another. In this case, the main thread will get manually
* started after constructing the 'Process'.
*/
- if (!elf_ds.valid())
+ if (type == TYPE_FORKED)
return;
/* start main thread */
diff --git a/repos/gems/run/cpu_load_display.run b/repos/gems/run/cpu_load_display.run
index 41f52280b..f3a6dd55e 100644
--- a/repos/gems/run/cpu_load_display.run
+++ b/repos/gems/run/cpu_load_display.run
@@ -56,7 +56,7 @@ append config {
}
append_if [have_spec sdl] config {
-
+
diff --git a/repos/gems/run/gpt_write.run b/repos/gems/run/gpt_write.run
index 1ace87a05..43ed451a4 100644
--- a/repos/gems/run/gpt_write.run
+++ b/repos/gems/run/gpt_write.run
@@ -34,7 +34,7 @@ install_config {
-
+
diff --git a/repos/gems/run/leitzentrale.run b/repos/gems/run/leitzentrale.run
index 6e88ab8fe..97ba031aa 100644
--- a/repos/gems/run/leitzentrale.run
+++ b/repos/gems/run/leitzentrale.run
@@ -202,7 +202,7 @@ install_config {
-
+
diff --git a/repos/libports/run/avplay.run b/repos/libports/run/avplay.run
index 1691a7039..d99b97dd9 100644
--- a/repos/libports/run/avplay.run
+++ b/repos/libports/run/avplay.run
@@ -49,7 +49,7 @@ set config {
}
append_if [have_spec sdl] config {
-
+
diff --git a/repos/libports/run/mesa.inc b/repos/libports/run/mesa.inc
index ce8c82bbc..36704c861 100644
--- a/repos/libports/run/mesa.inc
+++ b/repos/libports/run/mesa.inc
@@ -53,7 +53,7 @@ set config {
}
append_if [have_spec linux] config {
-
+
diff --git a/repos/libports/run/qt5_drivers.inc b/repos/libports/run/qt5_drivers.inc
index 40921a13e..d6479742d 100644
--- a/repos/libports/run/qt5_drivers.inc
+++ b/repos/libports/run/qt5_drivers.inc
@@ -165,7 +165,7 @@ proc drivers_start_nodes { feature_arg } {
}
append_if [use_fb_sdl feature] start_nodes {
-
+
diff --git a/repos/libports/run/sdl.run b/repos/libports/run/sdl.run
index 9d99f707c..ab985fc2c 100644
--- a/repos/libports/run/sdl.run
+++ b/repos/libports/run/sdl.run
@@ -38,7 +38,7 @@ append config {
}
append_if [have_spec sdl] config {
-
+
diff --git a/repos/os/recipes/raw/drivers_interactive-linux/drivers.config b/repos/os/recipes/raw/drivers_interactive-linux/drivers.config
index 5f4e87482..36676a10f 100644
--- a/repos/os/recipes/raw/drivers_interactive-linux/drivers.config
+++ b/repos/os/recipes/raw/drivers_interactive-linux/drivers.config
@@ -13,7 +13,7 @@
-
+
diff --git a/repos/os/run/block_tester.run b/repos/os/run/block_tester.run
index c718a7dbd..b43dc94e1 100644
--- a/repos/os/run/block_tester.run
+++ b/repos/os/run/block_tester.run
@@ -71,7 +71,7 @@ append_if [expr !$use_linux] config {
append_if $use_linux config {
-
+
diff --git a/repos/os/run/demo.run b/repos/os/run/demo.run
index ebb095986..e8ec816d4 100644
--- a/repos/os/run/demo.run
+++ b/repos/os/run/demo.run
@@ -58,7 +58,7 @@ append config {
}
append_if [have_spec sdl] config {
-
+
diff --git a/repos/os/run/fb_bench.run b/repos/os/run/fb_bench.run
index 99afe92dc..b48876d71 100644
--- a/repos/os/run/fb_bench.run
+++ b/repos/os/run/fb_bench.run
@@ -61,7 +61,7 @@ append_if [have_spec gpio] config "
"
append_if [have_spec sdl] config {
-
+
diff --git a/repos/os/run/framebuffer.run b/repos/os/run/framebuffer.run
index 5430ac94e..85fa2a340 100644
--- a/repos/os/run/framebuffer.run
+++ b/repos/os/run/framebuffer.run
@@ -46,7 +46,7 @@ append config {
}
append_if [have_spec sdl] config {
-
+
diff --git a/repos/os/run/input.run b/repos/os/run/input.run
index 0eb19c0e2..8c1feb7f3 100644
--- a/repos/os/run/input.run
+++ b/repos/os/run/input.run
@@ -77,7 +77,7 @@ append_if [have_spec ps2] config {
}
append_if [have_spec sdl] config {
-
+
diff --git a/repos/os/run/loader.run b/repos/os/run/loader.run
index ad3c97b6e..bba24425a 100644
--- a/repos/os/run/loader.run
+++ b/repos/os/run/loader.run
@@ -41,7 +41,7 @@ append config {
append_platform_drv_config
append_if [have_spec sdl] config {
-
+
diff --git a/repos/os/run/lx_block.run b/repos/os/run/lx_block.run
index 0138bb9d0..df9181903 100644
--- a/repos/os/run/lx_block.run
+++ b/repos/os/run/lx_block.run
@@ -34,7 +34,7 @@ install_config {
-
+
diff --git a/repos/os/run/pointer.run b/repos/os/run/pointer.run
index 210c94bdd..a6e41863d 100644
--- a/repos/os/run/pointer.run
+++ b/repos/os/run/pointer.run
@@ -50,7 +50,7 @@ set config {
-
+
diff --git a/repos/os/run/rom_to_file.run b/repos/os/run/rom_to_file.run
index e41d26059..680e7fa22 100644
--- a/repos/os/run/rom_to_file.run
+++ b/repos/os/run/rom_to_file.run
@@ -44,7 +44,7 @@ install_config {
-
+
diff --git a/repos/os/src/init/child.cc b/repos/os/src/init/child.cc
index 67b386a7a..eaa7a7241 100644
--- a/repos/os/src/init/child.cc
+++ b/repos/os/src/init/child.cc
@@ -496,6 +496,10 @@ Init::Child::Route Init::Child::resolve_session_request(Service::Name const &ser
label == _unique_name && _unique_name != _binary_name)
return resolve_session_request(service_name, _binary_name);
+ /* supply binary as dynamic linker if '' */
+ if (!_use_ld && service_name == Rom_session::service_name() && label == "ld.lib.so")
+ return resolve_session_request(service_name, _binary_name);
+
/* check for "session_requests" ROM request */
if (service_name == Rom_session::service_name()
&& label.last_element() == Session_requester::rom_name())
diff --git a/repos/os/src/init/child.h b/repos/os/src/init/child.h
index 986789ba6..140a3f7e0 100644
--- a/repos/os/src/init/child.h
+++ b/repos/os/src/init/child.h
@@ -90,6 +90,11 @@ class Init::Child : Child_policy, Routed_service::Wakeup
typedef String<80> Version;
Version _version { _start_node->xml().attribute_value("version", Version()) };
+ /*
+ * True if the binary is loaded with ld.lib.so
+ */
+ bool const _use_ld = _start_node->xml().attribute_value("ld", true);
+
Default_route_accessor &_default_route_accessor;
Default_caps_accessor &_default_caps_accessor;
Ram_limit_accessor &_ram_limit_accessor;
diff --git a/repos/os/src/init/config.xsd b/repos/os/src/init/config.xsd
index 511aeaa95..e5da52ba8 100644
--- a/repos/os/src/init/config.xsd
+++ b/repos/os/src/init/config.xsd
@@ -144,6 +144,7 @@
+
diff --git a/repos/ports/run/dosbox.run b/repos/ports/run/dosbox.run
index 94fbe430f..e47b765e4 100644
--- a/repos/ports/run/dosbox.run
+++ b/repos/ports/run/dosbox.run
@@ -48,7 +48,7 @@ append config {
}
append_if [have_spec sdl] config {
-
+
diff --git a/repos/ports/run/netperf.inc b/repos/ports/run/netperf.inc
index eb3557978..a4fce3829 100644
--- a/repos/ports/run/netperf.inc
+++ b/repos/ports/run/netperf.inc
@@ -216,8 +216,14 @@ append_if $use_usb_driver config {
}
+# don't use the dynamic linker for loading the lx_hybrid nic_drv on Linux
+proc nic_drv_ld_attr {} {
+ if {[have_spec linux]} { return {ld="no"} }
+ return ""
+}
+
append_if $use_nic_driver config {
-
+
diff --git a/repos/ports/run/seoul.inc b/repos/ports/run/seoul.inc
index 1f7fbf8a2..76dbc6b49 100644
--- a/repos/ports/run/seoul.inc
+++ b/repos/ports/run/seoul.inc
@@ -250,7 +250,7 @@ append_if $use_framebuffer config {
if {!$use_fancy_stuff} {
append config {
-
+
}
append config "
"
@@ -264,10 +264,9 @@ append_if [expr $use_nic_session && !$use_nic_bridge] config {
append_if $use_framebuffer config {
}
append_if $use_genode_iso config {
+
-
-
}
append config {
diff --git a/repos/ports/run/virtualbox.run b/repos/ports/run/virtualbox.run
index f366f697f..814b0b2cf 100644
--- a/repos/ports/run/virtualbox.run
+++ b/repos/ports/run/virtualbox.run
@@ -108,7 +108,7 @@ append_if [have_spec framebuffer] config {
}
append_if [have_spec sdl] config {
-
+
diff --git a/repos/ports/src/noux/child_policy.h b/repos/ports/src/noux/child_policy.h
index 51f9ad626..caad94efa 100644
--- a/repos/ports/src/noux/child_policy.h
+++ b/repos/ports/src/noux/child_policy.h
@@ -194,6 +194,8 @@ class Noux::Child_policy : public Genode::Child_policy
{
return &static_cast(pd).address_space_region_map();
}
+
+ bool forked() const override { return _forked; }
};
#endif /* _NOUX__CHILD_POLICY_H_ */