Add some initial infrastructure for relocating the kernel in place.

MFC after:	2 months
Differential revision:	D1554
This commit is contained in:
Nathan Whitehorn 2015-01-19 17:58:01 +00:00
parent 3b50dff506
commit 98cd7a6655
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=277392
2 changed files with 56 additions and 3 deletions

View File

@ -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

View File

@ -119,6 +119,8 @@ SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
(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_Addr relocbase, const void *data,
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)