系统与基础设施lurklurk.org编辑精选
链接器入门指南
Beginner's Guide to Linkers (2010)
2010 — 2022,它一次次回到首页
黑点是上首页(≥ 50 分)的那次投稿,空心点是没冲上去的投稿,点越大分数越高。
导读
这是一篇面向初学者的链接器入门教程,讲解目标文件如何链接成可执行程序,涉及符号解析、重定位、静态库与动态库等核心概念。文章写于 2010 年,多年来多次登上 Hacker News 首页,被广泛认为是理解链接过程最平易近人的资料之一。
为什么经久不衰:链接器是许多程序员的知识盲区,而这篇文章用清晰易懂的方式补上了这块拼图,其内容历经十余年依然准确适用。
HN 评论精选
分享动态链接延迟绑定的机制:函数首次调用时才解析符号并回填地址
我在 gdb 里调试一个使用动态链接的程序时发现一个很有意思的现象:函数是延迟链接的,即在第一次被调用时才完成链接。程序启动时并不会直接接好 printf/fopen 的调用,而是通过一个中间表跳转到动态链接器的解析代码。每个动态链接函数第一次被调用时会经历符号查找过程,找到实际地址后,解析器会把指向该地址的跳转写回中间表,之后的调用就不再重复查找逻辑。用 LD_BIND_NOW 环境变量可以让它在启动时就完成所有查找。
briansteffens查看英文原文
One thing I found really interesting while playing around with gdb on a program with dynamic linking is that functions are linked lazily when they're first called. So rather than hooking up calls to printf/fopen when the program starts, those calls instead get hooked up through an intermediate table to jump into the dynamic linker's resolution code. The first time each dynamically-linked function is called, it goes through a process of looking up the symbol. Once it finds the actual address of the called function, it writes a jump to that resolved address over the spot in the intermediate table so subsequent calls won't repeat the lookup logic. Pretty cool to watch it happen. The call lookup code in the dynamic linker involves a bunch of strcmp calls, which makes sense, but I still found surprising for some reason. You can set the environment variable LD_BIND_NOW to make it do all these lookups at startup time.
链接器难懂难用,各平台实现各异,引用 Taylor 的名言提醒人们谨慎对待
gold 和 GNU 链接器的作者 Ian Lance Taylor 十多年前在 gcc-help 邮件列表上说过:“直接给链接器传命令需要你清楚自己在做什么。”我把这句话加进了我的 makefile,它并没有让链接器工作得更好,但确实让我在写下那些咒语时多想了一步链接器到底在干什么。链接脚本尤其难写对,想在 Linux/BSD 上做复杂的事情就离不开它。各平台的链接器各不相同:gnu ld、osx ld、gold、lld、Windows 用的那个……我不怕承认:我也就是把链接器命令行和脚本调到能跑为止。链接器本应更易理解易用,甚至有个安全漏洞正是利用了大家不理解链接器这一点。链接器确实是个痛点。
CalChris查看英文原文
There was a comment more than ten years back on gcc-help by Ian Lance Taylor, author of gold and the gnu linkers: Passing commands directly to the linker requires that you know what you are doing. I added this to my makefiles. It doesn't make the linker work any better. But it does make me think a little harder about what the linker is doing with my incantations. Linker scripts [1] are a particular pain to get write and if you want to do something complicated on Linux or BSD, you'll be using linker scripts. These are a gnu linker thing. The OSX linker doesn't have the same. Indeed, linkers are different or duplicated on each platform. gnu ld osx ld gold ld (Google) lld (llvm) whatever Windows uses because I don't know ... I'm not embarrassed to admit this: I get my linker command lines and scripts working and that's about it. But linkers should be easier to understand and use. There is even a security bug that relies on our not understanding them [2]. I can't sugar coat this: linkers are a pain. Taylor is right when he says Passing commands directly to the linker requires that you know what you are doing. [1] https://sourceware.org/binutils/docs/ld/Scripts.html [2] http://www.cse.psu.edu/~trj1/papers/ndss17.pdf
亲历者分享写链接器的有趣经历,认为这是理解用户态与 OS 边界的顿悟时刻
我职业生涯早期最有意思的项目之一,是为嵌入式 PLC 写一个 PE 文件链接器。另一个团队在写 gcc 编译器扩展和运行在 Windows PC 上的模拟器,模拟器代码都存在 DLL 里。思路很酷:你可以在 Windows 图形界面里编写和测试梯形图逻辑,点一个按钮生成 .exe 文件并上传到 PLC。PLC 的 RTOS 会调用我的链接器代码,把 DLL 的符号表与 PLC 中的嵌入式代码链接起来并做一些小的重定位。通过把所有梯形图逻辑放进加载的 .exe,他们能针对大小和速度做优化,而不必在 PLC 里跑梯形图解释器。如果有机会玩玩链接器,我建议你试试,这是关于用户态/操作系统边界的一个“顿悟”时刻。
dugmartin查看英文原文
One of the most fun work projects I had early in my career was writing a linker for PE files for an embedded PLC. Another team was writing some gcc compiler extensions and an emulator for the PLC that ran on Window's PCs with all the emulator code stored in DLLs. The idea was pretty cool - you could write and test ladder logic in a Window's GUI and then click a button to generate an .exe file and upload it to the PLC. The PLC's RTOS would then call my linker code which would link up the symbol tables for the DLLs with the embedded code in the PLC and do some other minor relocations. By putting all the ladder logic code in the loaded .exe they were able to optimize for size/speed (using gcc and heuristics of the ladder logic diagram) instead of running a ladder logic interpreter in the PLC. If you ever get a change to play around with a linker I'd suggest you do. It's one of those "aha" moments in CS about the userland/OS boundary.
推荐 Ian Lance Taylor 的链接器系列文章,认为其内容是精华
在我看来,关于链接器最好的文章是 Ian Lance Taylor(gold 链接器的作者)写的系列。虽然明显写得仓促、需要润色,但内容是精华。LWN 发布过一个带各部分链接的导读,让它更易读。我一直希望 Ian 能把它写成他提到过的那本书。
weinzierl查看英文原文
Best piece on linkers is in my opinion Ian Lance Taylor's (author of the gold linker) write up[1]. It obviously has been written in a hurry and could need some polish but the content is gold. LWN published an overview with links to the different parts, to make it a little more accessible[2]. I always hoped Ian would turn it into the book he mentioned in the post. [1] https://www.airs.com/blog/archives/38 [2] https://lwn.net/Articles/276782/
历次讨论
同类还值得读
TTY 揭秘(2008)
The TTY demystified (2008)
经典文章深入剖析了 Unix/Linux 中 TTY 子系统的工作原理,包括线路规程、终端驱动、信号与控制字符等机制。
系统与基础设施上首页 11 次 · 2009–2025linusakesson.net编辑精选为什么 GNU grep 这么快
Why GNU grep is Fast
FreeBSD 邮件列表上一篇广为流传的帖子,解释 GNU grep 为什么快:核心在于 Boyer-Moore 字符串搜索算法配合精心优化的内部循环和 I/O,让程序在搜索时“…
系统与基础设施上首页 9 次 · 2010–2022lists.freebsd.orgXplain:为普通人讲解 X11
Xplain – Explaining X11 for the rest of us
《Xplain》是作者(HN 用户 Jasper_)写的一系列 X11 长文,用他在浏览器中重建的 X11 绘图模型做交互演示,讲解 X11 的绘图模型与窗口系统设计。
系统与基础设施上首页 6 次 · 2013–2020magcius.github.io编辑精选旋风教程:为 Linux 创建极小 ELF 可执行文件(1999)
A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux (1999)
breadbox 写于 1999 年的经典教程,主题是如何为 Linux 手工构造并裁剪出体积极小的 ELF 可执行文件。
系统与基础设施上首页 6 次 · 2007–2025muppetlabs.comPostgreSQL 内部原理
The internals of PostgreSQL
《The Internals of PostgreSQL》是一本免费在线书籍,系统讲解 PostgreSQL 的内部实现,包括查询处理、并发控制、WAL、缓冲区管理等核心机制。
系统与基础设施上首页 5 次 · 2017–2025interdb.jp编辑精选