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

📄 dyngen.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                        }                    }#endif                                        if (val >= start_offset && val <= start_offset + copy_size) {                        n = strtol(p, NULL, 10);                        fprintf(outfile, "    label_offsets[%d] = %ld + (gen_code_ptr - gen_code_buf);\n", n, (long)(val - start_offset));                    }                }            }        }        /* load parameres in variables */        for(i = 0; i < nb_args; i++) {            fprintf(outfile, "    param%d = *opparam_ptr++;\n", i + 1);        }        /* patch relocations */#if defined(HOST_I386)            {                char name[256];                int type;                int addend;                int reloc_offset;                for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {                if (rel->r_offset >= start_offset &&		    rel->r_offset < start_offset + copy_size) {                    sym_name = get_rel_sym_name(rel);                    if (!sym_name)                        continue;                    reloc_offset = rel->r_offset - start_offset;                    if (strstart(sym_name, "__op_jmp", &p)) {                        int n;                        n = strtol(p, NULL, 10);                        /* __op_jmp relocations are done at                           runtime to do translated block                           chaining: the offset of the instruction                           needs to be stored */                        fprintf(outfile, "    jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n",                                n, reloc_offset);                        continue;                    }                    get_reloc_expr(name, sizeof(name), sym_name);                    addend = get32((uint32_t *)(text + rel->r_offset));#ifdef CONFIG_FORMAT_ELF                    type = ELF32_R_TYPE(rel->r_info);                    switch(type) {                    case R_386_32:                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",                                 reloc_offset, name, addend);                        break;                    case R_386_PC32:                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",                                 reloc_offset, name, reloc_offset, addend);                        break;                    default:                        error("unsupported i386 relocation (%d)", type);                    }#elif defined(CONFIG_FORMAT_COFF)                    {                        char *temp_name;                        int j;                        EXE_SYM *sym;                        temp_name = get_sym_name(symtab + *(uint32_t *)(rel->r_reloc->r_symndx));                        if (!strcmp(temp_name, ".data")) {                            for (j = 0, sym = symtab; j < nb_syms; j++, sym++) {                                if (strstart(sym->st_name, sym_name, NULL)) {                                    addend -= sym->st_value;                                }                            }                        }                    }                    type = rel->r_type;                    switch(type) {                    case DIR32:                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",                                 reloc_offset, name, addend);                        break;                    case DISP32:                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d -4;\n",                                 reloc_offset, name, reloc_offset, addend);                        break;                    default:                        error("unsupported i386 relocation (%d)", type);                    }#else#error unsupport object format#endif                }                }            }#elif defined(HOST_X86_64)            {                char name[256];                int type;                int addend;                int reloc_offset;                for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {                if (rel->r_offset >= start_offset &&		    rel->r_offset < start_offset + copy_size) {                    sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;                    get_reloc_expr(name, sizeof(name), sym_name);                    type = ELF32_R_TYPE(rel->r_info);                    addend = rel->r_addend;                    reloc_offset = rel->r_offset - start_offset;                    switch(type) {                    case R_X86_64_32:                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (uint32_t)%s + %d;\n",                                 reloc_offset, name, addend);                        break;                    case R_X86_64_32S:                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (int32_t)%s + %d;\n",                                 reloc_offset, name, addend);                        break;                    case R_X86_64_PC32:                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",                                 reloc_offset, name, reloc_offset, addend);                        break;                    default:                        error("unsupported X86_64 relocation (%d)", type);                    }                }                }            }#elif defined(HOST_PPC)            {#ifdef CONFIG_FORMAT_ELF                char name[256];                int type;                int addend;                int reloc_offset;                for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {                    if (rel->r_offset >= start_offset &&			rel->r_offset < start_offset + copy_size) {                        sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;                        reloc_offset = rel->r_offset - start_offset;                        if (strstart(sym_name, "__op_jmp", &p)) {                            int n;                            n = strtol(p, NULL, 10);                            /* __op_jmp relocations are done at                               runtime to do translated block                               chaining: the offset of the instruction                               needs to be stored */                            fprintf(outfile, "    jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n",                                    n, reloc_offset);                            continue;                        }                                                get_reloc_expr(name, sizeof(name), sym_name);                        type = ELF32_R_TYPE(rel->r_info);                        addend = rel->r_addend;                        switch(type) {                        case R_PPC_ADDR32:                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",                                     reloc_offset, name, addend);                            break;                        case R_PPC_ADDR16_LO:                            fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n",                                     reloc_offset, name, addend);                            break;                        case R_PPC_ADDR16_HI:                            fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n",                                     reloc_offset, name, addend);                            break;                        case R_PPC_ADDR16_HA:                            fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n",                                     reloc_offset, name, addend);                            break;                        case R_PPC_REL24:                            /* warning: must be at 32 MB distancy */                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",                                     reloc_offset, reloc_offset, name, reloc_offset, addend);                            break;                        default:                            error("unsupported powerpc relocation (%d)", type);                        }                    }                }#elif defined(CONFIG_FORMAT_MACH)				struct scattered_relocation_info *scarel;				struct relocation_info * rel;				char final_sym_name[256];				const char *sym_name;				const char *p;				int slide, sslide;				int i;					for(i = 0, rel = relocs; i < nb_relocs; i++, rel++) {					unsigned int offset, length, value = 0;					unsigned int type, pcrel, isym = 0;					unsigned int usesym = 0;									if(R_SCATTERED & rel->r_address) {						scarel = (struct scattered_relocation_info*)rel;						offset = (unsigned int)scarel->r_address;						length = scarel->r_length;						pcrel = scarel->r_pcrel;						type = scarel->r_type;						value = scarel->r_value;					} else {						value = isym = rel->r_symbolnum;						usesym = (rel->r_extern);						offset = rel->r_address;						length = rel->r_length;						pcrel = rel->r_pcrel;						type = rel->r_type;					}									slide = offset - start_offset;							if (!(offset >= start_offset && offset < start_offset + size)) 						continue;  /* not in our range */					sym_name = get_reloc_name(rel, &sslide);										if(usesym && symtab[isym].n_type & N_STAB)						continue; /* don't handle STAB (debug sym) */										if (sym_name && strstart(sym_name, "__op_jmp", &p)) {						int n;						n = strtol(p, NULL, 10);						fprintf(outfile, "    jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n",							n, slide);						continue; /* Nothing more to do */					}										if(!sym_name)					{						fprintf(outfile, "/* #warning relocation not handled in %s (value 0x%x, %s, offset 0x%x, length 0x%x, %s, type 0x%x) */\n",						           name, value, usesym ? "use sym" : "don't use sym", offset, length, pcrel ? "pcrel":"", type);						continue; /* dunno how to handle without final_sym_name */					}													                                           get_reloc_expr(final_sym_name, sizeof(final_sym_name),                                                        sym_name);					switch(type) {					case PPC_RELOC_BR24:					    if (!strstart(sym_name,"__op_gen_label",&p)) {    						fprintf(outfile, "{\n");    						fprintf(outfile, "    uint32_t imm = *(uint32_t *)(gen_code_ptr + %d) & 0x3fffffc;\n", slide);    						fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((imm + ((long)%s - (long)gen_code_ptr) + %d) & 0x03fffffc);\n", 											slide, slide, name, sslide );    						fprintf(outfile, "}\n");    					} else {							fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | (((long)%s - (long)gen_code_ptr - %d) & 0x03fffffc);\n",											slide, slide, final_sym_name, slide);    					}						break;					case PPC_RELOC_HI16:						fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d) >> 16;\n", 							slide, final_sym_name, sslide);						break;					case PPC_RELOC_LO16:						fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d);\n", 					slide, final_sym_name, sslide);                            break;					case PPC_RELOC_HA16:						fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d + 2) = (%s + %d + 0x8000) >> 16;\n", 							slide, final_sym_name, sslide);						break;				default:					error("unsupported powerpc relocation (%d)", type);				}			}#else#error unsupport object format#endif            }#elif defined(HOST_S390)            {                char name[256];                int type;                int addend;                int reloc_offset;                for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {                    if (rel->r_offset >= start_offset &&			rel->r_offset < start_offset + copy_size) {                        sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;                        get_reloc_expr(name, sizeof(name), sym_name);                        type = ELF32_R_TYPE(rel->r_info);                        addend = rel->r_addend;                        reloc_offset = rel->r_offset - start_offset;                        switch(type) {                        case R_390_32:                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",                                     reloc_offset, name, addend);                            break;                        case R_390_16:                            fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = %s + %d;\n",                                     reloc_offset, name, addend);                            break;                        case R_390_8:                            fprintf(outfile, "    *(uint8_t *)(gen_code_ptr + %d) = %s + %d;\n",                                     reloc_offset, name, addend);                            break;                        default:                            error("unsupported s390 relocation (%d)", type);                        }                    }                }            }#elif defined(HOST_ALPHA)            {                for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {		    if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {			int type;                        long reloc_offset;			type = ELF64_R_TYPE(rel->r_info);			sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name;                        reloc_offset = rel->r_offset - start_offset;			switch (type) {			case R_ALPHA_GPDISP:			    /* The gp is just 32 bit, and never changes, so it's easiest to emit it			       as an immediate instead of constructing it from the pv or ra.  */			    fprintf(outfile, "    immediate_ldah(gen_code_ptr + %ld, gp);\n",				    reloc_offset);			    fprintf(outfile, "    immediate_lda(gen_code_ptr + %ld, gp);\n",				    reloc_offset + (int)rel->r_addend);			    break;			case R_ALPHA_LITUSE:			    /* jsr to literal hint. Could be used to optimize to bsr. Ignore for			       now, since some called functions (libc) need pv to be set up.  */			    break;			case R_ALPHA_HINT:			    /* Branch target prediction hint. Ignore for now.  Should be already			       correct for in-function jumps.  */			    break;			case R_ALPHA_LITERAL:			    /* Load a literal from the GOT relative to the gp.  Since there's only a			       single gp, nothing is to be done.  */			    break;			case R_ALPHA_GPRELHIGH:			    /* Handle fake relocations against __op_param symbol.  Need to emit the			       high part of the immediate value instead.  Other symbols need no			       special treatment.  */			    if (strstart(sym_name, "__op_param", &p))				fprintf(outfile, "    immediate_ldah(gen_code_ptr + %ld, param%s);\n",					reloc_offset, p);			    break;			case R_ALPHA_GPRELLOW:			    if (strstart(sym_name, "__op_param", &p))				fprintf(outfile, "    immediate_lda(gen_code_ptr + %ld, param%s);\n",					reloc_offset, p);			    break;			case R_ALPHA_BRSGP:			    /* PC-relative jump. Tweak offset to skip the two instructions that try to			       set up the gp from the pv.  */			    fprintf(outfile, "    fix_bsr(gen_code_ptr + %ld, (uint8_t *) &%s - (gen_code_ptr + %ld + 4) + 8);\n",				    reloc_offset, sym_name, reloc_offset);			    break;			default:			    error("unsupported Alpha relocation (%d)", type);			}		    }                }            }#elif defined(HOST_IA64)            {		unsigned long sym_idx;		long code_offset;                char name[256];                int type;                long addend;                for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {		    sym_idx = ELF64_R_SYM(rel->r_info);                    if (rel->r_offset < start_offset			|| rel->r_offset >= start_offset + copy_size)			continue;		    sym_name = (strtab + symtab[sym_idx].st_name);		    code_offset = rel->r_offset - start_offset;		    if (strstart(sym_name, "__op_jmp", &p)) {			int n;			n = strtol(p, NULL, 10);			/* __op_jmp relocations are done at			   runtime to do translated block			   chaining: the offset of the instruction			   needs to be stored */			fprintf(outfile, "    jmp_offsets[%d] ="				"%ld + (gen_code_ptr - gen_code_buf);\n",				n, code_offset);			continue;		    }		    get_reloc_expr(name, sizeof(name), sym_name);		    type = ELF64_R_TYPE(rel->r_info);		    addend = rel->r_addend;		    switch(type) {		      case R_IA64_IMM64:			  fprintf(outfile,				  "    ia64_imm64(gen_code_ptr + %ld, "				  "%s + %ld);\n",				  code_offset, name, addend);			  break;		      case R_IA64_LTOFF22X:		      case R_IA64_LTOFF22:			  fprintf(outfile, "    IA64_LTOFF(gen_code_ptr + %ld,"				  " %s + %ld, %d);\n",				  code_offset, name, addend,				  (type == R_IA64_LTOFF22X));			  break;		      case R_IA64_LDXMOV:			  fprintf(outfile,				  "    ia64_ldxmov(gen_code_ptr + %ld,"				  " %s + %ld);\n", code_offset, name, addend);			  break;		      case R_IA64_PCREL21B:			  if (strstart(sym_name, "__op_gen_label", NULL)) {			      fprintf(outfile,				      "    ia64_imm21b(gen_code_ptr + %ld,"				      " (long) (%s + %ld -\n\t\t"				      "((long) gen_code_ptr + %ld)) >> 4);\n",				      code_offset, name, addend,				      code_offset & ~0xfUL);			  } else {			      fprintf(outfile,				      "    IA64

⌨️ 快捷键说明

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