Patchwork fix qruncom compilation problems

login
register
mail settings
Submitter Paolo Bonzini
Date Dec. 8, 2010, 12:49 p.m.
Message ID <1291812551-12590-1-git-send-email-pbonzini@redhat.com>
Download mbox | patch
Permalink /patch/74709/
State New
Headers show

Comments

Paolo Bonzini - Dec. 8, 2010, 12:49 p.m.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
        I had this patch lying around but I don't think I ever got
        qruncom to work completely.

 Makefile.target |    3 ++
 tests/Makefile  |    7 ++--
 tests/qruncom.c |   93 +++++++++++++++++++++++++++++++++++-------------------
 3 files changed, 67 insertions(+), 36 deletions(-)
Stefano Bonifazi - Dec. 8, 2010, 9:43 p.m.
On 12/08/2010 01:49 PM, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> ---
>          I had this patch lying around but I don't think I ever got
>          qruncom to work completely.
>
>   Makefile.target |    3 ++
>   tests/Makefile  |    7 ++--
>   tests/qruncom.c |   93 +++++++++++++++++++++++++++++++++++-------------------
>   3 files changed, 67 insertions(+), 36 deletions(-)
>
> diff --git a/Makefile.target b/Makefile.target
> index 5784844..4ac8f6f 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -339,6 +339,9 @@ obj-y += $(addprefix ../libdis/, $(libdis-y))
>   obj-y += $(libobj-y)
>   obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y))
>
> +else # !CONFIG_SOFTMMU
> +libqemu.a: $(addprefix ../, $(common-obj-y)) $(libobj-y) $(addprefix ../libdis/, $(libdis-y))
> +	ar rc $@ $^
>   endif # CONFIG_SOFTMMU
>
>   obj-y += $(addprefix ../, $(trace-obj-y))
> diff --git a/tests/Makefile b/tests/Makefile
> index e43ec70..6dbeb6f 100644
> --- a/tests/Makefile
> +++ b/tests/Makefile
> @@ -116,9 +116,10 @@ speed: sha1 sha1-i386
>
>   # broken test
>   # NOTE: -fomit-frame-pointer is currently needed : this is a bug in libqemu
> -qruncom: qruncom.c ../ioport-user.c ../i386-user/libqemu.a
> -	$(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 -I.. -I../i386-user -I../fpu \
> -              -o $@ $(filter %.c, $^) -L../i386-user -lqemu -lm
> +qruncom: qruncom.c
> +	#$(MAKE) -C ../i386-linux-user libqemu.a
> +	$(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 -I.. -I../linux-user -I../i386-linux-user -I../fpu \
> +              -o $@ $(filter %.c, $^) -L../i386-linux-user -lqemu -lm
>
>   # arm test
>   hello-arm: hello-arm.o
> diff --git a/tests/qruncom.c b/tests/qruncom.c
> index 079f7a2..66fc223 100644
> --- a/tests/qruncom.c
> +++ b/tests/qruncom.c
> @@ -12,10 +12,68 @@
>   #include<signal.h>
>   #include<malloc.h>
>
> +#define NEED_CPU_H 1
>   #include "cpu.h"
>
>   //#define SIGTEST
>
> +unsigned long guest_base = 0;
> +int have_guest_base = 0;
> +int singlestep = 0;
> +unsigned long last_brk = 0;
> +
> +void cpu_outb(uint32_t addr, uint8_t val)
> +{
> +    fprintf(stderr, "outb: port=0x%04"PRIx32", data=%02"PRIx8"\n",
> +            addr, val);
> +}
> +
> +void cpu_outw(uint32_t addr, uint16_t val)
> +{
> +    fprintf(stderr, "outw: port=0x%04"PRIx32", data=%04"PRIx16"\n",
> +            addr, val);
> +}
> +
> +void cpu_outl(uint32_t addr, uint32_t val)
> +{
> +    fprintf(stderr, "outl: port=0x%04"PRIx32", data=%08"PRIx32"\n",
> +            addr, val);
> +}
> +
> +uint8_t cpu_inb(uint32_t addr)
> +{
> +    fprintf(stderr, "inb: port=0x%04"PRIx32"\n", addr);
> +    return 0;
> +}
> +
> +uint16_t cpu_inw(uint32_t addr)
> +{
> +    fprintf(stderr, "inw: port=0x%04"PRIx32"\n", addr);
> +    return 0;
> +}
> +
> +uint32_t cpu_inl(uint32_t addr)
> +{
> +    fprintf(stderr, "inl: port=0x%04"PRIx32"\n", addr);
> +    return 0;
> +}
> +
> +void cpu_list_lock(void)
> +{
> +}
> +
> +void cpu_list_unlock(void)
> +{
> +}
> +
> +void mmap_lock(void)
> +{
> +}
> +
> +void mmap_unlock(void)
> +{
> +}
> +
>   int cpu_get_pic_interrupt(CPUState *env)
>   {
>       return -1;
> @@ -44,26 +102,6 @@ static void set_idt(int n, unsigned int dpl)
>       set_gate(idt_table + n, 0, dpl, 0, 0);
>   }
>
> -void qemu_free(void *ptr)
> -{
> -    free(ptr);
> -}
> -
> -void *qemu_malloc(size_t size)
> -{
> -    return malloc(size);
> -}
> -
> -void *qemu_mallocz(size_t size)
> -{
> -    void *ptr;
> -    ptr = qemu_malloc(size);
> -    if (!ptr)
> -        return NULL;
> -    memset(ptr, 0, size);
> -    return ptr;
> -}
> -
>   void *qemu_vmalloc(size_t size)
>   {
>       return memalign(4096, size);
> @@ -74,17 +112,6 @@ void qemu_vfree(void *ptr)
>       free(ptr);
>   }
>
> -void qemu_printf(const char *fmt, ...)
> -{
> -    va_list ap;
> -    va_start(ap, fmt);
> -    vprintf(fmt, ap);
> -    va_end(ap);
> -}
> -
> -/* XXX: this is a bug in helper2.c */
> -int errno;
> -
>   /**********************************************/
>
>   #define COM_BASE_ADDR    0x10100
> @@ -99,7 +126,7 @@ static void usage(void)
>
>   static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)
>   {
> -    return (uint8_t *)((seg<<  4) + (reg&  0xffff));
> +    return (uint8_t *)(uintptr_t) ((seg<<  4) + (reg&  0xffff));
>   }
>
>   static inline void pushw(CPUState *env, int val)
> @@ -241,7 +268,7 @@ int main(int argc, char **argv)
>           case EXCP0D_GPF:
>               {
>                   int int_num, ah;
> -                int_num = *(uint8_t *)(env->segs[R_CS].base + env->eip + 1);
> +                int_num = *(uint8_t *)(uintptr_t) (env->segs[R_CS].base + env->eip + 1);
>                   if (int_num != 0x21)
>                       goto unknown_int;
>                   ah = (env->regs[R_EAX]>>  8)&  0xff;
Hi!
Thank you for your help!

I've linked qemu-malloc.o and cutils.o together with qruncom.c and I 
managed to succesfully make it!
here the make line:
>     #$(MAKE) -C ../i386-linux-user libqemu.a
>     $(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 
> -I.. -I../linux-user -I../i386-linux-user -I../fpu \
>               -o $@ ../qemu-malloc.o ../cutils.o $(filter %.c, $^) 
> -L../i386-linux-user -lqemu -lm

Anyway running it with a com file as argument gave the error:
> mmap: Operation not permitted
I think the problem is with "MAP_FIXED" parameter in mmap 
(http://opengroup.org/onlinepubs/007908799/xsh/mmap.html) having chosen 
0x00000000 as starting address.. but it is pretty difficult for me atm 
to understand it, I've never used this function before and I am a 
beginner in these topics
Removing that parameter mmap succeeds, but then I get "segmentation 
fault" in cpu_init
Any idea?
Thank you in advance!
Stefano B.
Isaku Yamahata - Dec. 9, 2010, 3:32 a.m.
What is the reason to duplicate cpu_{in,out}[bwl]() instead of
ioport-user.c?

On Wed, Dec 08, 2010 at 01:49:11PM +0100, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>         I had this patch lying around but I don't think I ever got
>         qruncom to work completely.
> 
>  Makefile.target |    3 ++
>  tests/Makefile  |    7 ++--
>  tests/qruncom.c |   93 +++++++++++++++++++++++++++++++++++-------------------
>  3 files changed, 67 insertions(+), 36 deletions(-)
> 
> diff --git a/Makefile.target b/Makefile.target
> index 5784844..4ac8f6f 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -339,6 +339,9 @@ obj-y += $(addprefix ../libdis/, $(libdis-y))
>  obj-y += $(libobj-y)
>  obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y))
>  
> +else # !CONFIG_SOFTMMU
> +libqemu.a: $(addprefix ../, $(common-obj-y)) $(libobj-y) $(addprefix ../libdis/, $(libdis-y))
> +	ar rc $@ $^
>  endif # CONFIG_SOFTMMU
>  
>  obj-y += $(addprefix ../, $(trace-obj-y))
> diff --git a/tests/Makefile b/tests/Makefile
> index e43ec70..6dbeb6f 100644
> --- a/tests/Makefile
> +++ b/tests/Makefile
> @@ -116,9 +116,10 @@ speed: sha1 sha1-i386
>  
>  # broken test
>  # NOTE: -fomit-frame-pointer is currently needed : this is a bug in libqemu
> -qruncom: qruncom.c ../ioport-user.c ../i386-user/libqemu.a
> -	$(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 -I.. -I../i386-user -I../fpu \
> -              -o $@ $(filter %.c, $^) -L../i386-user -lqemu -lm
> +qruncom: qruncom.c
> +	#$(MAKE) -C ../i386-linux-user libqemu.a
> +	$(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 -I.. -I../linux-user -I../i386-linux-user -I../fpu \
> +              -o $@ $(filter %.c, $^) -L../i386-linux-user -lqemu -lm
>  
>  # arm test
>  hello-arm: hello-arm.o
> diff --git a/tests/qruncom.c b/tests/qruncom.c
> index 079f7a2..66fc223 100644
> --- a/tests/qruncom.c
> +++ b/tests/qruncom.c
> @@ -12,10 +12,68 @@
>  #include <signal.h>
>  #include <malloc.h>
>  
> +#define NEED_CPU_H 1
>  #include "cpu.h"
>  
>  //#define SIGTEST
>  
> +unsigned long guest_base = 0;
> +int have_guest_base = 0;
> +int singlestep = 0;
> +unsigned long last_brk = 0;
> +
> +void cpu_outb(uint32_t addr, uint8_t val)
> +{
> +    fprintf(stderr, "outb: port=0x%04"PRIx32", data=%02"PRIx8"\n",
> +            addr, val);
> +}
> +
> +void cpu_outw(uint32_t addr, uint16_t val)
> +{
> +    fprintf(stderr, "outw: port=0x%04"PRIx32", data=%04"PRIx16"\n",
> +            addr, val);
> +}
> +
> +void cpu_outl(uint32_t addr, uint32_t val)
> +{
> +    fprintf(stderr, "outl: port=0x%04"PRIx32", data=%08"PRIx32"\n",
> +            addr, val);
> +}
> +
> +uint8_t cpu_inb(uint32_t addr)
> +{
> +    fprintf(stderr, "inb: port=0x%04"PRIx32"\n", addr);
> +    return 0;
> +}
> +
> +uint16_t cpu_inw(uint32_t addr)
> +{
> +    fprintf(stderr, "inw: port=0x%04"PRIx32"\n", addr);
> +    return 0;
> +}
> +
> +uint32_t cpu_inl(uint32_t addr)
> +{
> +    fprintf(stderr, "inl: port=0x%04"PRIx32"\n", addr);
> +    return 0;
> +}
> +
> +void cpu_list_lock(void)
> +{
> +}
> +
> +void cpu_list_unlock(void)
> +{
> +}
> +
> +void mmap_lock(void)
> +{
> +}
> +
> +void mmap_unlock(void)
> +{
> +}
> +
>  int cpu_get_pic_interrupt(CPUState *env)
>  {
>      return -1;
> @@ -44,26 +102,6 @@ static void set_idt(int n, unsigned int dpl)
>      set_gate(idt_table + n, 0, dpl, 0, 0);
>  }
>  
> -void qemu_free(void *ptr)
> -{
> -    free(ptr);
> -}
> -
> -void *qemu_malloc(size_t size)
> -{
> -    return malloc(size);
> -}
> -
> -void *qemu_mallocz(size_t size)
> -{
> -    void *ptr;
> -    ptr = qemu_malloc(size);
> -    if (!ptr)
> -        return NULL;
> -    memset(ptr, 0, size);
> -    return ptr;
> -}
> -
>  void *qemu_vmalloc(size_t size)
>  {
>      return memalign(4096, size);
> @@ -74,17 +112,6 @@ void qemu_vfree(void *ptr)
>      free(ptr);
>  }
>  
> -void qemu_printf(const char *fmt, ...)
> -{
> -    va_list ap;
> -    va_start(ap, fmt);
> -    vprintf(fmt, ap);
> -    va_end(ap);
> -}
> -
> -/* XXX: this is a bug in helper2.c */
> -int errno;
> -
>  /**********************************************/
>  
>  #define COM_BASE_ADDR    0x10100
> @@ -99,7 +126,7 @@ static void usage(void)
>  
>  static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)
>  {
> -    return (uint8_t *)((seg << 4) + (reg & 0xffff));
> +    return (uint8_t *)(uintptr_t) ((seg << 4) + (reg & 0xffff));
>  }
>  
>  static inline void pushw(CPUState *env, int val)
> @@ -241,7 +268,7 @@ int main(int argc, char **argv)
>          case EXCP0D_GPF:
>              {
>                  int int_num, ah;
> -                int_num = *(uint8_t *)(env->segs[R_CS].base + env->eip + 1);
> +                int_num = *(uint8_t *)(uintptr_t) (env->segs[R_CS].base + env->eip + 1);
>                  if (int_num != 0x21)
>                      goto unknown_int;
>                  ah = (env->regs[R_EAX] >> 8) & 0xff;
> -- 
> 1.7.3.2
> 
>
Paolo Bonzini - Dec. 9, 2010, 7:16 a.m.
On 12/09/2010 04:32 AM, Isaku Yamahata wrote:
> What is the reason to duplicate cpu_{in,out}[bwl]() instead of
> ioport-user.c?

That's the reason why I hadn't submitted the patch so far, it's not 
really finished.  I also wanted to remove the need for mmap(MAP_FIXED).

Paolo
Paolo Bonzini - Dec. 9, 2010, 7:16 a.m.
On 12/08/2010 10:43 PM, Stefano Bonifazi wrote:
> I've linked qemu-malloc.o and cutils.o together with qruncom.c and I
> managed to succesfully make it!
> here the make line:
>> #$(MAKE) -C ../i386-linux-user libqemu.a
>> $(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 -I..
>> -I../linux-user -I../i386-linux-user -I../fpu \
>> -o $@ ../qemu-malloc.o ../cutils.o $(filter %.c, $^)
>> -L../i386-linux-user -lqemu -lm
>
> Anyway running it with a com file as argument gave the error:
>> mmap: Operation not permitted
> I think the problem is with "MAP_FIXED" parameter in mmap
> (http://opengroup.org/onlinepubs/007908799/xsh/mmap.html) having chosen
> 0x00000000 as starting address.. but it is pretty difficult for me atm
> to understand it, I've never used this function before and I am a
> beginner in these topics
> Removing that parameter mmap succeeds, but then I get "segmentation
> fault" in cpu_init

You have to run it as root I think.

Paolo
Stefano Bonifazi - Dec. 9, 2010, 5:29 p.m.
On 12/09/2010 08:16 AM, Paolo Bonzini wrote:
> On 12/08/2010 10:43 PM, Stefano Bonifazi wrote:
>>
>> Anyway running it with a com file as argument gave the error:
>>> mmap: Operation not permitted
>>
>
> You have to run it as root I think.
>
> Paolo
Thank you! Running as root worked, though it raises then the following 
error (from gdb) I am currently trying to understand:
> /home/stefano/LinuxDev/qemu-0.12.5/tcg/tcg.c:1367: tcg fatal error
>
> Program received signal SIGABRT, Aborted.
> 0x0012e416 in __kernel_vsyscall ()
Surely any hint on how to to fix this will be very welcome :)

I wish I could understand also what was wrong before, I mean /mmap/.. I 
understand you can't babysit me, but the gap between what one studies at 
university and the real world is very big and I feel lost :(
I've read pretty much about mmap trying to figure out myself but 
understanding how to map a file (what I could find in every article 
about mmap online) is not the same as understanding how it works inside 
QEMU ..
I know each process gets its own logical address space, if I understood 
fine mmap should take a portion of qruncom address space and give it to 
the emulator that should then see that as its own address space (please 
correct me if I am wrong!) ..
Now if I got fine the flag MAP_FIXED, obliges the process to give that 
portion of address space starting at its /addr/ parameter (the first).. 
or if it is not possible to give an error..
My big doubt is how can the process give exactly that portion of address 
space starting at zero by just  running it as root?.. I am expecting 
that area of address space to be taken by I dunno, code, data of the 
process itself.. honestly I don't know how things are allocated when a 
process is run(and I wish I could learn that).. but how can one think 
that addresses around zero are free for a mapping??
I'll appreciate very much any explanation, or links where to learn those 
topics! :)
Thank you very much!
Best Regards!
Stefano B.
Paolo Bonzini - Dec. 10, 2010, 8:53 a.m.
On 12/09/2010 06:29 PM, Stefano Bonifazi wrote:
> how can one think that addresses around zero are free for a mapping??

Addresses around zero are always free, because if they weren't you 
couldn't detect NULL pointer dereferences reliably.

mmap-ing at zero thus is a tricky operation, because it removes the 
possibility to detect NULL pointer dereferences.  What's worse, such 
ability would be lost even for _kernel_ dereferences of NULL, thus 
opening a large security hole for privilege-escalation or kernel 
exploits.  So, mmap-ing addresses close to zero is restricted to root.

Paolo
Stefano Bonifazi - Dec. 10, 2010, 9:43 p.m.
On 12/10/2010 09:53 AM, Paolo Bonzini wrote:
> On 12/09/2010 06:29 PM, Stefano Bonifazi wrote:
>> how can one think that addresses around zero are free for a mapping??
>
> Addresses around zero are always free, because if they weren't you 
> couldn't detect NULL pointer dereferences reliably.
>
> mmap-ing at zero thus is a tricky operation, because it removes the 
> possibility to detect NULL pointer dereferences.  What's worse, such 
> ability would be lost even for _kernel_ dereferences of NULL, thus 
> opening a large security hole for privilege-escalation or kernel 
> exploits.  So, mmap-ing addresses close to zero is restricted to root.
>
> Paolo

Hi!
Thank you! Very clear explanation! :)

- So why can't I simply change the following:
> vm86_mem = mmap((void *)0x00000000, 0x110000,
>                     PROT_WRITE | PROT_READ | PROT_EXEC,
>                     MAP_FIXED|MAP_ANON | MAP_PRIVATE, -1, 0);
> page_set_flags(0x00000000, 0x110000,
>                    PAGE_WRITE | PAGE_READ | PAGE_EXEC | PAGE_VALID);
into something like:
>> vm86_mem = mmap((void *)0x00000000, 0x110000,
>>                     PROT_WRITE | PROT_READ | PROT_EXEC,
>>                     MAP_ANON | MAP_PRIVATE, -1, 0);
>> page_set_flags(vm86_mem, 0x110000+vm86_mem,
>>                    PAGE_WRITE | PAGE_READ | PAGE_EXEC | PAGE_VALID);
?


- Any luck with the tcg fatal error? I am trying to understand how tcg 
works for fixing the error.. but it is so complicated! :)
Thank You again!
Best Regards!
Stefano B.
Stefano Bonifazi - Dec. 11, 2010, 2:42 p.m.
-----Original Message-----
From: Paolo Bonzini [mailto:pbonzini@redhat.com] 
Sent: venerdì 10 dicembre 2010 22:49
To: Stefano Bonifazi
Subject: Re: [PATCH] fix qruncom compilation problems

>For runcom (without the "q") this wouldn't work, because it runs the code
in vm86 mode.  It's possible that this is ok for qruncom with other >changes
to let the TCG backend know about vm86_mem.

So informing the interpreter with 

>> page_set_flags(0x00000000+vm86_mem, 0x110000+vm86_mem, PAGE_WRITE |
PAGE_READ | 
>> PAGE_EXEC | PAGE_VALID); 

Would be not enough?

>I was looking at this in my free time and it seriously shrunk later, so I'm
afraid I cannot help.

Surely I do understand you! Your help has been very very useful and
appreciated already thank you! May you direct me to somebody who's working
on it? Some TCG guru who could understand immediately what's wrong? :)
I noticed, far now,  that each question on this mailing list is answered
only by one QEMU developer, is that a sort of policy or just a coincidence? 

Again thank you!
Best regards!
Stefano B.
Paolo Bonzini - Dec. 13, 2010, 8:27 a.m.
On 12/11/2010 03:42 PM, Stefano Bonifazi wrote:
> Surely I do understand you! Your help has been very very useful and
> appreciated already thank you! May you direct me to somebody who's working
> on it? Some TCG guru who could understand immediately what's wrong?:)
> I noticed, far now,  that each question on this mailing list is answered
> only by one QEMU developer, is that a sort of policy or just a coincidence?

It's a coincidence. :)

Paolo

Patch

diff --git a/Makefile.target b/Makefile.target
index 5784844..4ac8f6f 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -339,6 +339,9 @@  obj-y += $(addprefix ../libdis/, $(libdis-y))
 obj-y += $(libobj-y)
 obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y))
 
+else # !CONFIG_SOFTMMU
+libqemu.a: $(addprefix ../, $(common-obj-y)) $(libobj-y) $(addprefix ../libdis/, $(libdis-y))
+	ar rc $@ $^
 endif # CONFIG_SOFTMMU
 
 obj-y += $(addprefix ../, $(trace-obj-y))
diff --git a/tests/Makefile b/tests/Makefile
index e43ec70..6dbeb6f 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -116,9 +116,10 @@  speed: sha1 sha1-i386
 
 # broken test
 # NOTE: -fomit-frame-pointer is currently needed : this is a bug in libqemu
-qruncom: qruncom.c ../ioport-user.c ../i386-user/libqemu.a
-	$(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 -I.. -I../i386-user -I../fpu \
-              -o $@ $(filter %.c, $^) -L../i386-user -lqemu -lm
+qruncom: qruncom.c
+	#$(MAKE) -C ../i386-linux-user libqemu.a
+	$(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 -I.. -I../linux-user -I../i386-linux-user -I../fpu \
+              -o $@ $(filter %.c, $^) -L../i386-linux-user -lqemu -lm
 
 # arm test
 hello-arm: hello-arm.o
diff --git a/tests/qruncom.c b/tests/qruncom.c
index 079f7a2..66fc223 100644
--- a/tests/qruncom.c
+++ b/tests/qruncom.c
@@ -12,10 +12,68 @@ 
 #include <signal.h>
 #include <malloc.h>
 
+#define NEED_CPU_H 1
 #include "cpu.h"
 
 //#define SIGTEST
 
+unsigned long guest_base = 0;
+int have_guest_base = 0;
+int singlestep = 0;
+unsigned long last_brk = 0;
+
+void cpu_outb(uint32_t addr, uint8_t val)
+{
+    fprintf(stderr, "outb: port=0x%04"PRIx32", data=%02"PRIx8"\n",
+            addr, val);
+}
+
+void cpu_outw(uint32_t addr, uint16_t val)
+{
+    fprintf(stderr, "outw: port=0x%04"PRIx32", data=%04"PRIx16"\n",
+            addr, val);
+}
+
+void cpu_outl(uint32_t addr, uint32_t val)
+{
+    fprintf(stderr, "outl: port=0x%04"PRIx32", data=%08"PRIx32"\n",
+            addr, val);
+}
+
+uint8_t cpu_inb(uint32_t addr)
+{
+    fprintf(stderr, "inb: port=0x%04"PRIx32"\n", addr);
+    return 0;
+}
+
+uint16_t cpu_inw(uint32_t addr)
+{
+    fprintf(stderr, "inw: port=0x%04"PRIx32"\n", addr);
+    return 0;
+}
+
+uint32_t cpu_inl(uint32_t addr)
+{
+    fprintf(stderr, "inl: port=0x%04"PRIx32"\n", addr);
+    return 0;
+}
+
+void cpu_list_lock(void)
+{
+}
+
+void cpu_list_unlock(void)
+{
+}
+
+void mmap_lock(void)
+{
+}
+
+void mmap_unlock(void)
+{
+}
+
 int cpu_get_pic_interrupt(CPUState *env)
 {
     return -1;
@@ -44,26 +102,6 @@  static void set_idt(int n, unsigned int dpl)
     set_gate(idt_table + n, 0, dpl, 0, 0);
 }
 
-void qemu_free(void *ptr)
-{
-    free(ptr);
-}
-
-void *qemu_malloc(size_t size)
-{
-    return malloc(size);
-}
-
-void *qemu_mallocz(size_t size)
-{
-    void *ptr;
-    ptr = qemu_malloc(size);
-    if (!ptr)
-        return NULL;
-    memset(ptr, 0, size);
-    return ptr;
-}
-
 void *qemu_vmalloc(size_t size)
 {
     return memalign(4096, size);
@@ -74,17 +112,6 @@  void qemu_vfree(void *ptr)
     free(ptr);
 }
 
-void qemu_printf(const char *fmt, ...)
-{
-    va_list ap;
-    va_start(ap, fmt);
-    vprintf(fmt, ap);
-    va_end(ap);
-}
-
-/* XXX: this is a bug in helper2.c */
-int errno;
-
 /**********************************************/
 
 #define COM_BASE_ADDR    0x10100
@@ -99,7 +126,7 @@  static void usage(void)
 
 static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)
 {
-    return (uint8_t *)((seg << 4) + (reg & 0xffff));
+    return (uint8_t *)(uintptr_t) ((seg << 4) + (reg & 0xffff));
 }
 
 static inline void pushw(CPUState *env, int val)
@@ -241,7 +268,7 @@  int main(int argc, char **argv)
         case EXCP0D_GPF:
             {
                 int int_num, ah;
-                int_num = *(uint8_t *)(env->segs[R_CS].base + env->eip + 1);
+                int_num = *(uint8_t *)(uintptr_t) (env->segs[R_CS].base + env->eip + 1);
                 if (int_num != 0x21)
                     goto unknown_int;
                 ah = (env->regs[R_EAX] >> 8) & 0xff;