diff --git a/repos/base/src/lib/ldso/exception.cc b/repos/base/src/lib/ldso/exception.cc
index 4941ca89cc..049253f5a3 100644
--- a/repos/base/src/lib/ldso/exception.cc
+++ b/repos/base/src/lib/ldso/exception.cc
@@ -38,22 +38,22 @@ extern "C" int dl_iterate_phdr(int (*callback) (Phdr_info *info, size_t size, vo
 	int err = 0;
 	Phdr_info info;
 
-	/* forbid object list manipulation during traversal */
-	Mutex::Guard guard(Linker::shared_object_mutex());
+	bool last = false;
+	Linker::for_each_object([&] (Linker::Object &obj) {
 
-	for (Object *e = obj_list_head();e; e = e->next_obj()) {
+		if (last) return;
 
-		info.addr  = e->reloc_base();
-		info.name  = e->name();
-		info.phdr  = e->file()->phdr.phdr;
-		info.phnum = e->file()->phdr.count;
+		info.addr  = obj.reloc_base();
+		info.name  = obj.name();
+		info.phdr  = obj.file()->phdr.phdr;
+		info.phnum = obj.file()->phdr.count;
 
 		if (verbose_exception)
-			log(e->name(), " reloc ", Hex(e->reloc_base()));
+			log(obj.name(), " reloc ", Hex(obj.reloc_base()));
 
 		if ((err = callback(&info, sizeof(Phdr_info), data)))
-			break;
-	}
+			last = true;
+	});
 
 	return err;
 }
@@ -89,27 +89,28 @@ extern "C" unsigned long dl_unwind_find_exidx(unsigned long pc, int *pcount)
 	enum { EXIDX_ENTRY_SIZE = 8 };
 	*pcount = 0;
 
-	/* forbid object list manipulation during traversal */
-	Mutex::Guard guard(Linker::shared_object_mutex());
+	unsigned long value = 0;
 
-	for (Object *e = obj_list_head(); e; e = e->next_obj()) {
+	Linker::for_each_object([&] (Object &obj) {
+
+		if (value) return;
 
 		/* address of first PT_LOAD header */
-		addr_t base = e->reloc_base() + e->file()->start;
+		addr_t base = obj.reloc_base() + obj.file()->start;
 
 		/* is the 'pc' somewhere within this ELF image */
-		if ((pc < base) || (pc >= base + e->file()->size))
-			continue;
+		if ((pc < base) || (pc >= base + obj.file()->size))
+			return;
 
 		/* retrieve PHDR of exception-table segment */
-		Elf::Phdr const *exidx = phdr_exidx(e->file());
+		Elf::Phdr const *exidx = phdr_exidx(obj.file());
 		if (!exidx)
-			continue;
+			return;
 
 		*pcount = exidx->p_memsz / EXIDX_ENTRY_SIZE;
-		return exidx->p_vaddr + e->reloc_base();
-	}
+		value = exidx->p_vaddr + obj.reloc_base();
+	});
 
-	return 0;
+	return value;
 }
 
diff --git a/repos/base/src/lib/ldso/include/linker.h b/repos/base/src/lib/ldso/include/linker.h
index 937f113f20..ea95c7c11c 100644
--- a/repos/base/src/lib/ldso/include/linker.h
+++ b/repos/base/src/lib/ldso/include/linker.h
@@ -115,11 +115,6 @@ namespace Linker {
 	Object &load(Env &, Allocator &md_alloc, char const *path, Dependency &dep,
 	             Keep keep);
 
-	/**
-	 * Returns the head of the global object list
-	 */
-	Object *obj_list_head();
-
 	/**
 	 * Returns the root-dependeny of the dynamic binary
 	 */
@@ -151,6 +146,7 @@ class Linker::Object : private Fifo<Object>::Element,
 	public:
 
 		typedef String<128> Name;
+		class   Object_list;
 
 	protected:
 
@@ -162,6 +158,8 @@ class Linker::Object : private Fifo<Object>::Element,
 		File const *_file       { nullptr };
 		Elf::Addr   _reloc_base { 0 };
 
+		static Object_list &_object_list();
+
 	public:
 
 		void init(Name const &name, Elf::Addr reloc_base)
@@ -177,6 +175,41 @@ class Linker::Object : private Fifo<Object>::Element,
 			_reloc_base = file.reloc_base;
 		}
 
+		class Object_list
+		{
+			private:
+
+				Fifo<Object> _fifo  { };
+				Mutex        _mutex { };
+
+			public:
+
+				void enqueue(Object &obj)
+				{
+					Mutex::Guard guard(_mutex);
+					_fifo.enqueue(obj);
+				}
+
+				void remove(Object &obj)
+				{
+					Mutex::Guard guard(_mutex);
+					_fifo.remove(obj);
+				}
+
+				template <typename FUNC>
+				void for_each(FUNC const &func)
+				{
+					Mutex::Guard guard(_mutex);
+					_fifo.for_each(func);
+				}
+		};
+
+		template <typename FUNC>
+		static void with_object_list(FUNC const func)
+		{
+			func(_object_list());
+		}
+
 		virtual ~Object() { }
 
 		Elf::Addr        reloc_base() const { return _reloc_base; }
@@ -190,15 +223,11 @@ class Linker::Object : private Fifo<Object>::Element,
 		virtual void relocate(Bind) = 0;
 
 		virtual bool keep() const = 0;
+		virtual void force_keep() = 0;
 
 		virtual void load() = 0;
 		virtual bool unload() { return false;}
 
-		/**
-		 * Next object in global object list
-		 */
-		virtual Object *next_obj() const = 0;
-
 		/**
 		 * Next object in initialization list
 		 */
@@ -228,6 +257,19 @@ class Linker::Object : private Fifo<Object>::Element,
 };
 
 
+namespace Linker {
+	/**
+	 * Apply func to each object
+	 */
+	template <typename FUNC>
+	void for_each_object(FUNC const &func)
+	{
+		Object::with_object_list([&] (Object::Object_list &list) {
+			list.for_each(func); });
+	}
+}
+
+
 /**
  * Dependency of object
  */
diff --git a/repos/base/src/lib/ldso/main.cc b/repos/base/src/lib/ldso/main.cc
index 752d793203..6a8d156c36 100644
--- a/repos/base/src/lib/ldso/main.cc
+++ b/repos/base/src/lib/ldso/main.cc
@@ -75,10 +75,18 @@ Genode::Mutex &Linker::shared_object_mutex()
 	return _mutex;
 }
 
+
 /**************************************************************
  ** ELF object types (shared object, dynamic binaries, ldso  **
  **************************************************************/
 
+Object::Object_list &Object::_object_list()
+{
+	static Object_list _list;
+	return _list;
+}
+
+
 /**
  * The actual ELF object, one per file
  */
@@ -134,7 +142,8 @@ class Linker::Elf_object : public Object, private Fifo<Elf_object>::Element
 		{
 			/* register for static construction and relocation */
 			Init::list()->insert(this);
-			obj_list()->enqueue(*this);
+			with_object_list([&] (Object_list &list) {
+				list.enqueue(*this); });
 
 			/* add to link map */
 			Debug::state_change(Debug::ADD, nullptr);
@@ -156,7 +165,8 @@ class Linker::Elf_object : public Object, private Fifo<Elf_object>::Element
 			Debug::state_change(Debug::CONSISTENT, nullptr);
 
 			/* remove from loaded objects list */
-			obj_list()->remove(*this);
+			with_object_list([&] (Object_list &list) {
+				list.remove(*this); });
 			Init::list()->remove(this);
 		}
 
@@ -201,7 +211,7 @@ class Linker::Elf_object : public Object, private Fifo<Elf_object>::Element
 			Link_map::make_first(&_map);
 		}
 
-		void force_keep() { _keep = KEEP; }
+		void force_keep() override { _keep = KEEP; }
 
 		Link_map const &link_map() const override { return _map; }
 		Dynamic  const &dynamic()  const override { return _dyn; }
@@ -234,22 +244,6 @@ class Linker::Elf_object : public Object, private Fifo<Elf_object>::Element
 		 */
 		Object *next_init() const override { return _next_object(); }
 
-		/**
-		 * Next in object list
-		 */
-		Object *next_obj() const override {
-			return Fifo<Elf_object>::Element::next();
-		}
-
-		/**
-		 * Object list
-		 */
-		static Fifo<Elf_object> *obj_list()
-		{
-			static Fifo<Elf_object> _list;
-			return &_list;
-		}
-
 		void load()   override { _ref_count++; }
 		bool unload() override { return (_keep == DONT_KEEP) && !(--_ref_count); }
 
@@ -331,7 +325,8 @@ Linker::Ld &Linker::Ld::linker()
 	{
 		Ld_vtable()
 		{
-			Elf_object::obj_list()->enqueue(*this);
+			with_object_list([&] (Object_list &list) {
+				list.enqueue(*this); });
 			plt_setup();
 		}
 	};
@@ -543,32 +538,28 @@ Object &Linker::load(Env &env, Allocator &md_alloc, char const *path,
                      Dependency &dep, Keep keep)
 {
 	Object *result = nullptr;
-	Elf_object::obj_list()->for_each([&] (Object &e) {
-		if (result == nullptr) {
-			if (verbose_loading)
-				log("LOAD: ", Linker::file(path), " == ", e.name());
+	Object::with_object_list([&] (Object::Object_list &list) {
+		list.for_each([&] (Object &obj) {
 
-			if (!strcmp(Linker::file(path), e.name())) {
-				e.load();
-				result = &e;
+			if (result == nullptr) {
+				if (verbose_loading)
+					log("LOAD: ", Linker::file(path), " == ", obj.name());
+
+				if (!strcmp(Linker::file(path), obj.name())) {
+					obj.load();
+					result = &obj;
+				}
 			}
-		}
+		});
 	});
+
 	if (result == nullptr)
 		result = new (md_alloc) Elf_object(env, md_alloc, path, dep, keep);
+
 	return *result;
 }
 
 
-Object *Linker::obj_list_head()
-{
-	Object *result = nullptr;
-	Elf_object::obj_list()->head([&result] (Object &obj) {
-		result = &obj; });
-	return result;
-}
-
-
 Elf::Sym const *Linker::lookup_symbol(unsigned sym_index, Dependency const &dep,
                                       Elf::Addr *base, bool undef, bool other)
 {
@@ -748,22 +739,24 @@ 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) {
+	Object::with_object_list([&] (Object::Object_list &list) {
+		list.for_each([&] (Object const &obj) {
 
-		Elf_file const *elf_file_ptr =
-			obj.file() ? dynamic_cast<Elf_file const *>(obj.file()) : nullptr;
+			Elf_file const *elf_file_ptr =
+				obj.file() ? dynamic_cast<Elf_file const *>(obj.file()) : nullptr;
 
-		if (!elf_file_ptr)
-			return;
+			if (!elf_file_ptr)
+				return;
 
-		elf_file_ptr->with_rw_phdr([&] (Elf::Phdr const &phdr) {
+			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 };
+				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);
+				fn.supply_object_info(info);
+			});
 		});
 	});
 }
@@ -771,9 +764,11 @@ void Genode::Dynamic_linker::_for_each_loaded_object(Env &, For_each_fn const &f
 
 void Dynamic_linker::keep(Env &, char const *binary)
 {
-	Elf_object::obj_list()->for_each([&] (Elf_object &obj) {
-		if (Object::Name(binary) == obj.name())
-			obj.force_keep(); });
+	Object::with_object_list([&] (Object::Object_list &list) {
+		list.for_each([&] (Object &obj) {
+			if (Object::Name(binary) == obj.name())
+				obj.force_keep(); });
+	});
 }
 
 
@@ -829,8 +824,10 @@ void Component::construct(Genode::Env &env)
 			    " .. ", Hex(Thread::stack_area_virtual_base() +
 			                Thread::stack_area_virtual_size() - 1),
 			    ": stack area");
-			Elf_object::obj_list()->for_each([] (Object const &obj) {
-				dump_link_map(obj); });
+			Object::with_object_list([] (Object::Object_list &list) {
+				list.for_each([] (Object const &obj) {
+					dump_link_map(obj); });
+			});
 		}
 	} catch (...) {  }
 
diff --git a/repos/base/src/lib/ldso/shared_object.cc b/repos/base/src/lib/ldso/shared_object.cc
index 6c6798a3ef..9ded9a2afc 100644
--- a/repos/base/src/lib/ldso/shared_object.cc
+++ b/repos/base/src/lib/ldso/shared_object.cc
@@ -27,9 +27,16 @@ static Linker::Root_object const &to_root(void *h)
 
 static Linker::Object *find_obj(Genode::addr_t addr)
 {
-	for (Linker::Object *e = Linker::obj_list_head(); e; e = e->next_obj())
-		if (addr >= e->link_map().addr  && addr < e->link_map().addr + e->size())
-			return e;
+	Linker::Object *elf = 0;
+	Linker::for_each_object([&] (Linker::Object &e) {
+		if (elf) return;
+
+		if (addr >= e.link_map().addr  && addr < e.link_map().addr + e.size())
+			elf = &e;
+	});
+
+	if (elf)
+		return elf;
 
 	throw Genode::Address_info::Invalid_address();
 }