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 Add support for dynamic linking on the Sup...



details:   https://anonhg.NetBSD.org/src/rev/96eed3aaf89c
branches:  trunk
changeset: 521710:96eed3aaf89c
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Sun Feb 03 23:34:42 2002 +0000

description:
Add support for dynamic linking on the SuperH.  From Marcus Comstedt,
with some bug fixes (namely, don't forget to consider the addend when
processing relocations) from me.

diffstat:

 libexec/ld.elf_so/Makefile              |    5 +-
 libexec/ld.elf_so/arch/sh3/Makefile.inc |    6 +
 libexec/ld.elf_so/arch/sh3/rtld_start.S |  137 ++++++++++++++++++++++++++++++++
 libexec/ld.elf_so/reloc.c               |   78 +++++++++++++++--
 libexec/ld.elf_so/rtld.c                |    8 +-
 5 files changed, 218 insertions(+), 16 deletions(-)

diffs (truncated from 350 to 300 lines):

diff -r 06491627bb7c -r 96eed3aaf89c libexec/ld.elf_so/Makefile
--- a/libexec/ld.elf_so/Makefile        Sun Feb 03 23:32:10 2002 +0000
+++ b/libexec/ld.elf_so/Makefile        Sun Feb 03 23:34:42 2002 +0000
@@ -1,8 +1,8 @@
-#      $NetBSD: Makefile,v 1.45 2002/01/23 15:10:24 skrll Exp $
+#      $NetBSD: Makefile,v 1.46 2002/02/03 23:34:42 thorpej Exp $
 
 .include <bsd.own.mk>                  # for OBJECT_FMT definition
 
-ARCHSUBDIR= ${MACHINE_ARCH:C/mipse[bl]/mips/}
+ARCHSUBDIR= ${MACHINE_ARCH:C/mipse[bl]/mips/:C/sh3e[bl]/sh3/}
 M= ${.CURDIR}/arch/${ARCHSUBDIR}
 
 .if ((${MACHINE_ARCH} == "alpha") ||                                   \
@@ -11,6 +11,7 @@
      (${MACHINE_ARCH} == "m68k") ||                                    \
      (${MACHINE_ARCH} == "mipsel") || (${MACHINE_ARCH} == "mipseb") || \
      (${MACHINE_ARCH} == "powerpc") ||                                 \
+     (${MACHINE_ARCH} == "sh3eb") || (${MACHINE_ARCH} == "sh3el") ||   \
      (${MACHINE_ARCH} == "sparc") ||                                   \
      (${MACHINE_ARCH} == "sparc64") ||                                 \
      (${MACHINE_ARCH} == "x86_64") ||                                  \
diff -r 06491627bb7c -r 96eed3aaf89c libexec/ld.elf_so/arch/sh3/Makefile.inc
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/libexec/ld.elf_so/arch/sh3/Makefile.inc   Sun Feb 03 23:34:42 2002 +0000
@@ -0,0 +1,6 @@
+#      $NetBSD: Makefile.inc,v 1.1 2002/02/03 23:34:43 thorpej Exp $
+
+SRCS+= rtld_start.S
+
+CPPFLAGS+= -fpic -DELFSIZE=32 -DVARPSZ
+LDFLAGS+= -Bshareable -Bsymbolic -e .rtld_start
diff -r 06491627bb7c -r 96eed3aaf89c libexec/ld.elf_so/arch/sh3/rtld_start.S
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/libexec/ld.elf_so/arch/sh3/rtld_start.S   Sun Feb 03 23:34:42 2002 +0000
@@ -0,0 +1,137 @@
+/*     $NetBSD: rtld_start.S,v 1.1 2002/02/03 23:34:43 thorpej Exp $   */
+
+/*-
+ * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Marcus Comstedt.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+       .text
+       .align  2
+       .globl  .rtld_start
+       .type   .rtld_start,@function
+
+.rtld_start:
+
+       /* relocate GOT, so that we can use global function calls in rtld.c */
+
+       mova    1f,r0
+       mov.l   @r0,r1
+       add     r1,r0   /* r0 = _GLOBAL_OFFSET_TABLE_ */
+
+       mov.l   2f,r1
+       add     r0,r1   /* r1 = GOT end */
+       mov.l   3f,r2
+       mov.l   @(r0,r2),r3     /* r3 = where the linker thinks GOT end is */
+       mov     r1,r2
+       sub     r3,r2   /* r2 = displacement */
+4:
+       mov.l   @r0+,r3         /* add displacement to all GOT entries */
+       cmp/hs  r1,r0
+       add     #-4,r0
+       add     r2,r3
+       mov.l   r3,@r0
+       bf/s    4b
+       add     #4,r0
+
+       bra     4f              /* all done */
+       nop     
+               
+       .align  2
+1:     .long   _GLOBAL_OFFSET_TABLE_
+2:     .long   _DYNAMIC@GOTOFF
+3:     .long   _DYNAMIC@GOT
+
+                       
+4:
+       add     #-8,r15                 /* Make room for return args */
+       mov     r15,r4
+       mov.l   1f,r0
+       add     #(1f-3f),r0
+       bsrf    r0                      /* _rtld(sp) */
+       mov.l   r9,@-r15                /* save ps_strings */
+3:
+       mov.l   @r15+,r9                /* restore ps_strings */
+       
+       mov.l   @r15+,r7                /* arg: cleanup */
+       mov.l   @r15+,r8                /* arg: obj */
+
+       mov.l   @r15,r4                 /* restore argc */
+
+       mov     r15,r5                  /* restore argv */
+       add     #4,r5
+
+       mov     r4,r6                   /* restore envp */
+       shll2   r6
+       add     r15,r6
+       jmp     @r0
+       add     #8,r6
+       .align  2
+1:     .long   _rtld-.
+       .size   .rtld_start,.-.rtld_start
+       
+       .align  2
+       .globl  _rtld_bind_start
+       .type   _rtld_bind_start,@function
+_rtld_bind_start:      /* r0 = flag, r1 = reloff, r2 = obj */
+       mov.l   r3,@-r15        /* save registers */
+       mov.l   r4,@-r15
+       mov.l   r5,@-r15
+       mov.l   r6,@-r15
+       mov.l   r7,@-r15
+       sts.l   mach,@-r15
+       sts.l   macl,@-r15
+       sts.l   pr,@-r15
+
+       mov.l   2f,r0
+       add     #(2f-4f),r0
+       mov     r2,r4           /* copy of obj */
+       bsrf    r0              /* call the binder */
+       mov     r1,r5           /* copy of relobj */
+4:     
+       lds.l   @r15+,pr        /* restore registers */
+       lds.l   @r15+,macl
+       lds.l   @r15+,mach
+       mov.l   @r15+,r7
+       mov.l   @r15+,r6
+       mov.l   @r15+,r5
+       mov.l   @r15+,r4
+       jmp     @r0
+       mov.l   @r15+,r3
+       .align  2
+2:     .long   _rtld_bind-.
+       .size   _rtld_bind_start,.-_rtld_bind_start
+
+       .end
diff -r 06491627bb7c -r 96eed3aaf89c libexec/ld.elf_so/reloc.c
--- a/libexec/ld.elf_so/reloc.c Sun Feb 03 23:32:10 2002 +0000
+++ b/libexec/ld.elf_so/reloc.c Sun Feb 03 23:34:42 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: reloc.c,v 1.50 2002/01/06 03:54:42 eeh Exp $    */
+/*     $NetBSD: reloc.c,v 1.51 2002/02/03 23:34:42 thorpej Exp $        */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -159,7 +159,8 @@
        const Elf_Sym   *def;
        const Obj_Entry *defobj;
 #if defined(__alpha__) || defined(__arm__) || defined(__i386__) || \
-    defined(__m68k__) || defined(__powerpc__) || defined(__vax__)
+    defined(__m68k__) || defined(__powerpc__) || defined(__sh__) || \
+    defined(__vax__)
        Elf_Addr         tmp;
 #endif
 
@@ -263,6 +264,54 @@
                break;
 #endif /* __m68k__ */
 
+#if defined(__sh__)
+       case R_TYPE(GOT32):
+               def = _rtld_find_symdef(_rtld_objlist, rela->r_info, NULL, obj,
+                   &defobj, false);
+               if (def == NULL)
+                       return -1;
+
+               tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
+                   rela->r_addend);
+               if (*where != tmp) 
+                       *where = tmp;
+               rdbg(dodebug, ("GOT32 %s in %s --> %p in %s",
+                   defobj->strtab + def->st_name, obj->path,
+                   (void *)*where, defobj->path));
+               break;
+
+       case R_TYPE(REL32):  
+               /*
+                * I don't think the dynamic linker should ever see this
+                * type of relocation, but some versions of Binutils
+                * generate it.
+                */
+               def = _rtld_find_symdef(_rtld_objlist, rela->r_info, NULL, obj,
+                   &defobj, false);
+               if (def == NULL)
+                       return -1;
+
+               *where += (Elf_Addr)(defobj->relocbase + def->st_value +
+                   rela->r_addend) - (Elf_Addr)where;
+               rdbg(dodebug, ("PC32 %s in %s --> %p in %s",
+                   defobj->strtab + def->st_name, obj->path,
+                   (void *)*where, defobj->path));
+               break;
+
+       case R_TYPE(DIR32):
+               def = _rtld_find_symdef(_rtld_objlist, rela->r_info, NULL, obj,
+                   &defobj, false);
+               if (def == NULL)
+                       return -1;
+
+               *where += (Elf_Addr)(defobj->relocbase + def->st_value +
+                   rela->r_addend);
+               rdbg(dodebug, ("32 %s in %s --> %p in %s",
+                   defobj->strtab + def->st_name, obj->path,
+                   (void *)*where, defobj->path));
+               break;
+#endif /* __sh__ */
+
 #if defined(__alpha__)
        case R_TYPE(REFQUAD):
                def = _rtld_find_symdef(_rtld_objlist, rela->r_info, NULL, obj,
@@ -298,7 +347,8 @@
            }
 #endif /* __alpha__ */
 
-#if defined(__alpha__) || defined(__i386__) || defined(__m68k__)
+#if defined(__alpha__) || defined(__i386__) || defined(__m68k__) || \
+    defined(__sh__)
        case R_TYPE(GLOB_DAT):
                def = _rtld_find_symdef(_rtld_objlist, rela->r_info, NULL, obj,
                    &defobj, false);
@@ -313,8 +363,16 @@
                    defobj->strtab + def->st_name, obj->path,
                    (void *)*where, defobj->path));
                break;
-
-#if !defined(__alpha__)
+#if defined(__sh__)
+       case R_TYPE(RELATIVE):
+               if (rela->r_addend)
+                       *where = (Elf_Addr)obj->relocbase + rela->r_addend;
+               else
+                       *where += (Elf_Addr)obj->relocbase;
+               rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
+                   (void *)*where));
+               break;
+#elif !defined(__alpha__)
        case R_TYPE(RELATIVE):
                *where += (Elf_Addr)obj->relocbase;
                rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
@@ -337,7 +395,7 @@
                }
                rdbg(dodebug, ("COPY (avoid in main)"));
                break;
-#endif /* __i386__ || __alpha__ || __m68k__ */
+#endif /* __i386__ || __alpha__ || __m68k__ || defined(__sh__) */
 
 #if defined(__mips__)
        case R_TYPE(REL32):
@@ -557,7 +615,7 @@
        /* Fully resolve procedure addresses now */
 
 #if defined(__alpha__) || defined(__arm__) || defined(__i386__) || \
-    defined(__m68k__) || defined(__vax__)
+    defined(__m68k__) || defined(__sh__) || defined(__vax__)
        if (bind_now || obj->pltgot == NULL) {
                const Elf_Sym  *def;
                const Obj_Entry *defobj;
@@ -574,7 +632,7 @@
                        return -1;
 
                new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
-#if defined(__vax__)
+#if defined(__sh__) || defined(__vax__)



Home | Main Index | Thread Index | Old Index