diff options
Diffstat (limited to 'ldso')
-rw-r--r-- | ldso/ldso/arc/dl-sysdep.h | 15 | ||||
-rw-r--r-- | ldso/ldso/arc/elfinterp.c | 4 | ||||
-rw-r--r-- | ldso/ldso/dl-elf.c | 32 |
3 files changed, 49 insertions, 2 deletions
diff --git a/ldso/ldso/arc/dl-sysdep.h b/ldso/ldso/arc/dl-sysdep.h index 08b3bade8..ca62a2c04 100644 --- a/ldso/ldso/arc/dl-sysdep.h +++ b/ldso/ldso/arc/dl-sysdep.h @@ -69,11 +69,16 @@ do { \ } while(0) /* Here we define the magic numbers that this dynamic loader should accept */ +#ifdef __A7__ #define MAGIC1 EM_ARCOMPACT +#define ELF_TARGET "ARCompact" /* For error messages */ +#elif defined(__HS__) +#define MAGIC1 EM_ARCV2 +#define ELF_TARGET "ARCv2" /* For error messages */ +#endif + #undef MAGIC2 -/* Used for error messages */ -#define ELF_TARGET "ARC" struct elf_resolve; extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, @@ -81,6 +86,8 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, extern unsigned __udivmodsi4(unsigned, unsigned) attribute_hidden; +#ifdef __A7__ +/* using "C" causes an indirection via __umodsi3 -> __udivmodsi4 */ #define do_rem(result, n, base) ((result) = \ \ __builtin_constant_p (base) ? (n) % (unsigned) (base) : \ @@ -95,6 +102,10 @@ extern unsigned __udivmodsi4(unsigned, unsigned) attribute_hidden; r1; \ }) \ ) +#elif defined(__HS__) +/* ARCv2 has hardware assisted divide/mod */ +#define do_rem(result, n, base) ((result) = (n) % (unsigned) (base)) +#endif /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or TLS variable so PLT entries should not be allowed to define the value. diff --git a/ldso/ldso/arc/elfinterp.c b/ldso/ldso/arc/elfinterp.c index d26c94705..7c31d3ac7 100644 --- a/ldso/ldso/arc/elfinterp.c +++ b/ldso/ldso/arc/elfinterp.c @@ -11,7 +11,11 @@ */ #include "ldso.h" +#ifdef __A7__ #define ARC_PLT_SIZE 12 +#else +#define ARC_PLT_SIZE 16 +#endif unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, unsigned int plt_pc) diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index d42b91281..49b516390 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -326,6 +326,38 @@ struct elf_resolve *_dl_load_shared_library(unsigned rflags, struct dyn_elf **rp if (tpnt1 != NULL) return tpnt1; +#ifdef __LDSO_RUNPATH_OF_EXECUTABLE__ + /* Very last resort, try the executable's DT_RUNPATH and DT_RPATH */ + /* http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#shobj_dependencies + * The set of directories specified by a given DT_RUNPATH entry is + * used to find only the immediate dependencies of the executable or + * shared object containing the DT_RUNPATH entry. That is, it is + * used only for those dependencies contained in the DT_NEEDED + * entries of the dynamic structure containing the DT_RUNPATH entry, + * itself. One object's DT_RUNPATH entry does not affect the search + * for any other object's dependencies. + * + * glibc (around 2.19) violates this and the usual suspects are + * abusing this bug^Wrelaxed, user-friendly behaviour. + */ + + pnt = (char *) _dl_loaded_modules->dynamic_info[DT_RUNPATH]; + if (pnt) { + pnt += (unsigned long) _dl_loaded_modules->dynamic_info[DT_STRTAB]; + _dl_if_debug_dprint("\tsearching exe's RUNPATH='%s'\n", pnt); + if ((tpnt1 = search_for_named_library(libname, rflags, pnt, rpnt)) != NULL) + return tpnt1; + } + pnt = (char *) _dl_loaded_modules->dynamic_info[DT_RPATH]; + if (pnt) { + pnt += (unsigned long) _dl_loaded_modules->dynamic_info[DT_STRTAB]; + _dl_if_debug_dprint("\tsearching exe's RPATH='%s'\n", pnt); + if ((tpnt1 = search_for_named_library(libname, rflags, pnt, rpnt)) != NULL) + return tpnt1; + } +#endif + + goof: /* Well, we shot our wad on that one. All we can do now is punt */ if (_dl_internal_error_number) |