genode/repos/base/src/lib/ldso/so_support.c

72 lines
2.1 KiB
C

/**
* \brief Shared-object support code
* \author Sebastian Sumpf
* \author Christian Helmuth
* \date 2009-08-14
*
* Support code comprises hooks for execution of static constructors and
* ARM-EABI dynamic linking.
*
* The ARM cross compiler uses the __gnu_Unwind_Find_exidx hook to locate a
* 'ARM.exidx' section within a shared object. For this to work
* 'dl_unwind_find_exidx' is excuted by 'ldso', which returns the section
* address if it finds a shared object within the range of the provieded
* program counter.
*/
/*
* Copyright (C) 2009-2020 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#define BEG { (ld_hook) ~1U }
#define END { (ld_hook) 0 }
#define SECTION(x) __attribute__((used,section( x )))
typedef void (*ld_hook)(void);
static ld_hook _lctors_start[1] SECTION("_mark_ctors_start") = BEG;
static ld_hook _lctors_end[1] SECTION("_mark_ctors_end") = END;
/*
* '__dso_handle' needs to be defined in the main program and in each shared
* object. Because ld.lib.so is both of them, '__dso_handle' is weak here.
*/
void *__dso_handle __attribute__((__visibility__("hidden")))
__attribute__((weak)) = &__dso_handle;
/* called by dynamic linker on library startup (ld.lib.so) */
extern void _init(void) __attribute__((used,section(".init")));
extern void _init(void)
{
/* call static constructors */
for (ld_hook *func = _lctors_end; func > _lctors_start + 1; (*--func)());
}
/*
* from gcc/config/arm/unwind-arm.h
*/
typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
/*
* Dummy for static libs, implemented in ldso for dynamic case
*/
extern _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount) __attribute__((weak));
extern _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount)
{
return 0;
}
/*
* Called from libgcc_eh.a file 'gcc/config/arm/unwind-arm.c' in function
* 'get_eit_entry'
*/
extern _Unwind_Ptr __gnu_Unwind_Find_exidx (_Unwind_Ptr pc, int *pcount)
{
return dl_unwind_find_exidx(pc, pcount);
}