aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2009-09-29 09:47:14 -0300
committerMarcelo Tosatti <mtosatti@redhat.com>2009-09-29 09:47:14 -0300
commit044034ffe753189bc21868f7cfc18db2e69c4bc1 (patch)
tree896dae5fa88589e22834b58613244a1b02938d15
parentMerge commit 'add16157d72454347feb240007da4f90b9d9bae6' into upstream-merge (diff)
parenttarget-ppc: log instructions start in TCG code (diff)
downloadqemu-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.c27
-rw-r--r--bsd-user/main.c44
-rw-r--r--bsd-user/qemu.h3
-rw-r--r--target-mips/translate.c4
-rw-r--r--target-ppc/translate.c2
-rw-r--r--tcg/i386/tcg-target.c30
-rw-r--r--vl.c8
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;
diff --git a/vl.c b/vl.c
index 2c00baa34..6b620367e 100644
--- a/vl.c
+++ b/vl.c
@@ -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);
}