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/sparc Add support for unaligned reloc...



details:   https://anonhg.NetBSD.org/src/rev/3bcc9cf55eb3
branches:  trunk
changeset: 572491:3bcc9cf55eb3
user:      martin <martin%NetBSD.org@localhost>
date:      Wed Jan 05 09:18:53 2005 +0000

description:
Add support for unaligned relocs on sparc, from PR 26858.
Should also fix PR 25901 and PR 18296.

diffstat:

 libexec/ld.elf_so/arch/sparc/mdreloc.c |  49 +++++++++++++++++++++++++++------
 1 files changed, 40 insertions(+), 9 deletions(-)

diffs (110 lines):

diff -r 7f8e5e95d031 -r 3bcc9cf55eb3 libexec/ld.elf_so/arch/sparc/mdreloc.c
--- a/libexec/ld.elf_so/arch/sparc/mdreloc.c    Wed Jan 05 09:17:36 2005 +0000
+++ b/libexec/ld.elf_so/arch/sparc/mdreloc.c    Wed Jan 05 09:18:53 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mdreloc.c,v 1.33 2003/07/24 10:12:29 skrll Exp $       */
+/*     $NetBSD: mdreloc.c,v 1.34 2005/01/05 09:18:53 martin Exp $      */
 
 /*-
  * Copyright (c) 1999, 2002 The NetBSD Foundation, Inc.
@@ -66,6 +66,7 @@
 #define _RF_P          0x20000000              /* Location relative */
 #define _RF_G          0x10000000              /* GOT offset */
 #define _RF_B          0x08000000              /* Load address relative */
+#define _RF_U          0x04000000              /* Unaligned */
 #define _RF_SZ(s)      (((s) & 0xff) << 8)     /* memory target size */
 #define _RF_RS(s)      ( (s) & 0xff)           /* right shift */
 static const int reloc_target_flags[] = {
@@ -92,7 +93,7 @@
        _RF_S|_RF_A|            _RF_SZ(32) | _RF_RS(0),         /* GLOB_DAT */
                                _RF_SZ(32) | _RF_RS(0),         /* JMP_SLOT */
              _RF_A|    _RF_B|  _RF_SZ(32) | _RF_RS(0),         /* RELATIVE */
-       _RF_S|_RF_A|            _RF_SZ(32) | _RF_RS(0),         /* UA_32 */
+       _RF_S|_RF_A|    _RF_U|  _RF_SZ(32) | _RF_RS(0),         /* UA_32 */
 
        /*unknown*/             _RF_SZ(32) | _RF_RS(0),         /* PLT32 */
        /*unknown*/             _RF_SZ(32) | _RF_RS(0),         /* HIPLT22 */
@@ -107,6 +108,9 @@
        _RF_S|_RF_A|/*unknown*/ _RF_SZ(32) | _RF_RS(0),         /* HH22 */
        _RF_S|_RF_A|/*unknown*/ _RF_SZ(32) | _RF_RS(0),         /* HM10 */
        _RF_S|_RF_A|/*unknown*/ _RF_SZ(32) | _RF_RS(0),         /* LM22 */
+       _RF_S|_RF_A|_RF_P|/*unknown*/   _RF_SZ(32) | _RF_RS(0), /* PC_HH22 */
+       _RF_S|_RF_A|_RF_P|/*unknown*/   _RF_SZ(32) | _RF_RS(0), /* PC_HM10 */
+       _RF_S|_RF_A|_RF_P|/*unknown*/   _RF_SZ(32) | _RF_RS(0), /* PC_LM22 */
        _RF_S|_RF_A|_RF_P|/*unknown*/   _RF_SZ(32) | _RF_RS(0), /* WDISP16 */
        _RF_S|_RF_A|_RF_P|/*unknown*/   _RF_SZ(32) | _RF_RS(0), /* WDISP19 */
        /*unknown*/             _RF_SZ(32) | _RF_RS(0),         /* GLOB_JMP */
@@ -124,14 +128,16 @@
        "GLOB_DAT", "JMP_SLOT", "RELATIVE", "UA_32", "PLT32",
        "HIPLT22", "LOPLT10", "LOPLT10", "PCPLT22", "PCPLT32",
        "10", "11", "64", "OLO10", "HH22",
-       "HM10", "LM22", "WDISP16", "WDISP19", "GLOB_JMP",
-       "7", "5", "6"
+       "HM10", "LM22", "PC_HH22", "PC_HM10", "PC_LM22", 
+       "WDISP16", "WDISP19", "GLOB_JMP", "7", "5", "6"
 };
 #endif
 
 #define RELOC_RESOLVE_SYMBOL(t)                ((reloc_target_flags[t] & _RF_S) != 0)
 #define RELOC_PC_RELATIVE(t)           ((reloc_target_flags[t] & _RF_P) != 0)
 #define RELOC_BASE_RELATIVE(t)         ((reloc_target_flags[t] & _RF_B) != 0)
+#define RELOC_UNALIGNED(t)             ((reloc_target_flags[t] & _RF_U) != 0)
+#define RELOC_USE_ADDEND(t)            ((reloc_target_flags[t] & _RF_A) != 0)
 #define RELOC_TARGET_SIZE(t)           ((reloc_target_flags[t] >> 8) & 0xff)
 #define RELOC_VALUE_RIGHTSHIFT(t)      (reloc_target_flags[t] & 0xff)
 
@@ -153,6 +159,7 @@
        _BM(10), _BM(11), -1,           /* _10, _11, _64 */
        _BM(10), _BM(22),               /* _OLO10, _HH22 */
        _BM(10), _BM(22),               /* _HM10, _LM22 */
+       _BM(22), _BM(10), _BM(22),      /* _PC_HH22, _PC_HM10, _PC_LM22 */
        _BM(16), _BM(19),               /* _WDISP16, _WDISP19 */
        -1,                             /* GLOB_JMP */
        _BM(7), _BM(5), _BM(6)          /* _7, _5, _6 */
@@ -299,17 +306,41 @@
                value >>= RELOC_VALUE_RIGHTSHIFT(type);
                value &= mask;
 
-               /* We ignore alignment restrictions here */
-               *where &= ~mask;
-               *where |= value;
+               if (RELOC_UNALIGNED(type)) {
+                       /* Handle unaligned relocations. */
+                       Elf_Addr tmp = 0;
+                       char *ptr = (char *)where;
+                       int i, size = RELOC_TARGET_SIZE(type)/8;
+
+                       /* Read it in one byte at a time. */
+                       for (i=0; i<size; i++)
+                               tmp = (tmp << 8) | ptr[i];
+
+                       tmp &= ~mask;
+                       tmp |= value;
+
+                       /* Write it back out. */
+                       for (i=0; i<size; i++)
+                               ptr[i] = ((tmp >> (8*i)) & 0xff);
+#ifdef RTLD_DEBUG_RELOC
+                       value = (Elf_Word)tmp;
+#endif
+
+               } else {
+                       *where &= ~mask;
+                       *where |= value;
+#ifdef RTLD_DEBUG_RELOC
+                       value = (Elf_Word)*where;
+#endif
+               }
 #ifdef RTLD_DEBUG_RELOC
                if (RELOC_RESOLVE_SYMBOL(type)) {
                        rdbg(("%s %s in %s --> %p in %s", reloc_names[type],
                            obj->strtab + obj->symtab[symnum].st_name,
-                           obj->path, (void *)*where, defobj->path));
+                           obj->path, (void *)value, defobj->path));
                } else {
                        rdbg(("%s in %s --> %p", reloc_names[type],
-                           obj->path, (void *)*where));
+                           obj->path, (void *)value));
                }
 #endif
        }



Home | Main Index | Thread Index | Old Index