1. 1. 原生程序的启动流程分析 (P194.)

原生程序的启动流程分析 (P194.)

  1. GCC命令参数说明
  • 未使用默认C库:

    Android 未使用glibc作为C库,而是采用了google自己开发的Bionic C因此编译时需要加入 -nostdlib

  • 静态链接:

    gcc 命令参数中指定 -Bstatic,在生成可执行程序时会链接 crtbegin_static.ocrtend_android.ocrtbegin_static.o 文件中定义了静态链接的启动函数 _start,这个函数是程序启动时的第一个函数。

  • 动态链接:

    需要在gcc命令中指定 -Bdynamic,在生成可执行文件时会链接 crtbegin_dynamic.ocrtend_android.o 目标文件,并且动态链接时需要通过 –dynamic-linker 指定 加载器,默认为 /system/bin/linker。在生成的可执行程序中,每个程序都会包含一个 .interp 段存入程序的 加载器。 动态库的启动函数 _start 位于 crtbegin_dynamic.o 文件中。

  • 链接脚本:

    无论是动态链接还是静态链接Android原生程序,在链接时都会传入一个链接脚本根据链接时指定参数的不同,所传入的链接脚本也不一样,所有的链接脚本位于Android NDK的 toolchains\arm-linux-android-4.4.3\prebuilt\windows\arm-linux-androideabi\lib\ldscripts 目录。默认情况下链接时会传入 armelf_linux_eabi.x 脚本文件,该文件的第五行代码 ENTRY(_start) 指出程序入口函数为_start。

    1
    2
    3
    4
    5
    6
    /* 此处省略N行 */
    OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
    "elf32-littlearm")
    OUTPUT_ARCH(arm)
    ENTRY(_start)
    /* 此处省略N行 */
  • crtbegin_dynamic.S 与 crtbegin_static.S 位于Android源码位置:

    bionic\libc\arch-arm\bionic目录下