summaryrefslogtreecommitdiff
path: root/ldso
diff options
context:
space:
mode:
Diffstat (limited to 'ldso')
-rw-r--r--ldso/ldso/arc/dl-sysdep.h15
-rw-r--r--ldso/ldso/arc/elfinterp.c4
-rw-r--r--ldso/ldso/dl-elf.c32
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)