OKL4 3.0 l4_do_page_fault() in syscall_loop.c - binary patching

2 messages Options
Embed this post
Permalink
Badea Daniel

OKL4 3.0 l4_do_page_fault() in syscall_loop.c - binary patching

Reply Threaded More More options
Print post
Permalink
Hi,

The  Linux ARM EABI toolchain provided here: http://wiki.ok-labs.com/#OKL43.0Release does not provide a cross GDB. Because I want to use Skyeye's GDB server I tried to use another toolchain instead of the official one: CodeSourcery's arm-2008q3-72-arm-none-linux-gnueabi (GCC 4.3.2) instead of arm-unknown-linux-gnueabi (GCC 4.2.4).

Changing toolchains results in init() being unable to start because of a page fault at address 0xffff0fa0.
I tracked the problem back to l4_do_page_fault() in syscall_loop.c which does some 'magic' runtime patching of the code that caused the fault. Quote:

        /*
         * Binary patching for NPTL
         *
         * XXX ??? Better place this thing?
         */
        if (user_mode(regs) && ((address & PAGE_MASK) == 0xffff0000)){
        ....

Only 0xffff0fc0 and 0xffff0fe0 fault addresses are handled.

Briefly:

a) for fault at 0xffff0fc0, code :

                mvn r3, #0xf000
                mov lr, pc
                sub pc, r3, #63

   is replaced (on Gumstix) with:
 
                mov r3, #0x01fc0000
                mov lr, pc
                orr pc, r3, #0x3a400

b) for fault at 0xffff0fe0, code:

                mvn r0, #0xf000
                mov lr, pc
                sub pc, r0, #31

   is replaced with:

                mov r0, #0xff000000
                ldr r0, [r0, #0x0ff0]
                ldr r0, [r0, #56]

When I use the new toolchain I get an additional fault at 0xffff0fa0 which I don't know how to handle. The offending code looks like:

                mvn ip, #61440 ; 0xf000
                mov lr, pc
                sub pc, ip, #95 ; 0x5f

Questions:
a) What is the purpose of binary patching, why does it work and how to handle 0xffff0fa0?
    What is the meaning of the magic 0x01fc0000 | 0x3a400 address?
b) If you just wanted to patch the C library why don't you made a source code patch and distribute with the toolchain?

Thanks,
Daniel
aparna

Re: OKL4 3.0 l4_do_page_fault() in syscall_loop.c - binary patching

Reply Threaded More More options
Print post
Permalink
Hi Daniel,

I am using the codesourcery arm-2008q3 toolchain with okl4 2.1 . I am simulating for kzm_arm11 on qemu and init fails to start.
However to compile with this toolchain, I had to use ld-linux.so.3 instead of ld-linux.so.2 which is the one available with the arm-2008q3 toolchain. (I made changes  in rootfs-2.6.23-v2/Sconscript ).My output is as follows:
...

vtimer: init done (handle: 1, owner: 18001, mask: 1)
Requesting timer: 10000000
Timer_device freq: 70000000
Mount-cache hash table entries: 512
ptrace_break_init unimplemented
NET: Registered protocol family 16
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 1024 (order: 1, 8192 bytes)
TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
TCP reno registered
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
loop: module loaded
 igms0: unknown partition table
Iguana ramdisk driver initialized
kobject_add failed for ttyS0 with -EEXIST, don't try to register things with the same name in the same directory.
This architecture does not implement dump_stack()
Iguana virtual serial driver v1.0
TCP cubic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
NET: Registered protocol family 15
VFS: Mounted root (ext2 filesystem) readonly.
vserial: init done (handle: 0, owner: 18001, mask: 2)

There is no output from this point onwards. However I do not get any pagefault. I was wondering if you have progressed further with why init fails to start.

Thanks
Aparna

Badea Daniel wrote:
Hi,

The  Linux ARM EABI toolchain provided here: http://wiki.ok-labs.com/#OKL43.0Release does not provide a cross GDB. Because I want to use Skyeye's GDB server I tried to use another toolchain instead of the official one: CodeSourcery's arm-2008q3-72-arm-none-linux-gnueabi (GCC 4.3.2) instead of arm-unknown-linux-gnueabi (GCC 4.2.4).

Changing toolchains results in init() being unable to start because of a page fault at address 0xffff0fa0.
I tracked the problem back to l4_do_page_fault() in syscall_loop.c which does some 'magic' runtime patching of the code that caused the fault. Quote:

        /*
         * Binary patching for NPTL
         *
         * XXX ??? Better place this thing?
         */
        if (user_mode(regs) && ((address & PAGE_MASK) == 0xffff0000)){
        ....

Only 0xffff0fc0 and 0xffff0fe0 fault addresses are handled.

Briefly:

a) for fault at 0xffff0fc0, code :

                mvn r3, #0xf000
                mov lr, pc
                sub pc, r3, #63

   is replaced (on Gumstix) with:
 
                mov r3, #0x01fc0000
                mov lr, pc
                orr pc, r3, #0x3a400

b) for fault at 0xffff0fe0, code:

                mvn r0, #0xf000
                mov lr, pc
                sub pc, r0, #31

   is replaced with:

                mov r0, #0xff000000
                ldr r0, [r0, #0x0ff0]
                ldr r0, [r0, #56]

When I use the new toolchain I get an additional fault at 0xffff0fa0 which I don't know how to handle. The offending code looks like:

                mvn ip, #61440 ; 0xf000
                mov lr, pc
                sub pc, ip, #95 ; 0x5f

Questions:
a) What is the purpose of binary patching, why does it work and how to handle 0xffff0fa0?
    What is the meaning of the magic 0x01fc0000 | 0x3a400 address?
b) If you just wanted to patch the C library why don't you made a source code patch and distribute with the toolchain?

Thanks,
Daniel