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