From 48134c2a0b8b51ad961f87e532db57b8521facea Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Tue, 8 Aug 2017 14:08:43 +0200 Subject: [PATCH] ldso/cxx: show symbols names of undefined references Fixes #2482 --- .../base/src/include/base/internal/globals.h | 3 ++ repos/base/src/lib/cxx/misc.cc | 36 +++++++++++++++- repos/base/src/lib/ldso/include/types.h | 43 ++++++++++++++++++- repos/base/src/lib/ldso/main.cc | 14 ++++-- repos/base/src/lib/ldso/shared_object.cc | 12 +++++- 5 files changed, 101 insertions(+), 7 deletions(-) diff --git a/repos/base/src/include/base/internal/globals.h b/repos/base/src/include/base/internal/globals.h index f0d4f46b18..7b873d7c1f 100644 --- a/repos/base/src/include/base/internal/globals.h +++ b/repos/base/src/include/base/internal/globals.h @@ -41,6 +41,9 @@ namespace Genode { void destroy_signal_thread(); + void cxx_demangle(char const*, char*, size_t); + void cxx_current_exception(char *out, size_t size); + Id_space &env_session_id_space(); Env &internal_env(); } diff --git a/repos/base/src/lib/cxx/misc.cc b/repos/base/src/lib/cxx/misc.cc index 01c33a7b07..665f3b7979 100644 --- a/repos/base/src/lib/cxx/misc.cc +++ b/repos/base/src/lib/cxx/misc.cc @@ -11,6 +11,10 @@ * under the terms of the GNU Affero General Public License version 3. */ +/* libsupc++ includes */ +#include + +/* Genode includes */ #include #include #include @@ -18,7 +22,8 @@ #include #include -#include +/* base-internal includes */ +#include extern "C" void __cxa_pure_virtual() @@ -226,3 +231,32 @@ extern "C" __attribute__((weak)) void __stack_chk_fail_local(void) { Genode::error("Violated stack boundary"); } + + +/******************************* + ** Demangling of C++ symbols ** + *******************************/ + +extern "C" void free(void *); + +void Genode::cxx_demangle(char const *symbol, char *out, size_t size) +{ + char *demangled_name = __cxxabiv1::__cxa_demangle(symbol, nullptr, nullptr, nullptr); + if (demangled_name) { + Genode::strncpy(out, demangled_name, size); + free(demangled_name); + } else { + Genode::strncpy(out, symbol, size); + } +} + + +void Genode::cxx_current_exception(char *out, size_t size) +{ + std::type_info *t = __cxxabiv1::__cxa_current_exception_type(); + + if (!t) + return; + + cxx_demangle(t->name(), out, size); +} diff --git a/repos/base/src/lib/ldso/include/types.h b/repos/base/src/lib/ldso/include/types.h index 3eb1fb9986..b34901f086 100644 --- a/repos/base/src/lib/ldso/include/types.h +++ b/repos/base/src/lib/ldso/include/types.h @@ -21,6 +21,7 @@ #include #include #include +#include namespace Linker { @@ -31,9 +32,49 @@ namespace Linker { */ class Incompatible : Exception { }; class Invalid_file : Exception { }; - class Not_found : Exception { }; class Fatal : Exception { }; + class Not_found : Exception + { + private: + + enum { CAPACITY = 128 }; + char _buf[CAPACITY]; + + public: + + Not_found() : _buf("") { } + Not_found(char const *str) + { + cxx_demangle(str, _buf, CAPACITY); + } + + void print(Output &out) const + { + Genode::print(out, Cstring(_buf, CAPACITY)); + } + }; + + class Current_exception + { + private: + + enum { CAPACITY = 128 }; + char _buf[CAPACITY]; + + public: + + Current_exception() : _buf("") + { + cxx_current_exception(_buf, CAPACITY); + } + + void print(Output &out) const + { + Genode::print(out, Cstring(_buf, CAPACITY)); + } + }; + enum Keep { DONT_KEEP = Shared_object::DONT_KEEP, KEEP = Shared_object::KEEP }; diff --git a/repos/base/src/lib/ldso/main.cc b/repos/base/src/lib/ldso/main.cc index 4cfd4b67d7..92358ef4f7 100644 --- a/repos/base/src/lib/ldso/main.cc +++ b/repos/base/src/lib/ldso/main.cc @@ -291,8 +291,11 @@ Elf::Addr Ld::jmp_slot(Dependency const &dep, Elf::Size index) Reloc_jmpslot slot(dep, dep.obj().dynamic().pltrel_type(), dep.obj().dynamic().pltrel(), index); return slot.target_addr(); + } catch (Linker::Not_found &symbol) { + error("LD: jump slot relocation failed for symbol: '", symbol, "'"); + throw; } catch (...) { - error("LD: jump slot relocation failed. FATAL!"); + error("LD: jump slot relocation failed:: '", Current_exception(), "'"); throw; } @@ -564,7 +567,7 @@ Elf::Sym const *Linker::lookup_symbol(char const *name, Dependency const &dep, if (binary_ptr && &dep != binary_ptr->first_dep()) { return lookup_symbol(name, *binary_ptr->first_dep(), base, undef, other); } else { - throw Not_found(); + throw Not_found(name); } } @@ -572,7 +575,7 @@ Elf::Sym const *Linker::lookup_symbol(char const *name, Dependency const &dep, log("LD: return ", weak_symbol); if (!weak_symbol) - throw Not_found(); + throw Not_found(name); *base = weak_base; return weak_symbol; @@ -661,8 +664,11 @@ void Component::construct(Genode::Env &env) /* load binary and all dependencies */ try { binary_ptr = unmanaged_singleton(env, *heap(), config.bind()); + } catch(Linker::Not_found &symbol) { + error("LD: symbol not found: '", symbol, "'"); + throw; } catch (...) { - error("LD: failed to load program"); + error("LD: exception during program load: '", Current_exception(), "'"); throw; } diff --git a/repos/base/src/lib/ldso/shared_object.cc b/repos/base/src/lib/ldso/shared_object.cc index 65c4d3e006..614e40dadb 100644 --- a/repos/base/src/lib/ldso/shared_object.cc +++ b/repos/base/src/lib/ldso/shared_object.cc @@ -74,7 +74,17 @@ Genode::Shared_object::Shared_object(Env &env, Allocator &md_alloc, Linker::dump_link_map(to_root(_handle).first_dep()->obj()); } catch (...) { } - } catch (...) { throw Invalid_file(); } + } catch(Linker::Not_found &symbol) { + warning("LD: symbol not found: '", symbol, "'"); + throw Invalid_file(); + + } catch (...) { + if (Linker::verbose) + warning("LD: exception during Shared_object open: " + "'", Current_exception(), "'"); + + throw Invalid_file(); + } }