linux内存管理 (五) 2 用户空间 glibc中的重点文件分析

编译相关(属于glibc-devel包)
  • 编译脚本
/lib/libc.so
/lib/libpthread.so
  • 函数入口
// https://www.cnblogs.com/ruiy/archive/2014/03/04/glibc.html
// https://blog.csdn.net/farmwang/article/details/73195951
//  跟 程序的 启动有关,一般会将其 与 程序一起链接 
crt1.o:                   ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
	// crt是c runtime 的缩写,用于执行进入main之前的初始化和退出main之后的扫尾工作。
	// crt1.o是启动elf的关键文件,_start就在他里面,不链这个文件,你的程序找不到启动入口 
在你的系统里面找到它,然后在链接的时候指定它就可以了
gcrt1.o:                  ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
Scrt1.o:                  ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
crti.o:                   ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
crtn.o:                   ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
Mcrt1.o:                  ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
libieee.a:                ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
libmcheck.a:              ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped

C语言和C++语言的支持


crt1.o, crti.o, crtbegin.o, crtend.o, crtn.o

前面这5个目标文件的作用分别是、初始化、构造、析构和结束,它们 通常会被自动链接到应用程序中


crt1.o, crti.o crtn.o 由 glibc 提供 , crtbegin.o crtend.o 由gcc 提供 , 五个.o相当于之前版本的 crt0.o

链接顺序:
	在标准的linux平台下,link的顺序是:ld crt1.o crti.o [user_objects] [system_libraries] crtn.o
	/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/specs
	*startfile:
	%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}}    crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}

crt1.o : 
		 作用是启动
		 crt1.o是crt0.o的后续演进版本
		 crt1.o有
		 	1. .init段
		 	2. .fini段 
		 	3. _start 函数的入口 // 还是说 _start函数就是入口
		 _start
		 	__libc_start_main // 初始化libc
		 	main // 用户main函数
crti.o :
		作用是C的初始化
		全局静态对象这样的代码需要在main函数之前
		使用 .init段
		在.init段中执行初始化函数init

crtn.o :
		作用是C的去初始化
		crtn.o则用于在.fini区中执行进程终止退出处理函数fini()函数
		即当程序正常退出时(main()返回之后),系统会安排执行.fini 中的代码

crtbegin.o : 
		作用是C++的初始化
		C++则必须依赖crtbegin.o实现,C++语言的启动模块,由编译器gcc提供
		在.ctors中执行全局构造(constructor)

crtend.o :
		作用是C++的去初始化
		在.dtors区中执行全局析构 (destructor)函数




crt0.o
  Older style of the initial runtime code ?  Usually not generated anymore
  with Linux toolchains, but often found in bare metal toolchains.  Serves
  same purpose as crt1.o (see below).
crt1.o
  Newer style of the initial runtime code.  Contains the _start symbol which
  sets up the env with argc/argv/libc _init/libc _fini before jumping to the
  libc main.  glibc calls this file 'start.S'.
crti.o
  Defines the function prolog; _init in the .init section and _fini in the
  .fini section.  glibc calls this 'initfini.c'.
crtn.o
  Defines the function epilog.  glibc calls this 'initfini.c'.
Scrt1.o
  Used in place of crt1.o when generating PIEs.
gcrt1.o
  Used in place of crt1.o when generating code with profiling information.
  Compile with -pg.  Produces output suitable for the gprof util.
Mcrt1.o
  Like gcrt1.o, but is used with the prof utility.  glibc installs this as
  a dummy file as it's useless on linux systems.


crtbegin.o
  GCC uses this to find the start of the constructors.
crtbeginS.o
  Used in place of crtbegin.o when generating shared objects/PIEs.
crtbeginT.o
  Used in place of crtbegin.o when generating static executables.
crtend.o
  GCC uses this to find the start of the destructors.
crtendS.o
  Used in place of crtend.o when generating shared objects/PIEs.

  crtbeginS.o和crtendS.o的作用与crtbegin.o crtend.o类似,但用于创建共享模块中
  • 所需链接库的链接
./libanl.so
./libBrokenLocale.so
./libcrypt.so
./libdl.so
./libm.so
./libnsl.so
./libnss_compat.so
./libnss_dns.so
./libnss_files.so
./libnss_hesiod.so
./libnss_nis.so
./libnss_nisplus.so
./libresolv.so
./librt.so
./libthread_db.so
./libutil.so
加载相关(属于glibc包)
ld-2.5.1.so

root:~# ls -l /lib/ld-linux.so.2 
lrwxrwxrwx 1 root root 11 2020-10-19 03:08 /lib/ld-linux.so.2 -> ld-2.5.1.so


该程序的主要目的是将二进制文件映射到内存中,加载程序中任何引用的库(例如前面提到的libm.so.6),然后将控制权交给正在执行的二进制文件的起始地址。

该程序被定义为ELF文件的结构的一部分,位于程序标题的INTERP部分。对于32位linux二进制文件,这是32位解释器的典型名称。对于64位二进制文​​件,您会发现它通常称为ld-linux-x86_64.so.2(对于64位x86平台)。

您可以使用readelf -l和INTERP部分自己确定此信息:

INTERP         0x0000000000000238 0x0000000000400238 0x0000000000400238
               0x000000000000001c 0x000000000000001c  R      1
    [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
根据shell/exec加载elf程序的原理,是先解析ELF,
定位并加载ld-linux.so这个程序加载器(该so路径需要通过ELF直接确定,且不依赖其他库),
然后再解析elf中需要load的共享库,但这之前可以通过LD_PRELOAD来提前预先加载共享库
运行链接相关(属于glibc包)
/etc/ld.so.conf 
/etc/ld.so.cache
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值