博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Glibc辅助运行库 (C RunTime Library): crt0.o,crt1.o,crti.o crtn.o,crtbegin.o crtend.o
阅读量:5759 次
发布时间:2019-06-18

本文共 2319 字,大约阅读时间需要 7 分钟。

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 中的代码。

posted on
2014-03-04 08:17 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/ruiy/p/glibc.html

你可能感兴趣的文章
Rainbond 5.0.4版本发布-做最好用的云应用操作系统
查看>>
Java判断是否为垃圾_Java GC如何判断对象是否为垃圾
查看>>
多项式前k项和java_多项式朴素贝叶斯softmax改变
查看>>
java数组只能交换0下标和n_编程练习-只用0交换排序数组
查看>>
php图片赋值,php如何优雅地赋值
查看>>
【探索HTML5第二弹01】HTML5的前世今生以及来世
查看>>
Failed to connect to remote VM. Connection refused. Connection refused: connect
查看>>
freeze
查看>>
设计模式 ( 十八 ):State状态模式 -- 行为型
查看>>
OracleLinux安装说明
查看>>
nova分析(7)—— nova-scheduler
查看>>
Entity Framework 实体框架的形成之旅--Code First模式中使用 Fluent API 配置(6)
查看>>
OpenMediaVault 搭建git,ssh无法连接问题
查看>>
【Web动画】SVG 实现复杂线条动画
查看>>
使用Wireshark捕捉USB通信数据
查看>>
Apache Storm 官方文档 —— FAQ
查看>>
iOS 高性能异构滚动视图构建方案 —— LazyScrollView
查看>>
Java 重载、重写、构造函数详解
查看>>
【Best Practice】基于阿里云数加·StreamCompute快速构建网站日志实时分析大屏
查看>>
HybridDB实例新购指南
查看>>