ldso/cxx: show symbols names of undefined references

Fixes #2482
This commit is contained in:
Sebastian Sumpf 2017-08-08 14:08:43 +02:00 committed by Christian Helmuth
parent ee40d29b91
commit 48134c2a0b
5 changed files with 101 additions and 7 deletions

View File

@ -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<Parent::Client> &env_session_id_space();
Env &internal_env();
}

View File

@ -11,6 +11,10 @@
* under the terms of the GNU Affero General Public License version 3.
*/
/* libsupc++ includes */
#include <cxxabi.h>
/* Genode includes */
#include <base/env.h>
#include <base/log.h>
#include <base/stdint.h>
@ -18,7 +22,8 @@
#include <base/thread.h>
#include <util/string.h>
#include <cxxabi.h>
/* base-internal includes */
#include <base/internal/globals.h>
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);
}

View File

@ -21,6 +21,7 @@
#include <util/fifo.h>
#include <util/misc_math.h>
#include <util/string.h>
#include <base/internal/globals.h>
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("<unkown>") { }
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("<unkown>")
{
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 };

View File

@ -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<Binary>(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;
}

View File

@ -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();
}
}