[yocto] [EDT][prelink-cross] LD_PRELOAD Implementation in Prelink
Maninder Singh
maninder1.s at samsung.com
Sun May 17 22:17:22 PDT 2015
EP-F6AA0618C49C4AEDA73BFF1B39950BAB
Hi,
Subject: [PATCH 1/1] LD_PRELOAD Implementation in Prelink
prelink fails if there are ld_preload libs present at target with below error.
expect libsX.so.1, found /lib/libY.so in dependency order
where libY.so.1 is ld_preload lib
To use this feature :
./prelink --ld-preload=libpreload1.so:libpreload2.so:.... upto 20 libs
Order of libraries to be preloaded is significant. Make sure sequence
mentioned in prelink
should be same as runtime sequence.
Signed-off-by: Vaneet Narang <v.narang at samsung.com>
Signed-off-by: Maninder Singh <maninder1.s at samsung.com>
Reviewed-by: Ajeet Yadav <ajeet.v at samsung.com>
Reviewed-by: Geon-ho Kim <gh007.kim at samsung.com>
---
src/gather.c | 8 +++++++-
src/get.c | 9 ++++++++-
src/main.c | 6 ++++++
src/prelink.h | 1 +
src/rtld/rtld.c | 51 +++++++++++++++++++++++++++++++++++++++++++++------
5 files changed, 67 insertions(+), 8 deletions(-)
diff --git a/src/gather.c b/src/gather.c
index c3d3128..5ccd243 100644
--- a/src/gather.c
+++ b/src/gather.c
@@ -61,7 +61,7 @@ gather_deps (DSO *dso, struct prelink_entry *ent)
{
int i, j, seen = 0;
FILE *f = NULL;
- const char *argv[6];
+ const char *argv[8];
const char *envp[5];
char *line = NULL, *p, *q = NULL;
const char **depends = NULL;
@@ -74,6 +74,7 @@ gather_deps (DSO *dso, struct prelink_entry *ent)
int nliblist = 0;
const char *dl;
const char *ent_filename;
+ int etype = dso->ehdr.e_type;
if (check_dso (dso))
{
@@ -181,6 +182,11 @@ gather_deps (DSO *dso, struct prelink_entry *ent)
argv[i++] = "--library-path";
argv[i++] = ld_library_path;
}
+
+ if(etype == ET_EXEC && ld_preload) {
+ argv[i++] = "--ld-preload";
+ argv[i++] = ld_preload;
+ }
argv[i++] = "--target-paths";
argv[i++] = ent_filename;
argv[i] = NULL;
diff --git a/src/get.c b/src/get.c
index 6a63f02..043af22 100644
--- a/src/get.c
+++ b/src/get.c
@@ -641,12 +641,13 @@ prelink_get_relocations (struct prelink_info *info)
{
FILE *f;
DSO *dso = info->dso;
- const char *argv[6];
+ const char *argv[8];
const char *envp[4];
int i, ret, status;
char *p;
const char *dl = dynamic_linker ?: dso->arch->dynamic_linker;
const char *ent_filename;
+ int etype = info->dso->ehdr.e_type;
if (info->ent->type == ET_DYN)
{
@@ -709,6 +710,12 @@ prelink_get_relocations (struct prelink_info *info)
argv[i++] = "--library-path";
argv[i++] = ld_library_path;
}
+
+ if(etype == ET_EXEC && ld_preload) {
+ argv[i++] = "--ld-preload";
+ argv[i++] = ld_preload;
+ }
+
argv[i++] = "--target-paths";
argv[i++] = ent_filename;
argv[i] = NULL;
diff --git a/src/main.c b/src/main.c
index 15c1d53..a99816d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -59,6 +59,7 @@ const char *ld_library_path;
const char *prelink_conf = PRELINK_CONF;
const char *prelink_cache = PRELINK_CACHE;
const char *undo_output;
+char *ld_preload = NULL;
int noreexecinit;
time_t initctime;
@@ -84,6 +85,7 @@ static char argp_doc[] = PRELINK_PROG " -- program to relocate and prelink ELF s
#define OPT_SYSROOT 0x8d
#define OPT_RTLD 0x8e
#define OPT_ALLOW_TEXTREL 0x8f
+#define OPT_LD_PRELOAD 0x90
static struct argp_option options[] = {
{"all", 'a', 0, 0, "Prelink all binaries" },
@@ -123,6 +125,7 @@ static struct argp_option options[] = {
{"rtld", OPT_RTLD, "RTLD", OPTION_HIDDEN, "" },
{"init", 'i', 0, 0, "Do not re-execute init" },
{"allow-textrel", OPT_ALLOW_TEXTREL, 0, 0, "Allow text relocations even on architectures where they may not work" },
+ {"ld-preload", OPT_LD_PRELOAD, "LIBLIST", 0, "List of libraries preloaded on target" },
{ 0 }
};
@@ -250,6 +253,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
case OPT_ALLOW_TEXTREL:
allow_bad_textrel = 1;
break;
+ case OPT_LD_PRELOAD:
+ ld_preload = arg;
+ break;
default:
return ARGP_ERR_UNKNOWN;
}
diff --git a/src/prelink.h b/src/prelink.h
index 66aba99..a6ce607 100644
--- a/src/prelink.h
+++ b/src/prelink.h
@@ -597,6 +597,7 @@ extern enum verify_method_t verify_method;
extern int quick;
extern long long seed;
extern GElf_Addr mmap_reg_start, mmap_reg_end, layout_page_size;
+extern char *ld_preload;
extern const char *sysroot;
diff --git a/src/rtld/rtld.c b/src/rtld/rtld.c
index 2ad3ade..f014bea 100644
--- a/src/rtld/rtld.c
+++ b/src/rtld/rtld.c
@@ -47,6 +47,7 @@ unsigned int _dl_debug_mask = 0;
/* LD_DYNAMIC_WEAK option. Default is off, changing to 1
is equivalent to setting LD_DYNAMIC_WEAK. */
unsigned int _dl_dynamic_weak = 0;
+#define MAX_PRELOADED_LIBS 20
struct search_path
{
@@ -60,6 +61,7 @@ int host_paths;
char * dst_ORIGIN;
char * dst_PLATFORM = ""; /* undefined */
char * dst_LIB = "lib";
+char * ld_preload = NULL;
void string_to_path (struct search_path *path, const char *string);
@@ -73,11 +75,13 @@ static char argp_doc[] = PRELINK_RTLD_PROG " -- program to simulate the runtime
#define OPT_SYSROOT 0x8c
#define OPT_LIBRARY_PATH 0x8e
#define OPT_TARGET_PATHS 0x8f
+#define OPT_LD_PRELOAD 0x90
static struct argp_option options[] = {
{"library-path", OPT_LIBRARY_PATH, "LIBRARY_PATH", 0, "Set library search path to LIBRARY_PATH" },
{"root", OPT_SYSROOT, "ROOT_PATH", 0, "Prefix all paths with ROOT_PATH" },
{"target-paths", OPT_TARGET_PATHS, 0, 0, "Specified paths are based on ROOT_PATH" },
+ {"ld-preload", OPT_LD_PRELOAD, "LIBLIST", 0, "List of libraries needs to be preloaded"},
{ 0 }
};
@@ -95,6 +99,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
case OPT_TARGET_PATHS:
host_paths = 0;
break;
+ case OPT_LD_PRELOAD:
+ ld_preload = arg;
+ break;
default:
return ARGP_ERR_UNKNOWN;
}
@@ -582,6 +589,8 @@ load_dsos (DSO *dso, int host_paths)
{
struct dso_list *dso_list, *dso_list_tail, *cur_dso_ent, *new_dso_ent;
struct stat64 st;
+ int total_preload = 0;
+ char * libname[MAX_PRELOADED_LIBS] = {NULL};
/* Assume it's static unless we find DT_NEEDED entries */
static_binary = 1;
@@ -604,6 +613,22 @@ load_dsos (DSO *dso, int host_paths)
cur_dso_ent = dso_list_tail = dso_list;
+ if(dso->ehdr.e_type == ET_EXEC && ld_preload) {
+ char *next_lib = ld_preload;
+ libname[total_preload] = ld_preload;
+ total_preload++;
+ next_lib=strchr(ld_preload,':');
+ while(next_lib!=NULL){
+ *next_lib = '\0';
+ next_lib++;
+ libname[total_preload] = next_lib;
+ total_preload++;
+ next_lib=strchr(next_lib,':');
+ }
+ }
+ else {
+ total_preload = 0;
+ }
while (cur_dso_ent != NULL)
{
DSO *cur_dso, *new_dso;
@@ -624,9 +649,16 @@ load_dsos (DSO *dso, int host_paths)
{
int ndx, maxndx;
maxndx = data->d_size / cur_dso->shdr[cur_dso->dynamic].sh_entsize;
- for (ndx = 0; ndx < maxndx; ++ndx)
+ for (ndx = 0; ndx < maxndx + total_preload; ++ndx)
{
- gelfx_getdyn (cur_dso->elf, data, ndx, &dyn);
+
+ if(ndx - total_preload >= 0) {
+ gelfx_getdyn (cur_dso->elf, data, ndx - total_preload, &dyn);
+ }
+ else {
+ dyn.d_tag = DT_NEEDED;
+ }
+
if (dyn.d_tag == DT_NULL)
break;
if (dyn.d_tag == DT_NEEDED)
@@ -635,10 +667,17 @@ load_dsos (DSO *dso, int host_paths)
static_binary = 0;
char *new_name=NULL, *new_canon_name=NULL;
- const char *soname = get_data (cur_dso,
- cur_dso->info[DT_STRTAB]
- + dyn.d_un.d_val,
- NULL, NULL);
+ char * soname = NULL;
+ if(ndx - total_preload >= 0) {
+ soname = get_data (cur_dso,
+ cur_dso->info[DT_STRTAB]
+ + dyn.d_un.d_val,
+ NULL, NULL);
+ }
+ else {
+ soname = libname[ndx];
+ }
+
new_dso_ent = in_dso_list (dso_list, soname, NULL);
if (new_dso_ent == NULL)
{
--
1.7.1
Thanks
Maninder Singh
More information about the yocto
mailing list