Subject: Dynamic ELF support
To: None <port-sh3@netbsd.org>
From: Marcus Comstedt <marcus@idonex.se>
List: port-sh3
Date: 04/09/2001 01:17:25
--Multipart_Mon_Apr__9_01:16:09_2001-1
Content-Type: text/plain; charset=US-ASCII
Hi.
Since I noticed that support for dynamic binaries wasn't implemented
in the SH3/SH4 port, I decided I should give it a go (as I really need
to use shared libraries). The attached patch works with a trivial
test library, so it's better than nothing at least. Please take a
look, or try it out even. It shouldn't break anything not related to
dynamic executables (which didn't work anyway), but I'll wait at least
a week or so before committing anything so you can give it a proper
peer review. Note that you need to use an up to date toolchain (gcc
3.0 and a current snapshot of binutils) to build ld.elf_so as the
older toolchains can't create proper PIC code. Also, rtld_start.S
assumes that you don't have LEADING_UNDERSCORE.
Enjoy.
// Marcus
--Multipart_Mon_Apr__9_01:16:09_2001-1
Content-Type: application/octet-stream; type=patch
Content-Disposition: attachment; filename="dynamic.patch"
Content-Transfer-Encoding: quoted-printable
Index: lib/csu/sh3_elf/crt0.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/basesrc/lib/csu/sh3_elf/crt0.c,v
retrieving revision 1.4
diff -U3 -r1.4 crt0.c
--- lib/csu/sh3_elf/crt0.c 2001/02/25 15:51:24 1.4
+++ lib/csu/sh3_elf/crt0.c 2001/04/08 23:04:37
@@ -35,17 +35,31 @@
* <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
*/
=
-#undef DYNAMIC /* XXX */
-
#include "common.h"
=
void _start __P((int, char **, char **, void (*cleanup) __P((void)),
const Obj_Entry *, struct ps_strings *));
=
#ifdef __LEADING_UNDERSCORE
-__asm (".globl start; start =3D __start");
+__asm ("
+ .text
+ .align 2
+ .globl start
+start:
+ mov.l r9,@-r15
+ bra __start
+ mov.l r8,@-r15
+");
#else
-__asm (".globl __start; __start =3D _start");
+__asm ("
+ .text
+ .align 2
+ .globl __start
+__start:
+ mov.l r9,@-r15
+ bra _start
+ mov.l r8,@-r15
+");
#endif
=
void
Index: libexec/ld.elf_so/Makefile
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/basesrc/libexec/ld.elf_so/Makefile,v
retrieving revision 1.36
diff -U3 -r1.36 Makefile
--- libexec/ld.elf_so/Makefile 2001/01/14 09:39:26 1.36
+++ libexec/ld.elf_so/Makefile 2001/04/08 23:04:37
@@ -2,7 +2,7 @@
=
.include <bsd.own.mk> # for OBJECT_FMT definition
=
-ARCHSUBDIR=3D ${MACHINE_ARCH:C/mipse[bl]/mips/}
+ARCHSUBDIR=3D ${MACHINE_ARCH:C/mipse[bl]/mips/:C/sh3e[bl]/sh3/}
M=3D ${.CURDIR}/arch/${ARCHSUBDIR}
=
.if ((${MACHINE_ARCH} =3D=3D "alpha") || \
@@ -10,6 +10,7 @@
(${MACHINE_ARCH} =3D=3D "m68k") || \
(${MACHINE_ARCH} =3D=3D "mipsel") || (${MACHINE_ARCH} =3D=3D "mipse=
b") || \
(${MACHINE_ARCH} =3D=3D "powerpc") || \
+ (${MACHINE_ARCH} =3D=3D "sh3eb") || (${MACHINE_ARCH} =3D=3D "sh3el"=
) || \
(${MACHINE_ARCH} =3D=3D "sparc") || \
(${MACHINE_ARCH} =3D=3D "sparc64") || \
(${MACHINE_ARCH} =3D=3D "vax")) && \
Index: libexec/ld.elf_so/reloc.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/basesrc/libexec/ld.elf_so/reloc.c,v
retrieving revision 1.34
diff -U3 -r1.34 reloc.c
--- libexec/ld.elf_so/reloc.c 2001/02/04 22:11:12 1.34
+++ libexec/ld.elf_so/reloc.c 2001/04/08 23:04:37
@@ -149,10 +149,14 @@
=
#ifndef __sparc__
=
-#if defined(__alpha__) || defined(__i386__) || defined(__m68k__)
+#if defined(__alpha__) || defined(__i386__) || defined(__m68k__) || defi=
ned(__sh__)
extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
extern Elf_Dyn _DYNAMIC;
+#ifdef __sh__
+#define _GLOBAL_OFFSET_TABLE_ \
+ ({ void *__got; __asm__ ("mov r12,%0" : "=3Dz" (__got)); __got; })
#endif
+#endif
=
int
_rtld_relocate_nonplt_object(obj, rela, dodebug)
@@ -164,7 +168,7 @@
const Elf_Sym *def;
const Obj_Entry *defobj;
#if defined(__alpha__) || defined(__i386__) || defined(__m68k__) || \
- defined(__powerpc__) || defined(__vax__)
+ defined(__sh__) || defined(__powerpc__) || defined(__vax__)
Elf_Addr tmp;
#endif
=
@@ -268,6 +272,54 @@
break;
#endif /* __m68k__ */
=
+#if defined(__sh__)
+ case R_TYPE(GOT32):
+
+ def =3D _rtld_find_symdef(_rtld_objlist, rela->r_info, NULL, obj,
+ &defobj, false);
+ if (def =3D=3D NULL)
+ return -1;
+
+ tmp =3D (Elf_Addr)(defobj->relocbase + def->st_value);
+ if (*where !=3D tmp)
+ *where =3D 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 the binutils-2.6 tools sometimes
+ * generate it.
+ */
+
+ def =3D _rtld_find_symdef(_rtld_objlist, rela->r_info, NULL, obj,
+ &defobj, false);
+ if (def =3D=3D NULL)
+ return -1;
+
+ *where +=3D (Elf_Addr)(defobj->relocbase + def->st_value) -
+ (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 =3D _rtld_find_symdef(_rtld_objlist, rela->r_info, NULL, obj,
+ &defobj, false);
+ if (def =3D=3D NULL)
+ return -1;
+
+ *where +=3D (Elf_Addr)(defobj->relocbase + def->st_value);
+ 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 =3D _rtld_find_symdef(_rtld_objlist, rela->r_info, NULL, obj,
@@ -285,7 +337,7 @@
break;
#endif /* __alpha__ */
=
-#if defined(__alpha__) || defined(__i386__) || defined(__m68k__)
+#if defined(__alpha__) || defined(__i386__) || defined(__m68k__) || defi=
ned(__sh__)
case R_TYPE(GLOB_DAT):
def =3D _rtld_find_symdef(_rtld_objlist, rela->r_info, NULL, obj,
&defobj, false);
@@ -327,7 +379,7 @@
}
rdbg(dodebug, ("COPY (avoid in main)"));
break;
-#endif /* __i386__ || __alpha__ || __m68k__ */
+#endif /* __i386__ || __alpha__ || __m68k__ || __sh__ */
=
#if defined(__mips__)
case R_TYPE(REL32):
@@ -455,7 +507,7 @@
#endif
=
#if defined(__alpha__) || defined(__i386__) || defined(__m68k__) || \
- defined(__vax__)
+ defined(__sh__) || defined(__vax__)
if (bind_now || obj->pltgot =3D=3D NULL) {
const Elf_Sym *def;
const Obj_Entry *defobj;
@@ -476,7 +528,7 @@
defobj->strtab + def->st_name,
(void *)*where, (void *)new_value));
} else
-#endif /* __alpha__ || __i386__ || __m68k__ || __vax__ */
+#endif /* __alpha__ || __i386__ || __m68k__ || __sh__ || __vax__ */
if (!obj->mainprog) {
/* Just relocate the GOT slots pointing into the PLT */
new_value =3D *where + (Elf_Addr)(obj->relocbase);
@@ -637,7 +689,6 @@
if (!ok)
return -1;
=
-
/* Set some sanity-checking numbers in the Obj_Entry. */
obj->magic =3D RTLD_MAGIC;
obj->version =3D RTLD_VERSION;
@@ -651,7 +702,7 @@
=
/* Set the special PLTGOT entries. */
if (obj->pltgot !=3D NULL) {
-#if defined(__i386__) || defined(__m68k__)
+#if defined(__i386__) || defined(__m68k__) || defined(__sh__)
obj->pltgot[1] =3D (Elf_Addr) obj;
obj->pltgot[2] =3D (Elf_Addr) & _rtld_bind_start;
#endif
Index: libexec/ld.elf_so/rtld.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/basesrc/libexec/ld.elf_so/rtld.c,v
retrieving revision 1.44
diff -U3 -r1.44 rtld.c
--- libexec/ld.elf_so/rtld.c 2001/02/03 13:25:00 1.44
+++ libexec/ld.elf_so/rtld.c 2001/04/08 23:04:38
@@ -221,7 +221,7 @@
#endif
assert(objself.needed =3D=3D NULL);
=
-#if !defined(__mips__) && !defined(__i386__) && !defined(__vax__)
+#if !defined(__mips__) && !defined(__i386__) && !defined(__vax__) && !de=
fined(__sh__)
/* no relocation for mips/i386 */
assert(!objself.textrel);
#endif
Index: libexec/ld.elf_so/arch/sh3/Makefile.inc
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: Makefile.inc
diff -N Makefile.inc
--- /dev/null Mon Apr 9 02:00:00 2001
+++ Makefile.inc Mon Apr 9 02:04:38 2001
@@ -0,0 +1,6 @@
+# $NetBSD$
+
+SRCS+=3D rtld_start.S
+
+CPPFLAGS+=3D -fpic -DELFSIZE=3D32 -DVARPSZ
+LDFLAGS+=3D -Bshareable -Bsymbolic -e .rtld_start
Index: libexec/ld.elf_so/arch/sh3/rtld_start.S
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: rtld_start.S
diff -N rtld_start.S
--- /dev/null Mon Apr 9 02:00:00 2001
+++ rtld_start.S Mon Apr 9 02:04:38 2001
@@ -0,0 +1,137 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * 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 th=
e
+ * documentation and/or other materials provided with the distributio=
n.
+ * 3. All advertising materials mentioning features or use of this softw=
are
+ * 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 CONTRIBU=
TORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT L=
IMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTI=
CULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBU=
TORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, O=
R
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSIN=
ESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER =
IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS=
E)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED O=
F 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 =3D _GLOBAL_OFFSET_TABLE_ */
+
+ mov.l 2f,r1
+ add r0,r1 /* r1 =3D GOT end */
+ mov.l 3f,r2
+ mov.l @(r0,r2),r3 /* r3 =3D where the linker thinks GOT end is */
+ mov r1,r2
+ sub r3,r2 /* r2 =3D 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 =3D flag, r1 =3D reloff, r2 =3D 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
+
+ =
Index: share/mk/bsd.own.mk
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/sharesrc/share/mk/bsd.own.mk,v
retrieving revision 1.158
diff -U3 -r1.158 bsd.own.mk
--- share/mk/bsd.own.mk 2001/03/19 17:01:12 1.158
+++ share/mk/bsd.own.mk 2001/04/08 23:04:38
@@ -85,7 +85,7 @@
NOLINT=3D1
NOPROFILE=3D1
OBJECT_FMT?=3DCOFF
-NOPIC?=3D1
+# NOPIC?=3D1
.endif
=
# The sparc64 port is incomplete.
Index: sys/arch/sh3/include/elf_machdep.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/syssrc/sys/arch/sh3/include/elf_machdep.h,v
retrieving revision 1.4
diff -U3 -r1.4 elf_machdep.h
--- sys/arch/sh3/include/elf_machdep.h 2001/03/29 03:23:33 1.4
+++ sys/arch/sh3/include/elf_machdep.h 2001/04/08 23:04:38
@@ -18,3 +18,41 @@
/* no 64-bit ELF machine types supported */
=
#define ARCH_ELFSIZE 32 /* MD native binary size */
+
+/* sh relocations */
+#define R_SH_NONE 0
+#define R_SH_DIR32 1
+#define R_SH_REL32 2
+#define R_SH_DIR8WPN 3
+#define R_SH_IND12W 4
+#define R_SH_DIR8WPL 5
+#define R_SH_DIR8WPZ 6
+#define R_SH_DIR8BP 7
+#define R_SH_DIR8W 8
+#define R_SH_DIR8L 9
+/* The following relocations are GNU extensions. */
+#define R_SH_SWITCH16 25
+#define R_SH_SWITCH32 26
+#define R_SH_USES 27
+#define R_SH_COUNT 28
+#define R_SH_ALIGN 29
+#define R_SH_CODE 30
+#define R_SH_DATA 31
+#define R_SH_LABEL 32
+#define R_SH_SWITCH8 33
+#define R_SH_GNU_VTINHERIT 34
+#define R_SH_GNU_VTENTRY 35
+#define R_SH_LOOP_START 36
+#define R_SH_LOOP_END 37
+/* Dynamic binary relocations */
+#define R_SH_GOT32 160
+#define R_SH_PLT32 161
+#define R_SH_COPY 162
+#define R_SH_GLOB_DAT 163
+#define R_SH_JMP_SLOT 164
+#define R_SH_RELATIVE 165
+#define R_SH_GOTOFF 166
+#define R_SH_GOTPC 167
+
+#define R_TYPE(name) __CONCAT(R_SH_,name)
+
Index: sys/arch/sh3/sh3/sh3_machdep.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/syssrc/sys/arch/sh3/sh3/sh3_machdep.c,v
retrieving revision 1.11
diff -U3 -r1.11 sh3_machdep.c
--- sys/arch/sh3/sh3/sh3_machdep.c 2001/03/15 06:10:48 1.11
+++ sys/arch/sh3/sh3/sh3_machdep.c 2001/04/08 23:04:38
@@ -429,9 +429,8 @@
tf->tf_spc =3D pack->ep_entry;
tf->tf_ssr =3D PSL_USERSET;
tf->tf_r15 =3D stack;
-#ifdef TODO
+
tf->tf_r9 =3D (int)PS_STRINGS;
-#endif
}
=
struct queue {
--Multipart_Mon_Apr__9_01:16:09_2001-1--