ARM gcc Kunihiko IMAI <bak d2.dion.ne.jp> 2009 1 11 ARM gcc 1 2 2 2 3 3 4 3 4.1................................. 3 4.2............................................ 4 4.3........................................ 5 5 6 5.1................................................... 6 5.2............................................ 7 5.3........................................ 7 6 char 8 6.1................................................... 8 6.2............................................ 9 6.3........................................ 9 7 soft fp hard fp 10 7.1............................................. 10 7.1.1 FPU................................... 10 7.1.2........................... 10 7.1.3............................................ 10 7.2 ARM........................................... 11
1. 2 7.2.1........................................ 11 7.2.2.............................................. 12 7.2.3........................................ 13 7.2.4.................................... 13 8 EABI legacy ABI 14 8.1 ABI............................................... 14 8.2 ABI.............................................. 14 8.2.1 legacy ABI.......................................... 14 8.2.2 ARM EABI.......................................... 14 8.3.................................................. 15 8.4.............................................. 15 8.5 Debian......................................... 16 8.6.............................................. 17 8.6.1................................ 17 8.6.2............................. 17 8.7........................................ 17 9 memcpy() 17 9.1.................................................. 17 9.2............................................ 18 9.3................................................. 19 9.4.................................................. 19 10 19 1 XScale ARM CPU gcc binutils 2
3. 3 3 x86 C ARM toolchain OS ARM Linux 4 RISC ARM x86 4.1 ARM ARM Linux ARM Linux /proc/cpu/alignment $ cat /proc/cpu/alignment User: 0 System: 0 Skipped: 0 Half: 0 Word: 0 Multi: 0 User faults: 0 (ignored) x86 #include <stdio.h> main ( void ) char *str = "\x01\x23\x45\x67\x89\xab\xcd\xef";
4. 4 unsigned *u = (unsigned *)(str + 1); printf ( "%08x\n", *u ); x86 89674523 ARM 01674523 /proc/cpu/alignment User $ cat /proc/cpu/alignment User: 1 System: 0 Skipped: 0 Half: 0 Word: 0 Multi: 0 User faults: 0 (ignored) +3 +2 +1 +0 67 45 23 01 str ef cd ab 89 +3 +2 +1 +0 02 01 00 x86 03 unsigned +3 +2 +1 +0 02 01 00 03 ARM 4.2
4. 5 x86 x86 x86 4.3 4.1 (ARM Linux ) /proc/cpu/alignment 2 # echo 2 >/proc/cpu/alignment # cat /proc/cpu/alignment User: 1 System: 0 Skipped: 0 Half: 0 Word: 0 Multi: 0 User faults: 2 (fixup) x86 x86 89674523 /proc/cpu/alignment bit OR 3 warn fixup 0 ignore 1 warn dmesg 2 fixup 4 signal core
5. 6 x86 aligned read x86 unaligned read read ARM unaligned(fixup) read aligned access read fixup 5 RISC 5.1 x86 x86 ARM #include <stdio.h> struct s0 ; unsigned char a, b, c; struct s1 char d; struct s0 e; ; main ( void ) struct s1 s;
5. 7 void *s_a = (void *)&s, *d_a = (void *)&s.d, *e_a = (void *)&s.e; printf ( "d = %d\n", d_a - s_a ); printf ( "e = %d\n", e_a - s_a ); x86 d = 0 e = 1 ARM d = 0 e = 4 5.2 5.3 gcc attribute ((packed)) #include <stdio.h> struct s0 char a, b, c; attribute ((packed)); struct s1 char d;
6. char 8 struct s0 e; attribute ((packed)); main ( void ) struct s1 s; void *s_a = (void *)&s, *d_a = (void *)&s.d, *e_a = (void *)&s.e; printf ( "d = %d\n", d_a - s_a ); printf ( "e = %d\n", e_a - s_a ); ARM d = 0 e = 1 x86 x86 x86 6 char ARM toolchain ARM gcc char unsinged char x86 gcc signed char char C C C char C 6.1
6. char 9 #include <stdio.h> main ( void ) char c1 = 0xff, c2 = 0x01; if ( c1 > c2 ) printf ( "c1 > c2\n" ); else printf ( "c1 <= c2\n" ); x86 signed char c1 = -1, c2 = 1 c1 <= c2 ARM unsigned char c1 = 255, c2 = 1 c1 > c2 6.2 char signed char C 6.3 ARM gcc -fsigned-char char signed char x86 $ gcc -fsigned-char char.c c1 <= c2
7. soft fp hard fp 10 7 soft fp hard fp fp 7.1 x86 FPU Floating Poing Unit; SoC 7.1.1 FPU CPU 7.1.2 gcc --msoft-float FPU FPU 7.1.3 FPU < < FPU
7. soft fp hard fp 11 7.2 ARM ARM 7.2.1 C /* foo.c */ int foo ( int a, int b ) return a + b; /* main.c */ #include <stdio.h> extern int foo ( int a, int b ); main ( void ) printf ( "%d\n", foo ( 1, 2 ) ); C $ gcc foo.c -msoft-float -c $ gcc main.c -c $ gcc foo.o main.o foo.c -msoft-float main.c x86 PowerPC a.out ARM toolchain $ gcc main.o foo.o /usr/bin/ld: ERROR: /usr/lib/gcc/arm-linux-gnu/4.0.4/libgcc_s.so uses hardware FP, whereas a.out uses software FP /usr/bin/ld: failed to merge target specific data of file /usr/lib/gcc/arm-linu x-gnu/4.0.4/libgcc_s.so /usr/bin/ld: ERROR: /lib/libc.so.6 uses hardware FP, whereas a.out uses softwar
7. soft fp hard fp 12 e FP ( collect2: ld returned 1 exit status 7.2.2 /usr/bin/ld: ERROR: /usr/lib/gcc/arm-linux-gnu/4.0.4/libgcc_s.so uses hardware FP, whereas a.out uses software FP hardware FP software FP google toolchain 1 readelf x86 $ readelf -h foo.o ELF : : 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 : ELF32 : 2 : 1 (current) OS/ABI: UNIX - System V ABI : 0 : REL ( ) : Intel 80386 : 0x1 : 0x0 : 0 ( ) : 192 ( ) : 0x0 : 52 ( ) : 0 ( ) : 0 : 40 ( ) Number of section headers: 9 Section header string table index: 6 x86 1
7. soft fp hard fp 13 $ readelf -h foo.o main.o : foo.o ELF : : 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 : main.o ELF : : 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 ARM $ readelf -h foo.o main.o : foo.o ELF : : 7f 45 4c 46 01 01 01 61 00 00 00 00 00 00 00 00 : 0x200, GNU EABI, software FP : main.o ELF : : 7f 45 4c 46 01 01 01 61 00 00 00 00 00 00 00 00 : 0x0 ELF soft FP hard FP 7.2.3 soft FP hard FP readelf soft FP hard FP 7.2.4 --no-warn-mismatch gcc --Wl,--no-warn-mismatch soft FP hard FP
8. EABI legacy ABI 14 $ gcc -Wl,--no-warn-mismatch foo.o main.o 8 EABI legacy ABI 8.1 ABI ABI (Application Binary Interface) C 8.2 ABI ARM Linux ABI 8.2.1 legacy ABI ARM gcc ABI gcc -mabi=apcs-gnu 8.2.2 ARM EABI ARM holdings 2 ABI gcc 4.1 -mabi=aapcs-linux 2 http://www.arm.com/products/devtools/abi.html
8. EABI legacy ABI 15 8.3 ABI Linux (linux-2.6.x/arch/arm/kconfig) Since there are major incompatibilities between the legacy ABI and EABI, especially with regard to structure member alignment, this option also changes the kernel syscall calling convention to disambiguate both ABIs and allow for backward compatibility support (selected with CONFIG OABI COMPAT). /* abitest.c */ #include <stdio.h> struct foo ; char a; main ( void ) printf ( "sizeof(struct foo) = %d\n", sizeof(struct foo)); lagacy ABI $ gcc -mabi=apcs-gnu abitest.c sizeof(struct foo) = 4 $ ARM EABI $ gcc -mabi=aapcs-linux abitest.c sizeof(struct foo) = 1 $ 8.4 ARM EABI legacy ABI readelf
8. EABI legacy ABI 16 $ gcc -mabi=aapcs-linux -c abitest.c # ARM EABI $ readelf -h abitest.o ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00...... Flags: 0x4000000, Version4 EABI...... $ gcc -mabi=apcs-gnu abitest.c # legacy ABI $ readelf -h abitest.o ELF Header: Magic: 7f 45 4c 46 01 01 01 61 00 00 00 00 00 00 00 00...... Flags: 0x400, GNU EABI, VFP...... readelf Flags: legacy ABI GNU EABI ARM EABI Version4 EABI 8.5 Debian Debian lenny test EABI arm legacy ABI armel ARM EABI
9. memcpy() 17 8.6 ABI 8.6.1 ABI 8.6.2 ABI 8.7 Linux CONFIG AEABI CONFIG OABI COMPAT EABI EABI legacy ABI legacy ABI EABI apache ABI 9 memcpy() 9.1 #include <string.h> int foo ( char *to, char *from ) char buf[1024]; memcpy ( buf, "12345", 6 );
9. memcpy() 18 $ gcc -O0 -c foo.c $ nm foo.o 00000000 T foo $ memcpy() -O0 #include <string.h> int foo ( char *to, char *from, int len ) memcpy ( to, from, len ); $ gcc -O0 -c foo2.c $ nm foo2.o 00000000 T foo U memcpy memcpy() 9.2 gcc memcpy() x86 gcc info memcpy mempcpy memmove memset strcpy stpcpy strncpy strcat strncat
10. 19 9.3 gcc 32bit word align 9.4 gcc void *my_memcpy( void *dest, const void *src, size_t n ) char *s = (char *)src, *d = (char *)dest; while ( n-- ) *(d++) = *(f++); return dest; int foo ( char *to, char *from ) char buf[1024]; my_memcpy ( buf, "12345", 6 ); memcpy my memcpy() 10 RISC CPU RISC CPU char soft fp / hard fp ABI memcpy ARM gcc