*/
#include "qemu/osdep.h"
-#include "qemu-common.h"
+#include "qemu/help-texts.h"
#include "qemu/units.h"
#include "qemu/accel.h"
-#include "sysemu/tcg.h"
#include "qemu-version.h"
#include <sys/syscall.h>
#include <sys/resource.h>
#include "qapi/error.h"
#include "qemu.h"
+#include "user-internals.h"
#include "qemu/path.h"
#include "qemu/queue.h"
#include "qemu/config-file.h"
#include "qemu/module.h"
#include "qemu/plugin.h"
#include "exec/exec-all.h"
+#include "exec/gdbstub.h"
#include "tcg/tcg.h"
#include "qemu/timer.h"
#include "qemu/envlist.h"
#include "target_elf.h"
#include "cpu_loop-common.h"
#include "crypto/init.h"
+#include "fd-trans.h"
+#include "signal-common.h"
+#include "loader.h"
+#include "user-mmap.h"
+
+#ifdef CONFIG_SEMIHOSTING
+#include "semihosting/semihost.h"
+#endif
#ifndef AT_FLAGS_PRESERVE_ARGV0
#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
* Used to support command line arguments overriding environment variables.
*/
static int last_log_mask;
+static const char *last_log_filename;
/*
* When running 32-on-64 we should make sure we can fit all of the possible
static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
const char *qemu_uname_release;
+#if !defined(TARGET_DEFAULT_STACK_SIZE)
/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
we allocate a bigger stack. Need a better solution, for example
by remapping the process stack directly at the right place */
-unsigned long guest_stack_size = 8 * 1024 * 1024UL;
-
-#if defined(TARGET_I386)
-int cpu_get_pic_interrupt(CPUX86State *env)
-{
- return -1;
-}
+#define TARGET_DEFAULT_STACK_SIZE 8 * 1024 * 1024UL
#endif
+unsigned long guest_stack_size = TARGET_DEFAULT_STACK_SIZE;
+
/***********************************************************/
/* Helper routines for implementing atomic operations. */
/* Assumes contents are already zeroed. */
void init_task_state(TaskState *ts)
{
+ long ticks_per_sec;
+ struct timespec bt;
+
ts->used = 1;
ts->sigaltstack_used = (struct target_sigaltstack) {
.ss_sp = 0,
.ss_size = 0,
.ss_flags = TARGET_SS_DISABLE,
};
+
+ /* Capture task start time relative to system boot */
+
+ ticks_per_sec = sysconf(_SC_CLK_TCK);
+
+ if ((ticks_per_sec > 0) && !clock_gettime(CLOCK_BOOTTIME, &bt)) {
+ /* start_boottime is expressed in clock ticks */
+ ts->start_boottime = bt.tv_sec * (uint64_t) ticks_per_sec;
+ ts->start_boottime += bt.tv_nsec * (uint64_t) ticks_per_sec /
+ NANOSECONDS_PER_SECOND;
+ }
}
CPUArchState *cpu_copy(CPUArchState *env)
static void handle_arg_log_filename(const char *arg)
{
- qemu_set_log_filename(arg, &error_fatal);
+ last_log_filename = arg;
}
static void handle_arg_set_env(const char *arg)
"", "[[enable=]<pattern>][,events=<file>][,file=<file>]"},
#ifdef CONFIG_PLUGIN
{"plugin", "QEMU_PLUGIN", true, handle_arg_plugin,
- "", "[file=]<file>[,arg=<string>]"},
+ "", "[file=]<file>[,<argname>=<argvalue>]"},
#endif
{"version", "QEMU_VERSION", false, handle_arg_version,
"", "display version information and exit"},
int i;
int ret;
int execfd;
- int log_mask;
unsigned long max_reserved_va;
bool preserve_argv0;
struct rlimit lim;
if (getrlimit(RLIMIT_STACK, &lim) == 0
&& lim.rlim_cur != RLIM_INFINITY
- && lim.rlim_cur == (target_long)lim.rlim_cur) {
+ && lim.rlim_cur == (target_long)lim.rlim_cur
+ && lim.rlim_cur > guest_stack_size) {
guest_stack_size = lim.rlim_cur;
}
}
optind = parse_args(argc, argv);
- log_mask = last_log_mask | (enable_strace ? LOG_STRACE : 0);
- if (log_mask) {
- qemu_log_needs_buffers();
- qemu_set_log(log_mask);
- }
+ qemu_set_log_filename_flags(last_log_filename,
+ last_log_mask | (enable_strace * LOG_STRACE),
+ &error_fatal);
if (!trace_init_backends()) {
exit(1);
cpu->opaque = ts;
task_settid(ts);
+ fd_trans_init();
+
ret = loader_exec(execfd, exec_path, target_argv, target_environ, regs,
info, &bprm);
if (ret != 0) {
g_free(target_environ);
if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
- qemu_log("guest_base %p\n", (void *)guest_base);
- log_page_dump("binary load");
-
- qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
- qemu_log("end_code 0x" TARGET_ABI_FMT_lx "\n", info->end_code);
- qemu_log("start_code 0x" TARGET_ABI_FMT_lx "\n", info->start_code);
- qemu_log("start_data 0x" TARGET_ABI_FMT_lx "\n", info->start_data);
- qemu_log("end_data 0x" TARGET_ABI_FMT_lx "\n", info->end_data);
- qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n", info->start_stack);
- qemu_log("brk 0x" TARGET_ABI_FMT_lx "\n", info->brk);
- qemu_log("entry 0x" TARGET_ABI_FMT_lx "\n", info->entry);
- qemu_log("argv_start 0x" TARGET_ABI_FMT_lx "\n", info->arg_start);
- qemu_log("env_start 0x" TARGET_ABI_FMT_lx "\n",
- info->arg_end + (abi_ulong)sizeof(abi_ulong));
- qemu_log("auxv_start 0x" TARGET_ABI_FMT_lx "\n", info->saved_auxv);
+ FILE *f = qemu_log_trylock();
+ if (f) {
+ fprintf(f, "guest_base %p\n", (void *)guest_base);
+ fprintf(f, "page layout changed following binary load\n");
+ page_dump(f);
+
+ fprintf(f, "start_brk 0x" TARGET_ABI_FMT_lx "\n",
+ info->start_brk);
+ fprintf(f, "end_code 0x" TARGET_ABI_FMT_lx "\n",
+ info->end_code);
+ fprintf(f, "start_code 0x" TARGET_ABI_FMT_lx "\n",
+ info->start_code);
+ fprintf(f, "start_data 0x" TARGET_ABI_FMT_lx "\n",
+ info->start_data);
+ fprintf(f, "end_data 0x" TARGET_ABI_FMT_lx "\n",
+ info->end_data);
+ fprintf(f, "start_stack 0x" TARGET_ABI_FMT_lx "\n",
+ info->start_stack);
+ fprintf(f, "brk 0x" TARGET_ABI_FMT_lx "\n",
+ info->brk);
+ fprintf(f, "entry 0x" TARGET_ABI_FMT_lx "\n",
+ info->entry);
+ fprintf(f, "argv_start 0x" TARGET_ABI_FMT_lx "\n",
+ info->argv);
+ fprintf(f, "env_start 0x" TARGET_ABI_FMT_lx "\n",
+ info->envp);
+ fprintf(f, "auxv_start 0x" TARGET_ABI_FMT_lx "\n",
+ info->saved_auxv);
+ qemu_log_unlock(f);
+ }
}
target_set_brk(info->brk);
generating the prologue until now so that the prologue can take
the real value of GUEST_BASE into account. */
tcg_prologue_init(tcg_ctx);
- tcg_region_init();
target_cpu_copy_regs(env, regs);
}
gdb_handlesig(cpu, 0);
}
+
+#ifdef CONFIG_SEMIHOSTING
+ qemu_semihosting_guestfd_init();
+#endif
+
cpu_loop(env);
/* never exits */
return 0;