# 1. ELF header(ELF64_Ehdr)中 e_type、e_machine、e_entry、e_phoff、e_shoff 等字段的含义 A e_entry 是程序入口的虚拟地址,而 e_phoff 指向程序头表偏移 ✓ 正确答案 B e_type 用于标识 ELF 文件的目标机器架构 C e_shoff 指向程序头表的偏移 D e_machine 表示 ELF 文件的类型
# 2. ELF(Executable and Linkable Format)的 relocatable(.o)、executable、shared object、core dump 四类文件 A core dump 是共享库 B executable 文件包含重定位信息供链接器合并 C relocatable 文件包含未解析符号与重定位信息,供链接器使用 ✓ 正确答案 D shared object 是进程崩溃时的内存快照
# 3. Program header(Elf64_Phdr)的 PT_LOAD、PT_INTERP、PT_DYNAMIC 段类型 A PT_DYNAMIC 携带动态链接所需信息,如 DT_NEEDED 等 ✓ 正确答案 B PT_LOAD 指定动态链接器路径 C PT_INTERP 描述需要映射到内存的段权限 D PT_LOAD 指向解释器路径
# 4. Section header(Elf64_Shdr)的 .text、.data、.bss、.rodata 段 A .bss 段在文件中不占空间,加载时清零 ✓ 正确答案 B .text 段存放可读写的全局变量 C .rodata 段存放可写的初始化数据 D .data 段存放机器指令
# 5. ld.so 的动态链接流程,从 DT_NEEDED 解析、符号查找到重定位的完整链路 A 重定位发生在依赖解析之前 B DT_NEEDED 只记录主程序自身符号 C 符号查找在重定位完成之后进行 D ld.so 先解析 DT_NEEDED 依赖,再查找符号,最后执行重定位 ✓ 正确答案
# 6. ELF 调试信息(DWARF)的 .debug_info、.debug_line、.debug_frame A .debug_line 记录类型与变量描述 B .debug_frame 记录源代码行号到地址的映射 C .debug_info 以 DIE 描述类型、变量、函数等结构 ✓ 正确答案 D .debug_frame 存储符号表
# 7. readelf、objdump、nm、ldd、file 工具的实战 A readelf 用于反汇编机器码 B ldd 用于显示动态库依赖 ✓ 正确答案 C objdump 用于列出动态库依赖 D nm 用于解析 ELF 段头
# 8. 位置无关代码(PIC)与 PIE(Position Independent Executable) A PIC 和 PIE 是同一种概念,无区别 B PIE 是位置无关的可执行文件,配合 ASLR 提升安全性 ✓ 正确答案 C PIC 只能用于可执行文件 D PIE 不能加载到任意地址
# 9. ELF TLS(Thread Local Storage)的 .tdata 与 .tbss 段 A .tdata 存放未初始化的线程局部变量 B 线程通过 TP 寄存器基址寻址各自独立的 TLS 副本 ✓ 正确答案 C .tbss 存放已初始化的线程局部变量 D TLS 变量在所有线程间共享同一份存储
# 10. ELF note 段(.note.gnu.property、.note.gnu.build-id)的元数据 A .note.gnu.build-id 用于记录程序依赖的处理器安全特性 B .note.gnu.property 保存唯一哈希标识便于调试匹配 C note 段参与程序运行逻辑 D .note.gnu.property 记录 CET、IBT 等处理器特性声明 ✓ 正确答案
# 11. ELF 版本脚本(version script)的符号可见性控制 A version script 的 local 符号会进入动态符号表 B version script 只能增加符号,不能隐藏符号 C version script 通过 global/local 控制符号导出,并支持符号版本化 ✓ 正确答案 D version script 与符号可见性无关
# 12. binutils、lld、mold 三种链接器的性能差异 A GNU ld 采用多线程并行设计,速度最快 B mold 相比 lld 在速度上没有任何优势 C lld 是 LLVM 生态的链接器,采用多线程并行 ✓ 正确答案 D 三种链接器的 ELF 输出语义完全不同
# 13. x86-64 与 AArch64 的 ABI 差异对比 A x86-64 用 x0-x7 传整数参数 B x86-64 用 d0-d7 传浮点参数 C AArch64 用 x0-x7 传前 8 个整数参数 ✓ 正确答案 D AArch64 用 rdi-r9 传整数参数
# 14. 栈对齐(16 字节对齐)的 ABI 强制与崩溃边界 A SSE 指令(如 movaps)要求 16 字节对齐,栈未对齐会触发通用保护异常 ✓ 正确答案 B 16 字节对齐只是为了美观,与指令无关 C 栈对齐只在 32 位系统要求 D 违反栈对齐不会导致任何崩溃
# 15. 红区(red zone,128 字节)的工程语义 A 红区只允许叶函数使用,用于免去栈帧调整 ✓ 正确答案 B 红区位于 rsp 上方 128 字节 C 非叶函数也可随意使用红区 D 红区与信号处理器无关
# 16. 结构体返回的"内存参数"(sret)约定与寄存器返回的分界 A sret 返回方式将结果放入寄存器 B sret 不使用调用方分配的内存 C 所有结构体都必须用 sret 返回 D 超过 16 字节的结构体通常用 sret 隐藏指针返回 ✓ 正确答案
# 17. System V i386 ABI(32 位)的 cdecl ABI 传参规则 A cdecl 由调用者清栈,支持可变参数 ✓ 正确答案 B cdecl 使用寄存器传递参数 C cdecl 由被调函数清栈 D cdecl 返回值总是存放在 edx
# 18. x86-64 栈帧的 rbp 帧指针省略(-fomit-frame-pointer) A -fomit-frame-pointer 会保留 rbp 帧指针链 B 该选项与调试回溯无关 C 省略 rbp 会损失一个通用寄存器 D 省略 rbp 后,函数用 rsp 相对偏移访问局部变量 ✓ 正确答案
# 19. Itanium C++ ABI(itanium-cxx-abi)的 name mangling 规则 A 命名空间在 mangling 中不参与编码 B mangling 只用于普通函数,不处理模板 C C++ mangling 以 _Z 开头编码名称与类型 ✓ 正确答案 D mangling 使重载函数产生相同符号
# 20. x86-64 SysV 的 EH frame 与 DWARF CFI 异常处理 A .eh_frame 存储源代码行号 B 异常展开与普通 unwind 使用不同的机制 C 异常展开沿 CFI 逐帧回退并调用析构函数 ✓ 正确答案 D .eh_frame 只与信号处理有关
# 21. COFF(Common Object File Format)的 section table 与 symbol table A COFF 的 section table 记录符号名称 B COFF 的 symbol table 逐项描述各节 C COFF 与 ELF 的节组织结构完全相同 D COFF 的重定位表与 section 关联 ✓ 正确答案
# 22. Mach-O 与 ELF 在段(segment)vs 节(section)层次上的差异 A Mach-O 中 section 包含 segment B Mach-O 与 ELF 的层次结构完全相同 C ELF 的 program header 与 section 是强绑定关系 D Mach-O 采用 segment 包含 section 的两层结构 ✓ 正确答案
# 23. Mach-O 中 __objc_methlist、__objc_classlist 等 Objective-C 元数据 A __objc_methlist 保存类对象列表 B __objc_selrefs 保存方法实现 C __objc_classlist 列出所有类对象 ✓ 正确答案 D ObjC 元数据不参与运行时
# 24. Mach-O 的 __TEXT、__DATA 段的"两段式"模型 A __TEXT 与 __DATA 分离支持 W^X 与代码共享 ✓ 正确答案 B __DATA 段是可执行代码段 C __TEXT 段是可读写数据段 D 两段式模型无法实现代码共享
# 25. Mach-O 的 load commands,包括 LC_SEGMENT_64、LC_DYLD_INFO、LC_SYMTAB A LC_SEGMENT_64 提供符号表信息 B LC_DYLD_INFO 提供动态链接所需的绑定信息 ✓ 正确答案 C LC_SYMTAB 描述段的映射位置 D load commands 与加载过程无关
# 26. Mach-O 的 magic number,即 MH_MAGIC_64 与 MH_CIGAM_64(小端序)的区别 A MH_CIGAM_64 是字节交换后的魔数,用于识别字节序 ✓ 正确答案 B MH_MAGIC_64 与 MH_CIGAM_64 是同一值 C 魔数只用于识别文件大小 D CIGAM 表示文件已损坏
# 27. dyld 的 Mach-O 动态链接流程与 dyld_shared_cache A dyld 只加载主程序,不处理依赖库 B dyld_shared_cache 把系统库合并为单一映射以加快启动 ✓ 正确答案 C dyld_shared_cache 会增加内存占用与启动时间 D dyld 不做符号绑定
# 28. COFF 与 ELF 的 ABI 兼容性挑战 A COFF 与 ELF 的重定位类型完全一致 B COFF 与 ELF 使用相同的调试格式 C 同一二进制可在 Windows 与 Unix 直接复用 D COFF 与 ELF 在节组织、重定位与调用约定上存在多项差异 ✓ 正确答案
# 29. Mach-O 的 LC_CODE_SIGNATURE 签名与 LC_DYLD_INFO_ONLY 重定位 A LC_CODE_SIGNATURE 用于提供重定位信息 B LC_DYLD_INFO_ONLY 用于验证代码签名 C LC_CODE_SIGNATURE 用于验证二进制完整性,防止篡改 ✓ 正确答案 D 两者都与动态链接无关
# 30. --as-needed、--no-undefined、-z now 的链接器标志语义 A --as-needed 会强制链接所有库 B --no-undefined 允许未定义符号存在 C -z now 禁用 lazy binding,使 GOT 加载时全部解析 ✓ 正确答案 D -z now 会启用延迟绑定
# 31. 动态加载 dlopen/dlsym/dlclose 的运行时链接 A dlsym 用于加载共享库 B dlopen 返回库句柄,dlsym 通过句柄查找符号 ✓ 正确答案 C dlclose 增加库的引用计数 D dlopen 只能加载编译期已链接的库
# 32. 动态链接的"延迟绑定"(lazy binding)vs"立即绑定"(now binding)的取舍 A lazy binding 在加载时解析全部符号 B now binding 会加快启动速度 C lazy binding 会消除首次调用延迟 D now binding 配合 Full RELRO 使 GOT 只读,提升安全性 ✓ 正确答案
# 33. GCC 的 -fvisibility=hidden 与符号可见性控制 A -fvisibility=hidden 让所有符号默认可见 B 该选项会增加符号表体积 C 显式标注的符号才进入动态符号表,可规范共享库 ABI ✓ 正确答案 D 可见性控制与优化无关
# 34. 链接器"幽灵符号"(linker script symbol)与 VDSO A linker script 无法定义符号地址 B VDSO 只能在内核态使用 C VDSO 由内核映射到进程空间,用于用户态实现部分系统调用 ✓ 正确答案 D VDSO 会显著增加系统调用开销
# 35. 动态库的"按需加载"vs"预加载"的工程取舍 A 预加载适合符号覆盖,如拦截 malloc ✓ 正确答案 B 按需加载会在启动时加载全部库 C 按需加载无法用于插件 D 预加载会减少启动时间
# 36. 动态链接的 GOT/PLT 攻击(return-to-PLT) A return-to-PLT 是直接覆盖 GOT 的堆溢出攻击 B PLT 跳板无法被攻击者利用 C Full RELRO 使 GOT 只读,可提升对 GOT/PLT 攻击的防御 ✓ 正确答案 D ASLR 对 return-to-PLT 攻击无效
# 37. Itanium C++ ABI 的"COMDAT"折叠与"弱符号"边界 A COMDAT 节在链接时保留多个同名副本 B COMDAT 与弱符号无关 C 模板实例化会产生符号冲突 D 弱符号允许多个定义,链接器选择其一不报错 ✓ 正确答案
# 38. Java 的 JNI ABI 与 native 库的边界 A JNI 函数按 Java_包名_类名_方法名 规则命名 ✓ 正确答案 B JNIEnv 是普通结构体,不包含函数表 C JNI 不处理引用管理 D JNI 函数名与 Java 方法无关
# 39. Rust ABI 的"显式"(extern "C")与"自定义"(Rust ABI 不稳定)差异 A Rust 默认 ABI 是稳定的 C 调用约定 B extern "C" 采用稳定的 C 调用约定,适合 FFI ✓ 正确答案 C Rust ABI 保证跨语言兼容 D extern "C" 与 Rust ABI 完全相同
# 40. Go 的 ABI 在 1.17 之后的 register-based 改造 A Go 一直用栈传递参数 B Go 1.17+ 使用寄存器传递函数参数与返回值 ✓ 正确答案 C register-based ABI 会增加调用开销 D Go ABI 是对外暴露的稳定接口
# 41. WASM(WebAssembly)的线性内存与 ABI 模型 A WASM 有多个相互隔离的地址空间 B WASM 线性内存是唯一的连续地址空间 ✓ 正确答案 C WASM 调用约定依赖未定义行为 D WASM 无内存管理机制
# 42. 静态链接与动态链接在可执行体积、启动速度、内存共享与升级成本上如何取舍? A 静态链接可共享内存,内存占用更小 B 动态链接升级库只需替换文件,且可共享内存 ✓ 正确答案 C 静态链接启动速度更慢 D 动态链接体积更大
# 43. LTO(Link Time Optimization)在链接期做跨模块内联与死代码删除的原理是什么,构建开销从何而来? A LTO 无法进行常量传播 B LTO 只做单文件优化 C LTO 会降低链接时间 D LTO 在链接期合并 IR 进行跨模块内联与死代码删除 ✓ 正确答案
# 44. -ffunction-sections 配合 --gc-sections 如何剔除未引用函数,为何需结合 -fdata-sections? A 数据回收无需分节 B -ffunction-sections 让数据独立成节 C --gc-sections 回收所有节,包括被引用的 D -fdata-sections 让每个全局变量独立成节,配合 --gc-sections 回收未引用数据 ✓ 正确答案
# 45. 强符号与弱符号的解析规则是什么,多个目标文件定义同名弱符号时链接器如何选择? A 强符号优先于弱符号,多个弱符号时链接器选择一个 ✓ 正确答案 B 多个强符号同名时链接器选择任意一个 C 弱符号总是覆盖强符号 D 多个弱符号必然报错
# 46. 链接器如何确定输出文件中各段的加载地址(LMA)与虚拟地址(VMA),嵌入式场景为何要分离二者? A VMA 是段在文件中的加载地址 B VMA 与 LMA 总是不同 C 嵌入式场景中代码常存于 Flash(LMA)而运行于 RAM(VMA) ✓ 正确答案 D 链接脚本无法指定地址
# 47. 静态链接 glibc 为何会带来 NSS、TLS 等运行期功能的兼容问题? A 静态链接 glibc 后 NSS 模块仍可动态加载 B TLS 与静态链接无关 C 静态链接完全不影响 glibc 运行期功能 D NSS 需要动态加载模块,静态链接会破坏名字解析等功能 ✓ 正确答案
# 48. 链接器如何处理未定义符号与公共符号(common symbol),-fno-common 改变了什么行为? A -fno-common 会把多个 common 定义合并为公共符号 B -fno-common 会取消符号解析 C 未定义符号在链接时总是被忽略 D 默认 -fcommon 允许多个 TU 的未初始化变量合并为 common symbol ✓ 正确答案
# 49. Mach-O 的"通用二进制"(Universal/Fat binary)的多架构支持 A Fat binary 只能包含一个架构 B Fat binary 用 fat header 封装多架构切片,加载时按架构选择 ✓ 正确答案 C Universal binary 会减小体积 D Fat binary 与架构无关
# 50. 源码、ABI、API、行为兼容性构成的 ABI 兼容性"层" A ABI 兼容意味着已编译二进制无需重新编译即可运行 ✓ 正确答案 B 源码兼容保证二进制兼容 C API 兼容与行为兼容完全相同 D ABI 兼容不要求 API 兼容
# 51. ABI 稳定性的边界,新增函数 vs 修改函数签名 vs 修改 struct 布局如何取舍 A 修改函数签名不破坏 ABI 兼容性 B 修改 struct 布局不影响 ABI C 新增函数通常不破坏 ABI 兼容性 ✓ 正确答案 D 所有修改都破坏 ABI
# 52. Node.js 的 N-API 与 NAN 的 ABI 稳定性 A NAN 与 N-API 的稳定性相同 B NAN 提供稳定 ABI 无需重编译 C N-API 依赖 V8 内部头文件 D N-API 提供稳定 ABI,模块可在不同 Node 版本复用 ✓ 正确答案
# 53. Python 的 C API(CPython)的稳定 vs 不稳定边界 A 完整 C API 依赖内部数据结构,跨版本无需重编译 B 使用稳定 ABI(Py_LIMITED_API)的扩展可在多个 Python 版本复用 ✓ 正确答案 C PyObject 布局是稳定 ABI 的一部分 D 所有扩展都无需重编译
# 54. PLT(Procedure Linkage Table)与 GOT(Global Offset Table)的 lazy binding 机制 A lazy binding 下每次调用都重新解析 B lazy binding 下首次调用会解析并回填 GOT 槽位 ✓ 正确答案 C GOT 槽位在 lazy binding 下从不回填 D PLT 与 GOT 无关
# 55. 动态段的 DT_NEEDED、DT_SYMTAB、DT_STRTAB、DT_RELA 等动态表项 A DT_RELA 指向动态符号表 B DT_SYMTAB 指向字符串表 C DT_NEEDED 列出依赖库名 ✓ 正确答案 D DT_STRTAB 列出依赖库
# 56. 符号表(.symtab)与动态符号表(.dynsym)的差异 A .symtab 用于动态链接解析 B .symtab 是运行必需的 C strip 会移除 .dynsym 使程序无法运行 D .dynsym 只含动态链接所需符号,运行时实际使用 ✓ 正确答案
# 57. 重定位表(.rela.dyn、.rela.plt)的 RELA 与 REL 格式 A REL 重定位项包含 r_addend 字段 B RELA 重定位项包含显式的 r_addend 字段 ✓ 正确答案 C x86-64 使用 REL 格式 D RELA 与 REL 结构完全相同
# 58. strip 与符号去除的工程意义 A strip 只影响运行性能 B strip 会增大文件体积 C strip 移除符号表以减小体积,但会降低调试可读性 ✓ 正确答案 D strip 后无法运行程序
# 59. x86-64 SysV 的 PLT 与 lazy binding 的栈布局 A _dl_runtime_resolve 不接收参数 B lazy binding 不涉及栈操作 C GOT 槽位在首次调用后仍指向同一地址 D PLT 项通过把符号序号压栈并跳转解析例程来完成 lazy binding ✓ 正确答案
# 60. System V AMD64 ABI 中 rdi、rsi、rdx、rcx、r8、r9 这 6 个整数参数寄存器 A 第 7 个参数优先用 r10 传递 B 所有参数都通过栈传递 C 前 6 个整数参数依次用 rdi、rsi、rdx、rcx、r8、r9 传递 ✓ 正确答案 D 浮点参数用整数寄存器传递
# 61. System V AMD64 中 rax 与 rdx 承载返回值(128 位返回值)的规则 A 128 位整数返回值使用 rax+rdx 拼接 ✓ 正确答案 B 所有返回值都存放在 rdx C 浮点返回值使用 rax D 128 位返回值只能通过内存返回
# 62. 可变参数(variadic)的 AL 寄存器(浮点个数)传递 A AL 保存返回值 B AL 保存整数参数个数 C 可变参数函数不需要 AL 寄存器 D 可变参数函数调用时 AL 寄存器保存浮点参数个数 ✓ 正确答案
# 63. 浮点参数通过 XMM0-XMM7 寄存器传递的规则 A 浮点参数用栈传递所有参数 B 浮点参数用整数寄存器传递 C XMM0-XMM7 用于传递前 8 个浮点参数 ✓ 正确答案 D XMM 寄存器与浮点无关
# 64. AAPCS(AArch64 Procedure Call Standard)与 SysV 的对照 A AAPCS 用 XMM0-7 传整数参数 B AAPCS 用 rdi-r9 传整数参数 C AAPCS 用 x0-x7 传前 8 个整数参数 ✓ 正确答案 D AAPCS 的浮点参数用 x0-x7 传递
# 65. PE 的 section,包括 .text、.data、.rsrc、.reloc 与 DLL 导入表 A 导入表只列出 DLL 名,不含函数 B .text 存可写数据 C .rsrc 存代码 D .reloc 存基址重定位表,.rsrc 存资源 ✓ 正确答案
# 66. PE(Portable Executable,Windows COFF 扩展)的 DOS stub 与 PE header A DOS stub 的 e_lfanew 字段指向真正的 PE header ✓ 正确答案 B PE header 位于文件最开头 C DOS stub 用于现代 Windows 运行 D PE 签名是 "MZ"
# 67. COFF 的 PE32+(64 位 PE)格式 A PE32+ 的可选头使用 64 位字段以支持 64 位地址 ✓ 正确答案 B PE32+ 与 PE32 结构完全无关 C PE32+ 的 magic 为 0x10b D PE32+ 只能用于 32 位系统
# 68. Windows DLL 的导入表(import table)与导出表(export table) A 导出表列出 DLL 提供的符号,导入表列出依赖的符号 ✓ 正确答案 B 导入表提供 DLL 导出的符号 C 加载器不匹配导入与导出 D 导出表列出依赖的 DLL
# 69. DT_RPATH 与 DT_RUNPATH 的差异,即 RUNPATH 不传递给子进程 A DT_RUNPATH 只作用于当前对象,不传递给子进程 ✓ 正确答案 B DT_RPATH 不传递给子进程 C DT_RUNPATH 优先级高于 LD_LIBRARY_PATH D DT_RPATH 与 DT_RUNPATH 语义完全相同
# 70. RPATH、RUNPATH、LD_LIBRARY_PATH 的库搜索路径优先级 A DT_RPATH 优先级低于 LD_LIBRARY_PATH B DT_RUNPATH 的优先级低于 LD_LIBRARY_PATH ✓ 正确答案 C LD_LIBRARY_PATH 优先级最低 D 默认路径优先级最高
# 71. dlmopen 的命名空间隔离 A dlmopen 只有单一命名空间 B dlmopen 与 dlopen 完全等价 C dlmopen 无法区分库版本 D dlmopen 把库加载到独立命名空间以隔离同名符号 ✓ 正确答案
# 72. 版本脚本与符号版本(symbol versioning)的 ABI 兼容性 A 符号版本化让同一符号对应多个版本,实现多版本 ABI 共存 ✓ 正确答案 B 符号版本化只支持单一版本 C 版本脚本无法定义版本继承 D 符号版本化会破坏 ABI 兼容
# 73. 动态库的 SONAME 与版本号管理 A SONAME 指文件名而非版本 B SONAME 记录在 DT_SONAME 中,作为库的 ABI 版本标识 ✓ 正确答案 C 主版本号兼容时递增 D SONAME 与动态链接无关
# 74. ABI(Application Binary Interface)的范围,涵盖传参规则、数据布局、名称修饰与调用堆栈布局 A ABI 改变不影响二进制兼容 B ABI 只涉及数据布局 C ABI 与跨语言互操作无关 D ABI 涵盖传参规则、数据布局、名称修饰与调用堆栈布局 ✓ 正确答案
# 75. C 标准的版本(C89、C99、C11、C17、C23)的兼容性 A C99 是最早的 C 标准 B C11 引入原子操作与线程等新特性 ✓ 正确答案 C C 标准版本决定 ABI 兼容性 D C23 没有新增特性
# 76. C++ ABI 的对象布局(vptr、vtable)与 RTTI 的稳定性 A 对象布局可随意改变而保持 ABI 兼容 B vtable 不含虚函数地址 C RTTI 与对象布局无关 D 有虚函数的类对象开头含 vptr,vtable 含虚函数地址与 RTTI 信息 ✓ 正确答案
# 77. libstdc++ 与 libc++ 的 ABI 不兼容问题 A 两个标准库可以随意混用 B libstdc++ 与 libc++ 的内部布局与符号可能不同,混用会导致 ABI 不兼容 ✓ 正确答案 C 标准库内部布局由 C 标准定义 D 混用不影响运行
# 78. abi-compliance-checker、abidiff 等 ABI 兼容性测试工具 A 这些工具只检测运行时性能 B abidiff 比较库版本以检测符号与布局等 ABI 破坏 ✓ 正确答案 C abi-compliance-checker 无法比较结构体布局 D 这些工具与库升级无关
# 79. ABI 版本化(symbol versioning)的 Soname 演进 A symbol versioning 在符号粒度提供版本,Soname 在库粒度标识 ABI 主版本 ✓ 正确答案 B Soname 只影响符号版本化 C symbol versioning 与 Soname 无关 D 破坏性改动不改变 Soname