Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/libexec/ld.elf_so/arch/arm It is possible for reloc entries ...



details:   https://anonhg.NetBSD.org/src/rev/a211c99b1e1a
branches:  trunk
changeset: 536406:a211c99b1e1a
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Sun Sep 15 00:52:08 2002 +0000

description:
It is possible for reloc entries to point to unaligned locations; handle
this.

diffstat:

 libexec/ld.elf_so/arch/arm/mdreloc.c |  68 +++++++++++++++++++++++++++++++----
 1 files changed, 59 insertions(+), 9 deletions(-)

diffs (122 lines):

diff -r 4e7f914667ad -r a211c99b1e1a libexec/ld.elf_so/arch/arm/mdreloc.c
--- a/libexec/ld.elf_so/arch/arm/mdreloc.c      Sun Sep 15 00:50:18 2002 +0000
+++ b/libexec/ld.elf_so/arch/arm/mdreloc.c      Sun Sep 15 00:52:08 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mdreloc.c,v 1.15 2002/09/13 05:45:46 mycroft Exp $     */
+/*     $NetBSD: mdreloc.c,v 1.16 2002/09/15 00:52:08 thorpej Exp $     */
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -42,6 +42,30 @@
        }
 }
 
+/*
+ * It is possible for the compiler to emit relocations for unaligned data.
+ * We handle this situation with these inlines.
+ */
+#define        RELOC_ALIGNED_P(x) \
+       (((uintptr_t)(x) & (sizeof(void *) - 1)) == 0)
+
+static __inline Elf_Addr
+load_ptr(void *where)
+{
+       Elf_Addr res;
+
+       memcpy(&res, where, sizeof(res));
+
+       return (res);
+}
+
+static __inline void
+store_ptr(void *where, Elf_Addr val)
+{
+
+       memcpy(where, &val, sizeof(val));
+}
+
 int
 _rtld_relocate_nonplt_objects(obj, self)
        const Obj_Entry *obj;
@@ -69,11 +93,17 @@
 #if 1 /* XXX should not occur */
                case R_TYPE(PC24): {    /* word32 S - P + A */
                        Elf32_Sword addend;
+                       Elf_Addr val;
 
                        /*
                         * Extract addend and sign-extend if needed.
                         */
-                       addend = *where;
+                       if (__predict_true(RELOC_ALIGNED_P(where)))
+                               val = *where;
+                       else
+                               val = load_ptr(where);
+
+                       addend = val;
                        if (addend & 0x00800000)
                                addend |= 0xff000000;
 
@@ -93,10 +123,14 @@
                                return -1;
                        }
                        tmp >>= 2;
-                       *where = (*where & 0xff000000) | (tmp & 0x00ffffff);
+                       val = (val & 0xff000000) | (tmp & 0x00ffffff);
+                       if (__predict_true(RELOC_ALIGNED_P(where)))
+                               *where = val;
+                       else
+                               store_ptr(where, val);
                        rdbg(("PC24 %s in %s --> %p @ %p in %s",
                            obj->strtab + obj->symtab[symnum].st_name,
-                           obj->path, (void *)*where, where, defobj->path));
+                           obj->path, (void *)val, where, defobj->path));
                        break;
                }
 #endif
@@ -106,16 +140,32 @@
                        def = _rtld_find_symdef(symnum, obj, &defobj, false);
                        if (def == NULL)
                                return -1;
-                       *where += (Elf_Addr)defobj->relocbase + def->st_value;
+                       if (__predict_true(RELOC_ALIGNED_P(where))) {
+                               tmp = *where + (Elf_Addr)defobj->relocbase +
+                                   def->st_value;
+                               *where = tmp;
+                       } else {
+                               tmp = load_ptr(where) +
+                                   (Elf_Addr)defobj->relocbase +
+                                   def->st_value;
+                               store_ptr(where, tmp);
+                       }
                        rdbg(("ABS32/GLOB_DAT %s in %s --> %p @ %p in %s",
                            obj->strtab + obj->symtab[symnum].st_name,
-                           obj->path, (void *)*where, where, defobj->path));
+                           obj->path, (void *)tmp, where, defobj->path));
                        break;
 
                case R_TYPE(RELATIVE):  /* word32 B + A */
-                       *where += (Elf_Addr)obj->relocbase;
+                       if (__predict_true(RELOC_ALIGNED_P(where))) {
+                               tmp = *where + (Elf_Addr)obj->relocbase;
+                               *where = tmp;
+                       } else {
+                               tmp = load_ptr(where) +
+                                   (Elf_Addr)obj->relocbase;
+                               store_ptr(where, tmp);
+                       }
                        rdbg(("RELATIVE in %s --> %p", obj->path,
-                           (void *)*where));
+                           (void *)tmp));
                        break;
 
                case R_TYPE(COPY):
@@ -138,7 +188,7 @@
                        rdbg(("sym = %lu, type = %lu, offset = %p, "
                            "contents = %p, symbol = %s",
                            symnum, (u_long)ELF_R_TYPE(rel->r_info),
-                           (void *)rel->r_offset, (void *)*where,
+                           (void *)rel->r_offset, (void *)load_ptr(where),
                            obj->strtab + obj->symtab[symnum].st_name));
                        _rtld_error("%s: Unsupported relocation type %ld "
                            "in non-PLT relocations\n",



Home | Main Index | Thread Index | Old Index