svn commit: r186640 - head/sys/mips/mips

Warner Losh imp at FreeBSD.org
Wed Dec 31 07:38:05 UTC 2008


Author: imp
Date: Wed Dec 31 07:38:04 2008
New Revision: 186640
URL: http://svn.freebsd.org/changeset/base/186640

Log:
  First pass at 64-bit elf support

Added:
  head/sys/mips/mips/elf64_machdep.c   (contents, props changed)
     - copied, changed from r186189, head/sys/mips/mips/elf_machdep.c

Copied and modified: head/sys/mips/mips/elf64_machdep.c (from r186189, head/sys/mips/mips/elf_machdep.c)
==============================================================================
--- head/sys/mips/mips/elf_machdep.c	Tue Dec 16 19:15:31 2008	(r186189, copy source)
+++ head/sys/mips/mips/elf64_machdep.c	Wed Dec 31 07:38:04 2008	(r186640)
@@ -25,6 +25,8 @@
  *	from: src/sys/i386/i386/elf_machdep.c,v 1.20 2004/08/11 02:35:05 marcel
  */
 
+#define __ELF_WORD_SIZE 64
+
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
@@ -47,7 +49,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/elf.h>
 #include <machine/md_var.h>
 
-struct sysentvec elf32_freebsd_sysvec = {
+struct sysentvec elf64_freebsd_sysvec = {
 	.sv_size	= SYS_MAXSYSCALL,
 	.sv_table	= sysent,
 	.sv_mask	= 0,
@@ -61,7 +63,7 @@ struct sysentvec elf32_freebsd_sysvec = 
 	.sv_sigcode	= sigcode,
 	.sv_szsigcode	= &szsigcode,
 	.sv_prepsyscall	= NULL,
-	.sv_name	= "FreeBSD ELF32",
+	.sv_name	= "FreeBSD ELF64",
 	.sv_coredump	= __elfN(coredump),
 	.sv_imgact_try	= NULL,
 	.sv_minsigstksz	= MINSIGSTKSZ,
@@ -75,198 +77,41 @@ struct sysentvec elf32_freebsd_sysvec = 
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32
+	.sv_flags	= SV_ABI_FREEBSD | SV_LP64
 };
 
-static Elf32_Brandinfo freebsd_brand_info = {
-	.brand		= ELFOSABI_FREEBSD,
+static Elf64_Brandinfo freebsd_brand_gnutools_info64 = {
+	.brand		= ELFOSABI_NONE,
 	.machine	= EM_MIPS,
-	.compat_3_brand	= "FreeBSD",
+	.compat_3_brand	= "Unix System V ABI",
 	.emul_path	= NULL,
 	.interp_path	= "/libexec/ld-elf.so.1",
-	.sysvec		= &elf32_freebsd_sysvec,
-	.interp_newpath	= NULL,
-	.flags		= 0
+	.sysvec		= &elf64_freebsd_sysvec,
+	.interp_path	= "/libexec/ld-elf.so.1",
+	.flags		= BI_CAN_EXEC_DYN
 };
 
-SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY,
-    (sysinit_cfunc_t) elf32_insert_brand_entry,
-    &freebsd_brand_info);
+SYSINIT(gnu_mips_elf64, SI_SUB_EXEC, SI_ORDER_ANY,
+    (sysinit_cfunc_t) elf64_insert_brand_entry,
+    &freebsd_brand_gnutools_info64);
 
-static Elf32_Brandinfo freebsd_brand_oinfo = {
+static Elf64_Brandinfo freebsd_brand_info64 = {
 	.brand		= ELFOSABI_FREEBSD,
 	.machine	= EM_MIPS,
 	.compat_3_brand	= "FreeBSD",
 	.emul_path	= NULL,
-	.interp_path	= "/usr/libexec/ld-elf.so.1",
-	.sysvec		= &elf32_freebsd_sysvec,
+	.interp_path	= "/libexec/ld-elf.so.1",
+	.sysvec		= &elf64_freebsd_sysvec,
 	.interp_newpath	= NULL,
 	.flags		= 0
 };
 
-SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY,
-	(sysinit_cfunc_t) elf32_insert_brand_entry,
-	&freebsd_brand_oinfo);
-
+SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
+    (sysinit_cfunc_t) elf64_insert_brand_entry,
+    &freebsd_brand_info64);
 
 void
-elf32_dump_thread(struct thread *td __unused, void *dst __unused,
+elf64_dump_thread(struct thread *td __unused, void *dst __unused,
     size_t *off __unused)
 {
 }
-
-/* Process one elf relocation with addend. */
-static int
-elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
-    int type, int local, elf_lookup_fn lookup)
-{
-	Elf_Addr *where = (Elf_Addr *)NULL;;
-	Elf_Addr addr;
-	Elf_Addr addend = (Elf_Addr)0;
-	Elf_Word rtype = (Elf_Word)0, symidx;
-	const Elf_Rel *rel;
-	const Elf_Rela *rela;
-
-	switch (type) {
-	case ELF_RELOC_REL:
-		rel = (const Elf_Rel *)data;
-		where = (Elf_Addr *) (relocbase + rel->r_offset);
-		addend = *where;
-		rtype = ELF_R_TYPE(rel->r_info);
-		symidx = ELF_R_SYM(rel->r_info);
-		break;
-	case ELF_RELOC_RELA:
-		rela = (const Elf_Rela *)data;
-		where = (Elf_Addr *) (relocbase + rela->r_offset);
-		addend = rela->r_addend;
-		rtype = ELF_R_TYPE(rela->r_info);
-		symidx = ELF_R_SYM(rela->r_info);
-		break;
-	default:
-		panic("unknown reloc type %d\n", type);
-	}
-
-	if (local) {
-#if 0 /* TBD  */
-		if (rtype == R_386_RELATIVE) {	/* A + B */
-			addr = relocbase + addend;
-			if (*where != addr)
-				*where = addr;
-		}
-		return (0);
-#endif
-	}
-
-	switch (rtype) {
-
-		case R_MIPS_NONE:	/* none */
-			break;
-
-		case R_MIPS_16:	    /* S + sign-extend(A) */
-			/*
-			 * There shouldn't be R_MIPS_16 relocs in kernel objects.
-			 */
-			printf("kldload: unexpected R_MIPS_16 relocation\n");
-			return -1;
-			break;
-
-		case R_MIPS_32: /* S + A - P */
-			addr = lookup(lf, symidx, 1);
-			if (addr == 0)
-				return -1;
-			addr += addend;
-			if (*where != addr)
-				*where = addr;
-			break;
-
-		case R_MIPS_REL32:		/* A - EA + S */
-			/*
-			 * There shouldn't be R_MIPS_REL32 relocs in kernel objects?
-			 */
-			printf("kldload: unexpected R_MIPS_REL32 relocation\n");
-			return -1;
-			break;
-
-		case R_MIPS_26:	     /* ((A << 2) | (P & 0xf0000000) + S) >> 2 */
-			break;
-
-		case R_MIPS_HI16:
-			/* extern/local: ((AHL + S) - ((short)(AHL + S)) >> 16 */
-			/* _gp_disp: ((AHL + GP - P) - (short)(AHL + GP - P)) >> 16 */
-			break;
-
-		case R_MIPS_LO16:
-			/* extern/local: AHL + S */
-			/* _gp_disp: AHL + GP - P + 4 */
-			break;
-
-		case R_MIPS_GPREL16:
-			/* extern/local: ((AHL + S) - ((short)(AHL + S)) >> 16 */
-			/* _gp_disp: ((AHL + GP - P) - (short)(AHL + GP - P)) >> 16 */
-			break;
-
-		case R_MIPS_LITERAL: /* sign-extend(A) + L */
-			break;
-
-		case R_MIPS_GOT16: /* external: G */
-			/* local: tbd */
-			break;
-
-		case R_MIPS_PC16: /* sign-extend(A) + S - P */
-			break;
-
-		case R_MIPS_CALL16: /* G */
-			break;
-
-		case R_MIPS_GPREL32: /* A + S + GP0 - GP */
-			break;
-
-		case R_MIPS_GOTHI16: /* (G - (short)G) >> 16 + A */
-			break;
-
-		case R_MIPS_GOTLO16: /* G & 0xffff */
-			break;
-
-		case R_MIPS_CALLHI16: /* (G - (short)G) >> 16 + A */
-			break;
-
-		case R_MIPS_CALLLO16: /* G & 0xffff */
-			break;
-
-		default:
-			printf("kldload: unexpected relocation type %d\n",
-			    rtype);
-			return (-1);
-	}
-	return(0);
-}
-
-int
-elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
-    elf_lookup_fn lookup)
-{
-
-	return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup));
-}
-
-int
-elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data,
-    int type, elf_lookup_fn lookup)
-{
-
-	return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup));
-}
-
-int
-elf_cpu_load_file(linker_file_t lf __unused)
-{
-
-	return (0);
-}
-
-int
-elf_cpu_unload_file(linker_file_t lf __unused)
-{
-
-	return (0);
-}


More information about the svn-src-head mailing list