mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-30 23:52:49 +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 defined(TARGET_BIG_ENDIAN)
|
||||
CFLAGS += -EB
|
||||
LDFLAGS += -Wl,-EB
|
||||
LD += -EB
|
||||
. else
|
||||
CFLAGS += -EL
|
||||
LDFLAGS += -Wl,-EL
|
||||
LD += -EL
|
||||
. endif
|
||||
CFLAGS += -msoft-float -G0 -mno-dsp -mabicalls
|
||||
|
@ -89,6 +89,8 @@ libkern/umoddi3.c optional isa_mips32
|
||||
#libkern/mips/strcmp.S standard
|
||||
#libkern/mips/strncmp.S standard
|
||||
|
||||
kern/link_elf_obj.c standard
|
||||
|
||||
dev/cfe/cfe_api.c optional cfe
|
||||
dev/cfe/cfe_console.c optional cfe_console
|
||||
dev/cfe/cfe_env.c optional cfe_env
|
||||
|
@ -128,6 +128,10 @@ CFLAGS+= -fno-omit-frame-pointer
|
||||
CFLAGS+= -mlongcall -fno-omit-frame-pointer
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_ARCH} == "mips"
|
||||
CFLAGS+= -G0 -fno-pic -mno-abicalls -mlong-calls
|
||||
.endif
|
||||
|
||||
.if defined(FIRMWS)
|
||||
.if !exists(@)
|
||||
${KMOD:S/$/.c/}: @
|
||||
@ -174,7 +178,7 @@ ${PROG}.symbols: ${FULLPROG}
|
||||
${OBJCOPY} --only-keep-debug ${FULLPROG} ${.TARGET}
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_ARCH} != amd64
|
||||
.if ${MACHINE_ARCH} != amd64 && ${MACHINE_ARCH} != mips
|
||||
${FULLPROG}: ${KMOD}.kld
|
||||
${LD} -Bshareable ${LDFLAGS} -o ${.TARGET} ${KMOD}.kld
|
||||
.if !defined(DEBUG_FLAGS)
|
||||
@ -187,7 +191,7 @@ EXPORT_SYMS?= NO
|
||||
CLEANFILES+= export_syms
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_ARCH} != amd64
|
||||
.if ${MACHINE_ARCH} != amd64 && ${MACHINE_ARCH} != mips
|
||||
${KMOD}.kld: ${OBJS}
|
||||
.else
|
||||
${FULLPROG}: ${OBJS}
|
||||
@ -206,7 +210,8 @@ ${FULLPROG}: ${OBJS}
|
||||
export_syms | xargs -J% ${OBJCOPY} % ${.TARGET}
|
||||
.endif
|
||||
.endif
|
||||
.if !defined(DEBUG_FLAGS) && ${MACHINE_ARCH} == amd64
|
||||
.if !defined(DEBUG_FLAGS) && \
|
||||
(${MACHINE_ARCH} == amd64 || ${MACHINE_ARCH} == mips)
|
||||
${OBJCOPY} --strip-debug ${.TARGET}
|
||||
.endif
|
||||
|
||||
|
@ -853,8 +853,8 @@ link_elf_load_file(linker_class_t cls, const char *filename,
|
||||
panic("lost relatab");
|
||||
if (mapbase != (vm_offset_t)ef->address + mapsize)
|
||||
panic("mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n",
|
||||
mapbase, ef->address, mapsize,
|
||||
(vm_offset_t)ef->address + mapsize);
|
||||
(u_long)mapbase, ef->address, (u_long)mapsize,
|
||||
(u_long)(vm_offset_t)ef->address + mapsize);
|
||||
|
||||
/* Local intra-module relocations */
|
||||
link_elf_reloc_local(lf);
|
||||
|
@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <machine/elf.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/cache.h>
|
||||
|
||||
#ifdef __mips_n64
|
||||
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_Word rtype = (Elf_Word)0, symidx;
|
||||
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) {
|
||||
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);
|
||||
symidx = ELF_R_SYM(rel->r_info);
|
||||
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:
|
||||
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) {
|
||||
case R_MIPS_NONE: /* none */
|
||||
break;
|
||||
|
||||
case R_MIPS_NONE: /* none */
|
||||
break;
|
||||
|
||||
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);
|
||||
case R_MIPS_32: /* S + A */
|
||||
addr = lookup(lf, symidx, 1);
|
||||
if (addr == 0)
|
||||
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);
|
||||
}
|
||||
@ -299,6 +260,11 @@ int
|
||||
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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user