crt1.o, crti.o, crtbegin.o, crtend.o, crtn.o 等目标文件和daemon.o(由我们自己的C程序文件产生)链接成一个执行文件。前面这5个目标文件的作用分别是启动、初始化、构造、析构和结束,它们通常会被自动链接到应用程序中。例如,应用程序的main()函数就是通过这些文件来调用的。如果不进行标准的链接的话(编译选项-nostdlib),我们就必须指明这些必要的目标文件,如果未指定,链接器就会提示找不到_start符号,并因此导致链接失败。且,将目标文件提供给编译器的次序也很重要,因为GNU链接器(编译器会自动调用该链接器进行目标文件的链接)只是个单次处理链接器。

Glibc有几个辅助程序运行的运行库 (C RunTime Library),分别是/usr/lib/crt1.o、/usr/lib/crti.o和/usr/lib/crtn.o,其中crt1.o中包含程序的入口函数_start以及两个未定义的符号__libc_start_main和main,由_start负责调用__libc_start_main初始化libc,然后调用我们源代码中定义的main函数;另外,由于类似于全局静态对象这样的代码需要在main函数之前执行,crti.o和crtn.o负责辅助启动这些代码。另外,Gcc中同样也有crtbegin.o和crtend.o两个文件,这两个目标文件用于配合glibc来实现C++的全局构造和析构。

android bionic,这个C runtime library设计并不是功能特别强大,并且有些gnu glic中的函数没有实现,这是移植时会碰到的问题.而且,这个C runtime library也并没有采用crt0.o,crt1.o,crti.o crtn.o,crtbegin.o crtend.o,而是采用了android自己的crtbegin_dynamic.o, crtbegin_static.o 和crtend_android.o。crt1.o是crt0.o的后续演进版本,crt1.o中会非常重要的.init段和.fini段以及_start函数的入口..init段和.fini段实际上是靠crti.o以及crtn.o来实现的. init段是main函数之前的初始化工作代码, 比如全局变量的构造. fini段则负责main函数之后的清理工作.crti.o crtn.o是负责C的初始化,而C++则必须依赖crtbegin.o和crtend.o来帮助实现.
        So,在标准的linux平台下,link的顺序是:ld crt1.o crti.o [user_objects] [system_libraries] crtn.o
        而在android下,link的顺序是:arm-eabi-g++ crtbegin_dynamic.o [user_objects] [system_libraries]crtend_android.o
        所以这就是从另一个方面说明为什么不适合codesourcery之类编译来开发android底层东西的原因了,这里不包括BSP之类.

main()也是一个函数。

这是因为在编译连接时它将会作为crt0.s汇编程序的函数被调用。crt0.s是一个桩(stub)程序,名称中的“crt”是“C run-time”的缩写。该程序的目标文件将被链接在每个用户执行程序的开始部分,主要用于设置一些初始化全局变量。通常使用gcc编译链接生成文件时,gcc会自动把该文件的代码作为第一个模块链接在可执行程序中。在编译时使用显示详细信息选项“-v”就可以明显地看出这个链接操作过程。因此在通常的编译过程中,我们无需特别指定stub模块crt0.o。为了使用ELF格式的目标文件以及建立共享库模块文件,现在的编译器已经把crt0扩展成几个模块:crt1.0、crti.o、crtbegin.o、crtend.o和crtn.o。这些模块的链接顺序为crt1.o、crti.o、crtbegin.o(crtbeginS.o)、所有程序模块、crtend.o(crtendS.o)、crtn.o、库模块文件。gcc的配置文件specfile指定了这种链接顺序。其中,crt1.o、crti.o和crtn.o由C库提供,是C程序的“启动”模块;crtbegin.o和crtend.o是C++语言的启动模块,由编译器gcc提供;而crt1.o则与crt0.o的作用类似,主要用于在调用main()之前做一些初始化工作,全局符号_start就定义在这个模块中。crtbegin.o和crtend.o主要用于C++语言,在.ctors和.dtors区中执行全局构造(constructor)和析构(destructor)函数。crtbeginS.o和crtendS.o的作用与前两者类似,但用于创建共享模块中。crti.o用于在.init区中执行初始化函数init()。.init区中包含进程的初始化代码,即当程序开始执行时,系统会在调用main()之前先执行.init中的代码。crtn.o则用于在.fini区中执行进程终止退出处理函数fini()函数,即当程序正常退出时(main()返回之后),系统会安排执行.fini中的代码。

————————————————
版权声明:本文为CSDN博主「Dartagnan」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/dadoneo/article/details/8201403

crt0.o的更多相关文章

  1. Glibc辅助运行库 (C RunTime Library): crt0.o,crt1.o,crti.o crtn.o,crtbegin.o crtend.o

    crt1.o, crti.o, crtbegin.o, crtend.o, crtn.o 等目标文件和daemon.o(由我们自己的C程序文件产生)链接成一个执行文件.前面这5个目标文件的作用分别是启 ...

  2. crt0.S(_main)代码分析

    crt0,S(_main)代码分析 --- 1. 设置sp寄存器地址 //设置SP栈指针 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG ...

  3. LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main

    在创建MFC项目时,如果没有设置好项目参数, 就会在编译时产生很多连接错误, 如我今天遇到的: LIBCD.lib(crt0.obj) : error LNK2001: unresolved exte ...

  4. 《Walking the callstack(转载)》

    本文转载自:https://www.codeproject.com/articles/11132/walking-the-callstack Download demo project with so ...

  5. u-boot-2015.04 在tq2440上的移植(使用spl引导u-boot)

    本次移植跟以往的不同之处是采用了spl来引导u-boot,参考了博客http://blog.csdn.net/fulinus/article/details/42738641 下载链接:http:// ...

  6. uboot 第三天学习

    make jCPU_NUM 以CPU_NUM数量同时进行编译CPU_NUM = 当前PC的处理器数量*处理器的核心数 从上电开始1.系统上电,执行固化在IROM中的代码,目的初始化基本的系统功能,已经 ...

  7. VC 6中配置OpenGL开发环境

    2010,2012中配置类似 http://hi.baidu.com/yanzi52351/item/f9a600dffa4caa4ddcf9be1d VC 6中配置OpenGL开发环境 这里,我习惯 ...

  8. Android Bootloader LittleKernel的两篇文章 【转】

    转自:http://blog.csdn.net/loongembedded/article/details/41747523 2014-12-05 14:37 3599人阅读 评论(2) 收藏 举报 ...

  9. glibc与MSVC CRT(转载)

    glibc与MSVC CRT 运行库是平台相关的,因为它与操作系统结合得非常紧密.C语言的运行库从某种程度上来讲是C语言的程序和不同操作系统平台之间的抽象层,它将不同的操作系统API抽象成相同的库函数 ...

随机推荐

  1. shader飞线改进版

    项目github地址:https://github.com/ecojust/flyline 前面写过一个飞线(基于THREE.Line进行的颜色变化),只是简单地将可视区片元颜色的alpha通道值设为 ...

  2. java:ssh连接服务器,实现本地文件上传和下载

    1.连接至服务器:ssh hp@10.10.17.16 -p 5555    下载文件:scp -r hp@10.10.17.16:/ccc(服务器路径,文件夹下所有文件)  /path(本地路径) ...

  3. java:shiro(认证,赋予角色,授权...)

    1.shiro(权限框架(认证,赋予角色,授权...)): readme.txt(运行机制): 1.从jsp的form中的action属性跳转到springmvc的Handler中(controlle ...

  4. CTF—攻防练习之HTTP—SQL注入(SSI注入)

    主机:192.168.32.152 靶机:192.168.32.161 ssI是赋予html静态页面的动态效果,通过ssi执行命令,返回对应的结果,若在网站目录中发现了.stm .shtm .shtm ...

  5. app测试自动化操作方法之一

    1.在输入框里输入字符 dr.find_element_by_android_uiautomator\ ( 'new UiSelector().text("邮箱或手机号")').s ...

  6. 【ABAP系列】SAP ABAP 带有参数的AMDP的创建

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP 带有参数的AM ...

  7. 自定义 filter simple_tag inclusion_tag 总结

    在已经注册的app下创建templatetags的python包 在包内创建py文件 my_tags.py 在py文件中写代码: from django import template registe ...

  8. 【Python基础】lpthw - Exercise 47 自动化测试

    一.自动化测试的目的 利用自动化的测试代码取代手动测试,使得程序中的一些初级bug可以被自动检出,而无需人工进行重复繁琐的测试工作. 二.编写测试用例 利用上一节编写的skeleton,这次在proj ...

  9. python基础--合并两个列表

    a = [1,2,3] b = [4,5,6] # 将两个列表合并 # append方法是不行的 # a.append(b) # print(a) # [1, 2, 3, [4, 5, 6]] # 我 ...

  10. eclipse SVN插件的日常使用

    安装(我的安装方法,怎么方便怎么来) 1.打开eclipse,选择Help->Eclipse MarketPlace,搜索subclipse,点击install,等待.安装成功后会询问重启,点击 ...