linux内存管理 (五) 1 用户空间 用户态的内存管理

前言
之前只是 分析了 Linux内存管理系统启动 的全过程
也大概分析了 内存如何申请和释放,虽然着墨甚少
用户空间的内存管理一直没涉及.

现在想就 用户空间的内存管理说一下
可能涉及到以下概念 : 
	mmap brk  等 系统 调用 
	glibc中的内存管理

在此之前,需要了解应用程序的编译链接及加载过程
编译链接 需要
	gcc的(crtbegin.o crtend.o) 
	glibc的(crt1.o crti.o crtno) 

	gcc 的 cc1 collect2
	binutils的ld和as

运行需要 
	kernel 的 sys_execve
	glibc的ld.so
所以研究顺序是这样子的
	1. 应用程序的编译链接
	2. 应用程序的运行
	3. 系统调用
	4. glibc与内核交互中 内存相关部分
	5. glibc中的内存管理

Binutils 
	没有指定依赖的版本
gcc 
	指定了 glibc 的 最低版本
	--with-glibc-version=2.11
	此选项可确保包与主机的glibc版本兼容。它被设置为主机系统要求中指定的最低glibc要求。
kernel 
	没有指定依赖的版本
glibc 
	指定了 kernel的 最低版本(可在源码README中找到)
	--enable-kernel=3.2
	这告诉Glibc编译支持3.2及更高版本Linux内核的库。未启用较早内核的解决方法。
	$ file /lib64/libc-2.32.so
	/lib64/libc-2.32.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked (uses shared libs), BuildID[sha1]=d78066a9c36f5fd63e2f6ac851ae3515c4c9792a, for GNU/Linux 3.2, not stripped

其他

glibc

glibc-2.17 在 centos上 可以打出 10个包
glibc
glibc-xen
glibc-devel
glibc-static
glibc-headers
glibc-common
nscd
glibc-utils
glibc-debuginfo
glibc-debuginfo-common
装了6个
glibc-2.17-307.el7.1.x86_64
glibc-headers-2.17-307.el7.1.x86_64
glibc-utils-2.17-307.el7.1.x86_64
glibc-devel-2.17-307.el7.1.x86_64
glibc-common-2.17-307.el7.1.x86_64
glibc-static-2.17-307.el7.1.x86_64
glibc-2.5.1.tar.bz2 编译方法
tar xvf /lfs-sources/glibc-2.5.1.tar.bz2
cd glibc-2.5.1
mkdir -v ../glibc-build
cd ../glibc-build
../glibc-2.5.1/configure --prefix=/mnt/lfs/glibc \
--disable-profile --enable-add-ons \
--enable-kernel=2.6.0 --with-binutils=/tools/bin \
--without-gd --with-headers=/tools/include \
--without-selinux
make
mkdir -v /mnt/lfs/glibc/etc
touch /mnt/lfs/glibc/etc/ld.so.conf
make install
cd ..
rm -rf glibc-build
rm -rf glibc-2.5.1

glibc-2.5.1 编译出来的文件
编译出的普通文件数量(/usr 下面)

./bin :15 // bin 目录下 有 15个普通文件
./etc :3
./include :392
./info :13
./lib :288
./libexec :3
./sbin :7
./share :2121
  • bin & sbin

#ls bin/
catchsegv  gencat  getconf  getent  iconv  ldd  lddlibc4  locale  localedef  mtrace  pcprofiledump  rpcgen  sprof  tzselect  xtrace

# ls sbin 
iconvconfig  ldconfig  nscd  rpcinfo  sln  zdump  zic

16个二进制可执行文件 : 
	bin/gencat
	bin/getconf
	bin/getent
	bin/iconv
	bin/lddlibc4
	bin/locale
	bin/localedef
	bin/pcprofiledump
	bin/rpcgen
	bin/sprof
	sbin/iconvconfig
	sbin/ldconfig
	sbin/rpcinfo
	sbin/sln
	sbin/zdump
	sbin/zic
4个bash脚本文件
	bin/catchsegv
	bin/ldd
	bin/tzselect
	bin/xtrace
1个perl脚本文件
	bin/mtrace
1个ELF 32-bit LSB shared object
	sbin/nscd

  • etc & info & libexec
# ls etc/
ld.so.conf  // 文件中的每一行路径可作为 运行时链接路径,修改之后,要运行  ldconfig 才生效 // 注意 运行程序时并不会解析该文件
ld.so.cache // ldconfig 之后,所有库文件都会被缓存到 该文件中 , 运行程序时 会 解析该文件
			// strace 得到的信息 : open("/etc/ld.so.cache", O_RDONLY)      = 3
			// ld.so.cache 会记录 某个 libxxx.so在什么路径下
localtime   // 保存当前的时区 , timedatectl 运行的时候 会 读取文件
			// 该文件一般为链接 , 指向 /etc/localtime -> ../usr/share/zoneinfo/Asia/Shanghai
rpc 		// 不知道是干什么的,像是一个参考文件,没被程序使用


# file etc/ *
etc/ld.so.cache: data
etc/ld.so.conf:  empty
etc/localtime:   symbolic link to `../share/zoneinfo/Factory'
etc/rpc:         ASCII C program text

// info 信息 , info 命令会用到
# ls info/
dir        libc.info-1   libc.info-11  libc.info-3  libc.info-5  libc.info-7  libc.info-9
libc.info  libc.info-10  libc.info-2   libc.info-4  libc.info-6  libc.info-8

# file info/ *
info/dir:          data
info/libc.info:    data
info/libc.info-1:  data
info/libc.info-10: data
info/libc.info-11: data
info/libc.info-2:  data
info/libc.info-3:  data
info/libc.info-4:  data
info/libc.info-5:  data
info/libc.info-6:  data
info/libc.info-7:  data
info/libc.info-8:  data
info/libc.info-9:  data

// /libexec is reserved for executables initiated by an already runing program.
# ls libexec/ -R
libexec/:
getconf  pt_chown

libexec/getconf:
POSIX_V6_ILP32_OFF32  POSIX_V6_ILP32_OFFBIG

]# file libexec/ *
libexec/pt_chown: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, dynamically linked (uses shared libs), not stripped
libexec/getconf/POSIX_V6_ILP32_OFF32:  ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, dynamically linked (uses shared libs), not stripped
libexec/getconf/POSIX_V6_ILP32_OFFBIG: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, dynamically linked (uses shared libs), not stripped
  • lib
// 静态库,动态库
# ls  lib
crt1.o                    libBrokenLocale.so.1  libdl.so.2              libnss_compat.so         libnss_nisplus.so.2     librt-2.5.1.so
crti.o                    libbsd-compat.a       libg.a                  libnss_compat.so.2       libnss_nis.so           librt.a
crtn.o                    libc-2.5.1.so         libieee.a               libnss_dns-2.5.1.so      libnss_nis.so.2         librt.so
gconv                     libc.a                libm-2.5.1.so           libnss_dns.so            libpcprofile.so         librt.so.1
gcrt1.o                   libc_nonshared.a      libm.a                  libnss_dns.so.2          libpthread-2.5.1.so     libSegFault.so
ld-2.5.1.so               libcrypt-2.5.1.so     libmcheck.a             libnss_files-2.5.1.so    libpthread.a            libthread_db-1.0.so
ld-linux.so.2             libcrypt.a            libmemusage.so          libnss_files.so          libpthread_nonshared.a  libthread_db.so
libanl-2.5.1.so           libcrypt.so           libm.so                 libnss_files.so.2        libpthread.so           libthread_db.so.1
libanl.a                  libcrypt.so.1         libm.so.6               libnss_hesiod-2.5.1.so   libpthread.so.0         libutil-2.5.1.so
libanl.so                 libc.so               libnsl-2.5.1.so         libnss_hesiod.so         libresolv-2.5.1.so      libutil.a
libanl.so.1               libc.so.6             libnsl.a                libnss_hesiod.so.2       libresolv.a             libutil.so
libBrokenLocale-2.5.1.so  libdl-2.5.1.so        libnsl.so               libnss_nis-2.5.1.so      libresolv.so            libutil.so.1
libBrokenLocale.a         libdl.a               libnsl.so.1             libnss_nisplus-2.5.1.so  libresolv.so.2          Mcrt1.o
libBrokenLocale.so        libdl.so              libnss_compat-2.5.1.so  libnss_nisplus.so        librpcsvc.a             Scrt1.o


lib ]# s-dir_num  // usr/lib/gconv 下都是 so 文件
./gconv :240


lib ]# ls -l |grep "^-" | awk -F " " '{print $8}' | xargs   // 除去 /usr/lib/gconv 中的文件,有 48个普通文件
crt1.o crti.o crtn.o gcrt1.o ld-2.5.1.so libanl-2.5.1.so libanl.a libBrokenLocale-2.5.1.so libBrokenLocale.a libbsd-compat.a libc-2.5.1.so libc.a libc_nonshared.a libcrypt-2.5.1.so libcrypt.a libc.so libdl-2.5.1.so libdl.a libg.a libieee.a libm-2.5.1.so libm.a libmcheck.a libmemusage.so libnsl-2.5.1.so libnsl.a libnss_compat-2.5.1.so libnss_dns-2.5.1.so libnss_files-2.5.1.so libnss_hesiod-2.5.1.so libnss_nis-2.5.1.so libnss_nisplus-2.5.1.so libpcprofile.so libpthread-2.5.1.so libpthread.a libpthread_nonshared.a libpthread.so libresolv-2.5.1.so libresolv.a librpcsvc.a librt-2.5.1.so librt.a libSegFault.so libthread_db-1.0.so libutil-2.5.1.so libutil.a Mcrt1.o Scrt1.o




# ls |  xargs  file | sort -k 2 
// 这两个不知道为什么是 ASCII 文件
//名为.so的文件时,它可能是
//	1.共享库 // 运行时被使用
//	2.共享库的链接文件  // 链接时被使用
//	3.链接器脚本 		// GNU ld 系统上的.so文件有可能是链接器脚本 (例如 libc.so)
libc.so:                  ASCII C program text
libpthread.so:            ASCII C program text
// 静态库
libc.a:                   current ar archive
libg.a:                   current ar archive
libm.a:                   current ar archive
libdl.a:                  current ar archive
librt.a:                  current ar archive
libanl.a:                 current ar archive
libnsl.a:                 current ar archive
libutil.a:                current ar archive
libcrypt.a:               current ar archive
libresolv.a:              current ar archive
librpcsvc.a:              current ar archive
libpthread.a:             current ar archive
libbsd-compat.a:          current ar archive
libc_nonshared.a:         current ar archive
libBrokenLocale.a:        current ar archive
libpthread_nonshared.a:   current ar archive
// 用于编码间转换的gconv文件,头文件在 gconv.h
gconv:                    directory
//  跟 程序的 启动有关,一般会将其 与 程序一起链接 
crt1.o:                   ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
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
// 动态 库
libc-2.5.1.so:            ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libm-2.5.1.so:            ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libdl-2.5.1.so:           ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libmemusage.so:           ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
librt-2.5.1.so:           ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libSegFault.so:           ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libanl-2.5.1.so:          ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libnsl-2.5.1.so:          ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libpcprofile.so:          ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libutil-2.5.1.so:         ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libcrypt-2.5.1.so:        ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libresolv-2.5.1.so:       ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libnss_dns-2.5.1.so:      ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libnss_nis-2.5.1.so:      ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libpthread-2.5.1.so:      ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libthread_db-1.0.so:      ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libnss_files-2.5.1.so:    ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libnss_compat-2.5.1.so:   ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libnss_hesiod-2.5.1.so:   ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libnss_nisplus-2.5.1.so:  ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
libBrokenLocale-2.5.1.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, not stripped
ld-2.5.1.so:              ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), not stripped

// 链接文件 , 一般 .so 属于 devel 包中的数据
ld-linux.so.2:            symbolic link to `ld-2.5.1.so'
libanl.so.1:              symbolic link to `libanl-2.5.1.so'
libanl.so:                symbolic link to `libanl.so.1'
libBrokenLocale.so.1:     symbolic link to `libBrokenLocale-2.5.1.so'
libBrokenLocale.so:       symbolic link to `libBrokenLocale.so.1'
libc.so.6:                symbolic link to `libc-2.5.1.so'
libcrypt.so.1:            symbolic link to `libcrypt-2.5.1.so'
libcrypt.so:              symbolic link to `libcrypt.so.1'
libdl.so.2:               symbolic link to `libdl-2.5.1.so'
libdl.so:                 symbolic link to `libdl.so.2'
libm.so.6:                symbolic link to `libm-2.5.1.so'
libm.so:                  symbolic link to `libm.so.6'
libnsl.so.1:              symbolic link to `libnsl-2.5.1.so'
libnsl.so:                symbolic link to `libnsl.so.1'
libnss_compat.so.2:       symbolic link to `libnss_compat-2.5.1.so'
libnss_compat.so:         symbolic link to `libnss_compat.so.2'
libnss_dns.so.2:          symbolic link to `libnss_dns-2.5.1.so'
libnss_dns.so:            symbolic link to `libnss_dns.so.2'
libnss_files.so.2:        symbolic link to `libnss_files-2.5.1.so'
libnss_files.so:          symbolic link to `libnss_files.so.2'
libnss_hesiod.so.2:       symbolic link to `libnss_hesiod-2.5.1.so'
libnss_hesiod.so:         symbolic link to `libnss_hesiod.so.2'
libnss_nis.so.2:          symbolic link to `libnss_nis-2.5.1.so'
libnss_nisplus.so.2:      symbolic link to `libnss_nisplus-2.5.1.so'
libnss_nisplus.so:        symbolic link to `libnss_nisplus.so.2'
libnss_nis.so:            symbolic link to `libnss_nis.so.2'
libpthread.so.0:          symbolic link to `libpthread-2.5.1.so'
libresolv.so.2:           symbolic link to `libresolv-2.5.1.so'
libresolv.so:             symbolic link to `libresolv.so.2'
librt.so.1:               symbolic link to `librt-2.5.1.so'
librt.so:                 symbolic link to `librt.so.1'
libthread_db.so.1:        symbolic link to `libthread_db-1.0.so'
libthread_db.so:          symbolic link to `libthread_db.so.1'
libutil.so.1:             symbolic link to `libutil-2.5.1.so'
libutil.so:               symbolic link to `libutil.so.1'


  • share


share ]# s-dir_num 
// 18n(其来源是英文单词 internationalization 的首末字符i和n,18为中间的字符数)是“国际化”的简称。
// 在资讯领域,国际化(i18n)指让产品(出版物,软件,硬件等)无需做大的改变就能够适应不同的语言和地区的需要。
// 对程序来说,在不修改内部代码的情况下,能根据不同语言及地区显示相应的界面。 
// 在全球化的时代,国际化尤为重要,因为产品的潜在用户可能来自世界的各个角落。通常与i18n相关的还有L10n(“本地化”的简称)。
./i18n :461
// 用C编程时,可以用setlocale(LC_MESSAGES, "")取得默认的语言 ,头文件为 locale.h
// https://www.cnblogs.com/lanhaicode/p/10659763.html
./locale :28
// 所有 全球的 地区信息, 可被 /usr/etc/localtime 链接
./zoneinfo :1632

  • include

include ]# s-dir_num 
./arpa :6
./bits :98
./gnu :4
./net :10
./netash :1
./netatalk :1
./netax25 :1
./neteconet :1
./netinet :13
./netipx :1
./netpacket :1
./netrom :1
./netrose :1
./nfs :1
./protocols :4
./rpc :17
./rpcsvc :39
./scsi :3
./sys :80
当前目录(一层)下还有 109.h 文件(包括之前提到的 locale.h)
其他
  • libc.so.6 中的 6 是什么意思
In the early 1990s,the developers of the Linux kernel forked glibc. Their fork,called “Linux libc”,was maintained separately for years and released versions 2 through 5.

When FSF released glibc 2.0 in January 1997,. At this point,the Linux kernel developers discontinued their fork and returned to using FSF’s glibc.[6]

The last used version of Linux libc used the internal name (soname) libc.so.5. Following on from this,glibc 2.x on Linux uses the soname libc.so.6
  • libc.so 内容
root [ ~ ]# cat /usr/lib/libpthread.so 
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf32-i386)
GROUP ( /lib/libpthread.so.0 /usr/lib/libpthread_nonshared.a )
root [ ~ ]# cat /usr/lib/libc.so       
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf32-i386)
GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux.so.2 ) )

-------

[suweishuai@localhost ~]$ cat /usr/lib64/libpthread.so 
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /lib64/libpthread.so.0 /usr/lib64/libpthread_nonshared.a )
[suweishuai@localhost ~]$ cat /usr/lib64/libc.so
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a  AS_NEEDED ( /lib64/ld-linux-x86-64.so.2 ) )

  • crt
Files of the form *crt*.o are invariably C runtime startup code (the bulk of the C runtime tends to exist in libraries, the startup code is an object file as it's always needed).

The description of the various types can be found here, copied below to make the answer self-contained. First some definitions:

Mini FAQ about the misc libc/gcc crt files.

Some definitions:
     PIC - position independent code (-fPIC)
     PIE - position independent executable (-fPIE -pie)
     crt - C runtime
Then the various startup object files:

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.
And some others:

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.
Finally, common linking order:

General linking order:
     crt1.o crti.o crtbegin.o [-L paths] [user objects] [gcc libs]
       [C libs] [gcc libs] crtend.o crtn.o
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值