diff options
author | Marcelo Tosatti <mtosatti@redhat.com> | 2009-09-29 09:47:14 -0300 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2009-09-29 09:47:14 -0300 |
commit | 044034ffe753189bc21868f7cfc18db2e69c4bc1 (patch) | |
tree | 896dae5fa88589e22834b58613244a1b02938d15 | |
parent | Merge commit 'add16157d72454347feb240007da4f90b9d9bae6' into upstream-merge (diff) | |
parent | target-ppc: log instructions start in TCG code (diff) | |
download | qemu-kvm-044034ffe753189bc21868f7cfc18db2e69c4bc1.tar.gz qemu-kvm-044034ffe753189bc21868f7cfc18db2e69c4bc1.tar.bz2 qemu-kvm-044034ffe753189bc21868f7cfc18db2e69c4bc1.zip |
Merge commit '731c54f86988d3f28268f184fabfe9b2a32fb5d3' into upstream-merge
* commit '731c54f86988d3f28268f184fabfe9b2a32fb5d3':
target-ppc: log instructions start in TCG code
target-mips: log instructions start in TCG code
Win32: avoid a warning
BSD user: suppress a warning
BSD user: implement GUEST_BASE
tcg/i386: generates dec/inc instead of sub/add when possible
tcg/i386: optimize and $0xff(ff), reg
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r-- | bsd-user/elfload.c | 27 | ||||
-rw-r--r-- | bsd-user/main.c | 44 | ||||
-rw-r--r-- | bsd-user/qemu.h | 3 | ||||
-rw-r--r-- | target-mips/translate.c | 4 | ||||
-rw-r--r-- | target-ppc/translate.c | 2 | ||||
-rw-r--r-- | tcg/i386/tcg-target.c | 30 | ||||
-rw-r--r-- | vl.c | 8 |
7 files changed, 103 insertions, 15 deletions
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c index 48ec4ac15..19981f0a9 100644 --- a/bsd-user/elfload.c +++ b/bsd-user/elfload.c @@ -1107,10 +1107,10 @@ static void load_symbols(struct elfhdr *hdr, int fd) s->disas_num_syms = nsyms; #if ELF_CLASS == ELFCLASS32 s->disas_symtab.elf32 = syms; - s->lookup_symbol = lookup_symbolxx; + s->lookup_symbol = (lookup_symbol_t)lookup_symbolxx; #else s->disas_symtab.elf64 = syms; - s->lookup_symbol = lookup_symbolxx; + s->lookup_symbol = (lookup_symbol_t)lookup_symbolxx; #endif s->next = syminfos; syminfos = s; @@ -1337,6 +1337,29 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, info->mmap = 0; elf_entry = (abi_ulong) elf_ex.e_entry; +#if defined(CONFIG_USE_GUEST_BASE) + /* + * In case where user has not explicitly set the guest_base, we + * probe here that should we set it automatically. + */ + if (!have_guest_base) { + /* + * Go through ELF program header table and find out whether + * any of the segments drop below our current mmap_min_addr and + * in that case set guest_base to corresponding address. + */ + for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; + i++, elf_ppnt++) { + if (elf_ppnt->p_type != PT_LOAD) + continue; + if (HOST_PAGE_ALIGN(elf_ppnt->p_vaddr) < mmap_min_addr) { + guest_base = HOST_PAGE_ALIGN(mmap_min_addr); + break; + } + } + } +#endif /* CONFIG_USE_GUEST_BASE */ + /* Do this so that we can load the interpreter, if need be. We will change some of these later */ info->rss = 0; diff --git a/bsd-user/main.c b/bsd-user/main.c index 56710ec79..1bba2b505 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -37,6 +37,11 @@ #define DEBUG_LOGFILE "/tmp/qemu.log" int singlestep; +#if defined(CONFIG_USE_GUEST_BASE) +unsigned long mmap_min_addr; +unsigned long guest_base; +int have_guest_base; +#endif static const char *interp_prefix = CONFIG_QEMU_PREFIX; const char *qemu_uname_release = CONFIG_UNAME_RELEASE; @@ -607,6 +612,9 @@ static void usage(void) "-drop-ld-preload drop LD_PRELOAD for target process\n" "-E var=value sets/modifies targets environment variable(s)\n" "-U var unsets targets environment variable(s)\n" +#if defined(CONFIG_USE_GUEST_BASE) + "-B address set guest_base address to address\n" +#endif "-bsd type select emulated BSD type FreeBSD/NetBSD/OpenBSD (default)\n" "\n" "Debug options:\n" @@ -746,6 +754,11 @@ int main(int argc, char **argv) #endif exit(1); } +#if defined(CONFIG_USE_GUEST_BASE) + } else if (!strcmp(r, "B")) { + guest_base = strtol(argv[optind++], NULL, 0); + have_guest_base = 1; +#endif } else if (!strcmp(r, "drop-ld-preload")) { (void) envlist_unsetenv(envlist, "LD_PRELOAD"); } else if (!strcmp(r, "bsd")) { @@ -815,6 +828,34 @@ int main(int argc, char **argv) target_environ = envlist_to_environ(envlist, NULL); envlist_free(envlist); +#if defined(CONFIG_USE_GUEST_BASE) + /* + * Now that page sizes are configured in cpu_init() we can do + * proper page alignment for guest_base. + */ + guest_base = HOST_PAGE_ALIGN(guest_base); + + /* + * Read in mmap_min_addr kernel parameter. This value is used + * When loading the ELF image to determine whether guest_base + * is needed. + * + * When user has explicitly set the quest base, we skip this + * test. + */ + if (!have_guest_base) { + FILE *fp; + + if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) { + unsigned long tmp; + if (fscanf(fp, "%lu", &tmp) == 1) { + mmap_min_addr = tmp; + qemu_log("host mmap_min_addr=0x%lx\n", mmap_min_addr); + } + fclose(fp); + } + } +#endif /* CONFIG_USE_GUEST_BASE */ if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) { printf("Error loading %s\n", filename); @@ -828,6 +869,9 @@ int main(int argc, char **argv) free(target_environ); if (qemu_log_enabled()) { +#if defined(CONFIG_USE_GUEST_BASE) + qemu_log("guest_base 0x%lx\n", guest_base); +#endif log_page_dump(); qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk); diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h index cbee3e72f..9f4cd1ba0 100644 --- a/bsd-user/qemu.h +++ b/bsd-user/qemu.h @@ -84,6 +84,9 @@ typedef struct TaskState { void init_task_state(TaskState *ts); extern const char *qemu_uname_release; +#if defined(CONFIG_USE_GUEST_BASE) +extern unsigned long mmap_min_addr; +#endif /* ??? See if we can avoid exposing so much of the loader internals. */ /* diff --git a/target-mips/translate.c b/target-mips/translate.c index aabb69c2d..42a5753e2 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -7660,6 +7660,10 @@ static void decode_opc (CPUState *env, DisasContext *ctx) gen_goto_tb(ctx, 1, ctx->pc + 4); gen_set_label(l1); } + + if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) + tcg_gen_debug_insn_start(ctx->pc); + op = MASK_OP_MAJOR(ctx->opcode); rs = (ctx->opcode >> 21) & 0x1f; rt = (ctx->opcode >> 16) & 0x1f; diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 8844ad275..d4e81ce89 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -9032,6 +9032,8 @@ static inline void gen_intermediate_code_internal(CPUState *env, LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n", ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode), little_endian ? "little" : "big"); + if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) + tcg_gen_debug_insn_start(ctx.nip); ctx.nip += 4; table = env->opcodes; num_insns++; diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index a95fe4c20..b4e3b6fd4 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -276,11 +276,23 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, int arg, tcg_out_modrm_offset(s, 0x89, arg, arg1, arg2); } -static inline void tgen_arithi(TCGContext *s, int c, int r0, int32_t val) +static inline void tgen_arithi(TCGContext *s, int c, int r0, int32_t val, int cf) { - if (val == (int8_t)val) { + if (!cf && ((c == ARITH_ADD && val == 1) || (c == ARITH_SUB && val == -1))) { + /* inc */ + tcg_out_opc(s, 0x40 + r0); + } else if (!cf && ((c == ARITH_ADD && val == -1) || (c == ARITH_SUB && val == 1))) { + /* dec */ + tcg_out_opc(s, 0x48 + r0); + } else if (val == (int8_t)val) { tcg_out_modrm(s, 0x83, c, r0); tcg_out8(s, val); + } else if (c == ARITH_AND && val == 0xffu && r0 < 4) { + /* movzbl */ + tcg_out_modrm(s, 0xb6 | P_EXT, r0, r0); + } else if (c == ARITH_AND && val == 0xffffu) { + /* movzwl */ + tcg_out_modrm(s, 0xb7 | P_EXT, r0, r0); } else { tcg_out_modrm(s, 0x81, c, r0); tcg_out32(s, val); @@ -290,7 +302,7 @@ static inline void tgen_arithi(TCGContext *s, int c, int r0, int32_t val) static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) { if (val != 0) - tgen_arithi(s, ARITH_ADD, reg, val); + tgen_arithi(s, ARITH_ADD, reg, val, 0); } static void tcg_out_jxx(TCGContext *s, int opc, int label_index) @@ -338,7 +350,7 @@ static void tcg_out_brcond(TCGContext *s, int cond, /* test r, r */ tcg_out_modrm(s, 0x85, arg1, arg1); } else { - tgen_arithi(s, ARITH_CMP, arg1, arg2); + tgen_arithi(s, ARITH_CMP, arg1, arg2, 0); } } else { tcg_out_modrm(s, 0x01 | (ARITH_CMP << 3), arg2, arg1); @@ -955,7 +967,7 @@ static inline void tcg_out_op(TCGContext *s, int opc, c = ARITH_ADD; gen_arith: if (const_args[2]) { - tgen_arithi(s, c, args[0], args[2]); + tgen_arithi(s, c, args[0], args[2], 0); } else { tcg_out_modrm(s, 0x01 | (c << 3), args[2], args[0]); } @@ -1013,21 +1025,21 @@ static inline void tcg_out_op(TCGContext *s, int opc, case INDEX_op_add2_i32: if (const_args[4]) - tgen_arithi(s, ARITH_ADD, args[0], args[4]); + tgen_arithi(s, ARITH_ADD, args[0], args[4], 1); else tcg_out_modrm(s, 0x01 | (ARITH_ADD << 3), args[4], args[0]); if (const_args[5]) - tgen_arithi(s, ARITH_ADC, args[1], args[5]); + tgen_arithi(s, ARITH_ADC, args[1], args[5], 1); else tcg_out_modrm(s, 0x01 | (ARITH_ADC << 3), args[5], args[1]); break; case INDEX_op_sub2_i32: if (const_args[4]) - tgen_arithi(s, ARITH_SUB, args[0], args[4]); + tgen_arithi(s, ARITH_SUB, args[0], args[4], 1); else tcg_out_modrm(s, 0x01 | (ARITH_SUB << 3), args[4], args[0]); if (const_args[5]) - tgen_arithi(s, ARITH_SBB, args[1], args[5]); + tgen_arithi(s, ARITH_SBB, args[1], args[5], 1); else tcg_out_modrm(s, 0x01 | (ARITH_SBB << 3), args[5], args[1]); break; @@ -1459,7 +1459,7 @@ static int win32_start_timer(struct qemu_alarm_timer *t) flags); if (!data->timerId) { - fprintf(stderr, "Failed to initialize win32 alarm timer: %d\n", + fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n", GetLastError()); timeEndPeriod(data->period); return -1; @@ -1497,7 +1497,7 @@ static void win32_rearm_timer(struct qemu_alarm_timer *t) TIME_ONESHOT | TIME_PERIODIC); if (!data->timerId) { - fprintf(stderr, "Failed to re-arm win32 alarm timer %d\n", + fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n", GetLastError()); timeEndPeriod(data->period); @@ -3425,7 +3425,7 @@ static int qemu_event_init(void) { qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL); if (!qemu_event_handle) { - fprintf(stderr, "Failed CreateEvent: %d\n", GetLastError()); + fprintf(stderr, "Failed CreateEvent: %ld\n", GetLastError()); return -1; } qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL); @@ -3435,7 +3435,7 @@ static int qemu_event_init(void) static void qemu_event_increment(void) { if (!SetEvent(qemu_event_handle)) { - fprintf(stderr, "qemu_event_increment: SetEvent failed: %d\n", + fprintf(stderr, "qemu_event_increment: SetEvent failed: %ld\n", GetLastError()); exit (1); } |