diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | Makefile.objs | 1 | ||||
-rw-r--r-- | audio/Makefile.objs | 30 | ||||
-rw-r--r-- | audio/alsaaudio.c | 8 | ||||
-rw-r--r-- | audio/audio.c | 83 | ||||
-rw-r--r-- | audio/audio_int.h | 14 | ||||
-rw-r--r-- | audio/coreaudio.c | 8 | ||||
-rw-r--r-- | audio/dsoundaudio.c | 8 | ||||
-rw-r--r-- | audio/noaudio.c | 8 | ||||
-rw-r--r-- | audio/ossaudio.c | 8 | ||||
-rw-r--r-- | audio/paaudio.c | 8 | ||||
-rw-r--r-- | audio/sdlaudio.c | 8 | ||||
-rw-r--r-- | audio/spiceaudio.c | 8 | ||||
-rw-r--r-- | audio/wavaudio.c | 8 | ||||
-rwxr-xr-x | configure | 9 | ||||
-rw-r--r-- | hw/display/vga.c | 2 | ||||
-rw-r--r-- | hw/usb/redirect.c | 4 | ||||
-rw-r--r-- | include/block/aio-wait.h | 61 | ||||
-rw-r--r-- | include/qemu/log-for-trace.h | 35 | ||||
-rw-r--r-- | include/qemu/log.h | 18 | ||||
-rw-r--r-- | include/qemu/module.h | 1 | ||||
-rwxr-xr-x | scripts/create_config | 2 | ||||
-rwxr-xr-x | scripts/simpletrace.py | 6 | ||||
-rwxr-xr-x | scripts/tracetool.py | 2 | ||||
-rw-r--r-- | scripts/tracetool/__init__.py | 52 | ||||
-rw-r--r-- | scripts/tracetool/backend/log.py | 13 | ||||
-rw-r--r-- | tests/docker/dockerfiles/fedora.docker | 2 | ||||
-rwxr-xr-x | tests/docker/test-debug | 6 | ||||
-rw-r--r-- | trace-events | 6 | ||||
-rw-r--r-- | util/aio-wait.c | 2 |
30 files changed, 301 insertions, 124 deletions
@@ -425,6 +425,10 @@ dummy := $(call unnest-vars,, \ io-obj-y \ common-obj-y \ common-obj-m \ + ui-obj-y \ + ui-obj-m \ + audio-obj-y \ + audio-obj-m \ trace-obj-y) include $(SRC_PATH)/tests/Makefile.include diff --git a/Makefile.objs b/Makefile.objs index d8b44a2d3c..c6c9b8fc21 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -104,6 +104,7 @@ common-obj-$(CONFIG_LINUX) += fsdev/ common-obj-y += migration/ common-obj-y += audio/ +common-obj-m += audio/ common-obj-y += hw/ common-obj-y += replay/ diff --git a/audio/Makefile.objs b/audio/Makefile.objs index f6ce5c6744..db4fa7f18f 100644 --- a/audio/Makefile.objs +++ b/audio/Makefile.objs @@ -1,19 +1,31 @@ common-obj-y = audio.o noaudio.o wavaudio.o mixeng.o -common-obj-$(CONFIG_AUDIO_SDL) += sdlaudio.o -common-obj-$(CONFIG_AUDIO_OSS) += ossaudio.o common-obj-$(CONFIG_SPICE) += spiceaudio.o common-obj-$(CONFIG_AUDIO_COREAUDIO) += coreaudio.o -common-obj-$(CONFIG_AUDIO_ALSA) += alsaaudio.o common-obj-$(CONFIG_AUDIO_DSOUND) += dsoundaudio.o -common-obj-$(CONFIG_AUDIO_PA) += paaudio.o common-obj-$(CONFIG_AUDIO_PT_INT) += audio_pt_int.o common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o common-obj-y += wavcapture.o -sdlaudio.o-cflags := $(SDL_CFLAGS) -sdlaudio.o-libs := $(SDL_LIBS) -alsaaudio.o-libs := $(ALSA_LIBS) -paaudio.o-libs := $(PULSE_LIBS) coreaudio.o-libs := $(COREAUDIO_LIBS) dsoundaudio.o-libs := $(DSOUND_LIBS) -ossaudio.o-libs := $(OSS_LIBS) + +# alsa module +common-obj-$(CONFIG_AUDIO_ALSA) += alsa.mo +alsa.mo-objs = alsaaudio.o +alsa.mo-libs := $(ALSA_LIBS) + +# oss module +common-obj-$(CONFIG_AUDIO_OSS) += oss.mo +oss.mo-objs = ossaudio.o +oss.mo-libs := $(OSS_LIBS) + +# pulseaudio module +common-obj-$(CONFIG_AUDIO_PA) += pa.mo +pa.mo-objs = paaudio.o +pa.mo-libs := $(PULSE_LIBS) + +# sdl module +common-obj-$(CONFIG_AUDIO_SDL) += sdl.mo +sdl.mo-objs = sdlaudio.o +sdl.mo-cflags := $(SDL_CFLAGS) +sdl.mo-libs := $(SDL_LIBS) diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 92a96f8b2b..362a2276fd 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -1213,7 +1213,7 @@ static struct audio_pcm_ops alsa_pcm_ops = { .ctl_in = alsa_ctl_in, }; -struct audio_driver alsa_audio_driver = { +static struct audio_driver alsa_audio_driver = { .name = "alsa", .descr = "ALSA http://www.alsa-project.org", .options = alsa_options, @@ -1226,3 +1226,9 @@ struct audio_driver alsa_audio_driver = { .voice_size_out = sizeof (ALSAVoiceOut), .voice_size_in = sizeof (ALSAVoiceIn) }; + +static void register_audio_alsa(void) +{ + audio_driver_register(&alsa_audio_driver); +} +type_init(register_audio_alsa); diff --git a/audio/audio.c b/audio/audio.c index 7658d2af66..6eccdb17ee 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -45,15 +45,49 @@ The 1st one is the one used by default, that is the reason that we generate the list. */ -static struct audio_driver *drvtab[] = { -#ifdef CONFIG_SPICE - &spice_audio_driver, -#endif +static const char *audio_prio_list[] = { + "spice", CONFIG_AUDIO_DRIVERS - &no_audio_driver, - &wav_audio_driver + "none", + "wav", }; +static QLIST_HEAD(, audio_driver) audio_drivers; + +void audio_driver_register(audio_driver *drv) +{ + QLIST_INSERT_HEAD(&audio_drivers, drv, next); +} + +audio_driver *audio_driver_lookup(const char *name) +{ + struct audio_driver *d; + + QLIST_FOREACH(d, &audio_drivers, next) { + if (strcmp(name, d->name) == 0) { + return d; + } + } + + audio_module_load_one(name); + QLIST_FOREACH(d, &audio_drivers, next) { + if (strcmp(name, d->name) == 0) { + return d; + } + } + + return NULL; +} + +static void audio_module_load_all(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(audio_prio_list); i++) { + audio_driver_lookup(audio_prio_list[i]); + } +} + struct fixed_settings { int enabled; int nb_voices; @@ -1656,11 +1690,13 @@ static void audio_pp_nb_voices (const char *typ, int nb) void AUD_help (void) { - size_t i; + struct audio_driver *d; + + /* make sure we print the help text for modular drivers too */ + audio_module_load_all(); audio_process_options ("AUDIO", audio_options); - for (i = 0; i < ARRAY_SIZE (drvtab); i++) { - struct audio_driver *d = drvtab[i]; + QLIST_FOREACH(d, &audio_drivers, next) { if (d->options) { audio_process_options (d->name, d->options); } @@ -1672,8 +1708,7 @@ void AUD_help (void) printf ("Available drivers:\n"); - for (i = 0; i < ARRAY_SIZE (drvtab); i++) { - struct audio_driver *d = drvtab[i]; + QLIST_FOREACH(d, &audio_drivers, next) { printf ("Name: %s\n", d->name); printf ("Description: %s\n", d->descr); @@ -1807,6 +1842,7 @@ static void audio_init (void) const char *drvname; VMChangeStateEntry *e; AudioState *s = &glob_audio_state; + struct audio_driver *driver; if (s->drv) { return; @@ -1842,32 +1878,27 @@ static void audio_init (void) } if (drvname) { - int found = 0; - - for (i = 0; i < ARRAY_SIZE (drvtab); i++) { - if (!strcmp (drvname, drvtab[i]->name)) { - done = !audio_driver_init (s, drvtab[i]); - found = 1; - break; - } - } - - if (!found) { + driver = audio_driver_lookup(drvname); + if (driver) { + done = !audio_driver_init(s, driver); + } else { dolog ("Unknown audio driver `%s'\n", drvname); dolog ("Run with -audio-help to list available drivers\n"); } } if (!done) { - for (i = 0; !done && i < ARRAY_SIZE (drvtab); i++) { - if (drvtab[i]->can_be_default) { - done = !audio_driver_init (s, drvtab[i]); + for (i = 0; !done && i < ARRAY_SIZE(audio_prio_list); i++) { + driver = audio_driver_lookup(audio_prio_list[i]); + if (driver && driver->can_be_default) { + done = !audio_driver_init(s, driver); } } } if (!done) { - done = !audio_driver_init (s, &no_audio_driver); + driver = audio_driver_lookup("none"); + done = !audio_driver_init(s, driver); assert(done); dolog("warning: Using timer based audio emulation\n"); } diff --git a/audio/audio_int.h b/audio/audio_int.h index 700bd43143..244b454012 100644 --- a/audio/audio_int.h +++ b/audio/audio_int.h @@ -141,6 +141,7 @@ struct SWVoiceIn { QLIST_ENTRY (SWVoiceIn) entries; }; +typedef struct audio_driver audio_driver; struct audio_driver { const char *name; const char *descr; @@ -154,6 +155,7 @@ struct audio_driver { int voice_size_out; int voice_size_in; int ctl_caps; + QLIST_ENTRY(audio_driver) next; }; struct audio_pcm_ops { @@ -203,17 +205,11 @@ struct AudioState { int vm_running; }; -extern struct audio_driver no_audio_driver; -extern struct audio_driver oss_audio_driver; -extern struct audio_driver sdl_audio_driver; -extern struct audio_driver wav_audio_driver; -extern struct audio_driver alsa_audio_driver; -extern struct audio_driver coreaudio_audio_driver; -extern struct audio_driver dsound_audio_driver; -extern struct audio_driver pa_audio_driver; -extern struct audio_driver spice_audio_driver; extern const struct mixeng_volume nominal_volume; +void audio_driver_register(audio_driver *drv); +audio_driver *audio_driver_lookup(const char *name); + void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as); void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len); diff --git a/audio/coreaudio.c b/audio/coreaudio.c index c75142084f..638c60b300 100644 --- a/audio/coreaudio.c +++ b/audio/coreaudio.c @@ -722,7 +722,7 @@ static struct audio_pcm_ops coreaudio_pcm_ops = { .ctl_out = coreaudio_ctl_out }; -struct audio_driver coreaudio_audio_driver = { +static struct audio_driver coreaudio_audio_driver = { .name = "coreaudio", .descr = "CoreAudio http://developer.apple.com/audio/coreaudio.html", .options = coreaudio_options, @@ -735,3 +735,9 @@ struct audio_driver coreaudio_audio_driver = { .voice_size_out = sizeof (coreaudioVoiceOut), .voice_size_in = 0 }; + +static void register_audio_coreaudio(void) +{ + audio_driver_register(&coreaudio_audio_driver); +} +type_init(register_audio_coreaudio); diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c index bc39cb9b4d..3ed73a30d1 100644 --- a/audio/dsoundaudio.c +++ b/audio/dsoundaudio.c @@ -890,7 +890,7 @@ static struct audio_pcm_ops dsound_pcm_ops = { .ctl_in = dsound_ctl_in }; -struct audio_driver dsound_audio_driver = { +static struct audio_driver dsound_audio_driver = { .name = "dsound", .descr = "DirectSound http://wikipedia.org/wiki/DirectSound", .options = dsound_options, @@ -903,3 +903,9 @@ struct audio_driver dsound_audio_driver = { .voice_size_out = sizeof (DSoundVoiceOut), .voice_size_in = sizeof (DSoundVoiceIn) }; + +static void register_audio_dsound(void) +{ + audio_driver_register(&dsound_audio_driver); +} +type_init(register_audio_dsound); diff --git a/audio/noaudio.c b/audio/noaudio.c index 9ca9eaf01f..1bfebeca7d 100644 --- a/audio/noaudio.c +++ b/audio/noaudio.c @@ -160,7 +160,7 @@ static struct audio_pcm_ops no_pcm_ops = { .ctl_in = no_ctl_in }; -struct audio_driver no_audio_driver = { +static struct audio_driver no_audio_driver = { .name = "none", .descr = "Timer based audio emulation", .options = NULL, @@ -173,3 +173,9 @@ struct audio_driver no_audio_driver = { .voice_size_out = sizeof (NoVoiceOut), .voice_size_in = sizeof (NoVoiceIn) }; + +static void register_audio_none(void) +{ + audio_driver_register(&no_audio_driver); +} +type_init(register_audio_none); diff --git a/audio/ossaudio.c b/audio/ossaudio.c index a0428881c2..6c69622b4c 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -922,7 +922,7 @@ static struct audio_pcm_ops oss_pcm_ops = { .ctl_in = oss_ctl_in }; -struct audio_driver oss_audio_driver = { +static struct audio_driver oss_audio_driver = { .name = "oss", .descr = "OSS http://www.opensound.com", .options = oss_options, @@ -935,3 +935,9 @@ struct audio_driver oss_audio_driver = { .voice_size_out = sizeof (OSSVoiceOut), .voice_size_in = sizeof (OSSVoiceIn) }; + +static void register_audio_oss(void) +{ + audio_driver_register(&oss_audio_driver); +} +type_init(register_audio_oss); diff --git a/audio/paaudio.c b/audio/paaudio.c index aa0a7477d3..949769774d 100644 --- a/audio/paaudio.c +++ b/audio/paaudio.c @@ -937,7 +937,7 @@ static struct audio_pcm_ops qpa_pcm_ops = { .ctl_in = qpa_ctl_in }; -struct audio_driver pa_audio_driver = { +static struct audio_driver pa_audio_driver = { .name = "pa", .descr = "http://www.pulseaudio.org/", .options = qpa_options, @@ -951,3 +951,9 @@ struct audio_driver pa_audio_driver = { .voice_size_in = sizeof (PAVoiceIn), .ctl_caps = VOICE_VOLUME_CAP }; + +static void register_audio_pa(void) +{ + audio_driver_register(&pa_audio_driver); +} +type_init(register_audio_pa); diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c index e92135bd2f..9db5ac92bc 100644 --- a/audio/sdlaudio.c +++ b/audio/sdlaudio.c @@ -500,7 +500,7 @@ static struct audio_pcm_ops sdl_pcm_ops = { .ctl_out = sdl_ctl_out, }; -struct audio_driver sdl_audio_driver = { +static struct audio_driver sdl_audio_driver = { .name = "sdl", .descr = "SDL http://www.libsdl.org", .options = sdl_options, @@ -513,3 +513,9 @@ struct audio_driver sdl_audio_driver = { .voice_size_out = sizeof (SDLVoiceOut), .voice_size_in = 0 }; + +static void register_audio_sdl(void) +{ + audio_driver_register(&sdl_audio_driver); +} +type_init(register_audio_sdl); diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c index 5580e76307..6ad0eafbc6 100644 --- a/audio/spiceaudio.c +++ b/audio/spiceaudio.c @@ -391,7 +391,7 @@ static struct audio_pcm_ops audio_callbacks = { .ctl_in = line_in_ctl, }; -struct audio_driver spice_audio_driver = { +static struct audio_driver spice_audio_driver = { .name = "spice", .descr = "spice audio driver", .options = audio_options, @@ -411,3 +411,9 @@ void qemu_spice_audio_init (void) { spice_audio_driver.can_be_default = 1; } + +static void register_audio_spice(void) +{ + audio_driver_register(&spice_audio_driver); +} +type_init(register_audio_spice); diff --git a/audio/wavaudio.c b/audio/wavaudio.c index 068a595732..40adfa30c3 100644 --- a/audio/wavaudio.c +++ b/audio/wavaudio.c @@ -278,7 +278,7 @@ static struct audio_pcm_ops wav_pcm_ops = { .ctl_out = wav_ctl_out, }; -struct audio_driver wav_audio_driver = { +static struct audio_driver wav_audio_driver = { .name = "wav", .descr = "WAV renderer http://wikipedia.org/wiki/WAV", .options = wav_options, @@ -291,3 +291,9 @@ struct audio_driver wav_audio_driver = { .voice_size_out = sizeof (WAVVoiceOut), .voice_size_in = 0 }; + +static void register_audio_wav(void) +{ + audio_driver_register(&wav_audio_driver); +} +type_init(register_audio_wav); @@ -3354,7 +3354,7 @@ else fi glib_modules=gthread-2.0 if test "$modules" = yes; then - glib_modules="$glib_modules gmodule-2.0" + glib_modules="$glib_modules gmodule-export-2.0" fi # This workaround is required due to a bug in pkg-config file for glib as it @@ -5974,7 +5974,12 @@ fi echo "CONFIG_AUDIO_DRIVERS=$audio_drv_list" >> $config_host_mak for drv in $audio_drv_list; do def=CONFIG_AUDIO_$(echo $drv | LC_ALL=C tr '[a-z]' '[A-Z]') - echo "$def=y" >> $config_host_mak + case "$drv" in + alsa | oss | pa | sdl) + echo "$def=m" >> $config_host_mak ;; + *) + echo "$def=y" >> $config_host_mak ;; + esac done echo "ALSA_LIBS=$alsa_libs" >> $config_host_mak echo "PULSE_LIBS=$pulse_libs" >> $config_host_mak diff --git a/hw/display/vga.c b/hw/display/vga.c index 28f298b342..72181330b8 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1483,6 +1483,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) region_start = (s->start_addr * 4); region_end = region_start + (ram_addr_t)s->line_offset * height; + region_end += width * s->get_bpp(s) / 8; /* scanline length */ + region_end -= s->line_offset; if (region_end > s->vbe_size) { /* wraps around (can happen with cirrus vbe modes) */ region_start = 0; diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index ec174309db..65a9196c1a 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -106,10 +106,10 @@ struct USBRedirDevice { USBDevice dev; /* Properties */ CharBackend cs; + bool enable_streams; uint8_t debug; - char *filter_str; int32_t bootindex; - bool enable_streams; + char *filter_str; /* Data passed from chardev the fd_read cb to the usbredirparser read cb */ const uint8_t *read_buf; int read_buf_size; diff --git a/include/block/aio-wait.h b/include/block/aio-wait.h index f7a3972200..8c90a2e66e 100644 --- a/include/block/aio-wait.h +++ b/include/block/aio-wait.h @@ -50,8 +50,8 @@ * } */ typedef struct { - /* Is the main loop waiting for a kick? Accessed with atomic ops. */ - bool need_kick; + /* Number of waiting AIO_WAIT_WHILE() callers. Accessed with atomic ops. */ + unsigned num_waiters; } AioWait; /** @@ -71,35 +71,34 @@ typedef struct { * wait on conditions between two IOThreads since that could lead to deadlock, * go via the main loop instead. */ -#define AIO_WAIT_WHILE(wait, ctx, cond) ({ \ - bool waited_ = false; \ - bool busy_ = true; \ - AioWait *wait_ = (wait); \ - AioContext *ctx_ = (ctx); \ - if (in_aio_context_home_thread(ctx_)) { \ - while ((cond) || busy_) { \ - busy_ = aio_poll(ctx_, (cond)); \ - waited_ |= !!(cond) | busy_; \ - } \ - } else { \ - assert(qemu_get_current_aio_context() == \ - qemu_get_aio_context()); \ - assert(!wait_->need_kick); \ - /* Set wait_->need_kick before evaluating cond. */ \ - atomic_mb_set(&wait_->need_kick, true); \ - while (busy_) { \ - if ((cond)) { \ - waited_ = busy_ = true; \ - aio_context_release(ctx_); \ - aio_poll(qemu_get_aio_context(), true); \ - aio_context_acquire(ctx_); \ - } else { \ - busy_ = aio_poll(ctx_, false); \ - waited_ |= busy_; \ - } \ - } \ - atomic_set(&wait_->need_kick, false); \ - } \ +#define AIO_WAIT_WHILE(wait, ctx, cond) ({ \ + bool waited_ = false; \ + bool busy_ = true; \ + AioWait *wait_ = (wait); \ + AioContext *ctx_ = (ctx); \ + if (in_aio_context_home_thread(ctx_)) { \ + while ((cond) || busy_) { \ + busy_ = aio_poll(ctx_, (cond)); \ + waited_ |= !!(cond) | busy_; \ + } \ + } else { \ + assert(qemu_get_current_aio_context() == \ + qemu_get_aio_context()); \ + /* Increment wait_->num_waiters before evaluating cond. */ \ + atomic_inc(&wait_->num_waiters); \ + while (busy_) { \ + if ((cond)) { \ + waited_ = busy_ = true; \ + aio_context_release(ctx_); \ + aio_poll(qemu_get_aio_context(), true); \ + aio_context_acquire(ctx_); \ + } else { \ + busy_ = aio_poll(ctx_, false); \ + waited_ |= busy_; \ + } \ + } \ + atomic_dec(&wait_->num_waiters); \ + } \ waited_; }) /** diff --git a/include/qemu/log-for-trace.h b/include/qemu/log-for-trace.h new file mode 100644 index 0000000000..2f0a5b080e --- /dev/null +++ b/include/qemu/log-for-trace.h @@ -0,0 +1,35 @@ +/* log-for-trace.h: logging basics required by the trace.h generated + * by the log trace backend. + * + * This should not be included directly by any .c file: if you + * need to use the logging functions include "qemu/log.h". + * + * The purpose of splitting these parts out into their own header + * is to catch the easy mistake where a .c file includes trace.h + * but forgets to include qemu/log.h. Without this split, that + * would result in the .c file compiling fine when the default + * trace backend is in use but failing to compile with any other + * backend. + * + * This code is licensed under the GNU General Public License, + * version 2 or (at your option) any later version. + */ + +#ifndef QEMU_LOG_FOR_TRACE_H +#define QEMU_LOG_FOR_TRACE_H + +/* Private global variable, don't use */ +extern int qemu_loglevel; + +#define LOG_TRACE (1 << 15) + +/* Returns true if a bit is set in the current loglevel mask */ +static inline bool qemu_loglevel_mask(int mask) +{ + return (qemu_loglevel & mask) != 0; +} + +/* main logging function */ +int GCC_FMT_ATTR(1, 2) qemu_log(const char *fmt, ...); + +#endif diff --git a/include/qemu/log.h b/include/qemu/log.h index a50e994c21..ff92a8b86a 100644 --- a/include/qemu/log.h +++ b/include/qemu/log.h @@ -1,10 +1,11 @@ #ifndef QEMU_LOG_H #define QEMU_LOG_H +/* A small part of this API is split into its own header */ +#include "qemu/log-for-trace.h" -/* Private global variables, don't use */ +/* Private global variable, don't use */ extern FILE *qemu_logfile; -extern int qemu_loglevel; /* * The new API: @@ -41,16 +42,9 @@ static inline bool qemu_log_separate(void) #define CPU_LOG_MMU (1 << 12) #define CPU_LOG_TB_NOCHAIN (1 << 13) #define CPU_LOG_PAGE (1 << 14) -#define LOG_TRACE (1 << 15) +/* LOG_TRACE (1 << 15) is defined in log-for-trace.h */ #define CPU_LOG_TB_OP_IND (1 << 16) -/* Returns true if a bit is set in the current loglevel mask - */ -static inline bool qemu_loglevel_mask(int mask) -{ - return (qemu_loglevel & mask) != 0; -} - /* Lock output for a series of related logs. Since this is not needed * for a single qemu_log / qemu_log_mask / qemu_log_mask_and_addr, we * assume that qemu_loglevel_mask has already been tested, and that @@ -69,10 +63,6 @@ static inline void qemu_log_unlock(void) /* Logging functions: */ -/* main logging function - */ -int GCC_FMT_ATTR(1, 2) qemu_log(const char *fmt, ...); - /* vfprintf-like logging function */ static inline void GCC_FMT_ATTR(1, 0) diff --git a/include/qemu/module.h b/include/qemu/module.h index 9fea75aaeb..54300ab6e5 100644 --- a/include/qemu/module.h +++ b/include/qemu/module.h @@ -54,6 +54,7 @@ typedef enum { #define block_module_load_one(lib) module_load_one("block-", lib) #define ui_module_load_one(lib) module_load_one("ui-", lib) +#define audio_module_load_one(lib) module_load_one("audio-", lib) void register_module_init(void (*fn)(void), module_init_type type); void register_dso_module_init(void (*fn)(void), module_init_type type); diff --git a/scripts/create_config b/scripts/create_config index 603b826886..d727e5e36e 100755 --- a/scripts/create_config +++ b/scripts/create_config @@ -36,7 +36,7 @@ case $line in drivers=${line#*=} echo "#define CONFIG_AUDIO_DRIVERS \\" for drv in $drivers; do - echo " &${drv}_audio_driver,\\" + echo " \"${drv}\",\\" done echo "" ;; diff --git a/scripts/simpletrace.py b/scripts/simpletrace.py index a3a6315055..9d45c6ba4e 100755 --- a/scripts/simpletrace.py +++ b/scripts/simpletrace.py @@ -168,7 +168,7 @@ class Analyzer(object): def process(events, log, analyzer, read_header=True): """Invoke an analyzer on each event in a log.""" if isinstance(events, str): - events = read_events(open(events, 'r')) + events = read_events(open(events, 'r'), events) if isinstance(log, str): log = open(log, 'rb') @@ -199,7 +199,7 @@ def process(events, log, analyzer, read_header=True): fn_argcount = len(inspect.getargspec(fn)[0]) - 1 if fn_argcount == event_argcount + 1: # Include timestamp as first argument - return lambda _, rec: fn(*((rec[1:2],) + rec[3:3 + event_argcount])) + return lambda _, rec: fn(*(rec[1:2] + rec[3:3 + event_argcount])) elif fn_argcount == event_argcount + 2: # Include timestamp and pid return lambda _, rec: fn(*rec[1:3 + event_argcount]) @@ -233,7 +233,7 @@ def run(analyzer): '<trace-file>\n' % sys.argv[0]) sys.exit(1) - events = read_events(open(sys.argv[1], 'r')) + events = read_events(open(sys.argv[1], 'r'), sys.argv[1]) process(events, sys.argv[2], analyzer, read_header=read_header) if __name__ == '__main__': diff --git a/scripts/tracetool.py b/scripts/tracetool.py index c55a21518b..fe2b0771f2 100755 --- a/scripts/tracetool.py +++ b/scripts/tracetool.py @@ -142,7 +142,7 @@ def main(args): events = [] for arg in args: with open(arg, "r") as fh: - events.extend(tracetool.read_events(fh)) + events.extend(tracetool.read_events(fh, arg)) try: tracetool.generate(events, arg_group, arg_format, arg_backends, diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 3646c2b9fc..b20fac34a3 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -41,6 +41,51 @@ def out(*lines, **kwargs): lines = [ l % kwargs for l in lines ] sys.stdout.writelines("\n".join(lines) + "\n") +# We only want to allow standard C types or fixed sized +# integer types. We don't want QEMU specific types +# as we can't assume trace backends can resolve all the +# typedefs +ALLOWED_TYPES = [ + "int", + "long", + "short", + "char", + "bool", + "unsigned", + "signed", + "float", + "double", + "int8_t", + "uint8_t", + "int16_t", + "uint16_t", + "int32_t", + "uint32_t", + "int64_t", + "uint64_t", + "void", + "size_t", + "ssize_t", + "uintptr_t", + "ptrdiff_t", + # Magic substitution is done by tracetool + "TCGv", +] + +def validate_type(name): + bits = name.split(" ") + for bit in bits: + bit = re.sub("\*", "", bit) + if bit == "": + continue + if bit == "const": + continue + if bit not in ALLOWED_TYPES: + raise ValueError("Argument type '%s' is not in whitelist. " + "Only standard C types and fixed size integer " + "types should be used. struct, union, and " + "other complex pointer types should be " + "declared as 'void *'" % name) class Arguments: """Event arguments description.""" @@ -87,6 +132,7 @@ class Arguments: else: arg_type, identifier = arg.rsplit(None, 1) + validate_type(arg_type) res.append((arg_type, identifier)) return Arguments(res) @@ -291,13 +337,15 @@ class Event(object): self) -def read_events(fobj): +def read_events(fobj, fname): """Generate the output for the given (format, backends) pair. Parameters ---------- fobj : file Event description file. + fname : str + Name of event file Returns a list of Event objects """ @@ -312,7 +360,7 @@ def read_events(fobj): try: event = Event.build(line) except ValueError as e: - arg0 = 'Error on line %d: %s' % (lineno, e.args[0]) + arg0 = 'Error at %s:%d: %s' % (fname, lineno, e.args[0]) e.args = (arg0,) + e.args[1:] raise diff --git a/scripts/tracetool/backend/log.py b/scripts/tracetool/backend/log.py index da86f6b882..78933d03ad 100644 --- a/scripts/tracetool/backend/log.py +++ b/scripts/tracetool/backend/log.py @@ -20,7 +20,7 @@ PUBLIC = True def generate_h_begin(events, group): - out('#include "qemu/log.h"', + out('#include "qemu/log-for-trace.h"', '') @@ -35,14 +35,13 @@ def generate_h(event, group): else: cond = "trace_event_get_state(%s)" % ("TRACE_" + event.name.upper()) - out(' if (%(cond)s) {', + out(' if (%(cond)s && qemu_loglevel_mask(LOG_TRACE)) {', ' struct timeval _now;', ' gettimeofday(&_now, NULL);', - ' qemu_log_mask(LOG_TRACE,', - ' "%%d@%%zd.%%06zd:%(name)s " %(fmt)s "\\n",', - ' getpid(),', - ' (size_t)_now.tv_sec, (size_t)_now.tv_usec', - ' %(argnames)s);', + ' qemu_log("%%d@%%zd.%%06zd:%(name)s " %(fmt)s "\\n",', + ' getpid(),', + ' (size_t)_now.tv_sec, (size_t)_now.tv_usec', + ' %(argnames)s);', ' }', cond=cond, name=event.name, diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker index 994a35a332..a00004319e 100644 --- a/tests/docker/dockerfiles/fedora.docker +++ b/tests/docker/dockerfiles/fedora.docker @@ -2,7 +2,7 @@ FROM fedora:27 ENV PACKAGES \ ccache gettext git tar PyYAML sparse flex bison python3 bzip2 hostname \ glib2-devel pixman-devel zlib-devel SDL-devel libfdt-devel \ - gcc gcc-c++ clang make perl which bc findutils libaio-devel \ + gcc gcc-c++ llvm clang make perl which bc findutils libaio-devel \ nettle-devel libasan libubsan \ mingw32-pixman mingw32-glib2 mingw32-gmp mingw32-SDL mingw32-pkg-config \ mingw32-gtk2 mingw32-gtk3 mingw32-gnutls mingw32-nettle mingw32-libtasn1 \ diff --git a/tests/docker/test-debug b/tests/docker/test-debug index d020b06917..d3f9f70d01 100755 --- a/tests/docker/test-debug +++ b/tests/docker/test-debug @@ -1,6 +1,6 @@ #!/bin/bash -e # -# Compile and check with clang & --enable-debug. +# Compile and check with clang & --enable-debug --enable-sanitizers. # # Copyright (c) 2016-2018 Red Hat Inc. # @@ -19,8 +19,8 @@ requires clang asan cd "$BUILD_DIR" OPTS="--cxx=clang++ --cc=clang --host-cc=clang" -OPTS="--enable-debug $OPTS" +OPTS="--enable-debug --enable-sanitizers $OPTS" build_qemu $OPTS -make $MAKEFLAGS check +make $MAKEFLAGS V=1 check install_qemu diff --git a/trace-events b/trace-events index 89fcad0fd1..855b0ab240 100644 --- a/trace-events +++ b/trace-events @@ -68,9 +68,9 @@ memory_region_tb_read(int cpu_index, uint64_t addr, uint64_t value, unsigned siz memory_region_tb_write(int cpu_index, uint64_t addr, uint64_t value, unsigned size) "cpu %d addr 0x%"PRIx64" value 0x%"PRIx64" size %u" memory_region_ram_device_read(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u" memory_region_ram_device_write(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u" -flatview_new(FlatView *view, MemoryRegion *root) "%p (root %p)" -flatview_destroy(FlatView *view, MemoryRegion *root) "%p (root %p)" -flatview_destroy_rcu(FlatView *view, MemoryRegion *root) "%p (root %p)" +flatview_new(void *view, void *root) "%p (root %p)" +flatview_destroy(void *view, void *root) "%p (root %p)" +flatview_destroy_rcu(void *view, void *root) "%p (root %p)" # gdbstub.c gdbstub_op_start(const char *device) "Starting gdbstub using device %s" diff --git a/util/aio-wait.c b/util/aio-wait.c index 975afddf4c..b8a8f86dba 100644 --- a/util/aio-wait.c +++ b/util/aio-wait.c @@ -34,7 +34,7 @@ static void dummy_bh_cb(void *opaque) void aio_wait_kick(AioWait *wait) { /* The barrier (or an atomic op) is in the caller. */ - if (atomic_read(&wait->need_kick)) { + if (atomic_read(&wait->num_waiters)) { aio_bh_schedule_oneshot(qemu_get_aio_context(), dummy_bh_cb, NULL); } } |