Skip to content

Commit

Permalink
Merge remote-tracking branch 'morphis/multi-linker'
Browse files Browse the repository at this point in the history
  • Loading branch information
morphis committed Jun 15, 2016
2 parents a7696ca + ebb2f0b commit 111ffc0
Show file tree
Hide file tree
Showing 10 changed files with 204 additions and 96 deletions.
1 change: 1 addition & 0 deletions debian/libhybris-common1.install
@@ -1 +1,2 @@
usr/lib/*/libhybris-common.so.*
usr/lib/*/libhybris/linker/*.so
36 changes: 9 additions & 27 deletions hybris/common/Makefile.am
@@ -1,46 +1,28 @@
lib_LTLIBRARIES = \
libhybris-common.la

if WANT_STUB_LINKER
SUBDIRS = stub
libhybris_common_la_LIBADD = stub/libstub-linker.la
else
if WANT_EXPERIMENTAL
SUBDIRS = mm
libhybris_common_la_LIBADD = mm/libandroid-linker.la
else
# JB linker works fine for ICS
if HAS_ANDROID_4_0_0
SUBDIRS = jb
libhybris_common_la_LIBADD= jb/libandroid-linker.la
else
if HAS_ANDROID_5_0_0
SUBDIRS = jb
libhybris_common_la_LIBADD= jb/libandroid-linker.la
else
if HAS_ANDROID_2_3_0
SUBDIRS = gingerbread
libhybris_common_la_LIBADD= gingerbread/libandroid-linker.la
else
$(error No Android Version is defined)
endif
endif
endif
SUBDIRS =

if !WANT_ARCH_ARM64
SUBDIRS += jb
endif

if WANT_EXPERIMENTAL
SUBDIRS += mm
endif

libhybris_common_la_SOURCES = \
hooks.c \
hooks_shm.c \
strlcpy.c \
strlcat.c \
dlfcn.c \
logging.c \
sysconf.c
libhybris_common_la_CPPFLAGS = \
-I$(top_srcdir)/include \
$(ANDROID_HEADERS_CFLAGS) \
-I$(top_srcdir)/common
-I$(top_srcdir)/common \
-DLINKER_PLUGIN_DIR=\"$(libdir)/libhybris/linker\"
if WANT_TRACE
libhybris_common_la_CPPFLAGS += -DDEBUG
endif
Expand Down
44 changes: 0 additions & 44 deletions hybris/common/dlfcn.c

This file was deleted.

173 changes: 166 additions & 7 deletions hybris/common/hooks.c
Expand Up @@ -74,6 +74,13 @@ static locale_t hybris_locale;
static int locale_inited = 0;
static hybris_hook_cb hook_callback = NULL;

static void (*_android_linker_init)(int sdk_version) = NULL;
static void* (*_android_dlopen)(const char *filename, int flags) = NULL;
static void* (*_android_dlsym)(void *handle, const char *symbol) = NULL;
static void* (*_android_dladdr)(void *addr, Dl_info *info) = NULL;
static int (*_android_dlclose)(void *handle) = NULL;
static const char* (*_android_dlerror)(void) = NULL;

/* TODO:
* - Check if the int arguments at attr_set/get match the ones at Android
* - Check how to deal with memory leaks (specially with static initializers)
Expand Down Expand Up @@ -2177,6 +2184,41 @@ static wint_t _hybris_hook_getwc(FILE *stream)
return getwc(_get_actual_fp(stream));
}

static void *_hybris_hook_android_dlopen(const char *filename, int flag)
{
TRACE("filename %s flag %i", filename, flag);

return _android_dlopen(filename,flag);
}

static void *_hybris_hook_android_dlsym(void *handle, const char *symbol)
{
TRACE("handle %p symbol %s", handle, symbol);

return _android_dlsym(handle,symbol);
}

static void* _hybris_hook_android_dladdr(void *addr, Dl_info *info)
{
TRACE("addr %p info %p", addr, info);

return _android_dladdr(addr, info);
}

static int _hybris_hook_android_dlclose(void *handle)
{
TRACE("handle %p", handle);

return _android_dlclose(handle);
}

static const char *_hybris_hook_android_dlerror(void)
{
TRACE("");

return android_dlerror();
}

static struct _hook hooks[] = {
{"property_get", _hybris_hook_property_get },
{"property_set", _hybris_hook_property_set },
Expand Down Expand Up @@ -2427,11 +2469,11 @@ static struct _hook hooks[] = {
{"getservbyname", getservbyname},
{"strftime", strftime},
{"sysconf", _hybris_hook_sysconf},
{"dlopen", android_dlopen},
{"dlerror", android_dlerror},
{"dlsym", android_dlsym},
{"dladdr", android_dladdr},
{"dlclose", android_dlclose},
{"dlopen", _hybris_hook_android_dlopen},
{"dlerror", _hybris_hook_android_dlerror},
{"dlsym", _hybris_hook_android_dlsym},
{"dladdr", _hybris_hook_android_dladdr},
{"dlclose", _hybris_hook_android_dlclose},
/* dirent.h */
{"opendir", opendir},
{"fdopendir", fdopendir},
Expand Down Expand Up @@ -2613,11 +2655,128 @@ void* __hybris_get_hooked_symbol(const char *sym, const char *requester)
return NULL;
}

extern void android_linker_init();
static int get_android_sdk_version()
{
static int sdk_version = -1;

if (sdk_version > 0)
return sdk_version;

char *value = NULL;
property_get("ro.build.version.sdk", value, "19");

sdk_version = 19;
if (value)
sdk_version = atoi(value);

return sdk_version;
}

static void *linker_handle = NULL;

static void* load_linker(const char *path)
{
void *handle = dlopen(path, RTLD_LAZY);
if (!handle) {
fprintf(stderr, "ERROR: Failed to load hybris linker for Android SDK version %d\n",
get_android_sdk_version());
return NULL;
}
return handle;
}

#define LINKER_NAME_JB "jb"
#define LINKER_NAME_MM "mm"

static void android_linker_init(int sdk_version);

__attribute__((constructor))
static void hybris_linker_init()
{
LOGD("Linker initialization");
android_linker_init();

int sdk_version = get_android_sdk_version();

char path[PATH_MAX];
char *name = NULL;
/* See https://source.android.com/source/build-numbers.html for
* an overview over available SDK version numbers and which
* Android version they relate to. */
if (sdk_version < 21)
name = LINKER_NAME_JB;
else
name = LINKER_NAME_MM;

/* Allow our user to override the linker we select */
const char *user_linker = getenv("HYBRIS_LINKER");
if (user_linker)
name = user_linker;

char *linker_dir = LINKER_PLUGIN_DIR;
const char *user_linker_dir = getenv("HYBRIS_LINKER_DIR");
if (user_linker_dir)
linker_dir = user_linker_dir;

snprintf(path, PATH_MAX, "%s/%s.so", linker_dir, name);

LOGD("Loading linker from %s..", path);

linker_handle = load_linker(path);
if (!linker_handle)
exit(1);

/* Load all necessary symbols we need from the linker */
_android_linker_init = dlsym(linker_handle, "android_linker_init");
_android_dlopen = dlsym(linker_handle, "android_dlopen");
_android_dlsym = dlsym(linker_handle, "android_dlsym");
_android_dladdr = dlsym(linker_handle, "android_dladdr");
_android_dlclose = dlsym(linker_handle, "android_dlclose");
_android_dlerror = dlsym(linker_handle, "android_dlerror");

/* Now its time to setup the linker itself */
_android_linker_init(sdk_version);
}

void *hybris_dlopen(const char *filename, int flag)
{
return _android_dlopen(filename,flag);
}

void *hybris_dlsym(void *handle, const char *symbol)
{
return _android_dlsym(handle,symbol);
}

int hybris_dlclose(void *handle)
{
return _android_dlclose(handle);
}

const char *hybris_dlerror(void)
{
return _android_dlerror();
}

/* NOTE: As we're not linking directly with the linker anymore
* but several users are using android_* functions directly we
* have to export them here. */

void *android_dlopen(const char *filename, int flag)
{
return _android_dlopen(filename,flag);
}

void *android_dlsym(void *handle, const char *symbol)
{
return _android_dlsym(handle,symbol);
}

int android_dlclose(void *handle)
{
return _android_dlclose(handle);
}

const char *android_dlerror(void)
{
return _android_dlerror();
}
15 changes: 9 additions & 6 deletions hybris/common/jb/Makefile.am
Expand Up @@ -6,15 +6,15 @@ if WANT_ARCH_X86
ARCHFLAGS = -DANDROID_X86_LINKER
endif

noinst_LTLIBRARIES = \
libandroid-linker.la
libandroid_linker_la_SOURCES = \
modlibexecdir = $(libdir)/libhybris/linker
modlibexec_LTLIBRARIES = jb.la
jb_la_SOURCES = \
dlfcn.c \
linker.c \
linker_environ.c \
linker_format.c \
rt.c
libandroid_linker_la_CFLAGS = \
jb_la_CFLAGS = \
-I$(top_srcdir)/include \
$(ANDROID_HEADERS_CFLAGS) \
-I$(top_srcdir)/common \
Expand All @@ -23,9 +23,12 @@ libandroid_linker_la_CFLAGS = \
-DLINKER_AREA_SIZE=0x01000000 \
-DDEFAULT_HYBRIS_LD_LIBRARY_PATH="\"@DEFAULT_HYBRIS_LD_LIBRARY_PATH@\"" \
$(ARCHFLAGS)
jb_la_LDFLAGS = \
-module \
-avoid-version

if WANT_DEBUG
libandroid_linker_la_CFLAGS += -DLINKER_DEBUG=1
jb_la_CFLAGS += -DLINKER_DEBUG=1
else
libandroid_linker_la_CFLAGS += -DLINKER_DEBUG=0
jb_la_CFLAGS += -DLINKER_DEBUG=0
endif
3 changes: 2 additions & 1 deletion hybris/common/jb/linker.c
Expand Up @@ -2334,5 +2334,6 @@ unsigned __linker_init(unsigned **elfdata) {
return __linker_init_post_relocation(elfdata);
}

void android_linker_init() {
void android_linker_init(int sdk_version) {
(void) sdk_version;
}

0 comments on commit 111ffc0

Please sign in to comment.