mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-01 02:03:31 +00:00
Kernel module support for mips.
Reviewed by: gonzo Tested by: Alexandr Rybalko (ray@dlink.ua)
This commit is contained in:
parent
35873dcedb
commit
6f3c632700
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=204031
@ -203,11 +203,9 @@ LD += -EB
|
|||||||
.if ${MACHINE_ARCH} == "mips"
|
.if ${MACHINE_ARCH} == "mips"
|
||||||
. if defined(TARGET_BIG_ENDIAN)
|
. if defined(TARGET_BIG_ENDIAN)
|
||||||
CFLAGS += -EB
|
CFLAGS += -EB
|
||||||
LDFLAGS += -Wl,-EB
|
|
||||||
LD += -EB
|
LD += -EB
|
||||||
. else
|
. else
|
||||||
CFLAGS += -EL
|
CFLAGS += -EL
|
||||||
LDFLAGS += -Wl,-EL
|
|
||||||
LD += -EL
|
LD += -EL
|
||||||
. endif
|
. endif
|
||||||
CFLAGS += -msoft-float -G0 -mno-dsp -mabicalls
|
CFLAGS += -msoft-float -G0 -mno-dsp -mabicalls
|
||||||
|
@ -89,6 +89,8 @@ libkern/umoddi3.c optional isa_mips32
|
|||||||
#libkern/mips/strcmp.S standard
|
#libkern/mips/strcmp.S standard
|
||||||
#libkern/mips/strncmp.S standard
|
#libkern/mips/strncmp.S standard
|
||||||
|
|
||||||
|
kern/link_elf_obj.c standard
|
||||||
|
|
||||||
dev/cfe/cfe_api.c optional cfe
|
dev/cfe/cfe_api.c optional cfe
|
||||||
dev/cfe/cfe_console.c optional cfe_console
|
dev/cfe/cfe_console.c optional cfe_console
|
||||||
dev/cfe/cfe_env.c optional cfe_env
|
dev/cfe/cfe_env.c optional cfe_env
|
||||||
|
@ -128,6 +128,10 @@ CFLAGS+= -fno-omit-frame-pointer
|
|||||||
CFLAGS+= -mlongcall -fno-omit-frame-pointer
|
CFLAGS+= -mlongcall -fno-omit-frame-pointer
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
.if ${MACHINE_ARCH} == "mips"
|
||||||
|
CFLAGS+= -G0 -fno-pic -mno-abicalls -mlong-calls
|
||||||
|
.endif
|
||||||
|
|
||||||
.if defined(FIRMWS)
|
.if defined(FIRMWS)
|
||||||
.if !exists(@)
|
.if !exists(@)
|
||||||
${KMOD:S/$/.c/}: @
|
${KMOD:S/$/.c/}: @
|
||||||
@ -174,7 +178,7 @@ ${PROG}.symbols: ${FULLPROG}
|
|||||||
${OBJCOPY} --only-keep-debug ${FULLPROG} ${.TARGET}
|
${OBJCOPY} --only-keep-debug ${FULLPROG} ${.TARGET}
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if ${MACHINE_ARCH} != amd64
|
.if ${MACHINE_ARCH} != amd64 && ${MACHINE_ARCH} != mips
|
||||||
${FULLPROG}: ${KMOD}.kld
|
${FULLPROG}: ${KMOD}.kld
|
||||||
${LD} -Bshareable ${LDFLAGS} -o ${.TARGET} ${KMOD}.kld
|
${LD} -Bshareable ${LDFLAGS} -o ${.TARGET} ${KMOD}.kld
|
||||||
.if !defined(DEBUG_FLAGS)
|
.if !defined(DEBUG_FLAGS)
|
||||||
@ -187,7 +191,7 @@ EXPORT_SYMS?= NO
|
|||||||
CLEANFILES+= export_syms
|
CLEANFILES+= export_syms
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if ${MACHINE_ARCH} != amd64
|
.if ${MACHINE_ARCH} != amd64 && ${MACHINE_ARCH} != mips
|
||||||
${KMOD}.kld: ${OBJS}
|
${KMOD}.kld: ${OBJS}
|
||||||
.else
|
.else
|
||||||
${FULLPROG}: ${OBJS}
|
${FULLPROG}: ${OBJS}
|
||||||
@ -206,7 +210,8 @@ ${FULLPROG}: ${OBJS}
|
|||||||
export_syms | xargs -J% ${OBJCOPY} % ${.TARGET}
|
export_syms | xargs -J% ${OBJCOPY} % ${.TARGET}
|
||||||
.endif
|
.endif
|
||||||
.endif
|
.endif
|
||||||
.if !defined(DEBUG_FLAGS) && ${MACHINE_ARCH} == amd64
|
.if !defined(DEBUG_FLAGS) && \
|
||||||
|
(${MACHINE_ARCH} == amd64 || ${MACHINE_ARCH} == mips)
|
||||||
${OBJCOPY} --strip-debug ${.TARGET}
|
${OBJCOPY} --strip-debug ${.TARGET}
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
@ -853,8 +853,8 @@ link_elf_load_file(linker_class_t cls, const char *filename,
|
|||||||
panic("lost relatab");
|
panic("lost relatab");
|
||||||
if (mapbase != (vm_offset_t)ef->address + mapsize)
|
if (mapbase != (vm_offset_t)ef->address + mapsize)
|
||||||
panic("mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n",
|
panic("mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n",
|
||||||
mapbase, ef->address, mapsize,
|
(u_long)mapbase, ef->address, (u_long)mapsize,
|
||||||
(vm_offset_t)ef->address + mapsize);
|
(u_long)(vm_offset_t)ef->address + mapsize);
|
||||||
|
|
||||||
/* Local intra-module relocations */
|
/* Local intra-module relocations */
|
||||||
link_elf_reloc_local(lf);
|
link_elf_reloc_local(lf);
|
||||||
|
@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <machine/elf.h>
|
#include <machine/elf.h>
|
||||||
#include <machine/md_var.h>
|
#include <machine/md_var.h>
|
||||||
|
#include <machine/cache.h>
|
||||||
|
|
||||||
#ifdef __mips_n64
|
#ifdef __mips_n64
|
||||||
struct sysentvec elf64_freebsd_sysvec = {
|
struct sysentvec elf64_freebsd_sysvec = {
|
||||||
@ -163,7 +164,12 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
|
|||||||
Elf_Addr addend = (Elf_Addr)0;
|
Elf_Addr addend = (Elf_Addr)0;
|
||||||
Elf_Word rtype = (Elf_Word)0, symidx;
|
Elf_Word rtype = (Elf_Word)0, symidx;
|
||||||
const Elf_Rel *rel;
|
const Elf_Rel *rel;
|
||||||
const Elf_Rela *rela;
|
|
||||||
|
/*
|
||||||
|
* Stash R_MIPS_HI16 info so we can use it when processing R_MIPS_LO16
|
||||||
|
*/
|
||||||
|
static Elf_Addr ahl;
|
||||||
|
static Elf_Addr *where_hi16;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ELF_RELOC_REL:
|
case ELF_RELOC_REL:
|
||||||
@ -173,108 +179,63 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
|
|||||||
rtype = ELF_R_TYPE(rel->r_info);
|
rtype = ELF_R_TYPE(rel->r_info);
|
||||||
symidx = ELF_R_SYM(rel->r_info);
|
symidx = ELF_R_SYM(rel->r_info);
|
||||||
break;
|
break;
|
||||||
case ELF_RELOC_RELA:
|
|
||||||
rela = (const Elf_Rela *)data;
|
|
||||||
where = (Elf_Addr *) (relocbase + rela->r_offset);
|
|
||||||
addend = rela->r_addend;
|
|
||||||
rtype = ELF_R_TYPE(rela->r_info);
|
|
||||||
symidx = ELF_R_SYM(rela->r_info);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
panic("unknown reloc type %d\n", type);
|
panic("unknown reloc type %d\n", type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (local) {
|
|
||||||
#if 0 /* TBD */
|
|
||||||
if (rtype == R_386_RELATIVE) { /* A + B */
|
|
||||||
addr = elf_relocaddr(lf, relocbase + addend);
|
|
||||||
if (*where != addr)
|
|
||||||
*where = addr;
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (rtype) {
|
switch (rtype) {
|
||||||
|
case R_MIPS_NONE: /* none */
|
||||||
|
break;
|
||||||
|
|
||||||
case R_MIPS_NONE: /* none */
|
case R_MIPS_32: /* S + A */
|
||||||
break;
|
addr = lookup(lf, symidx, 1);
|
||||||
|
if (addr == 0)
|
||||||
case R_MIPS_16: /* S + sign-extend(A) */
|
|
||||||
/*
|
|
||||||
* There shouldn't be R_MIPS_16 relocs in kernel objects.
|
|
||||||
*/
|
|
||||||
printf("kldload: unexpected R_MIPS_16 relocation\n");
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_MIPS_32: /* S + A - P */
|
|
||||||
addr = lookup(lf, symidx, 1);
|
|
||||||
if (addr == 0)
|
|
||||||
return -1;
|
|
||||||
addr += addend;
|
|
||||||
if (*where != addr)
|
|
||||||
*where = addr;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_MIPS_REL32: /* A - EA + S */
|
|
||||||
/*
|
|
||||||
* There shouldn't be R_MIPS_REL32 relocs in kernel objects?
|
|
||||||
*/
|
|
||||||
printf("kldload: unexpected R_MIPS_REL32 relocation\n");
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_MIPS_26: /* ((A << 2) | (P & 0xf0000000) + S) >> 2 */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_MIPS_HI16:
|
|
||||||
/* extern/local: ((AHL + S) - ((short)(AHL + S)) >> 16 */
|
|
||||||
/* _gp_disp: ((AHL + GP - P) - (short)(AHL + GP - P)) >> 16 */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_MIPS_LO16:
|
|
||||||
/* extern/local: AHL + S */
|
|
||||||
/* _gp_disp: AHL + GP - P + 4 */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_MIPS_GPREL16:
|
|
||||||
/* extern/local: ((AHL + S) - ((short)(AHL + S)) >> 16 */
|
|
||||||
/* _gp_disp: ((AHL + GP - P) - (short)(AHL + GP - P)) >> 16 */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_MIPS_LITERAL: /* sign-extend(A) + L */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_MIPS_GOT16: /* external: G */
|
|
||||||
/* local: tbd */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_MIPS_PC16: /* sign-extend(A) + S - P */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_MIPS_CALL16: /* G */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_MIPS_GPREL32: /* A + S + GP0 - GP */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_MIPS_GOTHI16: /* (G - (short)G) >> 16 + A */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_MIPS_GOTLO16: /* G & 0xffff */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_MIPS_CALLHI16: /* (G - (short)G) >> 16 + A */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case R_MIPS_CALLLO16: /* G & 0xffff */
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
printf("kldload: unexpected relocation type %d\n",
|
|
||||||
rtype);
|
|
||||||
return (-1);
|
return (-1);
|
||||||
|
addr += addend;
|
||||||
|
if (*where != addr)
|
||||||
|
*where = addr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case R_MIPS_26: /* ((A << 2) | (P & 0xf0000000) + S) >> 2 */
|
||||||
|
addr = lookup(lf, symidx, 1);
|
||||||
|
if (addr == 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
addend &= 0x03ffffff;
|
||||||
|
addend <<= 2;
|
||||||
|
|
||||||
|
addr += ((Elf_Addr)where & 0xf0000000) | addend;
|
||||||
|
addr >>= 2;
|
||||||
|
|
||||||
|
*where &= ~0x03ffffff;
|
||||||
|
*where |= addr & 0x03ffffff;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case R_MIPS_HI16: /* ((AHL + S) - ((short)(AHL + S)) >> 16 */
|
||||||
|
ahl = addend << 16;
|
||||||
|
where_hi16 = where;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case R_MIPS_LO16: /* AHL + S */
|
||||||
|
ahl += (int16_t)addend;
|
||||||
|
addr = lookup(lf, symidx, 1);
|
||||||
|
if (addr == 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
addend &= 0xffff0000;
|
||||||
|
addend |= (uint16_t)(ahl + addr);
|
||||||
|
*where = addend;
|
||||||
|
|
||||||
|
addend = *where_hi16;
|
||||||
|
addend &= 0xffff0000;
|
||||||
|
addend |= ((ahl + addr) - (int16_t)(ahl + addr)) >> 16;
|
||||||
|
*where_hi16 = addend;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("kldload: unexpected relocation type %d\n",
|
||||||
|
rtype);
|
||||||
|
return (-1);
|
||||||
}
|
}
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
@ -299,6 +260,11 @@ int
|
|||||||
elf_cpu_load_file(linker_file_t lf __unused)
|
elf_cpu_load_file(linker_file_t lf __unused)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sync the I and D caches to make sure our relocations are visible.
|
||||||
|
*/
|
||||||
|
mips_icache_sync_all();
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user