Add some initial infrastructure for relocating the kernel in place.
MFC after: 2 months Differential revision: D1554
This commit is contained in:
parent
3b50dff506
commit
98cd7a6655
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=277392
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user