<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>suibianwanwan</title><description>记录技术实践与思考</description><link>https://blog.qtok.cloud/</link><item><title>[链接器的世界-实验篇15] 让反例决定质量：差分、变异与鲁棒性</title><link>https://blog.qtok.cloud/posts/linker-lab15-verification/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-lab15-verification/?lang=zh/</guid><description>实现可重放的变异与 panic 调查工具，通过原生运行、确定性检查和 GNU ld 差分测试检验此前的链接器后端。</description><pubDate>Tue, 06 Oct 2026 11:41:13 GMT</pubDate></item><item><title>[链接器的世界-实验篇14] 接住 rustc：把链接器变成真正的驱动程序</title><link>https://blog.qtok.cloud/posts/linker-lab14-rust/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-lab14-rust/?lang=zh/</guid><description>为累积的 class13 静态 PIE 后端实现命令行驱动，让 rustc 直接调用它，链接一个使用 core::fmt 的 no_std Rust 程序。</description><pubDate>Tue, 06 Oct 2026 11:41:13 GMT</pubDate></item><item><title>[链接器的世界-实验篇13] 地址也有语义：安全 ICF 与代码顺序</title><link>https://blog.qtok.cloud/posts/linker-lab13-icf-order/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-lab13-icf-order/?lang=zh/</guid><description>在 class12 的 ET_EXEC 与静态 PIE 后端上实现保守 ICF 和代码顺序，重定向引用并修正折叠副本的调试信息。</description><pubDate>Tue, 06 Oct 2026 11:41:13 GMT</pubDate></item><item><title>[链接器的世界-实验篇12] 让调试信息跟着地址走：DWARF、符号表与节头</title><link>https://blog.qtok.cloud/posts/linker-lab12-debug-info/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-lab12-debug-info/?lang=zh/</guid><description>为 ET_EXEC 与静态 PIE 补全调试节、符号表和节头表，区分图像地址、调试节偏移与 TLS 偏移。</description><pubDate>Tue, 06 Oct 2026 11:41:13 GMT</pubDate></item><item><title>[链接器的世界-实验篇11] 看穿间接层：GOT、指令松弛与静态 TLS</title><link>https://blog.qtok.cloud/posts/linker-lab11-riscv/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-lab11-riscv/?lang=zh/</guid><description>在 class9 的静态 PIE 上构建 GOT，实施课程支持的 mov 松弛，布局 TLS 模板，并用提供的启动代码安装主线程 TLS。</description><pubDate>Tue, 06 Oct 2026 11:41:13 GMT</pubDate></item><item><title>[链接器的世界-实验篇10] 不再原样复制：常量合并与展开表重建</title><link>https://blog.qtok.cloud/posts/linker-lab10-tls-and-got/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-lab10-tls-and-got/?lang=zh/</guid><description>在 class8 的 ET_EXEC 后端中合并重复常量，映射输入偏移，并为存活代码重建 .eh_frame 与搜索索引。</description><pubDate>Tue, 06 Oct 2026 11:41:13 GMT</pubDate></item><item><title>[链接器的世界-实验篇09] 不知道加载地址时怎么链接：自重定位的静态 PIE</title><link>https://blog.qtok.cloud/posts/linker-lab09-merge-and-unwind/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-lab09-merge-and-unwind/?lang=zh/</guid><description>在 class8 前端与 class6 布局之上生成静态 PIE，区分静态补丁和加载期指针，并通过提供的启动代码完成自重定位。</description><pubDate>Tue, 06 Oct 2026 11:41:13 GMT</pubDate></item><item><title>[链接器的世界-实验篇08] 只留下被用到的：可达性回收与链接映射</title><link>https://blog.qtok.cloud/posts/linker-lab08-static-pie/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-lab08-static-pie/?lang=zh/</guid><description>从入口和显式根追踪存活节，建立不依赖输出地址的链接计划，并输出确定、字节安全的 map。</description><pubDate>Tue, 06 Oct 2026 11:41:13 GMT</pubDate></item><item><title>[链接器的世界-实验篇07] 静态库按需取用：成员抽取的不动点</title><link>https://blog.qtok.cloud/posts/linker-lab07-static-libraries/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-lab07-static-libraries/?lang=zh/</guid><description>静态库是一组目标文件的容器，而不是一个更大的目标文件。本实验解析 ar 归档格式，按未解析的全局名字逐个抽取成员，并在同一个归档内反复扫描直到不再有新成员被选中。</description><pubDate>Tue, 06 Oct 2026 11:41:13 GMT</pubDate></item><item><title>[链接器的世界-原理篇16] 链接器工程：从能链接，到值得信赖</title><link>https://blog.qtok.cloud/posts/linker-16-engineering/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-16-engineering/?lang=zh/</guid><description>当输入增长到数万个目标文件，链接器既要提高速度，又要保持结果确定、错误可诊断。从并行阶段的依赖关系出发，讨论结构不变式、运行测试、差分测试、变异测试与模糊测试，分析增量链接和工具链集成怎样改变工程取舍。</description><pubDate>Sun, 04 Oct 2026 16:03:04 GMT</pubDate></item><item><title>[链接器的世界-原理篇15] 走出 ELF：Mach-O 与 PE/COFF 的另一套规则</title><link>https://blog.qtok.cloud/posts/linker-15-macho-pe/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-15-macho-pe/?lang=zh/</guid><description>从文件头、目录记录与内容的关系出发，对照 Mach-O 与 PE/COFF 的符号、重定位和加载机制；通过字节布局与地址换算解释导入、指针链、展开记录、去重及 TLS，并区分文件结构、链接接口与运行时契约。</description><pubDate>Sun, 04 Oct 2026 16:03:00 GMT</pubDate></item><item><title>[链接器的世界-原理篇14] C++ 与 Rust：语言特性留下的链接难题</title><link>https://blog.qtok.cloud/posts/linker-14-cxx-rust/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-14-cxx-rust/?lang=zh/</guid><description>两个 .cpp 包含同一个头文件，各自生成了同一个 inline 函数和模板实例，链接却不报重复定义。本文从这个谜题出发，读懂 Itanium C++ ABI 的名字修饰（_Z、N...E、模板参数、S_ 替换）、extern &quot;C&quot;，以及为什么普通函数不编码返回类型；用汇编拆开 COMDAT 组和弱定义这两种 vague linkage 实现，复现 vtable 卷入的 ODR 违规和 undefined reference to vtable；用链接顺序演示静态初始化顺序问题，看 init_priority 与 .init_array.N 的排序、guard 变量与 __cxa_guard_acquire。Rust 部分拆开 rlib，对比 legacy 与 v0 两套修饰，看 no_mangle、used、link_section，用 --print link-args 逐项读 rustc 交给链接器的命令行和依赖顺序，比较 panic=unwind 与 panic=abort 的大小，最后不带标准库和 C 运行时链接一个最小的 Rust 程序。</description><pubDate>Sun, 04 Oct 2026 16:02:56 GMT</pubDate></item><item><title>[链接器的世界-原理篇13] ABI 演进：库升级了，旧程序怎么办</title><link>https://blog.qtok.cloud/posts/linker-13-abi-evolution/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-13-abi-evolution/?lang=zh/</guid><description>结构体加了一个字段，没有重新编译的旧程序照样能加载，算出来的数却错了。动态链接只按名字和版本配对，不看类型和布局。本文从这个故障出发，讲 ABI 和 API 的区别、哪些改动会破坏 ABI；libtool 的 current:revision:age 怎样变成 soname 和文件名，Debian 的包名为什么带 soname；符号版本在实践中怎么用：版本节点继承、同一个函数的新旧两个实现、glibc 的 memcpy 和 fmemopen、在新系统上编译的程序为什么到旧系统上报 GLIBC_2.34 not found 以及怎样用旧 sysroot 解决；最后用 abidiff 和 abi-compliance-checker 在发布前查出被改坏的 ABI。实验统一在 x86-64 Linux 原生执行，以 glibc 2.43 和隔离解包的 glibc 2.17 对照。</description><pubDate>Sun, 04 Oct 2026 16:02:53 GMT</pubDate></item><item><title>[链接器的世界-原理篇12] 链接期优化：看见更多代码之后</title><link>https://blog.qtok.cloud/posts/linker-12-lto/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-12-lto/?lang=zh/</guid><description>分开编译形成了优化的信息边界，LTO 通过保留 IR 并协调符号决议跨越这条边界。本文解释定义选择、内部化与代码生成的分工，分析 ThinLTO 的并行与缓存机制，再讨论 ICF 的等价判定、地址身份，以及函数布局如何影响代码局部性。</description><pubDate>Sun, 04 Oct 2026 16:02:50 GMT</pubDate></item><item><title>[链接器的世界-原理篇11] 调试信息：让机器码认回源代码</title><link>https://blog.qtok.cloud/posts/linker-11-debug-info/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-11-debug-info/?lang=zh/</guid><description>从代码地址、调试节内偏移与被删除代码的 tombstone 出发，解释 DWARF 如何随链接结果变化；进一步分析索引形式、字符串合并、压缩、独立调试文件和 split DWARF 的引用与分发机制。</description><pubDate>Sun, 04 Oct 2026 16:02:44 GMT</pubDate></item><item><title>[链接器的世界-原理篇10] 链接器脚本：当程序需要自己安排内存</title><link>https://blog.qtok.cloud/posts/linker-10-linker-scripts-kernel/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-10-linker-scripts-kernel/?lang=zh/</guid><description>链接器脚本把输入节组织成输出映像，并约定符号地址、存储区域与入口。本文区分 ELF 文件偏移、VMA 和 LMA，解释启动代码如何完成映射、数据复制与 BSS 清零，再以 QEMU、xv6、JOS 和 ROM/RAM 布局分析地址约定失配的后果。最后讨论数据嵌入、节保留、排序、对齐与脚本断言。</description><pubDate>Sun, 04 Oct 2026 16:02:40 GMT</pubDate></item><item><title>[链接器的世界-原理篇09] TLS：同一个变量，每个线程各有一份</title><link>https://blog.qtok.cloud/posts/linker-09-tls/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-09-tls/?lang=zh/</guid><description>thread_local 变量在每个线程里是同一个名字、不同的地址。这个地址由编译器、链接器和动态加载器合作算出：.tdata/.tbss 与 PT_TLS 是模板，%fs 和 TPIDR_EL0 指向每个线程自己的那一份，四种访问模型在通用和快之间取舍，链接器在知道更多信息时把慢序列原地改写成快序列。本文用 clang、ld.lld 和 GNU ld 的真实输出走一遍全过程，最后解释&quot;cannot allocate memory in static TLS block&quot;的根因。</description><pubDate>Sun, 04 Oct 2026 16:02:38 GMT</pubDate></item><item><title>[链接器的世界-原理篇08] 栈展开：沿调用栈找到回去的路</title><link>https://blog.qtok.cloud/posts/linker-08-unwinding/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-08-unwinding/?lang=zh/</guid><description>函数一层套一层地调用，返回地址散落在栈上。打印调用栈、抛出 C++ 异常时，运行时要一层层退回调用者，靠的是编译器和汇编器写进 .eh_frame 的一张&quot;每条指令处怎么找回调用者&quot;的表。本章用真实目标文件逐字节拆开 CIE/FDE，讲 CFI 状态机、personality 与 LSDA、两阶段展开，以及链接器为 .eh_frame 和 .eh_frame_hdr 要做的事。</description><pubDate>Sun, 04 Oct 2026 16:02:37 GMT</pubDate></item><item><title>[链接器的世界-原理篇07] 动态链接：把最后的地址留给运行时</title><link>https://blog.qtok.cloud/posts/linker-07-dynamic-linking/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-07-dynamic-linking/?lang=zh/</guid><description>共享库的加载地址要到运行时才知道，它引用的符号甚至可能被别的库替换。链接器在链接时能做的，是把所有&quot;现在还填不了&quot;的地址集中到少数几处，再给动态链接器 ld.so 写一份说明书。本文从 PIC、GOT、PLT 讲到几类动态重定位、惰性绑定、RELRO、符号插入、符号版本和 ld.so 的启动顺序，全部配真实的目标文件与链接输出。</description><pubDate>Sun, 04 Oct 2026 16:02:34 GMT</pubDate></item><item><title>[链接器的世界-实验篇06] 文件里的字节与内存里的字节：数据、BSS 与段权限</title><link>https://blog.qtok.cloud/posts/linker-lab06-elf-loader/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-lab06-elf-loader/?lang=zh/</guid><description>只有代码的程序几乎没有用。本实验加入只读常量、已初始化全局变量、BSS 和 COMMON，用三个权限不同的加载段描述它们，并让内核替我们检查：写只读数据、执行数据段都会收到 SIGSEGV。</description><pubDate>Sun, 04 Oct 2026 16:02:33 GMT</pubDate></item><item><title>[链接器的世界-原理篇06] 从入口到 main：程序启动之前发生了什么</title><link>https://blog.qtok.cloud/posts/linker-06-loading/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-06-loading/?lang=zh/</guid><description>链接器写完程序头表就退场了，剩下的事归加载器。本文先读 xv6 的 kexec，看一个最小的加载器只用哪几个字段、做哪三道检查；再读 Linux 的 load_elf_binary，看 PT_INTERP、PT_GNU_STACK、基址选择、.bss 的页尾清零与匿名页、按需调页和 brk；然后打印初始进程栈和辅助向量，跟着 musl 的源码从 _start 走到 main，手工复现驱动程序加的五个启动文件，构建一个 static-pie 看 rcrt1.o 怎样自己处理 R_X86_64_RELATIVE；最后在真实内核上改坏 ELF，看加载器怎样守住安全边界。</description><pubDate>Sun, 04 Oct 2026 16:02:30 GMT</pubDate></item><item><title>[链接器的世界-实验篇05] 跨越文件的调用：合并代码，再填写位移</title><link>https://blog.qtok.cloud/posts/linker-lab05-layout/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-lab05-layout/?lang=zh/</guid><description>上一阶段的可执行文件只能来自一个没有重定位的目标文件。本实验让汇编写的入口调用另一个文件里用 C 编译的函数：合并多个代码节，计算每个字段的 S+A-P，并保证失败时不留下半写的字节。</description><pubDate>Sun, 04 Oct 2026 16:02:29 GMT</pubDate></item><item><title>[链接器的世界-原理篇05] 布局与 GC：给每个节找位置，让无用代码退场</title><link>https://blog.qtok.cloud/posts/linker-05-layout/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-05-layout/?lang=zh/</guid><description>同一个目标文件，用不同的链接器、不同的选项链接，填进机器码的数字都不一样。这些数字取决于布局：输入节怎么并成输出节、输出节怎么分进段、段放在哪个地址、哪些节被垃圾回收删掉。本文用 GNU ld 和 lld 的真实输出，讲清楚程序头的每个字段、文件偏移与虚拟地址为什么要同余、-z separate-code、PIE 与基址、--gc-sections 的标记过程、__start_/__stop_ 符号，以及链接器脚本和映射文件。</description><pubDate>Sun, 04 Oct 2026 16:02:26 GMT</pubDate></item><item><title>[链接器的世界-实验篇04] 第一个能运行的 ELF：两张程序头与一个入口</title><link>https://blog.qtok.cloud/posts/linker-lab04-relocations/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-lab04-relocations/?lang=zh/</guid><description>前四个阶段只在读输入。本实验第一次写输出：规划一个最小的可执行映像，手工序列化 ELF 头和两个程序头，让 Linux 内核直接运行它并返回 42。</description><pubDate>Sun, 04 Oct 2026 16:02:25 GMT</pubDate></item><item><title>[链接器的世界-原理篇04] 重定位：一次调用，四个字节的距离</title><link>https://blog.qtok.cloud/posts/linker-04-relocation/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-04-relocation/?lang=zh/</guid><description>从一个真正能运行的 Linux 程序出发，追踪 call 指令里的四个字节：输入节偏移如何变成 P，CPU 为什么从下一条指令算起，S+A-P 又如何落成机器码。再逐步进入负位移、绝对指针、不同加数、溢出和链接期指令改写。</description><pubDate>Sun, 04 Oct 2026 16:02:22 GMT</pubDate></item><item><title>[链接器的世界-实验篇03] 同一个名字，谁说了算：全局符号解析</title><link>https://blog.qtok.cloud/posts/linker-lab03-symbol-table/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-lab03-symbol-table/?lang=zh/</guid><description>先选择跨文件的全局定义，再绑定实际引用；保持局部身份、弱定义顺序和 COMMON 的大小与对齐要求，不在解析阶段分配地址。</description><pubDate>Sun, 04 Oct 2026 16:02:20 GMT</pubDate></item><item><title>[链接器的世界-原理篇03] 符号解析：同一个名字，究竟指向谁</title><link>https://blog.qtok.cloud/posts/linker-03-symbol-resolution/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-03-symbol-resolution/?lang=zh/</guid><description>从一个能独立运行的加法程序开始，亲手制造缺失定义、重复定义和库顺序错误。沿着“谁需要、谁提供、提供者是否进入链接”理解符号解析，再讨论弱定义、common、类型检查与 C++ 的边界。</description><pubDate>Sun, 04 Oct 2026 16:02:17 GMT</pubDate></item><item><title>[链接器的世界-实验篇02] 符号与重定位记录：目标文件留下的待办事项</title><link>https://blog.qtok.cloud/posts/linker-lab02-read-and-write-elf/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-lab02-read-and-write-elf/?lang=zh/</guid><description>解码符号和显式加数重定位，建立字符串表、符号表与被修补节之间的归属关系，保留后续选择与布局所需信息。</description><pubDate>Sun, 04 Oct 2026 16:02:16 GMT</pubDate></item><item><title>[链接器的世界-原理篇02] 拆开目标文件：一份等待组装的程序</title><link>https://blog.qtok.cloud/posts/linker-02-object-file/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-02-object-file/?lang=zh/</guid><description>从一个 main.c、一个 add.c 和一份手写汇编出发，看汇编器怎样按伪指令把字节摆进各个节，再用 llvm-objdump 和几十行 Python 一个字节一个字节拆开 ELF 目标文件：ELF 头、节头表、程序头表、节的类型与标志、符号表、机器码里留下的零字节和重定位表。</description><pubDate>Sun, 04 Oct 2026 16:02:13 GMT</pubDate></item><item><title>[链接器的世界-实验篇01] 节与名字：把一段字节切成有意义的区域</title><link>https://blog.qtok.cloud/posts/linker-lab01-toy-linker/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-lab01-toy-linker/?lang=zh/</guid><description>解码节头、借用文件内容并解析节名，让后续阶段使用带名字的 Section，而不是重复读取原始字段。</description><pubDate>Sun, 04 Oct 2026 16:02:09 GMT</pubDate></item><item><title>[链接器的世界-原理篇01] 地址不能总靠手填：链接器的演化之路</title><link>https://blog.qtok.cloud/posts/linker-01-history/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-01-history/?lang=zh/</guid><description>从 1949 年 EDSAC 的子程序库讲起，沿着&quot;一个问题催生一个发明&quot;的线索，看重定位、汇编器、目标文件、ELF、共享库、DWARF、.eh_frame、COMDAT、可执行栈标记和四代链接器是怎么一个接一个出现的，以及它们怎样把链接器推到今天的位置。</description><pubDate>Sun, 04 Oct 2026 16:02:07 GMT</pubDate></item><item><title>[链接器的世界-实验篇00] 先别相信输入：ELF 文件的第一道边界</title><link>https://blog.qtok.cloud/posts/linker-lab00-setup/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-lab00-setup/?lang=zh/</guid><description>检查字节范围、支持的 ELF64 头和节头索引，为后续解析建立不会溢出或越界的输入边界。</description><pubDate>Sun, 04 Oct 2026 16:02:05 GMT</pubDate></item><item><title>[链接器的世界-原理篇00] 从一条编译命令出发：程序如何连成整体</title><link>https://blog.qtok.cloud/posts/linker-00-start/?lang=zh/</link><guid isPermaLink="true">https://blog.qtok.cloud/posts/linker-00-start/?lang=zh/</guid><description>从一个正常的跨文件函数调用出发，拆开编译器驱动的预处理、编译、汇编与链接过程，再借类型不一致的程序辨认链接器的信息边界。沿着目标文件、可执行文件与内存映射，建立符号解析、布局、重定位以及编译、链接、加载、运行四个时期的联系，并提供统一的 Linux 本机实验环境。</description><pubDate>Sun, 04 Oct 2026 16:01:29 GMT</pubDate></item></channel></rss>