Statistics
| Branch: | Revision:

root / osdep.c @ 97eb5b14

History | View | Annotate | Download (10.1 kB)

1 ea88812f bellard
/*
2 ea88812f bellard
 * QEMU low level functions
3 ea88812f bellard
 * 
4 ea88812f bellard
 * Copyright (c) 2003 Fabrice Bellard
5 ea88812f bellard
 * 
6 ea88812f bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 ea88812f bellard
 * of this software and associated documentation files (the "Software"), to deal
8 ea88812f bellard
 * in the Software without restriction, including without limitation the rights
9 ea88812f bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 ea88812f bellard
 * copies of the Software, and to permit persons to whom the Software is
11 ea88812f bellard
 * furnished to do so, subject to the following conditions:
12 ea88812f bellard
 *
13 ea88812f bellard
 * The above copyright notice and this permission notice shall be included in
14 ea88812f bellard
 * all copies or substantial portions of the Software.
15 ea88812f bellard
 *
16 ea88812f bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 ea88812f bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 ea88812f bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 ea88812f bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 ea88812f bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 ea88812f bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 ea88812f bellard
 * THE SOFTWARE.
23 ea88812f bellard
 */
24 ea88812f bellard
#include <stdlib.h>
25 ea88812f bellard
#include <stdio.h>
26 ea88812f bellard
#include <stdarg.h>
27 ea88812f bellard
#include <string.h>
28 ea88812f bellard
#include <sys/mman.h>
29 ea88812f bellard
#include <sys/ipc.h>
30 ea88812f bellard
#include <errno.h>
31 ea88812f bellard
#include <unistd.h>
32 ea88812f bellard
33 ea88812f bellard
#include "cpu.h"
34 ea88812f bellard
35 ea88812f bellard
#if defined(__i386__) && !defined(CONFIG_SOFTMMU) && !defined(CONFIG_USER_ONLY)
36 ea88812f bellard
37 ea88812f bellard
/* When not using soft mmu, libc independant functions are needed for
38 ea88812f bellard
   the CPU core because it needs to use alternates stacks and
39 ea88812f bellard
   libc/thread incompatibles settings */
40 ea88812f bellard
41 ea88812f bellard
#include <linux/unistd.h>
42 ea88812f bellard
43 ea88812f bellard
#define QEMU_SYSCALL0(name) \
44 ea88812f bellard
{ \
45 ea88812f bellard
long __res; \
46 ea88812f bellard
__asm__ volatile ("int $0x80" \
47 ea88812f bellard
        : "=a" (__res) \
48 ea88812f bellard
        : "0" (__NR_##name)); \
49 ea88812f bellard
return __res; \
50 ea88812f bellard
}
51 ea88812f bellard
52 ea88812f bellard
#define QEMU_SYSCALL1(name,arg1) \
53 ea88812f bellard
{ \
54 ea88812f bellard
long __res; \
55 ea88812f bellard
__asm__ volatile ("int $0x80" \
56 ea88812f bellard
        : "=a" (__res) \
57 ea88812f bellard
        : "0" (__NR_##name),"b" ((long)(arg1))); \
58 ea88812f bellard
return __res; \
59 ea88812f bellard
}
60 ea88812f bellard
61 ea88812f bellard
#define QEMU_SYSCALL2(name,arg1,arg2) \
62 ea88812f bellard
{ \
63 ea88812f bellard
long __res; \
64 ea88812f bellard
__asm__ volatile ("int $0x80" \
65 ea88812f bellard
        : "=a" (__res) \
66 ea88812f bellard
        : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \
67 ea88812f bellard
return __res; \
68 ea88812f bellard
}
69 ea88812f bellard
70 ea88812f bellard
#define QEMU_SYSCALL3(name,arg1,arg2,arg3) \
71 ea88812f bellard
{ \
72 ea88812f bellard
long __res; \
73 ea88812f bellard
__asm__ volatile ("int $0x80" \
74 ea88812f bellard
        : "=a" (__res) \
75 ea88812f bellard
        : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
76 ea88812f bellard
                  "d" ((long)(arg3))); \
77 ea88812f bellard
return __res; \
78 ea88812f bellard
}
79 ea88812f bellard
80 ea88812f bellard
#define QEMU_SYSCALL4(name,arg1,arg2,arg3,arg4) \
81 ea88812f bellard
{ \
82 ea88812f bellard
long __res; \
83 ea88812f bellard
__asm__ volatile ("int $0x80" \
84 ea88812f bellard
        : "=a" (__res) \
85 ea88812f bellard
        : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
86 ea88812f bellard
          "d" ((long)(arg3)),"S" ((long)(arg4))); \
87 ea88812f bellard
return __res; \
88 ea88812f bellard
} 
89 ea88812f bellard
90 ea88812f bellard
#define QEMU_SYSCALL5(name,arg1,arg2,arg3,arg4,arg5) \
91 ea88812f bellard
{ \
92 ea88812f bellard
long __res; \
93 ea88812f bellard
__asm__ volatile ("int $0x80" \
94 ea88812f bellard
        : "=a" (__res) \
95 ea88812f bellard
        : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
96 ea88812f bellard
          "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \
97 ea88812f bellard
return __res; \
98 ea88812f bellard
}
99 ea88812f bellard
100 ea88812f bellard
#define QEMU_SYSCALL6(name,arg1,arg2,arg3,arg4,arg5,arg6) \
101 ea88812f bellard
{ \
102 ea88812f bellard
long __res; \
103 ea88812f bellard
__asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; int $0x80 ; pop %%ebp" \
104 ea88812f bellard
        : "=a" (__res) \
105 ea88812f bellard
        : "i" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
106 ea88812f bellard
          "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)), \
107 ea88812f bellard
          "0" ((long)(arg6))); \
108 ea88812f bellard
return __res; \
109 ea88812f bellard
}
110 ea88812f bellard
111 ea88812f bellard
int qemu_write(int fd, const void *buf, size_t n)
112 ea88812f bellard
{
113 ea88812f bellard
    QEMU_SYSCALL3(write, fd, buf, n);
114 ea88812f bellard
}
115 ea88812f bellard
116 ea88812f bellard
117 ea88812f bellard
118 ea88812f bellard
/****************************************************************/
119 ea88812f bellard
/* shmat replacement */
120 ea88812f bellard
121 ea88812f bellard
int qemu_ipc(int call, unsigned long first, 
122 ea88812f bellard
            unsigned long second, unsigned long third, 
123 ea88812f bellard
            void *ptr, unsigned long fifth)
124 ea88812f bellard
{
125 ea88812f bellard
    QEMU_SYSCALL6(ipc, call, first, second, third, ptr, fifth);
126 ea88812f bellard
}
127 ea88812f bellard
128 ea88812f bellard
#define SHMAT 21
129 ea88812f bellard
130 ea88812f bellard
/* we must define shmat so that a specific address will be used when
131 ea88812f bellard
   mapping the X11 ximage */
132 ea88812f bellard
void *shmat(int shmid, const void *shmaddr, int shmflg)
133 ea88812f bellard
{
134 ea88812f bellard
    void *ptr;
135 ea88812f bellard
    int ret;
136 ea88812f bellard
    /* we give an address in the right memory area */
137 ea88812f bellard
    if (!shmaddr)
138 ea88812f bellard
        shmaddr = get_mmap_addr(8192 * 1024);
139 ea88812f bellard
    ret = qemu_ipc(SHMAT, shmid, shmflg, (unsigned long)&ptr, (void *)shmaddr, 0);
140 ea88812f bellard
    if (ret < 0)
141 ea88812f bellard
        return NULL;
142 ea88812f bellard
    return ptr;
143 ea88812f bellard
}
144 ea88812f bellard
145 ea88812f bellard
/****************************************************************/
146 ea88812f bellard
/* memory allocation */
147 ea88812f bellard
148 ea88812f bellard
//#define DEBUG_MALLOC
149 ea88812f bellard
150 ea88812f bellard
#define MALLOC_BASE       0xab000000
151 ea88812f bellard
#define PHYS_RAM_BASE     0xac000000
152 ea88812f bellard
153 ea88812f bellard
#define MALLOC_ALIGN      16
154 ea88812f bellard
#define BLOCK_HEADER_SIZE 16
155 ea88812f bellard
156 ea88812f bellard
typedef struct MemoryBlock {
157 ea88812f bellard
    struct MemoryBlock *next;
158 ea88812f bellard
    unsigned long size; /* size of block, including header */
159 ea88812f bellard
} MemoryBlock;
160 ea88812f bellard
161 ea88812f bellard
static MemoryBlock *first_free_block;
162 ea88812f bellard
static unsigned long malloc_addr = MALLOC_BASE;
163 ea88812f bellard
164 ea88812f bellard
static void *malloc_get_space(size_t size)
165 ea88812f bellard
{
166 ea88812f bellard
    void *ptr;
167 ea88812f bellard
    size = TARGET_PAGE_ALIGN(size);
168 ea88812f bellard
    ptr = mmap((void *)malloc_addr, size, 
169 ea88812f bellard
               PROT_WRITE | PROT_READ, 
170 ea88812f bellard
               MAP_PRIVATE | MAP_FIXED | MAP_ANON, -1, 0);
171 ea88812f bellard
    if (ptr == MAP_FAILED)
172 ea88812f bellard
        return NULL;
173 ea88812f bellard
    malloc_addr += size;
174 ea88812f bellard
    return ptr;
175 ea88812f bellard
}
176 ea88812f bellard
177 ea88812f bellard
void *qemu_malloc(size_t size)
178 ea88812f bellard
{
179 ea88812f bellard
    MemoryBlock *mb, *mb1, **pmb;
180 ea88812f bellard
    void *ptr;
181 ea88812f bellard
    size_t size1, area_size;
182 ea88812f bellard
    
183 ea88812f bellard
    if (size == 0)
184 ea88812f bellard
        return NULL;
185 ea88812f bellard
186 ea88812f bellard
    size = (size + BLOCK_HEADER_SIZE + MALLOC_ALIGN - 1) & ~(MALLOC_ALIGN - 1);
187 ea88812f bellard
    pmb = &first_free_block;
188 ea88812f bellard
    for(;;) {
189 ea88812f bellard
        mb = *pmb;
190 ea88812f bellard
        if (mb == NULL)
191 ea88812f bellard
            break;
192 ea88812f bellard
        if (size <= mb->size)
193 ea88812f bellard
            goto found;
194 ea88812f bellard
        pmb = &mb->next;
195 ea88812f bellard
    }
196 ea88812f bellard
    /* no big enough blocks found: get new space */
197 ea88812f bellard
    area_size = TARGET_PAGE_ALIGN(size);
198 ea88812f bellard
    mb = malloc_get_space(area_size);
199 ea88812f bellard
    if (!mb)
200 ea88812f bellard
        return NULL;
201 ea88812f bellard
    size1 = area_size - size;
202 ea88812f bellard
    if (size1 > 0) {
203 ea88812f bellard
        /* create a new free block */
204 ea88812f bellard
        mb1 = (MemoryBlock *)((uint8_t *)mb + size);
205 ea88812f bellard
        mb1->next = NULL;
206 ea88812f bellard
        mb1->size = size1;
207 ea88812f bellard
        *pmb = mb1;
208 ea88812f bellard
    }
209 ea88812f bellard
    goto the_end;
210 ea88812f bellard
 found:
211 ea88812f bellard
    /* a free block was found: use it */
212 ea88812f bellard
    size1 = mb->size - size;
213 ea88812f bellard
    if (size1 > 0) {
214 ea88812f bellard
        /* create a new free block */
215 ea88812f bellard
        mb1 = (MemoryBlock *)((uint8_t *)mb + size);
216 ea88812f bellard
        mb1->next = mb->next;
217 ea88812f bellard
        mb1->size = size1;
218 ea88812f bellard
        *pmb = mb1;
219 ea88812f bellard
    } else {
220 ea88812f bellard
        /* suppress the first block */
221 ea88812f bellard
        *pmb = mb->next;
222 ea88812f bellard
    }
223 ea88812f bellard
 the_end:
224 ea88812f bellard
    mb->size = size;
225 ea88812f bellard
    mb->next = NULL;
226 ea88812f bellard
    ptr = ((uint8_t *)mb + BLOCK_HEADER_SIZE);
227 ea88812f bellard
#ifdef DEBUG_MALLOC
228 ea88812f bellard
    qemu_printf("malloc: size=0x%x ptr=0x%lx\n", size, (unsigned long)ptr);
229 ea88812f bellard
#endif
230 ea88812f bellard
    return ptr;
231 ea88812f bellard
}
232 ea88812f bellard
233 ea88812f bellard
void qemu_free(void *ptr)
234 ea88812f bellard
{
235 ea88812f bellard
    MemoryBlock *mb;
236 ea88812f bellard
237 ea88812f bellard
    mb = (MemoryBlock *)((uint8_t *)ptr - BLOCK_HEADER_SIZE);
238 ea88812f bellard
    mb->next = first_free_block;
239 ea88812f bellard
    first_free_block = mb;
240 ea88812f bellard
}
241 ea88812f bellard
242 ea88812f bellard
/****************************************************************/
243 ea88812f bellard
/* virtual memory allocation */
244 ea88812f bellard
245 ea88812f bellard
unsigned long mmap_addr = PHYS_RAM_BASE;
246 ea88812f bellard
247 ea88812f bellard
void *get_mmap_addr(unsigned long size)
248 ea88812f bellard
{
249 ea88812f bellard
    unsigned long addr;
250 ea88812f bellard
    addr = mmap_addr;
251 ea88812f bellard
    mmap_addr += ((size + 4095) & ~4095) + 4096;
252 ea88812f bellard
    return (void *)addr;
253 ea88812f bellard
}
254 ea88812f bellard
255 ea88812f bellard
#else
256 ea88812f bellard
257 ea88812f bellard
int qemu_write(int fd, const void *buf, size_t n)
258 ea88812f bellard
{
259 ea88812f bellard
    int ret;
260 ea88812f bellard
    ret = write(fd, buf, n);
261 ea88812f bellard
    if (ret < 0)
262 ea88812f bellard
        return -errno;
263 ea88812f bellard
    else
264 ea88812f bellard
        return ret;
265 ea88812f bellard
}
266 ea88812f bellard
267 ea88812f bellard
void *get_mmap_addr(unsigned long size)
268 ea88812f bellard
{
269 ea88812f bellard
    return NULL;
270 ea88812f bellard
}
271 ea88812f bellard
272 ea88812f bellard
void qemu_free(void *ptr)
273 ea88812f bellard
{
274 ea88812f bellard
    free(ptr);
275 ea88812f bellard
}
276 ea88812f bellard
277 ea88812f bellard
void *qemu_malloc(size_t size)
278 ea88812f bellard
{
279 ea88812f bellard
    return malloc(size);
280 ea88812f bellard
}
281 ea88812f bellard
282 ea88812f bellard
#endif
283 ea88812f bellard
284 ea88812f bellard
/****************************************************************/
285 ea88812f bellard
/* printf support */
286 ea88812f bellard
287 ea88812f bellard
static inline int qemu_isdigit(int c)
288 ea88812f bellard
{
289 ea88812f bellard
    return c >= '0' && c <= '9';
290 ea88812f bellard
}
291 ea88812f bellard
292 ea88812f bellard
#define OUTCHAR(c)        (buflen > 0? (--buflen, *buf++ = (c)): 0)
293 ea88812f bellard
294 ea88812f bellard
/* from BSD ppp sources */
295 ea88812f bellard
int qemu_vsnprintf(char *buf, int buflen, const char *fmt, va_list args)
296 ea88812f bellard
{
297 ea88812f bellard
    int c, i, n;
298 ea88812f bellard
    int width, prec, fillch;
299 ea88812f bellard
    int base, len, neg;
300 ea88812f bellard
    unsigned long val = 0;
301 ea88812f bellard
    const char *f;
302 ea88812f bellard
    char *str, *buf0;
303 ea88812f bellard
    char num[32];
304 ea88812f bellard
    static const char hexchars[] = "0123456789abcdef";
305 ea88812f bellard
306 ea88812f bellard
    buf0 = buf;
307 ea88812f bellard
    --buflen;
308 ea88812f bellard
    while (buflen > 0) {
309 ea88812f bellard
        for (f = fmt; *f != '%' && *f != 0; ++f)
310 ea88812f bellard
            ;
311 ea88812f bellard
        if (f > fmt) {
312 ea88812f bellard
            len = f - fmt;
313 ea88812f bellard
            if (len > buflen)
314 ea88812f bellard
                len = buflen;
315 ea88812f bellard
            memcpy(buf, fmt, len);
316 ea88812f bellard
            buf += len;
317 ea88812f bellard
            buflen -= len;
318 ea88812f bellard
            fmt = f;
319 ea88812f bellard
        }
320 ea88812f bellard
        if (*fmt == 0)
321 ea88812f bellard
            break;
322 ea88812f bellard
        c = *++fmt;
323 ea88812f bellard
        width = prec = 0;
324 ea88812f bellard
        fillch = ' ';
325 ea88812f bellard
        if (c == '0') {
326 ea88812f bellard
            fillch = '0';
327 ea88812f bellard
            c = *++fmt;
328 ea88812f bellard
        }
329 ea88812f bellard
        if (c == '*') {
330 ea88812f bellard
            width = va_arg(args, int);
331 ea88812f bellard
            c = *++fmt;
332 ea88812f bellard
        } else {
333 ea88812f bellard
            while (qemu_isdigit(c)) {
334 ea88812f bellard
                width = width * 10 + c - '0';
335 ea88812f bellard
                c = *++fmt;
336 ea88812f bellard
            }
337 ea88812f bellard
        }
338 ea88812f bellard
        if (c == '.') {
339 ea88812f bellard
            c = *++fmt;
340 ea88812f bellard
            if (c == '*') {
341 ea88812f bellard
                prec = va_arg(args, int);
342 ea88812f bellard
                c = *++fmt;
343 ea88812f bellard
            } else {
344 ea88812f bellard
                while (qemu_isdigit(c)) {
345 ea88812f bellard
                    prec = prec * 10 + c - '0';
346 ea88812f bellard
                    c = *++fmt;
347 ea88812f bellard
                }
348 ea88812f bellard
            }
349 ea88812f bellard
        }
350 ea88812f bellard
        /* modifiers */
351 ea88812f bellard
        switch(c) {
352 ea88812f bellard
        case 'l':
353 ea88812f bellard
            c = *++fmt;
354 ea88812f bellard
            break;
355 ea88812f bellard
        default:
356 ea88812f bellard
            break;
357 ea88812f bellard
        }
358 ea88812f bellard
        str = 0;
359 ea88812f bellard
        base = 0;
360 ea88812f bellard
        neg = 0;
361 ea88812f bellard
        ++fmt;
362 ea88812f bellard
        switch (c) {
363 ea88812f bellard
        case 'd':
364 ea88812f bellard
            i = va_arg(args, int);
365 ea88812f bellard
            if (i < 0) {
366 ea88812f bellard
                neg = 1;
367 ea88812f bellard
                val = -i;
368 ea88812f bellard
            } else
369 ea88812f bellard
                val = i;
370 ea88812f bellard
            base = 10;
371 ea88812f bellard
            break;
372 ea88812f bellard
        case 'o':
373 ea88812f bellard
            val = va_arg(args, unsigned int);
374 ea88812f bellard
            base = 8;
375 ea88812f bellard
            break;
376 ea88812f bellard
        case 'x':
377 ea88812f bellard
        case 'X':
378 ea88812f bellard
            val = va_arg(args, unsigned int);
379 ea88812f bellard
            base = 16;
380 ea88812f bellard
            break;
381 ea88812f bellard
        case 'p':
382 ea88812f bellard
            val = (unsigned long) va_arg(args, void *);
383 ea88812f bellard
            base = 16;
384 ea88812f bellard
            neg = 2;
385 ea88812f bellard
            break;
386 ea88812f bellard
        case 's':
387 ea88812f bellard
            str = va_arg(args, char *);
388 ea88812f bellard
            break;
389 ea88812f bellard
        case 'c':
390 ea88812f bellard
            num[0] = va_arg(args, int);
391 ea88812f bellard
            num[1] = 0;
392 ea88812f bellard
            str = num;
393 ea88812f bellard
            break;
394 ea88812f bellard
        default:
395 ea88812f bellard
            *buf++ = '%';
396 ea88812f bellard
            if (c != '%')
397 ea88812f bellard
                --fmt;                /* so %z outputs %z etc. */
398 ea88812f bellard
            --buflen;
399 ea88812f bellard
            continue;
400 ea88812f bellard
        }
401 ea88812f bellard
        if (base != 0) {
402 ea88812f bellard
            str = num + sizeof(num);
403 ea88812f bellard
            *--str = 0;
404 ea88812f bellard
            while (str > num + neg) {
405 ea88812f bellard
                *--str = hexchars[val % base];
406 ea88812f bellard
                val = val / base;
407 ea88812f bellard
                if (--prec <= 0 && val == 0)
408 ea88812f bellard
                    break;
409 ea88812f bellard
            }
410 ea88812f bellard
            switch (neg) {
411 ea88812f bellard
            case 1:
412 ea88812f bellard
                *--str = '-';
413 ea88812f bellard
                break;
414 ea88812f bellard
            case 2:
415 ea88812f bellard
                *--str = 'x';
416 ea88812f bellard
                *--str = '0';
417 ea88812f bellard
                break;
418 ea88812f bellard
            }
419 ea88812f bellard
            len = num + sizeof(num) - 1 - str;
420 ea88812f bellard
        } else {
421 ea88812f bellard
            len = strlen(str);
422 ea88812f bellard
            if (prec > 0 && len > prec)
423 ea88812f bellard
                len = prec;
424 ea88812f bellard
        }
425 ea88812f bellard
        if (width > 0) {
426 ea88812f bellard
            if (width > buflen)
427 ea88812f bellard
                width = buflen;
428 ea88812f bellard
            if ((n = width - len) > 0) {
429 ea88812f bellard
                buflen -= n;
430 ea88812f bellard
                for (; n > 0; --n)
431 ea88812f bellard
                    *buf++ = fillch;
432 ea88812f bellard
            }
433 ea88812f bellard
        }
434 ea88812f bellard
        if (len > buflen)
435 ea88812f bellard
            len = buflen;
436 ea88812f bellard
        memcpy(buf, str, len);
437 ea88812f bellard
        buf += len;
438 ea88812f bellard
        buflen -= len;
439 ea88812f bellard
    }
440 ea88812f bellard
    *buf = 0;
441 ea88812f bellard
    return buf - buf0;
442 ea88812f bellard
}
443 ea88812f bellard
444 ea88812f bellard
void qemu_vprintf(const char *fmt, va_list ap)
445 ea88812f bellard
{
446 ea88812f bellard
    char buf[1024];
447 ea88812f bellard
    int len;
448 ea88812f bellard
    
449 ea88812f bellard
    len = qemu_vsnprintf(buf, sizeof(buf), fmt, ap);
450 ea88812f bellard
    qemu_write(1, buf, len);
451 ea88812f bellard
}
452 ea88812f bellard
453 ea88812f bellard
void qemu_printf(const char *fmt, ...)
454 ea88812f bellard
{
455 ea88812f bellard
    va_list ap;
456 ea88812f bellard
    va_start(ap, fmt);
457 ea88812f bellard
    qemu_vprintf(fmt, ap);
458 ea88812f bellard
    va_end(ap);
459 ea88812f bellard
}