Qualcuno può aiutarmi con il mio problema di collegamento ARM + GCC + UCLIBC con crossdev?ARM gentoo crossdev con uclibc: serve OABI piuttosto che EABI
Pubblicato anche al Forum Gentoo qui: http://forums.gentoo.org/viewtopic-t-925012.html
Recentemente, mi è stato assegnato a un progetto che ha sviluppato eseguibili utilizzando un vecchio GCC con OABI. Come punto di riferimento, ecco un'uscita colpo di testa da readelf di un file eseguibile che viene eseguito bene sul sistema:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 61 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: ARM
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x9464
Start of program headers: 52 (bytes into file)
Start of section headers: 540956 (bytes into file)
Flags: 0x202, has entry point, GNU EABI, software FP
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 6
Size of section headers: 40 (bytes)
Number of section headers: 35
Section header string table index: 32
ho creaed un cross-compilatore tramite crossdev e l'ultima gcc/binutils/linux-headers/etc . e con EABI.
$ crossdev arm-softfloat-linux-uclibceabi
ho tranquillamente cominciato a popolare la mia cartella locale con eseguibili che utilizzano tale cross compiler solo di riprovare più tardi l'eseguibile sul mio hardware e scoprire che ho finito con un segmentation fault. Ho capito, solo con un po 'di googling, che avevo davvero bisogno di avere il vecchio, legacy ABI per uclibc: OABI. Il mio precedente cross compiler era da circa 2005.
Come un altro punto di riferimento, i miei eseguibili con EABI producevano intestazioni da readelf che sembrano un po 'come questo:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x8130
Start of program headers: 52 (bytes into file)
Start of section headers: 21284 (bytes into file)
Flags: 0x5000002, has entry point, Version5 EABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 7
Size of section headers: 40 (bytes)
Number of section headers: 21
Section header string table index: 18
mentre la macchina è lo stesso, il l'errore di segmentazione non fornisce un modo per eseguire il binario sul target.
Dopo aver cercato su google, ho scoperto che potrebbe esserci un modo per produrre codice con il compilatore eabi per il sistema legacy. Sono stato molto felice quando mi sono imbattuto questo comando:
$ arm-softfloat-linux-uclibceabi-gcc -mabi=apcs-gnu -static -c -o /mnt/arm_uclibc/tmp/test /mnt/arm/tmp/test.c && readelf -h /mnt/arm_uclibc/tmp/test
E ho finito con:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 61 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: ARM
ABI Version: 0
Type: REL (Relocatable file)
Machine: ARM
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 248 (bytes into file)
Flags: 0x600, GNU EABI, software FP, VFP
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 12
Section header string table index: 9
A questo punto, mi è stato sempre antsy e ho deciso di provare a creare un file eseguibile con il - Mabi = APC-gnu,
arm-softfloat-linux-uclibceabi-gcc -mabi=apcs-gnu -static -o /mnt/arm_uclibc/tmp/test /mnt/arm/tmp/test.c
e ottengo un errore di linker:
/usr/libexec/gcc/arm-softfloat-linux-uclibceabi/ld: error: Source object /tmp/ccDq2f6R.o has EABI version 0, but target /mnt/arm_uclibc/tmp/test has EABI version 5
/usr/libexec/gcc/arm-softfloat-linux-uclibceabi/ld: failed to merge target specific data of file /tmp/ccDq2f6R.o
collect2: ld returned 1 exit status
DOMANDA: Questo mi porta a credere che il mio EABI sia errato e ho bisogno di OABI. È giusto?
ho creduto che fosse il caso, così ho cominciato a guardare in uclibc tramite crossdev:
$ crossdev arm-softfloat-linux-uclibc -P -v
Sono lieto di comunicare che i file che si ottiene compilati in una sorta di oggetto binario hanno il diritto intestazione elfo. Quindi penso che questo sia quello che voglio.
Ma questo muore durante la compilazione per uclibc come segue:
make[1]: `lib/ld-uClibc.so' is up to date.
LD libuClibc-0.9.33.2.so
libc/libc_so.a(_fpmaxtostr.os): In function `_fpmaxtostr':
_fpmaxtostr.c:(.text+0xbc): undefined reference to `__nedf2'
_fpmaxtostr.c:(.text+0xe0): undefined reference to `__eqdf2'
_fpmaxtostr.c:(.text+0xfc): undefined reference to `__divdf3'
_fpmaxtostr.c:(.text+0x108): undefined reference to `__ltdf2'
_fpmaxtostr.c:(.text+0x17c): undefined reference to `__muldf3'
_fpmaxtostr.c:(.text+0x348): undefined reference to `__gedf2'
_fpmaxtostr.c:(.text+0x40c): undefined reference to `__fixunsdfsi'
libc/libc_so.a(__psfs_do_numeric.os): In function `__psfs_do_numeric':
__psfs_do_numeric.c:(.text+0x534): undefined reference to `__truncdfsf2'
libc/libc_so.a(close.oS):(.ARM.exidx+0x0): undefined reference to `__aeabi_unwind_cpp_pr0'
collect2: ld returned 1 exit status
make: *** [lib/libc.so] Error 1
Se ho rotto l'errore in modo corretto, credo che
1) Il Makefile braccio.arco non è correttamente costruendo __aeabi_unwind_cpp_pr0 perché il file è costruito solo quando EABI è impostato:
$ find . -name 'Makefile.arch' -exec grep -i -H -n 'pr1' "{}" \;
./uclibc-0.9.33.2/work/uClibc-0.9.33.2/libc/sysdeps/linux/arm/Makefile.arch:45: $(ARCH_OUT)/aeabi_sighandlers.os $(ARCH_OUT)/aeabi_unwind_cpp_pr1.o
$ find . -name 'aeabi_unwind_cpp_pr1.c*'
./uclibc-0.9.33.2/work/uClibc-0.9.33.2/libc/sysdeps/linux/arm/aeabi_unwind_cpp_pr1.c
$ cat ./uclibc-0.9.33.2/work/uClibc-0.9.33.2/libc/sysdeps/linux/arm/aeabi_unwind_cpp_pr1.c
#include <stdlib.h>
attribute_hidden void __aeabi_unwind_cpp_pr0 (void);
attribute_hidden void __aeabi_unwind_cpp_pr0 (void)
{
}
attribute_hidden void __aeabi_unwind_cpp_pr1 (void);
attribute_hidden void __aeabi_unwind_cpp_pr1 (void)
{
}
attribute_hidden void __aeabi_unwind_cpp_pr2 (void);
attribute_hidden void __aeabi_unwind_cpp_pr2 (void)
{
}
Credo che la correzione di questo errore è:
--- Makefile.arch.old 2012-05-28 00:43:52.918708833 -0500
+++ Makefile.arch.new 2012-05-28 00:44:30.658708443 -0500
@@ -42,5 +42,6 @@
libc-static-y += $(ARCH_OUT)/aeabi_lcsts.o $(ARCH_OUT)/aeabi_math.o \
$(ARCH_OUT)/aeabi_sighandlers.o
libc-nonshared-y += $(ARCH_OUT)/aeabi_lcsts.os $(ARCH_OUT)/aeabi_math.os \
- $(ARCH_OUT)/aeabi_sighandlers.os $(ARCH_OUT)/aeabi_unwind_cpp_pr1.o
+ $(ARCH_OUT)/aeabi_sighandlers.os
endif
+libc-nonshared-y += $(ARCH_OUT)/aeabi_unwind_cpp_pr1.o
2) Il soft-galleggiante nel GCC non è correttamente incluso dal linker. Non posso davvero dire perché a questo punto.
$ find . -name '*.c' -exec grep -i -H -n nedf2 "{}" \;
./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/mips/mips.c:11123: set_optab_libfunc (ne_optab, DFmode, "__mips16_nedf2");
./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/eqdf2.c:51:strong_alias(__eqdf2, __nedf2);
./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/testsuite/gcc.c-torture/execute/gofast.c:32:int nedf2 (double a, double b) { return a != b; }
./gcc-4.5.3-r2/work/gcc-4.5.3/libgcc/config/rx/rx-abi-functions.c:41:int _COM_CMPNEd (double a, double b) { return __nedf2 (a, b) != 0; }
$ ls ./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/
README double.h extendsftf2.c fixsfti.c fixunssfdi.c floatdisf.c floattitf.c floatuntidf.c lesf2.c negtf2.c single.h trunctfdf2.c
adddf3.c eqdf2.c extendxftf2.c fixtfdi.c fixunssfsi.c floatditf.c floatundidf.c floatuntisf.c letf2.c op-1.h soft-fp.h trunctfsf2.c
addsf3.c eqsf2.c fixdfdi.c fixtfsi.c fixunssfti.c floatsidf.c floatundisf.c floatuntitf.c muldf3.c op-2.h subdf3.c trunctfxf2.c
addtf3.c eqtf2.c fixdfsi.c fixtfti.c fixunstfdi.c floatsisf.c floatunditf.c gedf2.c mulsf3.c op-4.h subsf3.c unorddf2.c
divdf3.c extenddftf2.c fixdfti.c fixunsdfdi.c fixunstfsi.c floatsitf.c floatunsidf.c gesf2.c multf3.c op-8.h subtf3.c unordsf2.c
divsf3.c extended.h fixsfdi.c fixunsdfsi.c fixunstfti.c floattidf.c floatunsisf.c getf2.c negdf2.c op-common.h t-softfp unordtf2.c
divtf3.c extendsfdf2.c fixsfsi.c fixunsdfti.c floatdidf.c floattisf.c floatunsitf.c ledf2.c negsf2.c quad.h truncdfsf2.c
$ grep -i -H -n nedf2 ./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/*
./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/eqdf2.c:51:strong_alias(__eqdf2, __nedf2);
$ grep -i -H -n eqdf2 ./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/*
./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/eqdf2.c:35:CMPtype __eqdf2(DFtype a, DFtype b)
./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/eqdf2.c:51:strong_alias(__eqdf2, __nedf2);
$ grep -i -H -n divdf3 ./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/*
./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/divdf3.c:35:DFtype __divdf3(DFtype a, DFtype b)
$ grep -i -H -n ltdf2 ./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/*
./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/ledf2.c:51:strong_alias(__ledf2, __ltdf2);
$ grep -i -H -n muldf3 ./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/*
./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/muldf3.c:35:DFtype __muldf3(DFtype a, DFtype b)
$ grep -i -H -n gedf2 ./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/*
./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/gedf2.c:35:CMPtype __gedf2(DFtype a, DFtype b)
./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/gedf2.c:51:strong_alias(__gedf2, __gtdf2);
$ grep -i -H -n fixunsdfsi ./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/*
./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/fixunsdfsi.c:35:USItype __fixunsdfsi(DFtype a)
./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/t-softfp:71:softfp_func_list := $(filter-out floatdidf floatdisf fixunsdfsi fixunssfsi \
$ grep -i -H -n truncdfsf2 ./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/*
./gcc-4.5.3-r2/work/gcc-4.5.3/gcc/config/soft-fp/truncdfsf2.c:36:SFtype __truncdfsf2(DFtype a)
così ho cercato di forzare GCC di costruire per un soft-float e ottenere quello legato tardi entro build di uclibc:
$ UCLIBC_CPU=ARM926T ACCEPT_KEYWORDS="arm" CPU_CFLAGS="-marm -march=armv5te -mtune=arm926ej-s -mabi=apcs-gnu -mno-thumb" EXTRA_FLAGS="-msoft-float -mfloat-abi=soft" UCLIBC_EXTRA_CFLAGS="${CPU_CFLAGS} ${EXTRA_CFLAGS}" STAGE1_CFLAGS="${EXTRA_CFLAGS}" CFLAGS="${EXTRA_CFLAGS}" crossdev -A arm -t arm-softfloat-linux-uclibc -P -v
E poi ho controllato per vedere se -msoft-float e -mfloat -abi = soft sono stati utilizzati all'interno di qualsiasi registro per la compilazione.
$ find . -name '*.log' -exec grep -i -H -n msoft-float "{}" \;
<nothing>
$ find . -name '*.log'
./work/build/arm-softfloat-linux-uclibc/libgcc/config.log
./work/build/libcpp/config.log
./work/build/gcc/config.log
./work/build/fixincludes/config.log
./work/build/intl/config.log
./work/build/build-x86_64-pc-linux-gnu/libiberty/config.log
./work/build/build-x86_64-pc-linux-gnu/fixincludes/config.log
./work/build/libdecnumber/config.log
./work/build/libiberty/config.log
./work/build/config.log
./work/gcc-4.5.3/contrib/reghunt/examples/29478.log
./work/gcc-4.5.3/contrib/reghunt/examples/29906a.log
./work/gcc-4.5.3/contrib/reghunt/examples/29906b.log
./work/gcc-4.5.3/contrib/reghunt/examples/28970.log
./work/gcc-4.5.3/contrib/reghunt/examples/29106.log
./work/gcc-4.5.3/contrib/reghunt/examples/30643.log
./temp/elibtool.log
./temp/epatch_user.log
./temp/epatch.log
./temp/eclass-debug.log
./temp/build.log
Ma faccio notare che --with-float = dolce si trova all'interno del config.log, in modo che mi fa credere che il galleggiante avrebbe dovuto essere generato.
E noto il -D__GCC_FLOAT_NOT_NEEDED nelle opzioni di compilazione per gcc.
Ho eseguito una regressione su GCC per vedere dove si è verificata l'interruzione.
- gcc 4.x non funziona con uclibc. - a partire da 4.4.4-r2, uclibc ha un errore di collegamento con gcc - prima di 4.4.4, gcc non appare a
- gcc-3.4.6-r2 funziona a condizione che USE = -nptl è usato
Per riferimento mi sono imbattuto: binutils: 2.22-r1 Linux intestazione: 3.3, 3.4 uclibc: 0.9.33.2 gcc: 3.2.3-r4, 3.3.6-r1, 3.4.6 -r2, 4.1.4-r1, 4.3.3-r2, 4.4.2, 4.4.4-r2, 4.4.5, 4.4.6-r1, 4.4.7, 4.5.3-r2, 4.6.0, 4.6 .1-r1, 4.6.2, 4.6.3
Ora ho un lavoro 4.7.0 Cross compilatore per uClibc. Mi ci vorrà un po 'di tempo per scrivere tutte le modifiche. –