diff options
40 files changed, 474 insertions, 285 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 35d4496186..6115e4ec08 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -480,7 +480,7 @@ S: Maintained F: tcg/ia64/ MIPS target -M: Aurelien Jarno <aurelien@aurel32.ne> +M: Aurelien Jarno <aurelien@aurel32.net> S: Maintained F: tcg/mips/ diff --git a/arm-semi.c b/arm-semi.c index e9e6f8993f..5a62d03b36 100644 --- a/arm-semi.c +++ b/arm-semi.c @@ -440,15 +440,16 @@ uint32_t do_arm_semihosting(CPUState *env) /* Some C libraries assume the heap immediately follows .bss, so allocate it using sbrk. */ if (!ts->heap_limit) { - long ret; + abi_ulong ret; ts->heap_base = do_brk(0); limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE; /* Try a big heap, and reduce the size if that fails. */ for (;;) { ret = do_brk(limit); - if (ret != -1) + if (ret >= limit) { break; + } limit = (ts->heap_base >> 1) + (limit >> 1); } ts->heap_limit = limit; diff --git a/block-migration.c b/block-migration.c index 8d06a23649..0936c7d5ea 100644 --- a/block-migration.c +++ b/block-migration.c @@ -671,7 +671,7 @@ static int block_load(QEMUFile *f, void *opaque, int version_id) bs_prev = bs; total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS; if (total_sectors <= 0) { - error_report("Error getting length of block device %s\n", + error_report("Error getting length of block device %s", device_name); return -EINVAL; } diff --git a/block/qcow2.c b/block/qcow2.c index 2c51e7ccbd..48e1b95689 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -936,7 +936,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, (1 << cluster_bits) != cluster_size) { error_report( - "Cluster size must be a power of two between %d and %dk\n", + "Cluster size must be a power of two between %d and %dk", 1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - 10)); return -EINVAL; } diff --git a/block/sheepdog.c b/block/sheepdog.c index 0392ca8c9c..80d106c2b2 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -444,18 +444,12 @@ static SheepdogAIOCB *sd_aio_setup(BlockDriverState *bs, QEMUIOVector *qiov, static int sd_schedule_bh(QEMUBHFunc *cb, SheepdogAIOCB *acb) { if (acb->bh) { - error_report("bug: %d %d\n", acb->aiocb_type, acb->aiocb_type); + error_report("bug: %d %d", acb->aiocb_type, acb->aiocb_type); return -EIO; } acb->bh = qemu_bh_new(cb, acb); - if (!acb->bh) { - error_report("oom: %d %d\n", acb->aiocb_type, acb->aiocb_type); - return -EIO; - } - qemu_bh_schedule(acb->bh); - return 0; } @@ -598,7 +592,7 @@ static int connect_to_sdog(const char *addr, const char *port) ret = getaddrinfo(addr, port, &hints, &res0); if (ret) { - error_report("unable to get address info %s, %s\n", + error_report("unable to get address info %s, %s", addr, strerror(errno)); return -1; } @@ -628,7 +622,7 @@ static int connect_to_sdog(const char *addr, const char *port) goto success; } fd = -1; - error_report("failed connect to %s:%s\n", addr, port); + error_report("failed connect to %s:%s", addr, port); success: freeaddrinfo(res0); return fd; @@ -644,7 +638,7 @@ again: if (errno == EINTR || errno == EAGAIN) { goto again; } - error_report("failed to recv a rsp, %s\n", strerror(errno)); + error_report("failed to recv a rsp, %s", strerror(errno)); return 1; } @@ -703,7 +697,7 @@ static int send_req(int sockfd, SheepdogReq *hdr, void *data, ret = do_writev(sockfd, iov, sizeof(*hdr) + *wlen, 0); if (ret) { - error_report("failed to send a req, %s\n", strerror(errno)); + error_report("failed to send a req, %s", strerror(errno)); ret = -1; } @@ -723,7 +717,7 @@ static int do_req(int sockfd, SheepdogReq *hdr, void *data, ret = do_read(sockfd, hdr, sizeof(*hdr)); if (ret) { - error_report("failed to get a rsp, %s\n", strerror(errno)); + error_report("failed to get a rsp, %s", strerror(errno)); ret = -1; goto out; } @@ -735,7 +729,7 @@ static int do_req(int sockfd, SheepdogReq *hdr, void *data, if (*rlen) { ret = do_read(sockfd, data, *rlen); if (ret) { - error_report("failed to get the data, %s\n", strerror(errno)); + error_report("failed to get the data, %s", strerror(errno)); ret = -1; goto out; } @@ -772,7 +766,7 @@ static void send_pending_req(BDRVSheepdogState *s, uint64_t oid, uint32_t id) ret = add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov, 0, acb->aiocb_type); if (ret < 0) { - error_report("add_aio_request is failed\n"); + error_report("add_aio_request is failed"); free_aio_req(s, aio_req); if (QLIST_EMPTY(&acb->aioreq_head)) { sd_finish_aiocb(acb); @@ -805,7 +799,7 @@ static void aio_read_response(void *opaque) /* read a header */ ret = do_read(fd, &rsp, sizeof(rsp)); if (ret) { - error_report("failed to get the header, %s\n", strerror(errno)); + error_report("failed to get the header, %s", strerror(errno)); return; } @@ -816,7 +810,7 @@ static void aio_read_response(void *opaque) } } if (!aio_req) { - error_report("cannot find aio_req %x\n", rsp.id); + error_report("cannot find aio_req %x", rsp.id); return; } @@ -852,7 +846,7 @@ static void aio_read_response(void *opaque) ret = do_readv(fd, acb->qiov->iov, rsp.data_length, aio_req->iov_offset); if (ret) { - error_report("failed to get the data, %s\n", strerror(errno)); + error_report("failed to get the data, %s", strerror(errno)); return; } break; @@ -860,7 +854,7 @@ static void aio_read_response(void *opaque) if (rsp.result != SD_RES_SUCCESS) { acb->ret = -EIO; - error_report("%s\n", sd_strerror(rsp.result)); + error_report("%s", sd_strerror(rsp.result)); } rest = free_aio_req(s, aio_req); @@ -917,7 +911,7 @@ static int get_sheep_fd(BDRVSheepdogState *s) fd = connect_to_sdog(s->addr, s->port); if (fd < 0) { - error_report("%s\n", strerror(errno)); + error_report("%s", strerror(errno)); return -1; } @@ -925,7 +919,7 @@ static int get_sheep_fd(BDRVSheepdogState *s) ret = set_nodelay(fd); if (ret) { - error_report("%s\n", strerror(errno)); + error_report("%s", strerror(errno)); closesocket(fd); return -1; } @@ -1041,7 +1035,7 @@ static int find_vdi_name(BDRVSheepdogState *s, char *filename, uint32_t snapid, } if (rsp->result != SD_RES_SUCCESS) { - error_report("cannot get vdi info, %s, %s %d %s\n", + error_report("cannot get vdi info, %s, %s %d %s", sd_strerror(rsp->result), filename, snapid, tag); ret = -1; goto out; @@ -1069,7 +1063,7 @@ static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, uint64_t old_oid = aio_req->base_oid; if (!nr_copies) { - error_report("bug\n"); + error_report("bug"); } memset(&hdr, 0, sizeof(hdr)); @@ -1102,14 +1096,14 @@ static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, /* send a header */ ret = do_write(s->fd, &hdr, sizeof(hdr)); if (ret) { - error_report("failed to send a req, %s\n", strerror(errno)); + error_report("failed to send a req, %s", strerror(errno)); return -EIO; } if (wlen) { ret = do_writev(s->fd, iov, wlen, aio_req->iov_offset); if (ret) { - error_report("failed to send a data, %s\n", strerror(errno)); + error_report("failed to send a data, %s", strerror(errno)); return -EIO; } } @@ -1151,7 +1145,7 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies, ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen); if (ret) { - error_report("failed to send a request to the sheep\n"); + error_report("failed to send a request to the sheep"); return -1; } @@ -1159,7 +1153,7 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies, case SD_RES_SUCCESS: return 0; default: - error_report("%s\n", sd_strerror(rsp->result)); + error_report("%s", sd_strerror(rsp->result)); return -1; } } @@ -1212,7 +1206,7 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags) fd = connect_to_sdog(s->addr, s->port); if (fd < 0) { - error_report("failed to connect\n"); + error_report("failed to connect"); goto out; } @@ -1281,7 +1275,7 @@ static int do_sd_create(char *filename, int64_t vdi_size, } if (rsp->result != SD_RES_SUCCESS) { - error_report("%s, %s\n", sd_strerror(rsp->result), filename); + error_report("%s, %s", sd_strerror(rsp->result), filename); return -EIO; } @@ -1308,7 +1302,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options) memset(vdi, 0, sizeof(vdi)); memset(tag, 0, sizeof(tag)); if (parse_vdiname(&s, filename, vdi, &snapid, tag) < 0) { - error_report("invalid filename\n"); + error_report("invalid filename"); return -EINVAL; } @@ -1322,7 +1316,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options) } if (vdi_size > SD_MAX_VDI_SIZE) { - error_report("too big image size\n"); + error_report("too big image size"); return -EINVAL; } @@ -1334,7 +1328,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options) /* Currently, only Sheepdog backing image is supported. */ drv = bdrv_find_protocol(backing_file); if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) { - error_report("backing_file must be a sheepdog image\n"); + error_report("backing_file must be a sheepdog image"); return -EINVAL; } @@ -1345,7 +1339,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options) s = bs->opaque; if (!is_snapshot(&s->inode)) { - error_report("cannot clone from a non snapshot vdi\n"); + error_report("cannot clone from a non snapshot vdi"); bdrv_delete(bs); return -EINVAL; } @@ -1385,7 +1379,7 @@ static void sd_close(BlockDriverState *bs) if (!ret && rsp->result != SD_RES_SUCCESS && rsp->result != SD_RES_VDI_NOT_LOCKED) { - error_report("%s, %s\n", sd_strerror(rsp->result), s->name); + error_report("%s, %s", sd_strerror(rsp->result), s->name); } qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL, NULL); @@ -1407,10 +1401,10 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset) unsigned int datalen; if (offset < s->inode.vdi_size) { - error_report("shrinking is not supported\n"); + error_report("shrinking is not supported"); return -EINVAL; } else if (offset > SD_MAX_VDI_SIZE) { - error_report("too big image size\n"); + error_report("too big image size"); return -EINVAL; } @@ -1427,7 +1421,7 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset) close(fd); if (ret < 0) { - error_report("failed to update an inode.\n"); + error_report("failed to update an inode."); return -EIO; } @@ -1500,7 +1494,7 @@ static int sd_create_branch(BDRVSheepdogState *s) fd = connect_to_sdog(s->addr, s->port); if (fd < 0) { - error_report("failed to connect\n"); + error_report("failed to connect"); goto out; } @@ -1618,7 +1612,7 @@ static void sd_readv_writev_bh_cb(void *p) ret = add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov, create, acb->aiocb_type); if (ret < 0) { - error_report("add_aio_request is failed\n"); + error_report("add_aio_request is failed"); free_aio_req(s, aio_req); acb->ret = -EIO; goto out; @@ -1695,7 +1689,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) if (s->is_snapshot) { error_report("You can't create a snapshot of a snapshot VDI, " - "%s (%" PRIu32 ").\n", s->name, s->inode.vdi_id); + "%s (%" PRIu32 ").", s->name, s->inode.vdi_id); return -EINVAL; } @@ -1718,7 +1712,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id), s->inode.nr_copies, datalen, 0, 0); if (ret < 0) { - error_report("failed to write snapshot's inode.\n"); + error_report("failed to write snapshot's inode."); ret = -EIO; goto cleanup; } @@ -1726,7 +1720,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) ret = do_sd_create(s->name, s->inode.vdi_size, s->inode.vdi_id, &new_vid, 1, s->addr, s->port); if (ret < 0) { - error_report("failed to create inode for snapshot. %s\n", + error_report("failed to create inode for snapshot. %s", strerror(errno)); ret = -EIO; goto cleanup; @@ -1738,7 +1732,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) s->inode.nr_copies, datalen, 0); if (ret < 0) { - error_report("failed to read new inode info. %s\n", strerror(errno)); + error_report("failed to read new inode info. %s", strerror(errno)); ret = -EIO; goto cleanup; } @@ -1777,14 +1771,14 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) ret = find_vdi_name(s, vdi, snapid, tag, &vid, 1); if (ret) { - error_report("Failed to find_vdi_name\n"); + error_report("Failed to find_vdi_name"); ret = -ENOENT; goto out; } fd = connect_to_sdog(s->addr, s->port); if (fd < 0) { - error_report("failed to connect\n"); + error_report("failed to connect"); goto out; } @@ -1802,7 +1796,7 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) memcpy(&s->inode, buf, sizeof(s->inode)); if (!s->inode.vm_state_size) { - error_report("Invalid snapshot\n"); + error_report("Invalid snapshot"); ret = -ENOENT; goto out; } @@ -1819,7 +1813,7 @@ out: qemu_free(buf); qemu_free(old_s); - error_report("failed to open. recover old bdrv_sd_state.\n"); + error_report("failed to open. recover old bdrv_sd_state."); return ret; } @@ -1874,7 +1868,7 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) fd = connect_to_sdog(s->addr, s->port); if (fd < 0) { - error_report("failed to connect\n"); + error_report("failed to connect"); goto out; } @@ -1948,7 +1942,7 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data, } if (ret < 0) { - error_report("failed to save vmstate %s\n", strerror(errno)); + error_report("failed to save vmstate %s", strerror(errno)); ret = -EIO; goto cleanup; } diff --git a/blockdev.c b/blockdev.c index 1502575acb..7d579d6124 100644 --- a/blockdev.c +++ b/blockdev.c @@ -293,7 +293,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi) if ((buf = qemu_opt_get(opts, "trans")) != NULL) { if (!cyls) { - error_report("'%s' trans must be used with cyls,heads and secs", + error_report("'%s' trans must be used with cyls, heads and secs", buf); return NULL; } @@ -1640,7 +1640,7 @@ for drv in $audio_drv_list; do pa) audio_drv_probe $drv pulse/simple.h "-lpulse-simple -lpulse" \ - "pa_simple *s = NULL; pa_simple_free(s); return 0;" + "pa_simple *s = 0; pa_simple_free(s); return 0;" libs_softmmu="-lpulse -lpulse-simple $libs_softmmu" audio_pt_int="yes" ;; @@ -3483,7 +3483,9 @@ for bios_file in $source_path/pc-bios/*.bin $source_path/pc-bios/*.rom $source_p done mkdir -p $DIRS for f in $FILES ; do - test -e $f || symlink $source_path/$f $f + if [ -e "$source_path/$f" ] && ! [ -e "$f" ]; then + symlink "$source_path/$f" "$f" + fi done # temporary config to build submodules @@ -1349,8 +1349,15 @@ static struct DisplayAllocator default_allocator = { static void dumb_display_init(void) { DisplayState *ds = qemu_mallocz(sizeof(DisplayState)); + int width = 640; + int height = 480; + ds->allocator = &default_allocator; - ds->surface = qemu_create_displaysurface(ds, 640, 480); + if (is_fixedsize_console()) { + width = active_console->g_width; + height = active_console->g_height; + } + ds->surface = qemu_create_displaysurface(ds, width, height); register_displaystate(ds); } @@ -33,7 +33,10 @@ #include "qemu-thread.h" #include "cpus.h" + +#ifndef _WIN32 #include "compatfd.h" +#endif #ifdef SIGRTMIN #define SIG_IPI (SIGRTMIN+4) @@ -1207,12 +1207,16 @@ static inline void tb_alloc_page(TranslationBlock *tb, unsigned int n, tb_page_addr_t page_addr) { PageDesc *p; - TranslationBlock *last_first_tb; +#ifndef CONFIG_USER_ONLY + bool page_already_protected; +#endif tb->page_addr[n] = page_addr; p = page_find_alloc(page_addr >> TARGET_PAGE_BITS, 1); tb->page_next[n] = p->first_tb; - last_first_tb = p->first_tb; +#ifndef CONFIG_USER_ONLY + page_already_protected = p->first_tb != NULL; +#endif p->first_tb = (TranslationBlock *)((long)tb | n); invalidate_page_bitmap(p); @@ -1248,7 +1252,7 @@ static inline void tb_alloc_page(TranslationBlock *tb, /* if some code is already present, then the pages are already protected. So we handle the case where only the first TB is allocated in a physical page */ - if (!last_first_tb) { + if (!page_already_protected) { tlb_protect_code(page_addr); } #endif diff --git a/hw/armv7m.c b/hw/armv7m.c index 72d010a63b..83f3393eab 100644 --- a/hw/armv7m.c +++ b/hw/armv7m.c @@ -4,7 +4,7 @@ * Copyright (c) 2006-2007 CodeSourcery. * Written by Paul Brook * - * This code is licenced under the GPL. + * This code is licensed under the GPL. */ #include "sysbus.h" @@ -14,7 +14,7 @@ /* Bitbanded IO. Each word corresponds to a single bit. */ -/* Get the byte address of the real memory for a bitband acess. */ +/* Get the byte address of the real memory for a bitband access. */ static inline uint32_t bitband_addr(void * opaque, uint32_t addr) { uint32_t res; diff --git a/hw/lm32_sys.c b/hw/lm32_sys.c index 427b05fe1a..e5ff962f43 100644 --- a/hw/lm32_sys.c +++ b/hw/lm32_sys.c @@ -83,7 +83,7 @@ static void sys_write(void *opaque, target_phys_addr_t addr, uint32_t value) break; default: - error_report("lm32_sys: write access to unkown register 0x" + error_report("lm32_sys: write access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } diff --git a/hw/lm32_timer.c b/hw/lm32_timer.c index ed289847ac..49cbb22993 100644 --- a/hw/lm32_timer.c +++ b/hw/lm32_timer.c @@ -86,7 +86,7 @@ static uint32_t timer_read(void *opaque, target_phys_addr_t addr) r = (uint32_t)ptimer_get_count(s->ptimer); break; default: - error_report("lm32_timer: read access to unkown register 0x" + error_report("lm32_timer: read access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } @@ -124,7 +124,7 @@ static void timer_write(void *opaque, target_phys_addr_t addr, uint32_t value) TARGET_FMT_plx, addr << 2); break; default: - error_report("lm32_timer: write access to unkown register 0x" + error_report("lm32_timer: write access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c index e225087b99..09090e93b2 100644 --- a/hw/lm32_uart.c +++ b/hw/lm32_uart.c @@ -149,7 +149,7 @@ static uint32_t uart_read(void *opaque, target_phys_addr_t addr) TARGET_FMT_plx, addr << 2); break; default: - error_report("lm32_uart: read access to unkown register 0x" + error_report("lm32_uart: read access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } @@ -185,7 +185,7 @@ static void uart_write(void *opaque, target_phys_addr_t addr, uint32_t value) TARGET_FMT_plx, addr << 2); break; default: - error_report("lm32_uart: write access to unkown register 0x" + error_report("lm32_uart: write access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } diff --git a/hw/milkymist-ac97.c b/hw/milkymist-ac97.c index 6c9e318aa2..6104732f7d 100644 --- a/hw/milkymist-ac97.c +++ b/hw/milkymist-ac97.c @@ -103,7 +103,7 @@ static uint32_t ac97_read(void *opaque, target_phys_addr_t addr) break; default: - error_report("milkymist_ac97: read access to unkown register 0x" + error_report("milkymist_ac97: read access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } @@ -152,7 +152,7 @@ static void ac97_write(void *opaque, target_phys_addr_t addr, uint32_t value) break; default: - error_report("milkymist_ac97: write access to unkown register 0x" + error_report("milkymist_ac97: write access to unknown register 0x" TARGET_FMT_plx, addr); break; } diff --git a/hw/milkymist-memcard.c b/hw/milkymist-memcard.c index 06077af82a..22dc377d79 100644 --- a/hw/milkymist-memcard.c +++ b/hw/milkymist-memcard.c @@ -154,7 +154,7 @@ static uint32_t memcard_read(void *opaque, target_phys_addr_t addr) break; default: - error_report("milkymist_memcard: read access to unkown register 0x" + error_report("milkymist_memcard: read access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } @@ -210,7 +210,7 @@ static void memcard_write(void *opaque, target_phys_addr_t addr, uint32_t value) break; default: - error_report("milkymist_memcard: write access to unkown register 0x" + error_report("milkymist_memcard: write access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } diff --git a/hw/milkymist-minimac2.c b/hw/milkymist-minimac2.c index c4e28187b3..cd360264c1 100644 --- a/hw/milkymist-minimac2.c +++ b/hw/milkymist-minimac2.c @@ -234,20 +234,20 @@ static void minimac2_tx(MilkymistMinimac2State *s) uint8_t *buf = s->tx_buf; if (txcount < 64) { - error_report("milkymist_minimac2: ethernet frame too small (%u < %u)\n", + error_report("milkymist_minimac2: ethernet frame too small (%u < %u)", txcount, 64); goto err; } if (txcount > MINIMAC2_MTU) { - error_report("milkymist_minimac2: MTU exceeded (%u > %u)\n", + error_report("milkymist_minimac2: MTU exceeded (%u > %u)", txcount, MINIMAC2_MTU); goto err; } if (memcmp(buf, preamble_sfd, 8) != 0) { error_report("milkymist_minimac2: frame doesn't contain the preamble " - "and/or the SFD (%02x %02x %02x %02x %02x %02x %02x %02x)\n", + "and/or the SFD (%02x %02x %02x %02x %02x %02x %02x %02x)", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); goto err; } diff --git a/hw/milkymist-pfpu.c b/hw/milkymist-pfpu.c index 94e631510f..306d1ce287 100644 --- a/hw/milkymist-pfpu.c +++ b/hw/milkymist-pfpu.c @@ -301,7 +301,7 @@ static int pfpu_decode_insn(MilkymistPFPUState *s) } break; default: - error_report("milkymist_pfpu: unknown opcode %d\n", op); + error_report("milkymist_pfpu: unknown opcode %d", op); break; } @@ -358,7 +358,7 @@ static void pfpu_start(MilkymistPFPUState *s) /* decode at most MICROCODE_WORDS instructions */ if (i++ >= MICROCODE_WORDS) { error_report("milkymist_pfpu: too many instructions " - "executed in microcode. No VECTOUT?\n"); + "executed in microcode. No VECTOUT?"); break; } } diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c index 028f3b79ac..5ab35c3827 100644 --- a/hw/milkymist-softusb.c +++ b/hw/milkymist-softusb.c @@ -131,7 +131,7 @@ static inline void softusb_read_dmem(MilkymistSoftUsbState *s, { if (offset + len >= s->dmem_size) { error_report("milkymist_softusb: read dmem out of bounds " - "at offset 0x%x, len %d\n", offset, len); + "at offset 0x%x, len %d", offset, len); return; } @@ -143,7 +143,7 @@ static inline void softusb_write_dmem(MilkymistSoftUsbState *s, { if (offset + len >= s->dmem_size) { error_report("milkymist_softusb: write dmem out of bounds " - "at offset 0x%x, len %d\n", offset, len); + "at offset 0x%x, len %d", offset, len); return; } @@ -155,7 +155,7 @@ static inline void softusb_read_pmem(MilkymistSoftUsbState *s, { if (offset + len >= s->pmem_size) { error_report("milkymist_softusb: read pmem out of bounds " - "at offset 0x%x, len %d\n", offset, len); + "at offset 0x%x, len %d", offset, len); return; } @@ -167,7 +167,7 @@ static inline void softusb_write_pmem(MilkymistSoftUsbState *s, { if (offset + len >= s->pmem_size) { error_report("milkymist_softusb: write pmem out of bounds " - "at offset 0x%x, len %d\n", offset, len); + "at offset 0x%x, len %d", offset, len); return; } diff --git a/hw/milkymist-sysctl.c b/hw/milkymist-sysctl.c index 6bd0cb9740..7b2d544ac3 100644 --- a/hw/milkymist-sysctl.c +++ b/hw/milkymist-sysctl.c @@ -119,7 +119,7 @@ static uint32_t sysctl_read(void *opaque, target_phys_addr_t addr) break; default: - error_report("milkymist_sysctl: read access to unkown register 0x" + error_report("milkymist_sysctl: read access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } @@ -189,7 +189,7 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint32_t value) break; default: - error_report("milkymist_sysctl: write access to unkown register 0x" + error_report("milkymist_sysctl: write access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } diff --git a/hw/milkymist-tmu2.c b/hw/milkymist-tmu2.c index 9cebe3173b..790cdcb41c 100644 --- a/hw/milkymist-tmu2.c +++ b/hw/milkymist-tmu2.c @@ -352,21 +352,21 @@ static uint32_t tmu2_read(void *opaque, target_phys_addr_t addr) static void tmu2_check_registers(MilkymistTMU2State *s) { if (s->regs[R_BRIGHTNESS] > MAX_BRIGHTNESS) { - error_report("milkymist_tmu2: max brightness is %d\n", MAX_BRIGHTNESS); + error_report("milkymist_tmu2: max brightness is %d", MAX_BRIGHTNESS); } if (s->regs[R_ALPHA] > MAX_ALPHA) { - error_report("milkymist_tmu2: max alpha is %d\n", MAX_ALPHA); + error_report("milkymist_tmu2: max alpha is %d", MAX_ALPHA); } if (s->regs[R_VERTICESADDR] & 0x07) { error_report("milkymist_tmu2: vertex mesh address has to be 64-bit " - "aligned\n"); + "aligned"); } if (s->regs[R_TEXFBUF] & 0x01) { error_report("milkymist_tmu2: texture buffer address has to be " - "16-bit aligned\n"); + "16-bit aligned"); } } @@ -371,7 +371,7 @@ void qdev_init_nofail(DeviceState *dev) DeviceInfo *info = dev->info; if (qdev_init(dev) < 0) { - error_report("Initialization of device %s failed\n", info->name); + error_report("Initialization of device %s failed", info->name); exit(1); } } diff --git a/hw/strongarm.c b/hw/strongarm.c index de08bdf674..0e03d61a1f 100644 --- a/hw/strongarm.c +++ b/hw/strongarm.c @@ -1536,14 +1536,14 @@ StrongARMState *sa1110_init(unsigned int sdram_size, const char *rev) } if (strncmp(rev, "sa1110", 6)) { - error_report("Machine requires a SA1110 processor.\n"); + error_report("Machine requires a SA1110 processor."); exit(1); } s->env = cpu_init(rev); if (!s->env) { - error_report("Unable to find CPU definition\n"); + error_report("Unable to find CPU definition"); exit(1); } diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c index 59c6431676..524b841da1 100644 --- a/hw/usb-ccid.c +++ b/hw/usb-ccid.c @@ -1240,7 +1240,7 @@ static int ccid_card_init(DeviceState *qdev, DeviceInfo *base) return -1; } if (s->card != NULL) { - error_report("Warning: usb-ccid card already full, not adding\n"); + error_report("Warning: usb-ccid card already full, not adding"); return -1; } ret = info->initfn ? info->initfn(card) : ret; diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c index 7cedf1855d..7f6db7bffe 100644 --- a/hw/virtio-serial-bus.c +++ b/hw/virtio-serial-bus.c @@ -330,7 +330,7 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len) if (cpkt.event == VIRTIO_CONSOLE_DEVICE_READY) { if (!cpkt.value) { - error_report("virtio-serial-bus: Guest failure in adding device %s\n", + error_report("virtio-serial-bus: Guest failure in adding device %s", vser->bus.qbus.name); return; } @@ -356,7 +356,7 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len) switch(cpkt.event) { case VIRTIO_CONSOLE_PORT_READY: if (!cpkt.value) { - error_report("virtio-serial-bus: Guest failure in adding port %u for device %s\n", + error_report("virtio-serial-bus: Guest failure in adding port %u for device %s", port->id, vser->bus.qbus.name); break; } @@ -745,7 +745,7 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base) plugging_port0 = info->is_console && !find_port_by_id(port->vser, 0); if (find_port_by_id(port->vser, port->id)) { - error_report("virtio-serial-bus: A port already exists at id %u\n", + error_report("virtio-serial-bus: A port already exists at id %u", port->id); return -1; } @@ -756,7 +756,7 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base) } else { port->id = find_free_port_id(port->vser); if (port->id == VIRTIO_CONSOLE_BAD_ID) { - error_report("virtio-serial-bus: Maximum port limit for this device reached\n"); + error_report("virtio-serial-bus: Maximum port limit for this device reached"); return -1; } } @@ -764,7 +764,7 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base) max_nr_ports = tswap32(port->vser->config.max_nr_ports); if (port->id >= max_nr_ports) { - error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u\n", + error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u", max_nr_ports - 1); return -1; } diff --git a/hw/virtio.c b/hw/virtio.c index e6043de827..cc47a06a4e 100644 --- a/hw/virtio.c +++ b/hw/virtio.c @@ -797,7 +797,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f) /* Check it isn't doing very strange things with descriptor numbers. */ if (nheads > vdev->vq[i].vring.num) { error_report("VQ %d size 0x%x Guest index 0x%x " - "inconsistent with Host index 0x%x: delta 0x%x\n", + "inconsistent with Host index 0x%x: delta 0x%x", i, vdev->vq[i].vring.num, vring_avail_idx(&vdev->vq[i]), vdev->vq[i].last_avail_idx, nheads); @@ -805,7 +805,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f) } } else if (vdev->vq[i].last_avail_idx) { error_report("VQ %d address 0x0 " - "inconsistent with Host index 0x%x\n", + "inconsistent with Host index 0x%x", i, vdev->vq[i].last_avail_idx); return -1; } diff --git a/linux-user/elfload.c b/linux-user/elfload.c index dcfeb7a286..b2746f2558 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -927,7 +927,7 @@ struct exec #define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1)) #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1)) -#define DLINFO_ITEMS 12 +#define DLINFO_ITEMS 13 static inline void memcpy_fromfs(void * to, const void * from, unsigned long n) { @@ -1202,6 +1202,9 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, { abi_ulong sp; int size; + int i; + abi_ulong u_rand_bytes; + uint8_t k_rand_bytes[16]; abi_ulong u_platform; const char *k_platform; const int n = sizeof(elf_addr_t); @@ -1231,6 +1234,20 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, /* FIXME - check return value of memcpy_to_target() for failure */ memcpy_to_target(sp, k_platform, len); } + + /* + * Generate 16 random bytes for userspace PRNG seeding (not + * cryptically secure but it's not the aim of QEMU). + */ + srand((unsigned int) time(NULL)); + for (i = 0; i < 16; i++) { + k_rand_bytes[i] = rand(); + } + sp -= 16; + u_rand_bytes = sp; + /* FIXME - check return value of memcpy_to_target() for failure */ + memcpy_to_target(sp, k_rand_bytes, 16); + /* * Force 16 byte _final_ alignment here for generality. */ @@ -1271,6 +1288,8 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid()); NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP); NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK)); + NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes); + if (k_platform) NEW_AUX_ENT(AT_PLATFORM, u_platform); #ifdef ARCH_DLINFO @@ -1288,6 +1307,78 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, return sp; } +static void probe_guest_base(const char *image_name, + abi_ulong loaddr, abi_ulong hiaddr) +{ + /* Probe for a suitable guest base address, if the user has not set + * it explicitly, and set guest_base appropriately. + * In case of error we will print a suitable message and exit. + */ +#if defined(CONFIG_USE_GUEST_BASE) + const char *errmsg; + if (!have_guest_base && !reserved_va) { + unsigned long host_start, real_start, host_size; + + /* Round addresses to page boundaries. */ + loaddr &= qemu_host_page_mask; + hiaddr = HOST_PAGE_ALIGN(hiaddr); + + if (loaddr < mmap_min_addr) { + host_start = HOST_PAGE_ALIGN(mmap_min_addr); + } else { + host_start = loaddr; + if (host_start != loaddr) { + errmsg = "Address overflow loading ELF binary"; + goto exit_errmsg; + } + } + host_size = hiaddr - loaddr; + while (1) { + /* Do not use mmap_find_vma here because that is limited to the + guest address space. We are going to make the + guest address space fit whatever we're given. */ + real_start = (unsigned long) + mmap((void *)host_start, host_size, PROT_NONE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0); + if (real_start == (unsigned long)-1) { + goto exit_perror; + } + if (real_start == host_start) { + break; + } + /* That address didn't work. Unmap and try a different one. + The address the host picked because is typically right at + the top of the host address space and leaves the guest with + no usable address space. Resort to a linear search. We + already compensated for mmap_min_addr, so this should not + happen often. Probably means we got unlucky and host + address space randomization put a shared library somewhere + inconvenient. */ + munmap((void *)real_start, host_size); + host_start += qemu_host_page_size; + if (host_start == loaddr) { + /* Theoretically possible if host doesn't have any suitably + aligned areas. Normally the first mmap will fail. */ + errmsg = "Unable to find space for application"; + goto exit_errmsg; + } + } + qemu_log("Relocating guest address space from 0x" + TARGET_ABI_FMT_lx " to 0x%lx\n", + loaddr, real_start); + guest_base = real_start - loaddr; + } + return; + +exit_perror: + errmsg = strerror(errno); +exit_errmsg: + fprintf(stderr, "%s: %s\n", image_name, errmsg); + exit(-1); +#endif +} + + /* Load an ELF image into the address space. IMAGE_NAME is the filename of the image, to use in error messages. @@ -1373,63 +1464,7 @@ static void load_elf_image(const char *image_name, int image_fd, /* This is the main executable. Make sure that the low address does not conflict with MMAP_MIN_ADDR or the QEMU application itself. */ -#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 && !reserved_va) { - unsigned long host_start, real_start, host_size; - - /* Round addresses to page boundaries. */ - loaddr &= qemu_host_page_mask; - hiaddr = HOST_PAGE_ALIGN(hiaddr); - - if (loaddr < mmap_min_addr) { - host_start = HOST_PAGE_ALIGN(mmap_min_addr); - } else { - host_start = loaddr; - if (host_start != loaddr) { - errmsg = "Address overflow loading ELF binary"; - goto exit_errmsg; - } - } - host_size = hiaddr - loaddr; - while (1) { - /* Do not use mmap_find_vma here because that is limited to the - guest address space. We are going to make the - guest address space fit whatever we're given. */ - real_start = (unsigned long) - mmap((void *)host_start, host_size, PROT_NONE, - MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0); - if (real_start == (unsigned long)-1) { - goto exit_perror; - } - if (real_start == host_start) { - break; - } - /* That address didn't work. Unmap and try a different one. - The address the host picked because is typically right at - the top of the host address space and leaves the guest with - no usable address space. Resort to a linear search. We - already compensated for mmap_min_addr, so this should not - happen often. Probably means we got unlucky and host - address space randomization put a shared library somewhere - inconvenient. */ - munmap((void *)real_start, host_size); - host_start += qemu_host_page_size; - if (host_start == loaddr) { - /* Theoretically possible if host doesn't have any suitably - aligned areas. Normally the first mmap will fail. */ - errmsg = "Unable to find space for application"; - goto exit_errmsg; - } - } - qemu_log("Relocating guest address space from 0x" - TARGET_ABI_FMT_lx " to 0x%lx\n", loaddr, real_start); - guest_base = real_start - loaddr; - } -#endif + probe_guest_base(image_name, loaddr, hiaddr); } load_bias = load_addr - loaddr; @@ -1643,9 +1678,9 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) { int i, shnum, nsyms, sym_idx = 0, str_idx = 0; struct elf_shdr *shdr; - char *strings; - struct syminfo *s; - struct elf_sym *syms, *new_syms; + char *strings = NULL; + struct syminfo *s = NULL; + struct elf_sym *new_syms, *syms = NULL; shnum = hdr->e_shnum; i = shnum * sizeof(struct elf_shdr); @@ -1670,24 +1705,19 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) /* Now know where the strtab and symtab are. Snarf them. */ s = malloc(sizeof(*s)); if (!s) { - return; + goto give_up; } i = shdr[str_idx].sh_size; s->disas_strtab = strings = malloc(i); if (!strings || pread(fd, strings, i, shdr[str_idx].sh_offset) != i) { - free(s); - free(strings); - return; + goto give_up; } i = shdr[sym_idx].sh_size; syms = malloc(i); if (!syms || pread(fd, syms, i, shdr[sym_idx].sh_offset) != i) { - free(s); - free(strings); - free(syms); - return; + goto give_up; } nsyms = i / sizeof(struct elf_sym); @@ -1710,16 +1740,18 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) } } + /* No "useful" symbol. */ + if (nsyms == 0) { + goto give_up; + } + /* Attempt to free the storage associated with the local symbols that we threw away. Whether or not this has any effect on the memory allocation depends on the malloc implementation and how many symbols we managed to discard. */ new_syms = realloc(syms, nsyms * sizeof(*syms)); if (new_syms == NULL) { - free(s); - free(syms); - free(strings); - return; + goto give_up; } syms = new_syms; @@ -1734,6 +1766,13 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) s->lookup_symbol = lookup_symbolxx; s->next = syminfos; syminfos = s; + + return; + +give_up: + free(s); + free(strings); + free(syms); } int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, diff --git a/linux-user/flatload.c b/linux-user/flatload.c index cd7af7cdff..1062da3852 100644 --- a/linux-user/flatload.c +++ b/linux-user/flatload.c @@ -379,12 +379,11 @@ static int load_flat_file(struct linux_binprm * bprm, abi_long result; abi_ulong realdatastart = 0; abi_ulong text_len, data_len, bss_len, stack_len, flags; - abi_ulong memp = 0; /* for finding the brk area */ abi_ulong extra; abi_ulong reloc = 0, rp; int i, rev, relocs = 0; abi_ulong fpos; - abi_ulong start_code, end_code; + abi_ulong start_code; abi_ulong indx_len; hdr = ((struct flat_hdr *) bprm->buf); /* exec-header */ @@ -491,7 +490,6 @@ static int load_flat_file(struct linux_binprm * bprm, } reloc = datapos + (ntohl(hdr->reloc_start) - text_len); - memp = realdatastart; } else { @@ -506,7 +504,6 @@ static int load_flat_file(struct linux_binprm * bprm, realdatastart = textpos + ntohl(hdr->data_start); datapos = realdatastart + indx_len; reloc = (textpos + ntohl(hdr->reloc_start) + indx_len); - memp = textpos; #ifdef CONFIG_BINFMT_ZFLAT #error code needs checking @@ -552,11 +549,10 @@ static int load_flat_file(struct linux_binprm * bprm, /* The main program needs a little extra setup in the task structure */ start_code = textpos + sizeof (struct flat_hdr); - end_code = textpos + text_len; DBG_FLT("%s %s: TEXT=%x-%x DATA=%x-%x BSS=%x-%x\n", id ? "Lib" : "Load", bprm->filename, - (int) start_code, (int) end_code, + (int) start_code, (int) (textpos + text_len), (int) datapos, (int) (datapos + data_len), (int) (datapos + data_len), diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c index ac8c486c5f..62ebc7ed41 100644 --- a/linux-user/linuxload.c +++ b/linux-user/linuxload.c @@ -26,22 +26,6 @@ abi_long memcpy_to_target(abi_ulong dest, const void *src, return 0; } -static int in_group_p(gid_t g) -{ - /* return TRUE if we're in the specified group, FALSE otherwise */ - int ngroup; - int i; - gid_t grouplist[NGROUPS]; - - ngroup = getgroups(NGROUPS, grouplist); - for(i = 0; i < ngroup; i++) { - if(grouplist[i] == g) { - return 1; - } - } - return 0; -} - static int count(char ** vec) { int i; @@ -57,7 +41,7 @@ static int prepare_binprm(struct linux_binprm *bprm) { struct stat st; int mode; - int retval, id_change; + int retval; if(fstat(bprm->fd, &st) < 0) { return(-errno); @@ -73,14 +57,10 @@ static int prepare_binprm(struct linux_binprm *bprm) bprm->e_uid = geteuid(); bprm->e_gid = getegid(); - id_change = 0; /* Set-uid? */ if(mode & S_ISUID) { bprm->e_uid = st.st_uid; - if(bprm->e_uid != geteuid()) { - id_change = 1; - } } /* Set-gid? */ @@ -91,9 +71,6 @@ static int prepare_binprm(struct linux_binprm *bprm) */ if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { bprm->e_gid = st.st_gid; - if (!in_group_p(bprm->e_gid)) { - id_change = 1; - } } retval = read(bprm->fd, bprm->buf, BPRM_BUF_SIZE); diff --git a/linux-user/main.c b/linux-user/main.c index 1c91c30dcb..db5577bc50 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -318,7 +318,8 @@ void cpu_loop(CPUX86State *env) env->regs[R_EDX], env->regs[R_ESI], env->regs[R_EDI], - env->regs[R_EBP]); + env->regs[R_EBP], + 0, 0); break; #ifndef TARGET_ABI32 case EXCP_SYSCALL: @@ -330,7 +331,8 @@ void cpu_loop(CPUX86State *env) env->regs[R_EDX], env->regs[10], env->regs[8], - env->regs[9]); + env->regs[9], + 0, 0); env->eip = env->exception_next_eip; break; #endif @@ -734,7 +736,8 @@ void cpu_loop(CPUARMState *env) env->regs[2], env->regs[3], env->regs[4], - env->regs[5]); + env->regs[5], + 0, 0); } } else { goto error; @@ -830,7 +833,8 @@ void cpu_loop(CPUState *env) env->regs[2], env->regs[3], env->regs[4], - env->regs[5]); + env->regs[5], + 0, 0); } } else { goto error; @@ -1017,7 +1021,8 @@ void cpu_loop (CPUSPARCState *env) ret = do_syscall (env, env->gregs[1], env->regwptr[0], env->regwptr[1], env->regwptr[2], env->regwptr[3], - env->regwptr[4], env->regwptr[5]); + env->regwptr[4], env->regwptr[5], + 0, 0); if ((abi_ulong)ret >= (abi_ulong)(-515)) { #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) env->xcc |= PSR_CARRY; @@ -1610,7 +1615,7 @@ void cpu_loop(CPUPPCState *env) env->crf[0] &= ~0x1; ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6], env->gpr[7], - env->gpr[8]); + env->gpr[8], 0, 0); if (ret == (uint32_t)(-TARGET_QEMU_ESIGRETURN)) { /* Returning from a successful sigreturn syscall. Avoid corrupting register state. */ @@ -2071,7 +2076,7 @@ void cpu_loop(CPUMIPSState *env) env->active_tc.gpr[5], env->active_tc.gpr[6], env->active_tc.gpr[7], - arg5, arg6/*, arg7, arg8*/); + arg5, arg6, arg7, arg8); } if (ret == -TARGET_QEMU_ESIGRETURN) { /* Returning from a successful sigreturn syscall. @@ -2159,7 +2164,8 @@ void cpu_loop (CPUState *env) env->gregs[6], env->gregs[7], env->gregs[0], - env->gregs[1]); + env->gregs[1], + 0, 0); env->gregs[0] = ret; break; case EXCP_INTERRUPT: @@ -2228,7 +2234,8 @@ void cpu_loop (CPUState *env) env->regs[12], env->regs[13], env->pregs[7], - env->pregs[11]); + env->pregs[11], + 0, 0); env->regs[10] = ret; break; case EXCP_DEBUG: @@ -2287,7 +2294,8 @@ void cpu_loop (CPUState *env) env->regs[7], env->regs[8], env->regs[9], - env->regs[10]); + env->regs[10], + 0, 0); env->regs[3] = ret; env->sregs[SR_PC] = env->regs[14]; break; @@ -2397,7 +2405,8 @@ void cpu_loop(CPUM68KState *env) env->dregs[3], env->dregs[4], env->dregs[5], - env->aregs[0]); + env->aregs[0], + 0, 0); } break; case EXCP_INTERRUPT: @@ -2575,7 +2584,8 @@ void cpu_loop (CPUState *env) sysret = do_syscall(env, trapnr, env->ir[IR_A0], env->ir[IR_A1], env->ir[IR_A2], env->ir[IR_A3], - env->ir[IR_A4], env->ir[IR_A5]); + env->ir[IR_A4], env->ir[IR_A5], + 0, 0); if (trapnr == TARGET_NR_sigreturn || trapnr == TARGET_NR_rt_sigreturn) { break; @@ -2706,7 +2716,8 @@ void cpu_loop(CPUS390XState *env) env->regs[4], env->regs[5], env->regs[6], - env->regs[7]); + env->regs[7], + 0, 0); } break; case EXCP_ADDR: diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 237386caac..627c8b3423 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -192,7 +192,8 @@ abi_long do_brk(abi_ulong new_brk); void syscall_init(void); abi_long do_syscall(void *cpu_env, int num, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, - abi_long arg5, abi_long arg6); + abi_long arg5, abi_long arg6, abi_long arg7, + abi_long arg8); void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2); extern THREAD CPUState *thread_env; void cpu_loop(CPUState *env); diff --git a/linux-user/signal.c b/linux-user/signal.c index 11b25be7b8..7d168e100f 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -981,8 +981,8 @@ restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax) env->regs[R_ECX] = tswapl(sc->ecx); env->eip = tswapl(sc->eip); - cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3); - cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3); + cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs) | 3); + cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss) | 3); tmpflags = tswapl(sc->eflags); env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5); @@ -2080,7 +2080,6 @@ long do_sigreturn(CPUState *env) uint32_t up_psr, pc, npc; target_sigset_t set; sigset_t host_set; - abi_ulong fpu_save_addr; int err, i; sf_addr = env->regwptr[UREG_FP]; @@ -2120,10 +2119,11 @@ long do_sigreturn(CPUState *env) err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]); } - err |= __get_user(fpu_save_addr, &sf->fpu_save); - - //if (fpu_save) - // err |= restore_fpu_state(env, fpu_save); + /* FIXME: implement FPU save/restore: + * __get_user(fpu_save, &sf->fpu_save); + * if (fpu_save) + * err |= restore_fpu_state(env, fpu_save); + */ /* This is pretty much atomic, no amount locking would prevent * the races which exist anyways. @@ -2228,7 +2228,6 @@ void sparc64_set_context(CPUSPARCState *env) target_mc_gregset_t *grp; abi_ulong pc, npc, tstate; abi_ulong fp, i7, w_addr; - unsigned char fenab; int err; unsigned int i; @@ -2293,7 +2292,11 @@ void sparc64_set_context(CPUSPARCState *env) if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), abi_ulong) != 0) goto do_sigsegv; - err |= __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab)); + /* FIXME this does not match how the kernel handles the FPU in + * its sparc64_set_context implementation. In particular the FPU + * is only restored if fenab is non-zero in: + * __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab)); + */ err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs)); { uint32_t *src, *dst; diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 5cb27c7f9f..fed7a8fe0f 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -550,6 +550,15 @@ _syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds, size_t, sigsetsize) #endif +#if defined(TARGET_NR_pselect6) +#ifndef __NR_pselect6 +# define __NR_pselect6 -1 +#endif +#define __NR_sys_pselect6 __NR_pselect6 +_syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds, + fd_set *, exceptfds, struct timespec *, timeout, void *, sig); +#endif + extern int personality(int); extern int flock(int, int); extern int setfsuid(int); @@ -709,49 +718,81 @@ char *target_strerror(int err) static abi_ulong target_brk; static abi_ulong target_original_brk; +static abi_ulong brk_page; void target_set_brk(abi_ulong new_brk) { target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk); + brk_page = HOST_PAGE_ALIGN(target_brk); } +//#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0) +#define DEBUGF_BRK(message, args...) + /* do_brk() must return target values and target errnos. */ abi_long do_brk(abi_ulong new_brk) { - abi_ulong brk_page; abi_long mapped_addr; int new_alloc_size; - if (!new_brk) + DEBUGF_BRK("do_brk(%#010x) -> ", new_brk); + + if (!new_brk) { + DEBUGF_BRK("%#010x (!new_brk)\n", target_brk); return target_brk; - if (new_brk < target_original_brk) + } + if (new_brk < target_original_brk) { + DEBUGF_BRK("%#010x (new_brk < target_original_brk)\n", target_brk); return target_brk; + } - brk_page = HOST_PAGE_ALIGN(target_brk); - - /* If the new brk is less than this, set it and we're done... */ - if (new_brk < brk_page) { + /* If the new brk is less than the highest page reserved to the + * target heap allocation, set it and we're almost done... */ + if (new_brk <= brk_page) { + /* Heap contents are initialized to zero, as for anonymous + * mapped pages. */ + if (new_brk > target_brk) { + memset(g2h(target_brk), 0, new_brk - target_brk); + } target_brk = new_brk; + DEBUGF_BRK("%#010x (new_brk <= brk_page)\n", target_brk); return target_brk; } - /* We need to allocate more memory after the brk... */ - new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1); + /* We need to allocate more memory after the brk... Note that + * we don't use MAP_FIXED because that will map over the top of + * any existing mapping (like the one with the host libc or qemu + * itself); instead we treat "mapped but at wrong address" as + * a failure and unmap again. + */ + new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page); mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, PROT_READ|PROT_WRITE, - MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0)); + MAP_ANON|MAP_PRIVATE, 0, 0)); + + if (mapped_addr == brk_page) { + target_brk = new_brk; + brk_page = HOST_PAGE_ALIGN(target_brk); + DEBUGF_BRK("%#010x (mapped_addr == brk_page)\n", target_brk); + return target_brk; + } else if (mapped_addr != -1) { + /* Mapped but at wrong address, meaning there wasn't actually + * enough space for this brk. + */ + target_munmap(mapped_addr, new_alloc_size); + mapped_addr = -1; + DEBUGF_BRK("%#010x (mapped_addr != -1)\n", target_brk); + } + else { + DEBUGF_BRK("%#010x (otherwise)\n", target_brk); + } #if defined(TARGET_ALPHA) /* We (partially) emulate OSF/1 on Alpha, which requires we return a proper errno, not an unchanged brk value. */ - if (is_error(mapped_addr)) { - return -TARGET_ENOMEM; - } + return -TARGET_ENOMEM; #endif - - if (!is_error(mapped_addr)) { - target_brk = new_brk; - } + /* For everything else, return the previous break. */ return target_brk; } @@ -787,6 +828,20 @@ static inline abi_long copy_from_user_fdset(fd_set *fds, return 0; } +static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr, + abi_ulong target_fds_addr, + int n) +{ + if (target_fds_addr) { + if (copy_from_user_fdset(fds, target_fds_addr, n)) + return -TARGET_EFAULT; + *fds_ptr = fds; + } else { + *fds_ptr = NULL; + } + return 0; +} + static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr, const fd_set *fds, int n) @@ -952,6 +1007,7 @@ static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr, } #endif +#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect) /* do_select() must return target values and target errnos. */ static abi_long do_select(int n, abi_ulong rfd_addr, abi_ulong wfd_addr, @@ -962,26 +1018,17 @@ static abi_long do_select(int n, struct timeval tv, *tv_ptr; abi_long ret; - if (rfd_addr) { - if (copy_from_user_fdset(&rfds, rfd_addr, n)) - return -TARGET_EFAULT; - rfds_ptr = &rfds; - } else { - rfds_ptr = NULL; + ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n); + if (ret) { + return ret; } - if (wfd_addr) { - if (copy_from_user_fdset(&wfds, wfd_addr, n)) - return -TARGET_EFAULT; - wfds_ptr = &wfds; - } else { - wfds_ptr = NULL; + ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n); + if (ret) { + return ret; } - if (efd_addr) { - if (copy_from_user_fdset(&efds, efd_addr, n)) - return -TARGET_EFAULT; - efds_ptr = &efds; - } else { - efds_ptr = NULL; + ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n); + if (ret) { + return ret; } if (target_tv_addr) { @@ -1008,6 +1055,7 @@ static abi_long do_select(int n, return ret; } +#endif static abi_long do_pipe2(int host_pipe[], int flags) { @@ -3751,10 +3799,10 @@ static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr) #ifndef TARGET_ABI32 static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr) { - abi_long ret; + abi_long ret = 0; abi_ulong val; int idx; - + switch(code) { case TARGET_ARCH_SET_GS: case TARGET_ARCH_SET_FS: @@ -3773,13 +3821,13 @@ static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr) idx = R_FS; val = env->segs[idx].base; if (put_user(val, addr, abi_ulong)) - return -TARGET_EFAULT; + ret = -TARGET_EFAULT; break; default: ret = -TARGET_EINVAL; break; } - return 0; + return ret; } #endif @@ -4484,7 +4532,8 @@ int get_osversion(void) All errnos that do_syscall() returns must be -TARGET_<errcode>. */ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, - abi_long arg5, abi_long arg6) + abi_long arg5, abi_long arg6, abi_long arg7, + abi_long arg8) { abi_long ret; struct stat st; @@ -5569,7 +5618,102 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_pselect6 case TARGET_NR_pselect6: - goto unimplemented_nowarn; + { + abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr; + fd_set rfds, wfds, efds; + fd_set *rfds_ptr, *wfds_ptr, *efds_ptr; + struct timespec ts, *ts_ptr; + + /* + * The 6th arg is actually two args smashed together, + * so we cannot use the C library. + */ + sigset_t set; + struct { + sigset_t *set; + size_t size; + } sig, *sig_ptr; + + abi_ulong arg_sigset, arg_sigsize, *arg7; + target_sigset_t *target_sigset; + + n = arg1; + rfd_addr = arg2; + wfd_addr = arg3; + efd_addr = arg4; + ts_addr = arg5; + + ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n); + if (ret) { + goto fail; + } + ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n); + if (ret) { + goto fail; + } + ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n); + if (ret) { + goto fail; + } + + /* + * This takes a timespec, and not a timeval, so we cannot + * use the do_select() helper ... + */ + if (ts_addr) { + if (target_to_host_timespec(&ts, ts_addr)) { + goto efault; + } + ts_ptr = &ts; + } else { + ts_ptr = NULL; + } + + /* Extract the two packed args for the sigset */ + if (arg6) { + sig_ptr = &sig; + sig.size = _NSIG / 8; + + arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1); + if (!arg7) { + goto efault; + } + arg_sigset = tswapl(arg7[0]); + arg_sigsize = tswapl(arg7[1]); + unlock_user(arg7, arg6, 0); + + if (arg_sigset) { + sig.set = &set; + target_sigset = lock_user(VERIFY_READ, arg_sigset, + sizeof(*target_sigset), 1); + if (!target_sigset) { + goto efault; + } + target_to_host_sigset(&set, target_sigset); + unlock_user(target_sigset, arg_sigset, 0); + } else { + sig.set = NULL; + } + } else { + sig_ptr = NULL; + } + + ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr, + ts_ptr, sig_ptr)); + + if (!is_error(ret)) { + if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n)) + goto efault; + if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n)) + goto efault; + if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n)) + goto efault; + + if (ts_addr && host_to_target_timespec(ts_addr, &ts)) + goto efault; + } + } + break; #endif case TARGET_NR_symlink: { @@ -6029,8 +6173,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_syscall case TARGET_NR_syscall: - ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0); - break; + ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5, + arg6, arg7, arg8, 0); + break; #endif case TARGET_NR_wait4: { @@ -7058,7 +7203,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_osf_sigprocmask: { abi_ulong mask; - int how = arg1; + int how; sigset_t set, oldset; switch(arg1) { @@ -7077,7 +7222,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } mask = arg2; target_to_host_old_sigset(&set, &mask); - sigprocmask(arg1, &set, &oldset); + sigprocmask(how, &set, &oldset); host_to_target_old_sigset(&mask, &oldset); ret = mask; } @@ -7717,8 +7862,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #if defined(TARGET_NR_sync_file_range) case TARGET_NR_sync_file_range: #if TARGET_ABI_BITS == 32 +#if defined(TARGET_MIPS) + ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4), + target_offset64(arg5, arg6), arg7)); +#else ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3), target_offset64(arg4, arg5), arg6)); +#endif /* !TARGET_MIPS */ #else ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4)); #endif diff --git a/m68k-semi.c b/m68k-semi.c index 0371089b98..7fde10e8f3 100644 --- a/m68k-semi.c +++ b/m68k-semi.c @@ -370,7 +370,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) TaskState *ts = env->opaque; /* Allocate the heap using sbrk. */ if (!ts->heap_limit) { - long ret; + abi_ulong ret; uint32_t size; uint32_t base; @@ -379,8 +379,9 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) /* Try a big heap, and reduce the size if that fails. */ for (;;) { ret = do_brk(base + size); - if (ret != -1) + if (ret >= (base + size)) { break; + } size >>= 1; } ts->heap_limit = base + size; @@ -710,7 +710,7 @@ int qemu_find_nic_model(NICInfo *nd, const char * const *models, return i; } - error_report("qemu: Unsupported NIC model: %s", nd->model); + error_report("Unsupported NIC model: %s", nd->model); return -1; } diff --git a/net/socket.c b/net/socket.c index 7337f4fa10..bc1bf58894 100644 --- a/net/socket.c +++ b/net/socket.c @@ -530,7 +530,7 @@ int net_init_socket(QemuOpts *opts, qemu_opt_get(opts, "connect") || qemu_opt_get(opts, "mcast") || qemu_opt_get(opts, "localaddr")) { - error_report("listen=, connect=, mcast= and localaddr= is invalid with fd=\n"); + error_report("listen=, connect=, mcast= and localaddr= is invalid with fd="); return -1; } @@ -550,7 +550,7 @@ int net_init_socket(QemuOpts *opts, qemu_opt_get(opts, "connect") || qemu_opt_get(opts, "mcast") || qemu_opt_get(opts, "localaddr")) { - error_report("fd=, connect=, mcast= and localaddr= is invalid with listen=\n"); + error_report("fd=, connect=, mcast= and localaddr= is invalid with listen="); return -1; } @@ -566,7 +566,7 @@ int net_init_socket(QemuOpts *opts, qemu_opt_get(opts, "listen") || qemu_opt_get(opts, "mcast") || qemu_opt_get(opts, "localaddr")) { - error_report("fd=, listen=, mcast= and localaddr= is invalid with connect=\n"); + error_report("fd=, listen=, mcast= and localaddr= is invalid with connect="); return -1; } diff --git a/qemu-common.h b/qemu-common.h index 109498dd4d..abd7a75b72 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -112,11 +112,6 @@ static inline char *realpath(const char *path, char *resolved_path) _fullpath(resolved_path, path, _MAX_PATH); return resolved_path; } - -#define PRId64 "I64d" -#define PRIx64 "I64x" -#define PRIu64 "I64u" -#define PRIo64 "I64o" #endif /* FIXME: Remove NEED_CPU_H. */ diff --git a/qemu-error.c b/qemu-error.c index 41c191d528..4b20d283a2 100644 --- a/qemu-error.c +++ b/qemu-error.c @@ -193,6 +193,8 @@ void error_print_loc(void) /* * Print an error message to current monitor if we have one, else to stderr. + * Format arguments like sprintf(). The result should not contain + * newlines. * Prepend the current location and append a newline. * It's wrong to call this in a QMP monitor. Use qerror_report() there. */ diff --git a/qemu-img.c b/qemu-img.c index 4f162d1abe..32628b3110 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -304,11 +304,11 @@ static int img_create(int argc, char **argv) fmt = optarg; break; case 'e': - error_report("qemu-img: option -e is deprecated, please use \'-o " + error_report("option -e is deprecated, please use \'-o " "encryption\' instead!"); return 1; case '6': - error_report("qemu-img: option -6 is deprecated, please use \'-o " + error_report("option -6 is deprecated, please use \'-o " "compat6\' instead!"); return 1; case 'o': @@ -633,11 +633,11 @@ static int img_convert(int argc, char **argv) compress = 1; break; case 'e': - error_report("qemu-img: option -e is deprecated, please use \'-o " + error_report("option -e is deprecated, please use \'-o " "encryption\' instead!"); return 1; case '6': - error_report("qemu-img: option -6 is deprecated, please use \'-o " + error_report("option -6 is deprecated, please use \'-o " "compat6\' instead!"); return 1; case 'o': @@ -690,12 +690,12 @@ static int img_convert(int argc, char **argv) if (snapshot_name != NULL) { if (bs_n > 1) { - error_report("No support for concatenating multiple snapshot\n"); + error_report("No support for concatenating multiple snapshot"); ret = -1; goto out; } if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) { - error_report("Failed to load snapshot\n"); + error_report("Failed to load snapshot"); ret = -1; goto out; } diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index 6d36a7f7ae..5c02803411 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -34,6 +34,9 @@ #include "qemu-common.h" #ifdef CONFIG_VNC_PNG +/* The following define is needed by pngconf.h. Otherwise it won't compile, + because setjmp.h was already included by qemu-common.h. */ +#define PNG_SKIP_SETJMP_CHECK #include <png.h> #endif #ifdef CONFIG_VNC_JPEG |