diff --git a/repos/base/include/base/shared_object.h b/repos/base/include/base/shared_object.h
index cf586a9d7..fc24b71cf 100644
--- a/repos/base/include/base/shared_object.h
+++ b/repos/base/include/base/shared_object.h
@@ -18,11 +18,13 @@
#include
#include
#include
+#include
namespace Genode {
class Shared_object;
struct Address_info;
+ struct Dynamic_linker;
};
@@ -118,4 +120,55 @@ struct Genode::Address_info
Address_info(Genode::addr_t addr);
};
+
+class Genode::Dynamic_linker
+{
+ public:
+
+ struct Object_info
+ {
+ /* name of shared library, or "binary" for the main program */
+ typedef String<64> Name;
+ Name name;
+
+ Rom_dataspace_capability ds_cap;
+
+ /* pointer to the start of the read/writeable segment */
+ void *rw_start;
+
+ /* size of the read-writeable segment in bytes */
+ size_t rw_size;
+ };
+
+ private:
+
+ struct For_each_fn : Interface
+ {
+ virtual void supply_object_info(Object_info const &) const = 0;
+ };
+
+ static void _for_each_loaded_object(Env &, For_each_fn const &);
+
+ public:
+
+ /**
+ * Call 'fn' for each loaded object with 'Object_info' as argument
+ */
+ template
+ static inline void for_each_loaded_object(Env &env, FN const &fn)
+ {
+ struct For_each_fn_impl : For_each_fn
+ {
+ FN const &fn;
+
+ void supply_object_info(Object_info const &info) const { fn(info); }
+
+ For_each_fn_impl(FN const &fn) : fn(fn) { }
+
+ } wrapped_fn { fn };
+
+ _for_each_loaded_object(env, wrapped_fn);
+ }
+};
+
#endif /* _INCLUDE__BASE__SHARED_OBJECT_H_ */
diff --git a/repos/base/lib/symbols/ld b/repos/base/lib/symbols/ld
index 25b1a5d35..0afaeb5f6 100644
--- a/repos/base/lib/symbols/ld
+++ b/repos/base/lib/symbols/ld
@@ -106,6 +106,7 @@ _ZN6Genode13Shared_objectD1Ev T
_ZN6Genode13Shared_objectD2Ev T
_ZN6Genode13sleep_foreverEv T
_ZN6Genode14Capability_map6insertEmm T
+_ZN6Genode14Dynamic_linker23_for_each_loaded_objectERNS_3EnvERKNS0_11For_each_fnE T
_ZN6Genode14Rpc_entrypoint13_free_rpc_capERNS_10Pd_sessionENS_17Native_capabilityE T
_ZN6Genode14Rpc_entrypoint14_alloc_rpc_capERNS_10Pd_sessionENS_17Native_capabilityEm T
_ZN6Genode14Rpc_entrypoint17_activation_entryEv T
diff --git a/repos/base/src/lib/ldso/include/file.h b/repos/base/src/lib/ldso/include/file.h
index d951211f9..fce09531f 100644
--- a/repos/base/src/lib/ldso/include/file.h
+++ b/repos/base/src/lib/ldso/include/file.h
@@ -28,6 +28,12 @@ namespace Linker {
struct Phdr;
struct File;
struct Elf_file;
+
+ static inline bool is_rx(Elf::Phdr const &ph) {
+ return ((ph.p_flags & PF_MASK) == (PF_R | PF_X)); }
+
+ static inline bool is_rw(Elf::Phdr const &ph) {
+ return ((ph.p_flags & PF_MASK) == (PF_R | PF_W)); }
}
@@ -67,6 +73,17 @@ struct Linker::File
}
unsigned elf_phdr_count() const { return phdr.count; }
+
+ template
+ void with_rw_phdr(FN const &fn) const
+ {
+ for (unsigned i = 0; i < phdr.count; i++) {
+ if (is_rw(phdr.phdr[i])) {
+ fn(phdr.phdr[i]);
+ return;
+ }
+ }
+ }
};
@@ -212,12 +229,6 @@ struct Linker::Elf_file : File
}
}
- bool is_rx(Elf::Phdr const &ph) {
- return ((ph.p_flags & PF_MASK) == (PF_R | PF_X)); }
-
- bool is_rw(Elf::Phdr const &ph) {
- return ((ph.p_flags & PF_MASK) == (PF_R | PF_W)); }
-
/**
* Load PT_LOAD segments
*/
diff --git a/repos/base/src/lib/ldso/main.cc b/repos/base/src/lib/ldso/main.cc
index 4d05713ba..9f3cc2111 100644
--- a/repos/base/src/lib/ldso/main.cc
+++ b/repos/base/src/lib/ldso/main.cc
@@ -659,6 +659,29 @@ void Genode::exec_static_constructors()
}
+void Genode::Dynamic_linker::_for_each_loaded_object(Env &, For_each_fn const &fn)
+{
+ Elf_object::obj_list()->for_each([&] (Object const &obj) {
+
+ Elf_file const *elf_file_ptr =
+ obj.file() ? dynamic_cast(obj.file()) : nullptr;
+
+ if (!elf_file_ptr)
+ return;
+
+ elf_file_ptr->with_rw_phdr([&] (Elf::Phdr const &phdr) {
+
+ Object_info info { .name = obj.name(),
+ .ds_cap = elf_file_ptr->rom_cap,
+ .rw_start = (void *)(obj.reloc_base() + phdr.p_vaddr),
+ .rw_size = phdr.p_memsz };
+
+ fn.supply_object_info(info);
+ });
+ });
+}
+
+
void Component::construct(Genode::Env &env)
{
/* read configuration */