svn commit: r277392 - in head/sys/powerpc: aim powerpc

Nathan Whitehorn nwhitehorn at FreeBSD.org
Mon Jan 19 17:58:03 UTC 2015


Author: nwhitehorn
Date: Mon Jan 19 17:58:01 2015
New Revision: 277392
URL: https://svnweb.freebsd.org/changeset/base/277392

Log:
  Add some initial infrastructure for relocating the kernel in place.
  
  MFC after:	2 months
  Differential revision:	D1554

Modified:
  head/sys/powerpc/aim/locore64.S
  head/sys/powerpc/powerpc/elf64_machdep.c

Modified: head/sys/powerpc/aim/locore64.S
==============================================================================
--- head/sys/powerpc/aim/locore64.S	Mon Jan 19 17:36:52 2015	(r277391)
+++ head/sys/powerpc/aim/locore64.S	Mon Jan 19 17:58:01 2015	(r277392)
@@ -121,13 +121,33 @@ ASENTRY_NOPROF(__start)
 	.align 3
 0:	nop
 	bl	1f
-	.llong	__tocbase + 0x8000
+	.llong	__tocbase + 0x8000 - .
 1:	mflr	%r2
-	ld	%r2,0(%r2)
+	ld	%r1,0(%r2)
+	add	%r2,%r1,%r2
 
 	/* Set up the stack pointer */
 	ld	%r1,TOC_REF(tmpstk)(%r2)
-	addi	%r1,%r1,TMPSTKSZ-48
+	addi	%r1,%r1,TMPSTKSZ-96
+
+	/* Relocate kernel */
+	std	%r3,48(%r1)
+	std	%r4,56(%r1)
+	std	%r5,64(%r1)
+	std	%r6,72(%r1)
+	bl	1f
+	.llong _DYNAMIC-.
+1:	mflr	%r3
+	ld	%r4,0(%r3)
+	add	%r3,%r4,%r3
+	ld	%r4,-0x8000(%r2) /* First TOC entry is TOC base */
+	subf    %r4,%r4,%r2	/* Subtract from real TOC base to get base */
+	bl	elf_reloc_self
+	nop
+	ld	%r3,48(%r1)
+	ld	%r4,56(%r1)
+	ld	%r5,64(%r1)
+	ld	%r6,72(%r1)
 
 	/* Switch to 64-bit mode */
 	mfmsr	%r9

Modified: head/sys/powerpc/powerpc/elf64_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/elf64_machdep.c	Mon Jan 19 17:36:52 2015	(r277391)
+++ head/sys/powerpc/powerpc/elf64_machdep.c	Mon Jan 19 17:58:01 2015	(r277392)
@@ -119,6 +119,8 @@ SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_AN
 	(sysinit_cfunc_t) elf64_insert_brand_entry,
 	&freebsd_brand_oinfo);
 
+void elf_reloc_self(Elf_Dyn *dynp, Elf_Addr relocbase);
+
 void
 elf64_dump_thread(struct thread *td, void *dst, size_t *off)
 {
@@ -198,6 +200,37 @@ elf_reloc_internal(linker_file_t lf, Elf
 	return(0);
 }
 
+void
+elf_reloc_self(Elf_Dyn *dynp, Elf_Addr relocbase)
+{
+	Elf_Rela *rela = 0, *relalim;
+	Elf_Addr relasz = 0;
+	Elf_Addr *where;
+
+	/*
+	 * Extract the rela/relasz values from the dynamic section
+	 */
+	for (; dynp->d_tag != DT_NULL; dynp++) {
+		switch (dynp->d_tag) {
+		case DT_RELA:
+			rela = (Elf_Rela *)(relocbase+dynp->d_un.d_ptr);
+			break;
+		case DT_RELASZ:
+			relasz = dynp->d_un.d_val;
+			break;
+		}
+	}
+
+	/*
+	 * Relocate these values
+	 */
+	relalim = (Elf_Rela *)((caddr_t)rela + relasz);
+	for (; rela < relalim; rela++) {
+		where = (Elf_Addr *)(relocbase + rela->r_offset);
+		*where = (Elf_Addr)(relocbase + rela->r_addend);
+	}
+}
+
 int
 elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
     elf_lookup_fn lookup)


More information about the svn-src-head mailing list