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

📄 dyngen.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
	exit(1);    }    memset(plt, 0, sizeof(*plt));    plt->name = strdup(name);    plt->addend = addend;    /* append to plt-list: */    if (prev)	prev->next = plt;    else	plt_list = plt;    return index;}#endif#ifdef HOST_ARMint arm_emit_ldr_info(const char *name, unsigned long start_offset,                      FILE *outfile, uint8_t *p_start, uint8_t *p_end,                      ELF_RELOC *relocs, int nb_relocs){    uint8_t *p;    uint32_t insn;    int offset, min_offset, pc_offset, data_size, spare, max_pool;    uint8_t data_allocated[1024];    unsigned int data_index;    int type;    memset(data_allocated, 0, sizeof(data_allocated));    p = p_start;    min_offset = p_end - p_start;    spare = 0x7fffffff;    while (p < p_start + min_offset) {        insn = get32((uint32_t *)p);        /* TODO: Armv5e ldrd.  */        /* TODO: VFP load.  */        if ((insn & 0x0d5f0000) == 0x051f0000) {            /* ldr reg, [pc, #im] */            offset = insn & 0xfff;            if (!(insn & 0x00800000))                offset = -offset;            max_pool = 4096;            type = 0;        } else if ((insn & 0x0e5f0f00) == 0x0c1f0100) {            /* FPA ldf.  */            offset = (insn & 0xff) << 2;            if (!(insn & 0x00800000))                offset = -offset;            max_pool = 1024;            type = 1;        } else if ((insn & 0x0fff0000) == 0x028f0000) {            /* Some gcc load a doubleword immediate with               add regN, pc, #imm               ldmia regN, {regN, regM}               Hope and pray the compiler never generates somethin like               add reg, pc, #imm1; ldr reg, [reg, #-imm2]; */            int r;            r = (insn & 0xf00) >> 7;            offset = ((insn & 0xff) >> r) | ((insn & 0xff) << (32 - r));            max_pool = 1024;            type = 2;        } else {            max_pool = 0;            type = -1;        }        if (type >= 0) {            /* PC-relative load needs fixing up.  */            if (spare > max_pool - offset)                spare = max_pool - offset;            if ((offset & 3) !=0)                error("%s:%04x: pc offset must be 32 bit aligned",                      name, start_offset + p - p_start);            if (offset < 0)                error("%s:%04x: Embedded literal value",                      name, start_offset + p - p_start);            pc_offset = p - p_start + offset + 8;            if (pc_offset <= (p - p_start) ||                pc_offset >= (p_end - p_start))                error("%s:%04x: pc offset must point inside the function code",                      name, start_offset + p - p_start);            if (pc_offset < min_offset)                min_offset = pc_offset;            if (outfile) {                /* The intruction position */                fprintf(outfile, "    arm_ldr_ptr->ptr = gen_code_ptr + %d;\n",                        p - p_start);                /* The position of the constant pool data.  */                data_index = ((p_end - p_start) - pc_offset) >> 2;                fprintf(outfile, "    arm_ldr_ptr->data_ptr = arm_data_ptr - %d;\n",                        data_index);                fprintf(outfile, "    arm_ldr_ptr->type = %d;\n", type);                fprintf(outfile, "    arm_ldr_ptr++;\n");            }        }        p += 4;    }    /* Copy and relocate the constant pool data.  */    data_size = (p_end - p_start) - min_offset;    if (data_size > 0 && outfile) {        spare += min_offset;        fprintf(outfile, "    arm_data_ptr -= %d;\n", data_size >> 2);        fprintf(outfile, "    arm_pool_ptr -= %d;\n", data_size);        fprintf(outfile, "    if (arm_pool_ptr > gen_code_ptr + %d)\n"                         "        arm_pool_ptr = gen_code_ptr + %d;\n",                         spare, spare);        data_index = 0;        for (pc_offset = min_offset;             pc_offset < p_end - p_start;             pc_offset += 4) {            ELF_RELOC *rel;            int i, addend, type;            const char *sym_name;            char relname[1024];            /* data value */            addend = get32((uint32_t *)(p_start + pc_offset));            relname[0] = '\0';            for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {                if (rel->r_offset == (pc_offset + start_offset)) {                    sym_name = get_rel_sym_name(rel);                    /* the compiler leave some unnecessary references to the code */                    get_reloc_expr(relname, sizeof(relname), sym_name);                    type = ELF32_R_TYPE(rel->r_info);                    if (type != R_ARM_ABS32)                        error("%s: unsupported data relocation", name);                    break;                }            }            fprintf(outfile, "    arm_data_ptr[%d] = 0x%x",                    data_index, addend);            if (relname[0] != '\0')                fprintf(outfile, " + %s", relname);            fprintf(outfile, ";\n");            data_index++;        }    }    if (p == p_start)        goto arm_ret_error;    p -= 4;    insn = get32((uint32_t *)p);    /* The last instruction must be an ldm instruction.  There are several       forms generated by gcc:        ldmib sp, {..., pc}  (implies a sp adjustment of +4)        ldmia sp, {..., pc}        ldmea fp, {..., pc} */    if ((insn & 0xffff8000) == 0xe99d8000) {        if (outfile) {            fprintf(outfile,                    "    *(uint32_t *)(gen_code_ptr + %d) = 0xe28dd004;\n",                    p - p_start);        }        p += 4;    } else if ((insn & 0xffff8000) != 0xe89d8000        && (insn & 0xffff8000) != 0xe91b8000) {    arm_ret_error:        if (!outfile)            printf("%s: invalid epilog\n", name);    }    return p - p_start;}#endif#define MAX_ARGS 3/* generate op code */void gen_code(const char *name, host_ulong offset, host_ulong size,              FILE *outfile, int gen_switch){    int copy_size = 0;    uint8_t *p_start, *p_end;    host_ulong start_offset;    int nb_args, i, n;    uint8_t args_present[MAX_ARGS];    const char *sym_name, *p;    EXE_RELOC *rel;	    /* Compute exact size excluding prologue and epilogue instructions.     * Increment start_offset to skip epilogue instructions, then compute     * copy_size the indicate the size of the remaining instructions (in     * bytes).     */    p_start = text + offset;    p_end = p_start + size;    start_offset = offset;#if defined(HOST_I386) || defined(HOST_X86_64)#ifdef CONFIG_FORMAT_COFF    {        uint8_t *p;        p = p_end - 1;        if (p == p_start)            error("empty code for %s", name);        while (*p != 0xc3) {            p--;            if (p <= p_start)                error("ret or jmp expected at the end of %s", name);        }        copy_size = p - p_start;    }#else    {        int len;        len = p_end - p_start;        if (len == 0)            error("empty code for %s", name);        if (p_end[-1] == 0xc3) {            len--;        } else {            error("ret or jmp expected at the end of %s", name);        }        copy_size = len;    }#endif#elif defined(HOST_PPC)    {        uint8_t *p;        p = (void *)(p_end - 4);        if (p == p_start)            error("empty code for %s", name);        if (get32((uint32_t *)p) != 0x4e800020)            error("blr expected at the end of %s", name);        copy_size = p - p_start;    }#elif defined(HOST_S390)    {        uint8_t *p;        p = (void *)(p_end - 2);        if (p == p_start)            error("empty code for %s", name);        if ((get16((uint16_t *)p) & 0xfff0) != 0x07f0)            error("br expected at the end of %s", name);        copy_size = p - p_start;    }#elif defined(HOST_ALPHA)    {        uint8_t *p;        p = p_end - 4;#if 0        /* XXX: check why it occurs */        if (p == p_start)            error("empty code for %s", name);#endif        if (get32((uint32_t *)p) != 0x6bfa8001)            error("ret expected at the end of %s", name);        copy_size = p - p_start;    }#elif defined(HOST_IA64)    {        uint8_t *p;        p = (void *)(p_end - 4);        if (p == p_start)            error("empty code for %s", name);        /* br.ret.sptk.many b0;; */        /* 08 00 84 00 */        if (get32((uint32_t *)p) != 0x00840008)            error("br.ret.sptk.many b0;; expected at the end of %s", name);	copy_size = p_end - p_start;    }#elif defined(HOST_SPARC)    {#define INSN_SAVE       0x9de3a000#define INSN_RET        0x81c7e008#define INSN_RETL       0x81c3e008#define INSN_RESTORE    0x81e80000#define INSN_RETURN     0x81cfe008#define INSN_NOP        0x01000000#define INSN_ADD_SP     0x9c03a000 // add %sp, nn, %sp#define INSN_SUB_SP     0x9c23a000 // sub %sp, nn, %sp        uint32_t start_insn, end_insn1, end_insn2;        uint8_t *p;        p = (void *)(p_end - 8);        if (p <= p_start)            error("empty code for %s", name);        start_insn = get32((uint32_t *)(p_start + 0x0));        end_insn1 = get32((uint32_t *)(p + 0x0));        end_insn2 = get32((uint32_t *)(p + 0x4));        if (((start_insn & ~0x1fff) == INSN_SAVE) ||            (start_insn & ~0x1fff) == INSN_ADD_SP) {            p_start += 0x4;            start_offset += 0x4;            if (end_insn1 == INSN_RET && end_insn2 == INSN_RESTORE)                /* SPARC v7: ret; restore; */ ;            else if (end_insn1 == INSN_RETURN && end_insn2 == INSN_NOP)                /* SPARC v9: return; nop; */ ;            else if (end_insn1 == INSN_RETL && (end_insn2 & ~0x1fff) == INSN_SUB_SP)                /* SPARC v7: retl; sub %sp, nn, %sp; */ ;            else                error("ret; restore; not found at end of %s", name);        } else if (end_insn1 == INSN_RETL && end_insn2 == INSN_NOP) {            ;        } else {            error("No save at the beginning of %s", name);        }#if 0        /* Skip a preceeding nop, if present.  */        if (p > p_start) {            skip_insn = get32((uint32_t *)(p - 0x4));            if (skip_insn == INSN_NOP)                p -= 4;        }#endif        copy_size = p - p_start;    }#elif defined(HOST_SPARC64)    {#define INSN_SAVE       0x9de3a000#define INSN_RET        0x81c7e008#define INSN_RETL       0x81c3e008#define INSN_RESTORE    0x81e80000#define INSN_RETURN     0x81cfe008#define INSN_NOP        0x01000000#define INSN_ADD_SP     0x9c03a000 // add %sp, nn, %sp#define INSN_SUB_SP     0x9c23a000 // sub %sp, nn, %sp        uint32_t start_insn, end_insn1, end_insn2, skip_insn;        uint8_t *p;        p = (void *)(p_end - 8);#if 0        /* XXX: check why it occurs */        if (p <= p_start)            error("empty code for %s", name);#endif        start_insn = get32((uint32_t *)(p_start + 0x0));        end_insn1 = get32((uint32_t *)(p + 0x0));        end_insn2 = get32((uint32_t *)(p + 0x4));        if (((start_insn & ~0x1fff) == INSN_SAVE) ||            (start_insn & ~0x1fff) == INSN_ADD_SP) {            p_start += 0x4;            start_offset += 0x4;            if (end_insn1 == INSN_RET && end_insn2 == INSN_RESTORE)                /* SPARC v7: ret; restore; */ ;            else if (end_insn1 == INSN_RETURN && end_insn2 == INSN_NOP)                /* SPARC v9: return; nop; */ ;            else if (end_insn1 == INSN_RETL && (end_insn2 & ~0x1fff) == INSN_SUB_SP)                /* SPARC v7: retl; sub %sp, nn, %sp; */ ;            else                error("ret; restore; not found at end of %s", name);        } else if (end_insn1 == INSN_RETL && end_insn2 == INSN_NOP) {            ;        } else {            error("No save at the beginning of %s", name);        }        /* Skip a preceeding nop, if present.  */        if (p > p_start) {            skip_insn = get32((uint32_t *)(p - 0x4));            if (skip_insn == 0x01000000)                p -= 4;        }        copy_size = p - p_start;    }#elif defined(HOST_ARM)    {        uint32_t insn;        if ((p_end - p_start) <= 16)            error("%s: function too small", name);        if (get32((uint32_t *)p_start) != 0xe1a0c00d ||            (get32((uint32_t *)(p_start + 4)) & 0xffff0000) != 0xe92d0000 ||            get32((uint32_t *)(p_start + 8)) != 0xe24cb004)            error("%s: invalid prolog", name);        p_start += 12;        start_offset += 12;        insn = get32((uint32_t *)p_start);        if ((insn & 0xffffff00) == 0xe24dd000) {            /* Stack adjustment.  Assume op uses the frame pointer.  */            p_start -= 4;            start_offset -= 4;        }        copy_size = arm_emit_ldr_info(name, start_offset, NULL, p_start, p_end,                                      relocs, nb_relocs);    }#elif defined(HOST_M68K)    {        uint8_t *p;        p = (void *)(p_end - 2);        if (p == p_start)            error("empty code for %s", name);        // remove NOP's, probably added for alignment        while ((get16((uint16_t *)p) == 0x4e71) &&               (p>p_start))            p -= 2;        if (get16((uint16_t *)p) != 0x4e75)            error("rts expected at the end of %s", name);        copy_size = p - p_start;    }#elif defined(HOST_MIPS) || defined(HOST_MIPS64)    {#define INSN_RETURN     0x03e00008#define INSN_NOP        0x00000000        uint8_t *p = p_end;        if (p < (p_start + 0x8)) {            error("empty code for %s", name);        } else {            uint32_t end_insn1, end_insn2;            p -= 0x8;            end_insn1 = get32((uint32_t *)(p + 0x0));            end_insn2 = get32((uint32_t *)(p + 0x4));            if (end_insn1 != INSN_RETURN && end_insn2 != INSN_NOP)                error("jr ra not found at end of %s", name);        }        copy_size = p - p_start;    }#else

⌨️ 快捷键说明

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