diff options
author | andreast <andreast@FreeBSD.org> | 2012-09-21 18:21:31 +0000 |
---|---|---|
committer | andreast <andreast@FreeBSD.org> | 2012-09-21 18:21:31 +0000 |
commit | be9906f96c7ede292408ef02eae1e83ce8646c13 (patch) | |
tree | 8c66ad61cee16c938c43b51c6cfd108c35d51b07 /sys/boot/common | |
parent | 4415d2bdfd228486b8c7a38e43b084b5675fe3b5 (diff) | |
download | FreeBSD-src-be9906f96c7ede292408ef02eae1e83ce8646c13.zip FreeBSD-src-be9906f96c7ede292408ef02eae1e83ce8646c13.tar.gz |
Implement elfN(reloc) for powerpc. With this change the kernel is now able to
resolve dependencies of modules at boot time and load additional modules when
needed.
MFC after: 1 week
Diffstat (limited to 'sys/boot/common')
-rw-r--r-- | sys/boot/common/reloc_elf.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/sys/boot/common/reloc_elf.c b/sys/boot/common/reloc_elf.c index b614091..2b60d18 100644 --- a/sys/boot/common/reloc_elf.c +++ b/sys/boot/common/reloc_elf.c @@ -193,6 +193,31 @@ __elfN(reloc)(struct elf_file *ef, symaddr_fn *symaddr, const void *reldata, } return (0); +#elif defined(__powerpc__) + Elf_Size w; + const Elf_Rela *rela; + + switch (reltype) { + case ELF_RELOC_RELA: + rela = reldata; + if (relbase + rela->r_offset >= dataaddr && + relbase + rela->r_offset < dataaddr + len) { + switch (ELF_R_TYPE(rela->r_info)) { + case R_PPC_RELATIVE: + w = relbase + rela->r_addend; + bcopy(&w, (u_char *)data + (relbase + + rela->r_offset - dataaddr), sizeof(w)); + break; + default: + printf("\nunhandled relocation type %u\n", + (u_int)ELF_R_TYPE(rela->r_info)); + return (EFTYPE); + } + } + break; + } + + return (0); #else return (EOPNOTSUPP); #endif |