⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elfload.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
/* This is the Linux kernel elf-loading code, ported into user space */#include <stdio.h>#include <sys/types.h>#include <fcntl.h>#include <errno.h>#include <unistd.h>#include <sys/mman.h>#include <stdlib.h>#include <string.h>#include "qemu.h"#include "disas.h"/* from personality.h *//* * Flags for bug emulation. * * These occupy the top three bytes. */enum {	ADDR_NO_RANDOMIZE = 	0x0040000,	/* disable randomization of VA space */	FDPIC_FUNCPTRS =	0x0080000,	/* userspace function ptrs point to descriptors						 * (signal handling)						 */	MMAP_PAGE_ZERO =	0x0100000,	ADDR_COMPAT_LAYOUT =	0x0200000,	READ_IMPLIES_EXEC =	0x0400000,	ADDR_LIMIT_32BIT =	0x0800000,	SHORT_INODE =		0x1000000,	WHOLE_SECONDS =		0x2000000,	STICKY_TIMEOUTS	=	0x4000000,	ADDR_LIMIT_3GB = 	0x8000000,};/* * Personality types. * * These go in the low byte.  Avoid using the top bit, it will * conflict with error returns. */enum {	PER_LINUX =		0x0000,	PER_LINUX_32BIT =	0x0000 | ADDR_LIMIT_32BIT,	PER_LINUX_FDPIC =	0x0000 | FDPIC_FUNCPTRS,	PER_SVR4 =		0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,	PER_SVR3 =		0x0002 | STICKY_TIMEOUTS | SHORT_INODE,	PER_SCOSVR3 =		0x0003 | STICKY_TIMEOUTS |					 WHOLE_SECONDS | SHORT_INODE,	PER_OSR5 =		0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,	PER_WYSEV386 =		0x0004 | STICKY_TIMEOUTS | SHORT_INODE,	PER_ISCR4 =		0x0005 | STICKY_TIMEOUTS,	PER_BSD =		0x0006,	PER_SUNOS =		0x0006 | STICKY_TIMEOUTS,	PER_XENIX =		0x0007 | STICKY_TIMEOUTS | SHORT_INODE,	PER_LINUX32 =		0x0008,	PER_LINUX32_3GB =	0x0008 | ADDR_LIMIT_3GB,	PER_IRIX32 =		0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */	PER_IRIXN32 =		0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */	PER_IRIX64 =		0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */	PER_RISCOS =		0x000c,	PER_SOLARIS =		0x000d | STICKY_TIMEOUTS,	PER_UW7 =		0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,	PER_OSF4 =		0x000f,			 /* OSF/1 v4 */	PER_HPUX =		0x0010,	PER_MASK =		0x00ff,};/* * Return the base personality without flags. */#define personality(pers)	(pers & PER_MASK)/* this flag is uneffective under linux too, should be deleted */#ifndef MAP_DENYWRITE#define MAP_DENYWRITE 0#endif/* should probably go in elf.h */#ifndef ELIBBAD#define ELIBBAD 80#endif#ifdef TARGET_I386#define ELF_PLATFORM get_elf_platform()static const char *get_elf_platform(void){    static char elf_platform[] = "i386";    int family = (global_env->cpuid_version >> 8) & 0xff;    if (family > 6)        family = 6;    if (family >= 3)        elf_platform[1] = '0' + family;    return elf_platform;}#define ELF_HWCAP get_elf_hwcap()static uint32_t get_elf_hwcap(void){  return global_env->cpuid_features;}#ifdef TARGET_X86_64#define ELF_START_MMAP 0x2aaaaab000ULL#define elf_check_arch(x) ( ((x) == ELF_ARCH) )#define ELF_CLASS      ELFCLASS64#define ELF_DATA       ELFDATA2LSB#define ELF_ARCH       EM_X86_64static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop){    regs->rax = 0;    regs->rsp = infop->start_stack;    regs->rip = infop->entry;}#else#define ELF_START_MMAP 0x80000000/* * This is used to ensure we don't load something for the wrong architecture. */#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )/* * These are used to set parameters in the core dumps. */#define ELF_CLASS	ELFCLASS32#define ELF_DATA	ELFDATA2LSB#define ELF_ARCH	EM_386static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop){    regs->esp = infop->start_stack;    regs->eip = infop->entry;    /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program       starts %edx contains a pointer to a function which might be       registered using `atexit'.  This provides a mean for the       dynamic linker to call DT_FINI functions for shared libraries       that have been loaded before the code runs.       A value of 0 tells we have no such handler.  */    regs->edx = 0;}#endif#define USE_ELF_CORE_DUMP#define ELF_EXEC_PAGESIZE	4096#endif#ifdef TARGET_ARM#define ELF_START_MMAP 0x80000000#define elf_check_arch(x) ( (x) == EM_ARM )#define ELF_CLASS	ELFCLASS32#ifdef TARGET_WORDS_BIGENDIAN#define ELF_DATA	ELFDATA2MSB#else#define ELF_DATA	ELFDATA2LSB#endif#define ELF_ARCH	EM_ARMstatic inline void init_thread(struct target_pt_regs *regs, struct image_info *infop){    abi_long stack = infop->start_stack;    memset(regs, 0, sizeof(*regs));    regs->ARM_cpsr = 0x10;    if (infop->entry & 1)      regs->ARM_cpsr |= CPSR_T;    regs->ARM_pc = infop->entry & 0xfffffffe;    regs->ARM_sp = infop->start_stack;    /* FIXME - what to for failure of get_user()? */    get_user_ual(regs->ARM_r2, stack + 8); /* envp */    get_user_ual(regs->ARM_r1, stack + 4); /* envp */    /* XXX: it seems that r0 is zeroed after ! */    regs->ARM_r0 = 0;    /* For uClinux PIC binaries.  */    /* XXX: Linux does this only on ARM with no MMU (do we care ?) */    regs->ARM_r10 = infop->start_data;}#define USE_ELF_CORE_DUMP#define ELF_EXEC_PAGESIZE	4096enum{  ARM_HWCAP_ARM_SWP       = 1 << 0,  ARM_HWCAP_ARM_HALF      = 1 << 1,  ARM_HWCAP_ARM_THUMB     = 1 << 2,  ARM_HWCAP_ARM_26BIT     = 1 << 3,  ARM_HWCAP_ARM_FAST_MULT = 1 << 4,  ARM_HWCAP_ARM_FPA       = 1 << 5,  ARM_HWCAP_ARM_VFP       = 1 << 6,  ARM_HWCAP_ARM_EDSP      = 1 << 7,};#define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF              \                    | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT     \                    | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP)#endif#ifdef TARGET_SPARC#ifdef TARGET_SPARC64#define ELF_START_MMAP 0x80000000#ifndef TARGET_ABI32#define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS )#else#define elf_check_arch(x) ( (x) == EM_SPARC32PLUS || (x) == EM_SPARC )#endif#define ELF_CLASS   ELFCLASS64#define ELF_DATA    ELFDATA2MSB#define ELF_ARCH    EM_SPARCV9#define STACK_BIAS		2047static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop){#ifndef TARGET_ABI32    regs->tstate = 0;#endif    regs->pc = infop->entry;    regs->npc = regs->pc + 4;    regs->y = 0;#ifdef TARGET_ABI32    regs->u_regs[14] = infop->start_stack - 16 * 4;#else    if (personality(infop->personality) == PER_LINUX32)        regs->u_regs[14] = infop->start_stack - 16 * 4;    else        regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;#endif}#else#define ELF_START_MMAP 0x80000000#define elf_check_arch(x) ( (x) == EM_SPARC )#define ELF_CLASS   ELFCLASS32#define ELF_DATA    ELFDATA2MSB#define ELF_ARCH    EM_SPARCstatic inline void init_thread(struct target_pt_regs *regs, struct image_info *infop){    regs->psr = 0;    regs->pc = infop->entry;    regs->npc = regs->pc + 4;    regs->y = 0;    regs->u_regs[14] = infop->start_stack - 16 * 4;}#endif#endif#ifdef TARGET_PPC#define ELF_START_MMAP 0x80000000#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)#define elf_check_arch(x) ( (x) == EM_PPC64 )#define ELF_CLASS	ELFCLASS64#else#define elf_check_arch(x) ( (x) == EM_PPC )#define ELF_CLASS	ELFCLASS32#endif#ifdef TARGET_WORDS_BIGENDIAN#define ELF_DATA	ELFDATA2MSB#else#define ELF_DATA	ELFDATA2LSB#endif#define ELF_ARCH	EM_PPC/* * We need to put in some extra aux table entries to tell glibc what * the cache block size is, so it can use the dcbz instruction safely. */#define AT_DCACHEBSIZE          19#define AT_ICACHEBSIZE          20#define AT_UCACHEBSIZE          21/* A special ignored type value for PPC, for glibc compatibility.  */#define AT_IGNOREPPC            22/* * The requirements here are: * - keep the final alignment of sp (sp & 0xf) * - make sure the 32-bit value at the first 16 byte aligned position of *   AUXV is greater than 16 for glibc compatibility. *   AT_IGNOREPPC is used for that. * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC, *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined. */#define DLINFO_ARCH_ITEMS       5#define ARCH_DLINFO                                                     \do {                                                                    \        NEW_AUX_ENT(AT_DCACHEBSIZE, 0x20);                              \        NEW_AUX_ENT(AT_ICACHEBSIZE, 0x20);                              \        NEW_AUX_ENT(AT_UCACHEBSIZE, 0);                                 \        /*                                                              \         * Now handle glibc compatibility.                              \         */                                                             \	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\ } while (0)static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop){    abi_ulong pos = infop->start_stack;    abi_ulong tmp;#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)    abi_ulong entry, toc;#endif    _regs->gpr[1] = infop->start_stack;#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)    entry = ldq_raw(infop->entry) + infop->load_addr;    toc = ldq_raw(infop->entry + 8) + infop->load_addr;    _regs->gpr[2] = toc;    infop->entry = entry;#endif    _regs->nip = infop->entry;    /* Note that isn't exactly what regular kernel does     * but this is what the ABI wants and is needed to allow     * execution of PPC BSD programs.     */    /* FIXME - what to for failure of get_user()? */    get_user_ual(_regs->gpr[3], pos);    pos += sizeof(abi_ulong);    _regs->gpr[4] = pos;    for (tmp = 1; tmp != 0; pos += sizeof(abi_ulong))        tmp = ldl(pos);    _regs->gpr[5] = pos;}#define USE_ELF_CORE_DUMP#define ELF_EXEC_PAGESIZE	4096#endif#ifdef TARGET_MIPS#define ELF_START_MMAP 0x80000000#define elf_check_arch(x) ( (x) == EM_MIPS )#ifdef TARGET_MIPS64#define ELF_CLASS   ELFCLASS64#else#define ELF_CLASS   ELFCLASS32#endif#ifdef TARGET_WORDS_BIGENDIAN#define ELF_DATA	ELFDATA2MSB#else#define ELF_DATA	ELFDATA2LSB#endif#define ELF_ARCH    EM_MIPSstatic inline void init_thread(struct target_pt_regs *regs, struct image_info *infop){    regs->cp0_status = 2 << CP0St_KSU;    regs->cp0_epc = infop->entry;    regs->regs[29] = infop->start_stack;}#define USE_ELF_CORE_DUMP#define ELF_EXEC_PAGESIZE        4096#endif /* TARGET_MIPS */#ifdef TARGET_SH4#define ELF_START_MMAP 0x80000000#define elf_check_arch(x) ( (x) == EM_SH )#define ELF_CLASS ELFCLASS32#define ELF_DATA  ELFDATA2LSB#define ELF_ARCH  EM_SHstatic inline void init_thread(struct target_pt_regs *regs, struct image_info *infop){  /* Check other registers XXXXX */  regs->pc = infop->entry;  regs->regs[15] = infop->start_stack;}#define USE_ELF_CORE_DUMP#define ELF_EXEC_PAGESIZE        4096#endif#ifdef TARGET_CRIS#define ELF_START_MMAP 0x80000000#define elf_check_arch(x) ( (x) == EM_CRIS )#define ELF_CLASS ELFCLASS32#define ELF_DATA  ELFDATA2LSB#define ELF_ARCH  EM_CRISstatic inline void init_thread(struct target_pt_regs *regs, struct image_info *infop){  regs->erp = infop->entry;}#define USE_ELF_CORE_DUMP#define ELF_EXEC_PAGESIZE        8192#endif#ifdef TARGET_M68K#define ELF_START_MMAP 0x80000000#define elf_check_arch(x) ( (x) == EM_68K )#define ELF_CLASS	ELFCLASS32#define ELF_DATA	ELFDATA2MSB#define ELF_ARCH	EM_68K/* ??? Does this need to do anything?#define ELF_PLAT_INIT(_r) */static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop){    regs->usp = infop->start_stack;    regs->sr = 0;    regs->pc = infop->entry;}#define USE_ELF_CORE_DUMP#define ELF_EXEC_PAGESIZE	8192#endif#ifdef TARGET_ALPHA#define ELF_START_MMAP (0x30000000000ULL)#define elf_check_arch(x) ( (x) == ELF_ARCH )#define ELF_CLASS      ELFCLASS64#define ELF_DATA       ELFDATA2MSB#define ELF_ARCH       EM_ALPHAstatic inline void init_thread(struct target_pt_regs *regs, struct image_info *infop){    regs->pc = infop->entry;    regs->ps = 8;    regs->usp = infop->start_stack;    regs->unique = infop->start_data; /* ? */    printf("Set unique value to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n",           regs->unique, infop->start_data);}#define USE_ELF_CORE_DUMP#define ELF_EXEC_PAGESIZE        8192#endif /* TARGET_ALPHA */#ifndef ELF_PLATFORM#define ELF_PLATFORM (NULL)#endif#ifndef ELF_HWCAP#define ELF_HWCAP 0#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -