Skip to contentSkip to conversation

Fix arm self-modifying code

PATCH In review Paul Brook 4 participants 6 messages Aug 2, 2004

lore
Share & tools
lore

Paul Brook

author
#0 lore raw

PATCH 1/1 Fix arm self-modifying code

The patch adds the signal handling necessary to make arm self-modifying code work. You'll notice it looks remarkably similar to the sparc routine :)

This should fix the "uncaught target signal 11" crash people have been seeing.

Paul

Index: cpu-exec.c
===================================================================
RCS file: /cvsroot/qemu/qemu/cpu-exec.c,v
retrieving revision 1.38

cpu-exec.c +4 -0
diff -u -p -r1.38 cpu-exec.c
@@ -718,6 +719,10 @@ static inline int handle_cpu_signal(unsi
                                     int is_write, sigset_t *old_set,
                                     void *puc)
 {
+    /* XXX: locking issue */
+    if (is_write && page_unprotect(address, pc, puc)) {
+        return 1;
+    }
     /* XXX: do more */
     return 0;
 }
#1 lore raw
Quoted 5 lines · Paul Brook

The patch adds the signal handling necessary to make arm self-modifying code work. You'll notice it looks remarkably similar to the sparc routine :)

This should fix the "uncaught target signal 11" crash people have been seeing.

OK.. I made two 'hello world' binaries with these toolchains:
- armv5te-redhat-linux, gcc 3.3.3, glibc 2.3.2
- arm-unknown-linux-gnu, gcc 2.95.3, glibc 2.1.3

They both fail with 'uncaught target signal 11' when run under latest qemu plus your patch.

The arm-unknown-linux-gnu binary shows something really strange:

% ./qemu-arm ./hi-gcc-2.95.3-glibc-2.1.3
qemu: uncaught target signal 11 (Segmentation fault) - exiting % setarch i686 ./qemu-arm ./hi-gcc-2.95.3-glibc-2.1.3 hi!
%

So, then I backed out your patch from qemu, running a vanilla qemu from CVS. Same result -- crash when run directly, and works when run under setarch i686.

(I'm on Fedora Core 2.)

So then I grab strace, and see these differences (old vs. new) during startup:

-old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf7030000
+old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x55001000

and:

-old_mmap(NULL, 528384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf6faf000
-mprotect(0xf702f000, 4096, PROT_NONE) = 0
-munmap(0xf7030000, 4096) = 0
+old_mmap(NULL, 528384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x55002000
+mprotect(0x55082000, 4096, PROT_NONE) = 0
+munmap(0x55001000, 4096) = 0

Perhaps qemu-arm can't deal with 4G-split kernels?

(The setarch i686 trick doesn't work for the armv5te-redhat-linux binary, though.)

--L

#2 lore raw
Quoted 3 lines · Lennert Buytenhek

OK.. I made two 'hello world' binaries with these toolchains:
- armv5te-redhat-linux, gcc 3.3.3, glibc 2.3.2
- arm-unknown-linux-gnu, gcc 2.95.3, glibc 2.1.3

Some more data points.

I built seven different toolchains:
- arm-unknown-linux-gnu, gcc 2.95.3, glibc 2.1.3
- armv4e-redhat-linux, gcc 3.3.3, glibc 2.3.2
- armv4eb-redhat-linux, gcc 3.3.3, glibc 2.3.2
- armv5e-redhat-linux, gcc 3.3.3, glibc 2.3.2
- armv5eb-redhat-linux, gcc 3.3.3, glibc 2.3.2
- armv5te-redhat-linux, gcc 3.3.3, glibc 2.3.2
- armv5teb-redhat-linux, gcc 3.3.3, glibc 2.3.2

Results without setarch i686, latest qemu CVS without extra patches:

arm-unknown-linux-gnu           sig11
armv4e-redhat-linux             sig11
armv4eb-redhat-linux            Error loading ./hi-armv4eb-redhat-linux
armv5e-redhat-linux             sig11
armv5eb-redhat-linux            Error loading ./hi-armv5eb-redhat-linux
armv5te-redhat-linux            sig11
armv5teb-redhat-linux           Error loading ./hi-armv5teb-redhat-linux

Results with setarch i686, latest qemu CVS without extra patches:

arm-unknown-linux-gnu           hi!
armv4e-redhat-linux             hi!
armv4eb-redhat-linux            Error loading ./hi-armv4eb-redhat-linux
armv5e-redhat-linux             sig11
armv5eb-redhat-linux            Error loading ./hi-armv5eb-redhat-linux
armv5te-redhat-linux            sig11
armv5teb-redhat-linux           Error loading ./hi-armv5teb-redhat-linux

Results with setarch i686, latest qemu CVS plus your patch.qemu_5e:

arm-unknown-linux-gnu hi!
armv4e-redhat-linux hi!
armv4eb-redhat-linux Error loading ./hi-armv4eb-redhat-linux
armv5e-redhat-linux qemu: uncaught target signal 4 (Illegal instruction) - exiting
armv5eb-redhat-linux Error loading ./hi-armv5eb-redhat-linux
armv5te-redhat-linux qemu: uncaught target signal 4 (Illegal instruction) - exiting
armv5teb-redhat-linux Error loading ./hi-armv5teb-redhat-linux

Results with setarch i686, latest qemu CVS plus your patch.qemu_5e plus your patch_qemu.rrx:

arm-unknown-linux-gnu hi!
armv4e-redhat-linux hi!
armv4eb-redhat-linux Error loading ./hi-armv4eb-redhat-linux
armv5e-redhat-linux qemu: uncaught target signal 4 (Illegal instruction) - exiting
armv5eb-redhat-linux Error loading ./hi-armv5eb-redhat-linux
armv5te-redhat-linux qemu: uncaught target signal 4 (Illegal instruction) - exiting
armv5teb-redhat-linux Error loading ./hi-armv5teb-redhat-linux

Results with setarch i686, latest qemu CVS plus your patch.qemu_5e plus your patch_qemu.rrx plus your self-modify patch:

arm-unknown-linux-gnu hi!
armv4e-redhat-linux hi!
armv4eb-redhat-linux Error loading ./hi-armv4eb-redhat-linux
armv5e-redhat-linux qemu: uncaught target signal 4 (Illegal instruction) - exiting
armv5eb-redhat-linux Error loading ./hi-armv5eb-redhat-linux
armv5te-redhat-linux qemu: uncaught target signal 4 (Illegal instruction) - exiting
armv5teb-redhat-linux Error loading ./hi-armv5teb-redhat-linux

--L

#3 lore raw
In reply to Lennert Buytenhek
Quoted 5 lines

% ./qemu-arm ./hi-gcc-2.95.3-glibc-2.1.3
qemu: uncaught target signal 11 (Segmentation fault) - exiting % setarch i686 ./qemu-arm ./hi-gcc-2.95.3-glibc-2.1.3 hi!
%

QEMU with FC2 does create this segfault even with qemu-i386 and I use the LD_ASSUME_KERNEL=2.2.5 trick to override this problem..

Could you retry with the same trick please?

Thanks,
Hetz

#4 lore raw
Quoted 10 lines · Hetz Ben Hamo
Quoted 5 lines

% ./qemu-arm ./hi-gcc-2.95.3-glibc-2.1.3
qemu: uncaught target signal 11 (Segmentation fault) - exiting % setarch i686 ./qemu-arm ./hi-gcc-2.95.3-glibc-2.1.3 hi!
%

QEMU with FC2 does create this segfault even with qemu-i386 and I use the LD_ASSUME_KERNEL=2.2.5 trick to override this problem..

Could you retry with the same trick please?

That doesn't seem to make a difference:

% ./qemu-arm ./hi-gcc-2.95.3-glibc-2.1.3
qemu: uncaught target signal 11 (Segmentation fault) - exiting % setarch i686 ./qemu-arm ./hi-gcc-2.95.3-glibc-2.1.3 hi!
% LD_ASSUME_KERNEL=2.2.5 ./qemu-arm ./hi-gcc-2.95.3-glibc-2.1.3
qemu: uncaught target signal 11 (Segmentation fault) - exiting % export LD_ASSUME_KERNEL=2.2.5
% ./qemu-arm ./hi-gcc-2.95.3-glibc-2.1.3
qemu: uncaught target signal 11 (Segmentation fault) - exiting %

--L

#5 lore raw
In reply to Lennert Buytenhek

Le Mon, 02 Aug 2004 14:21:23 +0200, Lennert Buytenhek a écrit :

Quoted 9 lines · Paul Brook
Quoted 7 lines

The patch adds the signal handling necessary to make arm self-modifying code work. You'll notice it looks remarkably similar to the sparc routine :)

This should fix the "uncaught target signal 11" crash people have been seeing.

Quoted 7 lines

OK.. I made two 'hello world' binaries with these toolchains: - armv5te-redhat-linux, gcc 3.3.3, glibc 2.3.2 - arm-unknown-linux-gnu, gcc 2.95.3, glibc 2.1.3

They both fail with 'uncaught target signal 11' when run under latest qemu plus your patch.

Don't know if this can help but when playing with qemu-ppc I've experienced problem like this.
glibc-2.3.2 was build with --enable-kernel=2.4.0, setting this same option to 2.2.0 corrected the whole thing.