Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/powerpc/powerpc Rework to support more relocations....



details:   https://anonhg.NetBSD.org/src/rev/2e2125cf1eb7
branches:  trunk
changeset: 765876:2e2125cf1eb7
user:      matt <matt%NetBSD.org@localhost>
date:      Wed Jun 08 17:19:20 2011 +0000

description:
Rework to support more relocations.  Reorganize so code doesn't need to be
replicated over and over.

diffstat:

 sys/arch/powerpc/powerpc/kobj_machdep.c |  88 +++++++++++++++++++-------------
 1 files changed, 52 insertions(+), 36 deletions(-)

diffs (132 lines):

diff -r a28d7b28ab43 -r 2e2125cf1eb7 sys/arch/powerpc/powerpc/kobj_machdep.c
--- a/sys/arch/powerpc/powerpc/kobj_machdep.c   Wed Jun 08 16:24:50 2011 +0000
+++ b/sys/arch/powerpc/powerpc/kobj_machdep.c   Wed Jun 08 17:19:20 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kobj_machdep.c,v 1.4 2011/03/25 19:37:51 riz Exp $     */
+/*     $NetBSD: kobj_machdep.c,v 1.5 2011/06/08 17:19:20 matt Exp $    */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -52,7 +52,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.4 2011/03/25 19:37:51 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.5 2011/06/08 17:19:20 matt Exp $");
 
 #define        ELFSIZE         ARCH_ELFSIZE
 
@@ -69,8 +69,8 @@
        Elf_Addr *where;
        Elf32_Half *hwhere;
        Elf_Addr addr;
-       Elf_Addr addend;
-       Elf_Word rtype, symidx;
+       Elf_Sword addend;               /* needs to be signed */
+       u_int rtype, symidx;
        const Elf_Rela *rela;
 
        if (!isrela) {
@@ -88,18 +88,28 @@
                case R_PPC_NONE:
                break;
 
-       case R_PPC_32: /* word32 S + A */
+       case R_PPC_RELATIVE:    /* word32 B + A */
+               addend += relocbase;                    /* A += B */
+               break;
+
+       case R_PPC_REL32:       /* word32 S + A - P */
+       case R_PPC_REL16:       /* half16* (S + A - P) */
+       case R_PPC_REL16_LO:    /* half16 #lo(S + A - P) */
+       case R_PPC_REL16_HI:    /* half16 #hi(S + A - P) */
+       case R_PPC_REL16_HA:    /* half16 #ha(S + A - P) */
+               addend -= relocbase + rela->r_offset;   /* A -= P */
+               /* FALLTHROUGH */
+
+       case R_PPC_32:          /* word32 S + A */
+       case R_PPC_16:          /* half16* S + A */
+               case R_PPC_16_LO:       /* half16 #lo(S + A) */
+       case R_PPC_16_HA:       /* half16 #ha(S + A) */
+       case R_PPC_16_HI:       /* half16 #hi(S + A) */
                        addr = kobj_sym_lookup(ko, symidx);
                if (addr == 0)
                        return -1;
-               addr += addend;
-               *where = addr;
-               break;
 
-               case R_PPC_16_LO: /* #lo(S) */
-               addr = kobj_sym_lookup(ko, symidx);
-               if (addr == 0)
-                       return -1;
+#if 0
                /*
                 * addend values are sometimes relative to sections
                 * (i.e. .rodata) in rela, where in reality they
@@ -108,35 +118,41 @@
                if (addr > relocbase && addr <= (relocbase + addend))
                        addr = relocbase + addend;
                else
-                       addr += addend;
-               *hwhere = addr & 0xffff;
+#endif
+               addend += addr;                         /* A += S */
                break;
 
-       case R_PPC_16_HA: /* #ha(S) */
-               addr = kobj_sym_lookup(ko, symidx);
-               if (addr == 0)
+       default:
+                       printf("kobj_reloc: unexpected relocation type %u\n", rtype);
+               return -1;
+       }
+
+
+       switch (rtype) {
+       case R_PPC_RELATIVE:    /* word32 B + A */
+       case R_PPC_REL32:       /* word32 S + A - P */
+       case R_PPC_32:          /* word32 S + A */
+               *where = addend;
+               break;
+
+       case R_PPC_REL16:       /* half16* (S + A - P) */
+       case R_PPC_16:          /* half16* S + A */
+               if ((int16_t) addend != addend)
                        return -1;
-               /*
-                * addend values are sometimes relative to sections
-                * (i.e. .rodata) in rela, where in reality they
-                * are relative to relocbase. Detect this condition.
-                */
-               if (addr > relocbase && addr <= (relocbase + addend))
-                       addr = relocbase + addend;
-               else
-                       addr += addend;
-               *hwhere = ((addr >> 16) + ((addr & 0x8000) ? 1 : 0))
-                   & 0xffff;
+               /* FALLTHROUGH */
+       case R_PPC_REL16_LO:    /* half16 #lo(S + A - P) */
+               case R_PPC_16_LO:       /* half16 #lo(S + A) */
+               *hwhere = addend & 0xffff;
                break;
 
-       case R_PPC_RELATIVE: /* word32 B + A */
-                       *where = relocbase + addend;
-               break;
-
-       default:
-                       printf("kobj_reloc: unexpected relocation type %d\n",
-                   (int)rtype);
-               return -1;
+       case R_PPC_REL16_HA:    /* half16 #ha(S + A - P) */
+       case R_PPC_16_HA:       /* half16 #ha(S + A) */
+               addend += 0x8000;
+               /* FALLTHROUGH */
+       case R_PPC_REL16_HI:    /* half16 #hi(S + A - P) */
+       case R_PPC_16_HI:       /* half16 #hi(S + A) */
+               *hwhere = (addend >> 16) & 0xffff;
+               break;
        }
 
        return 0;



Home | Main Index | Thread Index | Old Index