Thursday, December 3, 2015

crosscompiling and gdb

As an example I m trying to see how division is implemented on arm and arm64.

created a test.c

int main(void)
{
        int a = 10;
        int b = 20;
        return (a/b);
}

Make sure to comple with -o option always because a.out doesn't has symbols

To compile for arm64
/usr2/arunks/workspace/LA.BR.1.3.1/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-gccc -o test64 test.c --sysroot=/usr2/arunks/workspace/LA.BR.1.3.1/prebuilts/ndk/9/platforms/android-17/arch-arm64/usr/

(gdb) disassemble main
Dump of assembler code for function main:
   0x00000000004005a8 <+0>:     sub     sp, sp, #0x10
   0x00000000004005ac <+4>:     mov     w0, #0xa                        // #10
   0x00000000004005b0 <+8>:     str     w0, [sp,#12]
   0x00000000004005b4 <+12>:    mov     w0, #0x14                       // #20
   0x00000000004005b8 <+16>:    str     w0, [sp,#8]
   0x00000000004005bc <+20>:    ldr     w1, [sp,#12]
   0x00000000004005c0 <+24>:    ldr     w0, [sp,#8]
   0x00000000004005c4 <+28>:    sdiv    w0, w1, w0
   0x00000000004005c8 <+32>:    add     sp, sp, #0x10
   0x00000000004005cc <+36>:    ret
End of assembler dump.


start gdb
/usr2/arunks/workspace/LA.BR.1.3.1/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-gcc -o test test.c --sysroot=/usr2/arunks/workspace/LA.BR.1.3.1/prebuilts/ndk/9/platforms/android-17/arch-arm/usr/

To compile for arm
/usr2/arunks/workspace/LA.BR.1.3.1/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-gdb test

start gdb
/usr2/arunks/workspace/LA.BR.1.3.1/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-gdb test

Dump of assembler code for function main:
   0x00008460 <+0>:     push    {r11, lr}
   0x00008464 <+4>:     add     r11, sp, #4
   0x00008468 <+8>:     sub     sp, sp, #8
   0x0000846c <+12>:    mov     r3, #10
   0x00008470 <+16>:    str     r3, [r11, #-8]
   0x00008474 <+20>:    mov     r3, #20
   0x00008478 <+24>:    str     r3, [r11, #-12]
   0x0000847c <+28>:    ldr     r0, [r11, #-8]
   0x00008480 <+32>:    ldr     r1, [r11, #-12]
   0x00008484 <+36>:    bl      0x8498 <__divsi3>
   0x00008488 <+40>:    mov     r3, r0
   0x0000848c <+44>:    mov     r0, r3
   0x00008490 <+48>:    sub     sp, r11, #4
   0x00008494 <+52>:    pop     {r11, pc}
End of assembler dump.

So arm32 implements division in software whereas arm64 has a dedicated instruction to do this.

2 comments:

prashant said...

Nice post Arun.

One query, is it absolutely require to have knowledge of "arm instructions set" FULLY

in order to solve kernel oops?

Arun KS said...

IMO it is very difficult to learn arm instruction set fully. You can always refer the manual. Why to store everything unnecessarily in your memory. :-)