summaryrefslogtreecommitdiffstats
path: root/sys/powerpc
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1998-10-16 03:55:01 +0000
committerpeter <peter@FreeBSD.org>1998-10-16 03:55:01 +0000
commit464de37ce6099f409aa233200a94ac38216aa211 (patch)
tree59ed738c6bca93117593ea63241912064597c130 /sys/powerpc
parentad0030e392049cd4f887968f40988dd6cf5e5ee0 (diff)
downloadFreeBSD-src-464de37ce6099f409aa233200a94ac38216aa211.zip
FreeBSD-src-464de37ce6099f409aa233200a94ac38216aa211.tar.gz
*gulp*. Jordan specifically OK'ed this..
This is the bulk of the support for doing kld modules. Two linker_sets were replaced by SYSINIT()'s. VFS's and exec handlers are self registered. kld is now a superset of lkm. I have converted most of them, they will follow as a seperate commit as samples. This all still works as a static a.out kernel using LKM's.
Diffstat (limited to 'sys/powerpc')
-rw-r--r--sys/powerpc/powerpc/elf_machdep.c74
1 files changed, 41 insertions, 33 deletions
diff --git a/sys/powerpc/powerpc/elf_machdep.c b/sys/powerpc/powerpc/elf_machdep.c
index 1e7c86d..847ab2a 100644
--- a/sys/powerpc/powerpc/elf_machdep.c
+++ b/sys/powerpc/powerpc/elf_machdep.c
@@ -22,7 +22,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id$
+ * $Id: elf_machdep.c,v 1.1 1998/09/11 08:47:02 dfr Exp $
*/
#include <sys/param.h>
@@ -38,73 +38,81 @@
/* Process one elf relocation with addend. */
int
-elf_reloc(linker_file_t lf, const Elf_Rela *rela, const char *sym)
+elf_reloc(linker_file_t lf, const void *data, int type, const char *sym)
{
Elf_Addr relocbase = (Elf_Addr) lf->address;
- Elf_Addr *where = (Elf_Addr *) (relocbase + rela->r_offset);
+ Elf_Addr *where;
+ Elf_Addr addr, tmp_value;
+ Elf_Addr addend;
+ Elf_Word rtype;
+ const Elf_Rel *rel;
+ const Elf_Rela *rela;
- switch (ELF_R_TYPE(rela->r_info)) {
+ switch (type) {
+ case ELF_RELOC_REL:
+ rel = (Elf_Rel *)data;
+ where = (Elf_Addr *) (relocbase + rel->r_offset);
+ addend = *where;
+ rtype = ELF_R_TYPE(rel->r_info);
+ break;
+ case ELF_RELOC_RELA:
+ rela = (Elf_Rela *)data;
+ where = (Elf_Addr *) (relocbase + rela->r_offset);
+ addend = rela->r_addend;
+ rtype = ELF_R_TYPE(rela->r_info);
+ break;
+ default:
+ panic("elf_reloc: unknown relocation mode %d\n", type);
+ }
- case R_ALPHA_REFQUAD: {
- Elf_Addr addr;
- Elf_Addr tmp_value;
+ switch (rtype) {
+ case R_ALPHA_REFQUAD:
addr = (Elf_Addr)
linker_file_lookup_symbol(lf, sym, 1);
if (addr == NULL)
return -1;
+ addr += addend;
+ if (*where != addr)
+ *where = addr;
+ break;
- tmp_value = addr + *where + rela->r_addend;
- if (*where != tmp_value)
- *where = tmp_value;
- }
- break;
-
- case R_ALPHA_GLOB_DAT: {
- Elf_Addr addr;
-
+ case R_ALPHA_GLOB_DAT:
addr = (Elf_Addr)
linker_file_lookup_symbol(lf, sym, 1);
if (addr == NULL)
return -1;
-
if (*where != addr)
*where = addr;
- }
- break;
+ break;
- case R_ALPHA_JMP_SLOT: {
+ case R_ALPHA_JMP_SLOT:
/* No point in lazy binding for kernel modules. */
- Elf_Addr addr;
-
addr = (Elf_Addr)
linker_file_lookup_symbol(lf, sym, 1);
if (addr == NULL)
return -1;
-
if (*where != addr)
*where = addr;
- }
- break;
+ break;
- case R_ALPHA_RELATIVE: {
- *where += relocbase;
- }
- break;
+ case R_ALPHA_RELATIVE:
+ addr = relocbase + addend;
+ if (*where != addr)
+ *where = addr;
+ break;
- case R_ALPHA_COPY: {
+ case R_ALPHA_COPY:
/*
* There shouldn't be copy relocations in kernel
* objects.
*/
printf("kldload: unexpected R_COPY relocation\n");
return -1;
- }
- break;
default:
printf("kldload: unexpected relocation type %d\n",
- ELF_R_TYPE(rela->r_info));
+ rtype);
return -1;
}
return(0);
OpenPOWER on IntegriCloud