Date: Wed, 31 Dec 2008 07:38:05 +0000 (UTC) From: Warner Losh <imp@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r186640 - head/sys/mips/mips Message-ID: <200812310738.mBV7c5Tg018568@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: imp Date: Wed Dec 31 07:38:04 2008 New Revision: 186640 URL: http://svn.freebsd.org/changeset/base/186640 Log: First pass at 64-bit elf support Added: head/sys/mips/mips/elf64_machdep.c (contents, props changed) - copied, changed from r186189, head/sys/mips/mips/elf_machdep.c Copied and modified: head/sys/mips/mips/elf64_machdep.c (from r186189, head/sys/mips/mips/elf_machdep.c) ============================================================================== --- head/sys/mips/mips/elf_machdep.c Tue Dec 16 19:15:31 2008 (r186189, copy source) +++ head/sys/mips/mips/elf64_machdep.c Wed Dec 31 07:38:04 2008 (r186640) @@ -25,6 +25,8 @@ * from: src/sys/i386/i386/elf_machdep.c,v 1.20 2004/08/11 02:35:05 marcel */ +#define __ELF_WORD_SIZE 64 + #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -47,7 +49,7 @@ __FBSDID("$FreeBSD$"); #include <machine/elf.h> #include <machine/md_var.h> -struct sysentvec elf32_freebsd_sysvec = { +struct sysentvec elf64_freebsd_sysvec = { .sv_size = SYS_MAXSYSCALL, .sv_table = sysent, .sv_mask = 0, @@ -61,7 +63,7 @@ struct sysentvec elf32_freebsd_sysvec = .sv_sigcode = sigcode, .sv_szsigcode = &szsigcode, .sv_prepsyscall = NULL, - .sv_name = "FreeBSD ELF32", + .sv_name = "FreeBSD ELF64", .sv_coredump = __elfN(coredump), .sv_imgact_try = NULL, .sv_minsigstksz = MINSIGSTKSZ, @@ -75,198 +77,41 @@ struct sysentvec elf32_freebsd_sysvec = .sv_setregs = exec_setregs, .sv_fixlimit = NULL, .sv_maxssiz = NULL, - .sv_flags = SV_ABI_FREEBSD | SV_ILP32 + .sv_flags = SV_ABI_FREEBSD | SV_LP64 }; -static Elf32_Brandinfo freebsd_brand_info = { - .brand = ELFOSABI_FREEBSD, +static Elf64_Brandinfo freebsd_brand_gnutools_info64 = { + .brand = ELFOSABI_NONE, .machine = EM_MIPS, - .compat_3_brand = "FreeBSD", + .compat_3_brand = "Unix System V ABI", .emul_path = NULL, .interp_path = "/libexec/ld-elf.so.1", - .sysvec = &elf32_freebsd_sysvec, - .interp_newpath = NULL, - .flags = 0 + .sysvec = &elf64_freebsd_sysvec, + .interp_path = "/libexec/ld-elf.so.1", + .flags = BI_CAN_EXEC_DYN }; -SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY, - (sysinit_cfunc_t) elf32_insert_brand_entry, - &freebsd_brand_info); +SYSINIT(gnu_mips_elf64, SI_SUB_EXEC, SI_ORDER_ANY, + (sysinit_cfunc_t) elf64_insert_brand_entry, + &freebsd_brand_gnutools_info64); -static Elf32_Brandinfo freebsd_brand_oinfo = { +static Elf64_Brandinfo freebsd_brand_info64 = { .brand = ELFOSABI_FREEBSD, .machine = EM_MIPS, .compat_3_brand = "FreeBSD", .emul_path = NULL, - .interp_path = "/usr/libexec/ld-elf.so.1", - .sysvec = &elf32_freebsd_sysvec, + .interp_path = "/libexec/ld-elf.so.1", + .sysvec = &elf64_freebsd_sysvec, .interp_newpath = NULL, .flags = 0 }; -SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY, - (sysinit_cfunc_t) elf32_insert_brand_entry, - &freebsd_brand_oinfo); - +SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY, + (sysinit_cfunc_t) elf64_insert_brand_entry, + &freebsd_brand_info64); void -elf32_dump_thread(struct thread *td __unused, void *dst __unused, +elf64_dump_thread(struct thread *td __unused, void *dst __unused, size_t *off __unused) { } - -/* Process one elf relocation with addend. */ -static int -elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, - int type, int local, elf_lookup_fn lookup) -{ - Elf_Addr *where = (Elf_Addr *)NULL;; - Elf_Addr addr; - Elf_Addr addend = (Elf_Addr)0; - Elf_Word rtype = (Elf_Word)0, symidx; - const Elf_Rel *rel; - const Elf_Rela *rela; - - switch (type) { - case ELF_RELOC_REL: - rel = (const Elf_Rel *)data; - where = (Elf_Addr *) (relocbase + rel->r_offset); - addend = *where; - 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 = relocbase + addend; - if (*where != addr) - *where = addr; - } - return (0); -#endif - } - - switch (rtype) { - - 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); - return (-1); - } - return(0); -} - -int -elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type, - elf_lookup_fn lookup) -{ - - return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup)); -} - -int -elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data, - int type, elf_lookup_fn lookup) -{ - - return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup)); -} - -int -elf_cpu_load_file(linker_file_t lf __unused) -{ - - return (0); -} - -int -elf_cpu_unload_file(linker_file_t lf __unused) -{ - - return (0); -}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812310738.mBV7c5Tg018568>