CSAPP3e-学习笔记-第七章


单选题:以下关于强符号和弱符号定义的描述中,错误的是(A)
A. 只有初始化为 0 的全局变量在链接中才为强符号
B. 局部符号没有强、弱符号的概念
C. 没有初始化的全局变量是弱符号
D. 全局使用的函数名都是强符号

CSAPP3e 7.6.1 链接器如何解析多重定义的全局符号

  • 强符号:函数和已初始化的全局变量
  • 弱符号:未初始化的全局变量

判断题:可重定位目标文件中未初始化的全局变量保存在 $.data$ 中(错)

判断题:程序的数据和代码不存放在同一个地方,代码在低地址段,数据在高地址段。(对)

CSAPP3e 7.4 可重定位目标文件

典型的 ELF 可重定位目标文件

夹在 ELF 头和节头部表之间的都是节。一个典型的 ELF 可重定位目标文件包含下面几个节:

  • $.text$:已编译程序的机器代码。

  • $.rodata$:只读数据,比如 printf 语句中的格式串和开关语句的跳转表。

  • $.data$:已初始化的全局和静态 C 变量。

    局部 C 变量在运行时被保存在栈中,既不出现在 $.data$ 节中,也不出现在 $.bss$ 节中。

  • $.bss$:未初始化的全局和静态 C 变量,以及所有被初始化为 $0$ 的全局或静态变量。

    用术语 $.bss$ 来表示未初始化的数据是很普遍的。一种记住 $.data$ 和 $.bss$ 节之间区别的简单方法是把 bss​ 看成是 “更好地节省空间(Better Save Space)” 的缩写。

  • $.symtab$:一个符号表,它存放在程序中定义和引用的函数和全局变量的信息。

  • $.rel.text$:一个 $.text$ 节中位置的列表,当链接器把这个目标文件和其他文件组合时,需要修改这些位置。

  • $.rel.data$:被模块引用或定义的所有全局变量的重定位信息。

CSAPP3e 7.5 符号和符号表

每个符号都被分配到目标文件的某个节,由 section 字段表示,该字段也是一个到节头部表的索引。有三个特殊的伪节,它们在节头部表中是没有条目的:

  • $ABS$:代表不该被重定位的符号
  • $UNDEF$:代表未定义的符号,也就是在本目标模块中引用,但是却在其他地方定义的符号
  • $COMMON$:表示还未被分配位置的未初始化的数据目标

注意, 只有可重定位目标文件中才有这些伪节,可执行目标文件中是没有的。

$COMMON$ 和 $.bss$ 的区别很细微。现代的 GCC 版本根据以下规则来将可重定位目标文件中的符号分配到 $COMMON$ 和 $.bss$ 中:

  • $COMMON$:未初始化的全局变量
  • $.bss$:未初始化的静态变量,以及初始化为 $0$ 的全局或静态变量

采用这种看上去很绝对的区分方式的原因来自于链接器执行符号解析的方式。


单选题:以下关于 ELF 可执行目标文件的程序头表(段头表)的叙述中,错误的是(B)
A. $.txt$ 节和 $.rodata$ 节都包含在只读代码段,而 $.data$ 节和 $.bss$ 节都包含在读写数据段
B. 用于描述可执行文件中的节与主存储器中的存储段之间的映射关系
C. 描述了段的起始虚拟地址、存储长度、存取方式和对齐方式

CSAPP3e 7.4 可重定位目标文件

ELF 头(ELF header)以一个 16 字节的序列开始,这个序列描述了生成该文件的系统的字的大小和字节顺序。

ELF 头剩下的部分包含帮助链接器语法分析和解释目标文件的信息。其中包括:

  • ELF 头的大小
  • 目标文件的类型(如可重定位、可执行或者共享的)
  • 机器类型(如 x86-64)
  • 节头部表(section header table)的文件偏移
  • 节头部表中条目的大小和数量

不同节的位置和大小是由节头部表描述的,其中目标文件中每个节都有一个固定大小的条目 。


单选题:以下关于链接过程中对符号定义的判断中,错误的是(A)
A. 函数内的局部变量声明 short x = 200; 中,x 是符号定义
B. 全局变量声明 int x, y; 中,xy 都是符号的定义
C. 全局变量声明 int xp = &x; 中,xpx 都是符号的定义
D. 静态局部变量声明 static int x = xp; 中,x 是符号的定义

CSAPP3e 7.2 静态链接

符号对应于一个函数、一个全局变量或一个静态变量(即 C 语言 中任何以 static 属性声明的变量)。

CSAPP3e 7.5 符号和符号表

每个可重定位目标模块 $m$ 都有一个符号表,它包含 $m$ 定义和引用的符号的信息。在链接器的上下文中,有三种不同的符号:

  • 由模块 $m$ 定义并能被其他模块引用的全局符号。全局链接器符号对应于非静态的 C 函数和全局变量。
  • 由其他模块定义并被模块 $m$ 引用的全局符号。这些符号称为外部符号,对应于在其他模块中定义的非静态 C 函数和全局变量。
  • 只被模块 $m$ 定义和引用的局部符号。它们对应于带 static 属性的 C 函数和全局变量。 这些符号在模块 $m$ 中任何位置都可见,但是不能被其他模块引用。

$.symtab$ 中的符号表不包含对应于本地非静态程序量的任何符号。这些符号在运行时在栈中被管理,链接器对此类符号不感兴趣。

定义为带有 C static 属性的本地过程变量是不在栈中管理的。相反,编译器在 $.data$ 或 $.bss$ 中为每个定义分配空间 ,并在符号表中创建一个有唯一名字的本地链接器符号。


单选题:以下是有关静态链接和动态链接比较的描述,其中错误的是(D)
A. 静态库函数更新后需对程序重新编译和链接,而共享库函数更新后程序无需重新编译和链接
B. 静态库函数代码包含在可执行目标文件中,而共享库函数代码不包含在可执行目标文件中
C. 静态链接情况下静态库函数在加载时被链接,动态链接情况下共享库函数可在加载或运行时被链接
D. 静态库函数代码包含在进程代码段中,而共享库函数代码不包含在进程代码段中


单选题:以下是关于链接过程中的符号解析的叙述,错误的是(A)
A. 同一个符号名可能在多个模块中定义,每个定义处的符号都必须分配空间
B. 符号解析的目的是将符号引用与某目标模块中的定义建立关联
C. 本地符号的解析比较简单,只要与本模块内定义的符号关联即可
D. 全局符号和外部符号需将模块内的引用与模块外定义的符号绑定


CSAPP3e-学习笔记-第七章
https://luoyuy.top/posts/f36f34702e61/
作者
LuoYu-Ying
发布于
2023年2月16日
许可协议