Gcc ARM gentoo与uclibc的交叉开发:需要OABI而不是EABI

Gcc ARM gentoo与uclibc的交叉开发:需要OABI而不是EABI,gcc,arm,gentoo,cross-compiling,uclibc,Gcc,Arm,Gentoo,Cross Compiling,Uclibc,有人能帮我解决我的ARM+GCC+UCLIBC与crossdev的链接问题吗 也发布到Gentoo论坛: 最近,我被分配到一个项目,该项目使用旧的GCC和OABI开发了可执行文件。作为参考,这里是readelf的头输出,它是一个在系统上正常运行的可执行文件: ELF Header: Magic: 7f 45 4c 46 01 01 01 61 00 00 00 00 00 00 00 00 Class: ELF32 Dat

有人能帮我解决我的ARM+GCC+UCLIBC与crossdev的链接问题吗

也发布到Gentoo论坛:

最近,我被分配到一个项目,该项目使用旧的GCC和OABI开发了可执行文件。作为参考,这里是readelf的头输出,它是一个在系统上正常运行的可执行文件:

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
我使用crossdev和最新的gcc/binutils/linux headers/等以及EABI创建了一个交叉编译器

$ crossdev arm-softfloat-linux-uclibceabi
我很高兴地开始使用交叉编译器在本地文件夹中填充可执行文件,但后来在我的硬件上尝试了该可执行文件,并发现最终出现了分段错误。我意识到,只是通过谷歌搜索,我真的需要为uclibc保留旧的、遗留的ABI:OABI。我以前的交叉编译器大约来自2005年

另一个参考点是,我使用eabi的可执行文件从readelf生成的头有点像这样:

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
#!/usr/bin/env sh
CHOST=${CHOST-arm-softfloat-linux-uclibc}
USE="-nptl" \
crossdev -t ${CHOST} \
 -A arm -P "--digest" \
 --g 4.7.0 --genv 'EXTRA_ECONF="--enable-obsolete --with-cpu=arm926ej-s \
                   --without-system-libunwind --with-mode=arm \
                   --with-abi=apcs-gnu --with-float-abi=soft"' \
 --lenv 'UCLIBC_CPU="ARM926T" \
         UCLIBC_EXTRA_CFLAGS="-marm -mcpu=arm926ej-s"'
虽然机器是相同的,但分段错误不能提供在目标上执行二进制文件的方法

在谷歌搜索了更多信息后,我发现可能有一种方法可以使用eabi编译器为遗留系统生成一些代码。当我运行这个命令时,我非常高兴:

$ 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
我最终得到了:

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
在这一点上,我感到不安,我决定尝试用-mabi=apcs gnu创建一个可执行文件

arm-softfloat-linux-uclibceabi-gcc -mabi=apcs-gnu -static -o /mnt/arm_uclibc/tmp/test /mnt/arm/tmp/test.c
我得到一个链接器错误:

/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
问题:这让我相信我的EABI不正确,我需要OABI。是这样吗

我相信情况确实如此,所以我开始通过crossdev研究uclibc:

$ crossdev arm-softfloat-linux-uclibc -P -v
我很高兴地报告,编译成某种对象二进制文件的文件具有正确的elf头。所以我想这就是我想要的

但在uclibc的编译过程中,这种情况会消失,如下所示:

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
如果我正确地分析了错误,我相信

1) arm Makefile.arch未正确构建_aeabi_unwind_cpp_pr0,因为该文件仅在设置EABI时生成:

$ 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)
{
}
2) 链接器也未正确包含gcc中的软浮点。我现在真的说不出为什么

$ 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)
因此,我试图强制GCC构建一个软浮点,并在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
然后我检查了是否在任何日志中使用了-msoft float和-mfloat abi=soft进行编译

$ 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
$find-名称'*.log'-execgrep-i-H-nmsoftfloat“{}”\;
$find-名称'*.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
/温度/epatch.log
./temp/eclass-debug.log
/temp/build.log
但是我注意到--with float=soft是在config.log中设置的,因此我认为应该已经生成了float。
我注意到在GCC的编译选项中不需要-D_uugcc_FLOAT_

我在GCC上运行了一个回归,以查看中断发生的位置

  • GCC4.x不适用于uclibc。 --从4.4.4-r2开始,uclibc与gcc的链接失败 --在4.4.4之前,gcc似乎没有
  • gcc-3.4.6-r2在使用USE=-nptl的情况下有效
  • 作为参考,我运行: 比努蒂尔斯:2.22-r1 Linux头文件: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。最终构建是:

    • 比努蒂尔斯-2.22-r1
    • gcc-4.7.0
    • linux-headers-3.4
    • uclibc-0.9.33.2
    我的crossdev arm softfloat linux uclibc编译器命令如下所示:

    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
    
    #!/usr/bin/env sh
    CHOST=${CHOST-arm-softfloat-linux-uclibc}
    USE="-nptl" \
    crossdev -t ${CHOST} \
     -A arm -P "--digest" \
     --g 4.7.0 --genv 'EXTRA_ECONF="--enable-obsolete --with-cpu=arm926ej-s \
                       --without-system-libunwind --with-mode=arm \
                       --with-abi=apcs-gnu --with-float-abi=soft"' \
     --lenv 'UCLIBC_CPU="ARM926T" \
             UCLIBC_EXTRA_CFLAGS="-marm -mcpu=arm926ej-s"'
    
    上面的选项可能并不都是必需的,但值得注意的是,gcc的下一个主要版本将淘汰uclibc的OABI,除非最终有一个愿意保持更新的开发人员。至少两年没有了

    另外,我没有使用gcc启用nptl。我认为可以在不启用nptl的情况下执行crossdev构建阶段3,然后使用nptl执行最终的gcc,但是我没有使用二进制文件进行任何测试来证明这实际上插入了nptl

    不幸的是,gcc和uclibc在开箱即用的情况下不能很好地配合。我还意识到我需要一些补丁来修复我发现的错误

    为了让自己更轻松,我还创建了一个补丁文件夹,这样我就不必用ebuild创建一个全新的覆盖。在emerge的执行过程中,这让我可以动态添加补丁。在大多数情况下,这将适用于大多数软件包。我仍在使用Python使其成为一个平滑的编译

    创建修补程序文件夹:

    $ mkdir /etc/portage/patches
    
    正在更新portage bashrc:

    File:  /etc/portage/bashrc
    #!/usr/bin/env sh
    [[ $(basename $(readlink -f $PORTAGE_CONFIGROOT/etc/make.profile)) == "embedded" ]] && . ${PORTDIR}/profiles/base/profile.bashrc
    
    post_src_install() {
        [[ -d ${D} ]] || return 0
        [[ ${E_MACHINE} == "" ]] && return 0
        cmdline=""
        for EM in $E_MACHINE; do
            cmdline+=" -e ^${EM}[[:space:]]";
        done
        output="$( cd ${D} && scanelf -RmyBF%a . | grep -v ${cmdline} )"
        [[ $output != "" ]] && { echo; echo "* Wrong EM_TYPE. Expected ${E_MACHINE}"; echo -e "${output}"; echo; exit 1; }
    }
    
    # We don't run this on the assumption that when you're
    # emerging binary packages, it's into a runtime ROOT
    # rather than build development ROOT.  The former doesn't
    # want hacking while the latter does.  
    if [[ $EBUILD_PHASE == "postinst" ]]; then
        [[ $SYSROOT == $ROOT ]] && cross-fix-root ${CHOST}
    fi
    
    eecho() {
        #[ "$NOCOLOR" = "false" ] && echo -ne '\e[1;34m>\e[1;36m>\e[1;35m>\e[0m ' || echo -n ">>> "
        echo -ne '\e[1;34m>\e[1;36m>\e[1;35m>\e[0m ' || echo -n ">>> "
        echo "$*"
    }
    
    run_autopatch () {
        #echo ">>> --------------------------------------------------------------------"
        #echo ">>>"
        #echo ">>>  Phase: $EBUILD_PHASE"
        #echo ">>>"
        #echo ">>> --------------------------------------------------------------------"
    
        patchit="no"
        if [[ $EBUILD_PHASE == prepare ]]; then
        patchit="yes"
        elif [[ $EBUILD_PHASE == configure ]]; then
        patchit="yes"
        elif [[ $EBUILD_PHASE == compile ]]; then
        patchit="yes"
        fi
    
        if [[ $patchit != "no" ]]; then
    #           echo ">>> Patching"
        [[ ! -d "$PATCH_OVERLAY" ]] && echo "PATCH_OVERLAY is not a directory: $PATCH_OVERLAY" && return 0;
        [[ ! -r ${ROOT}etc/portage/bashrc.autopatch ]] && echo "Couldn't read autopatch script: ${ROOT}/etc/portage/bashrc.autopatch" && return 0;
        source ${ROOT}etc/portage/bashrc.autopatch
        fi
    }
    
    if [[ " ${FEATURES} " == *" autopatch "* ]] || [[ $AUTOPATCH="yes" ]]; then
        run_autopatch
    fi
    
    还需要创建bashrc.autopatch

    File:  /etc/portage/bashrc.autopatch
    #!/usr/bin/env sh
    # <solar@gentoo> 2005
    # Distributed under the terms of the GNU General Public License v2
    # $Header: $
    # updated by brian bruggeman
    
    autopatch() {
    local diff level p patches patched 
    
    [[ ! -d "$PATCH_OVERLAY" ]] && return 0
    
    patches=$(ls -1 ${PATCH_OVERLAY}/${CATEGORY}/${PN}/${PN}-*.{patch,diff} 2>/dev/null)
    [[ $patches == "" ]] && echo "No patches found: ${PATCH_OVERLAY}/${CATEGORY}/${PN}/${PN}-*.patch" && return 0
    
        if [[ -d $S ]] && [[ -e $S ]]; then
        cd $S
    else
        echo ">>> Couldn't cd to $S"
    fi
    
        echo -e ' \e[0;36m*\e[0m '"Applying Autopatches from $PATCH_OVERLAY ..."
    for p in ${patches}; do
        p=$(basename $p)
        diff=${PATCH_OVERLAY}/${CATEGORY}/${PN}/${p}
        if [[ -e $diff ]] && [ ! -e ${S}/.${p} ]; then
            patched=0
            for level in 0 1 2 3 4; do
                if [[ $patched == 0 ]]; then
                    patch -g0 --dry -p${level} >/dev/null < $diff
                    if [ $? = 0 ]; then
                        echo -e ' \e[0;36m*\e[0m '"  (-p${level}) ${p}"
                        patch -g0 -p${level} < $diff > /dev/null && patched=1
                        touch $S/.${p}
                    fi
                fi
            done
            [[ $patched != 1 ]] && echo "!!! FAILED auto patching $p"
        else
            [[ ! -e $diff ]] && echo "!!! $diff does not exist, unable to auto patch"
        fi
    done
        echo -e ' \e[0;36m*\e[0m '"Done with patching auto patches ..."
    cd $OLDPWD
    }
    
    PATH=$PATH:/usr/sbin:/usr/bin:/bin:/sbin
    autopatch
    
    为uclibc创建修补程序:

    $ cd /etc/portage/packages
    $ mkdir -p cross-arm-softfloat-linux-uclibc/uclibc
    $ cd cross-arm-softfloat-linux-uclibc/uclibc
    $ touch uclibc-0.9.33.2-unwind-fixes.patch
    
    File: /etc/portage/packages/cross-arm-softfloat-linux-uclibc/uclibc/uclibc-0.9.33.2-unwind-fixes.patch
    Index: libc/sysdeps/linux/arm/Makefile.arch
    ===================================================================
    --- ./libc/sysdeps/linux/arm/Makefile.arch  2012-05-15 02:20:09.000000000 -0500
    +++ ./libc/sysdeps/linux/arm/Makefile.arch.new  2012-05-31 00:43:11.176050458 -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
    Index: libc/sysdeps/linux/arm/unwind.h
    ===================================================================
    --- ./libc/sysdeps/linux/arm/unwind.h   2012-05-31 00:57:39.356041552 -0500
    +++ ./libc/sysdeps/linux/arm/unwind.h.new   2012-05-31 01:04:55.436037080 -0500
    @@ -34,6 +34,8 @@
    
     #define __ARM_EABI_UNWINDER__ 1
    
    +#include <stdlib.h>
    +
     #ifdef __cplusplus
     extern "C" {
     #endif
    @@ -211,7 +213,7 @@
        _Unwind_Control_Block *, struct _Unwind_Context *, void *);
       _Unwind_Reason_Code _Unwind_ForcedUnwind (_Unwind_Control_Block *,
                            _Unwind_Stop_Fn, void *);
    -  _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *);
    +  extern _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *);
       void _Unwind_Complete(_Unwind_Control_Block *ucbp);
       void _Unwind_DeleteException (_Unwind_Exception *);
    
    $cd/etc/portage/packages
    $mkdir-p交叉臂softfloat linux uclibc/uclibc
    $cd交叉臂softfloat linux uclibc/uclibc
    $touch uclibc-0.9.33.2-unwind-fixes.patch
    文件:/etc/portage/packages/cross-arm-softfloat-linux-uclibc/uclibc/uclibc-0.9.33.2-unwind-fixes.patch
    索引:libc/sysdeps/linux/arm/Makefile.arch
    ===================================================================
    ---/libc/sysdeps/linux/arm/Makefile.arch 2012-05-15 02:20:09.000000000-0500
    +++./libc/sysdeps/linux/arm/Makefile.arch.new 2012-05