LLD 默认不生成 Map 文件,必须显式启用 --Map 参数并手动指定路径;clang -Wl,--Map 不生效是因为该参数需位于链接器命令行顶层且某些旧版 Clang 会丢弃它,最稳妥方式是直接调用 lld -flavor gnu 并传参。

LLD 默认不生成 Map 文件,必须显式启用 --Map 参数,且输出路径需手动指定(无默认文件名)。
为什么 clang -Wl,--Map=output.map 不生效?
常见错误是误以为 -Wl,--Map 会自动传递给 LLD。实际中:
- Clang 的
-Wl,前缀只对 GNU ld 兼容参数做透传,而 LLD 对--Map的解析更严格,要求它必须出现在链接器命令行的「顶层」位置,不能被-Wl,包裹; - 若用
clang main.o -Wl,--Map=output.map,LLD 实际收到的是--Map=output.map—— 这看似正确,但某些 Clang 版本(尤其是 14 以前)会因参数解析顺序问题丢弃该选项; - 最稳妥的方式是绕过 Clang 封装,直接调用
lld并显式传参。
正确生成 Map 文件的两种方式
方式一:用 clang 调用 LLD,并确保 --Map 在链接阶段被识别
- 加
-fuse-ld=lld强制使用 LLD; - 用
-Wl,--Map=output.map,但必须放在所有输入文件之后、输出选项之前(例如:clang -fuse-ld=lld main.o -Wl,--Map=output.map -o main); - 注意:
output.map是相对路径,若当前目录无写权限会静默失败,建议用绝对路径或先cd到可写目录。
方式二:跳过 Clang,直接调用 lld
- 先编译出目标文件:
clang -c main.c -o main.o; - 再执行:
lld -flavor gnu main.o --Map=output.map -o main; -
-flavor gnu是必需的(LLD 默认 flavor 是elf,但--Map只在gnuflavor 下支持); - 不加
-flavor gnu会导致报错:unknown argument: '--Map'。
Map 文件里有什么?哪些字段容易被忽略
LLD 生成的 Map 文件不是符号列表快照,而是带层级结构的地址分配视图:
-
.text、.data等 OutputSection 的起始地址和大小,含每个 InputSection 的偏移与来源文件; - 全局符号(
UND、DEF)按地址排序,但不会列出局部符号(LOCAL),除非加--verbose; - 常见盲点:
--Map不包含重定位信息(RELA)、调试段(.debug_*)或未定义符号的来源库路径 —— 它只反映地址布局结果; - 若需符号来源追溯,得配合
llvm-nm --defined-only main.o或llvm-readobj --symbols main单独分析。
Map 文件本身不压缩、不缓存,每次链接都会覆盖。如果构建系统并发运行多个链接任务,务必为每个任务指定唯一 --Map=xxx-<pid>.map</pid>,否则内容会相互污染。

















