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