根据mold的注释所讲,common symbols被用于C的tentative definition,tentative definition是指C语言在一个头文件中允许全局变量定义省略extern。
上一期我们讲解了一些符号相关的处理,这一期我们来讲一些对于section size的优化处理。
将OutputSection以及Got中的relocations以压缩的形式存储到relr.dyn,在这之后rel段的大小和layout就固定了。
https://homura.live/2023/02/26/mold/mold-1-read-input-files/ ObjectFile get_string 之前在读取符号表的时候是通过这种方式读取的 ,但我们没有讲解这个读取的细节 this->symbol_strtab = this->get_string(ctx, symtab_sec->sh_link); elf/mold.h template elf_sections[idx]); } 这里直接获取了get_string的结果,并且将对应的结果映射为了一个对应数据的span get_shndx 在之前从符号表取数据的时候是通过get_shndx实现的 elf/mold.h 虽然在mold的类结构中ObjectFile和SharedFile都是直接继承自InputFile,但对于实际的object和dso来说我觉得dso更倾向于是特别的object,不过这个从dso的全名(
之后再从每个流程中的具体实现开始阅读(如果我记得的话会回头在这里补上对应的链接),或者会以解决某些问题为线索写一篇,比如说某一些常见的参数具体在mold中怎么生效的,比如说whole_archive这种 链接前的准备流程 main.cc int main(int argc, char **argv) { mold::mold_version = mold::get_mold_version(); #if MOLD_IS_SOLD std::string cmd = mold::filepath(argv[0]).filename().string(); if (cmd == "ld64" || cmd == "ld64.mold") return mold::macho::main(argc, argv); #endif return mold::elf::main(argc
在讲主要的符号决议之前,先讲一下mold在符号决议执行之前做的一些其他处理。 ctx.internal_esyms; obj->symvers.resize(ctx.internal_esyms.size() - 1); defsym 关于前面提到的defsym,我们来看一下mold 符号决议 接下来是链接过程中比较重要的一个环节,符号决议(symbol resolve) 在mold中,这个部分做了四件事情 检测所有需要使用的objet files 移除重复的COMDAT段 进行符号决议的过程 archive extraction: .a成员只会在满足非archive object文件未定义符号之一的情况下才会被包含在最终的二进制文件中 链接时为了满足archive extraction的规则,mold
See" " https://github.com/rui314/mold/tree/main/docs/execstack.md" " for more info.
mold中称mergeable section原子单元为section pieces。 ObjectFile<E> *file) { file->resolve_section_pieces(ctx); }); } initialize_mergeable_sections mold
ctx.arg.oformat_binary) add_comment_string(ctx, mold_version); // Embed command line arguments if (char *env = getenv("MOLD_DEBUG"); env && env[0]) add_comment_string(ctx, "mold command line: 在mold中chunk则是表示用于输出的一片区域,关于Chunk类源码中有这样的注释 Chunk represents a contiguous region in an output file.
上一期主要讲了链接前的一些准备流程以及在mold中链接过程的简单介绍。这期开始我们从链接过程中的功能开始介绍。 当前所支持的FileType就是这些,但是注意,GitHub中mold项目下只存在elf文件的支持,mach的格式则是在sold这个项目中处理。 linker script mold的linker script根据解析的过程来看比较简单,没有在ld的脚本中的指定SECTION地址之类的内容,主要是对format以及符号version的一些控制。 在每次创建的时候会将对应的obj对象放入到全局的ctx.obj_pool中,mold中的内存与生命周期的管理方式则是全部交由ctx保有,到最后一起释放。 esym则是ElfSym的缩写,也就是Elf文件中的Symbol定义,而Symbol则是mold中自己定义的,相当于转换为自己想要的格式。
#ifdef MOLD_X86_64 // Exiting from a program with large memory usage is slow -- // it may take a few ctx.checkpoint(); 直接exit或者调用exit的清理的函数 –quick-exit Use quick_exit to exit (default) –no-quick-exit 在mold 至此,整个mold的链接过程已经完全结束了。下一期会进行一个总结,并且记录一下一些自己的想法
This doesn't save memory but saves disk space. mold中不论是指定order还是不指定都是遵循基本的两条规则 memory protection: 不同attr 而mold的做法是选择其中最大的align值。
typename E> void print_dependencies(Context<E> &ctx) { SyncOut(ctx) << R"(# This is an output of the mold E> void print_dependencies_full(Context<E> &ctx) { SyncOut(ctx) << R"(# This is an output of the mold response.txt", save_string(ctx, create_response_file(ctx))); tar->append("version.txt", save_string(ctx, mold_version repro") out << arg << "\n"; } return out.str(); } 根据代码我们得知,主要分为三部分 response_file,本质上是编译命令以及参数 mold
mold源码阅读十四 fix file layout and create output 上一期主要讲解了shdr计算更新的部分以及osec offset的设置,这期则是做链接最后的工作。 mold在.rel.dyn的末尾对IFUNC重定位进行分组,因为希望在运行用户提供的ifunc解析函数之前应用所有其他重定位。
相关的链接选项在mold中有如下几个 -s, –strip-all Strip .symtab section –retain-symbols-file FILE Keep 在mold中仅针对OutputSection,Got,Plt,PltGot这几个chunk来处理。 template <typename E> static constexpr bool needs_thunk = requires { E::thunk_size; }; 根据mold代码中的实现,目前需要 /mold-5-symbol/ dso template <typename E> void SharedFile<E>::compute_symtab_size(Context<E> &ctx) { 关于mold自行parse eh_frame的部分可以参考第二期的内容https://homura.live/2023/04/05/mold/mold-2-read-shared-files/ 在构造的过程主要由如下几部分组成
mold源码阅读十四 fix file layout and create output 上一期主要讲解了shdr计算更新的部分以及osec offset的设置,这期则是做链接最后的工作。 mold在.rel.dyn的末尾对IFUNC重定位进行分组,因为希望在运行用户提供的ifunc解析函数之前应用所有其他重定位。
主要功能包括: Youtube 音乐播放列表 缓存所有下载并储存 自动后台下载管理器 Github,https://github.com/ccgauche/ytermusic mold linker 项目发布 v1.7.1 mold linker 旨在通过减少构建时间来提高开发人员的工作效率,尤其是在调试-编辑-重建快速周期中,是现有 Unix linker 的替代品,它比 LLVM lld linker 快几倍 mold linker 项目作者创建了一个网站bluewhale.systems,用户可以购买非 AGPL 许可的 mold linker,并且作者正在考虑更改 mold/macOS 的许可。 Github v1.7.1发布链接,https://github.com/rui314/mold/releases/tag/v1.7.1 [博客] Rust 树数据结构 在 Rust 中实现链表时,一个众所周知的陷阱是默认的递归删除实现会导致长列表的堆栈溢出
end-to-end encrypted group video calls: https://signal.org/blog/how-to-build-encrypted-group-calls/ 现代链接器 mold v1.0 发布 mold 是一个更加现代的链接器,它是由 C++ 编写的,但能够与 Rust / Cargo 生态完美协作,提供更快地链接过程。 你可以使用 mold --run cargo build 来尝试它,或者将下述内容添加到 ~/.cargo/config.toml: [target.x86_64-unknown-linux-gnu] linker = "clang" rustflags = ["-C", "link-arg=-fuse-ld=/PATH/TO/mold"] GitHub - mold: https://github.com /rui314/mold This Week in Rust 421 新一期的 Rust 周报速递发布,快来看看有哪些内容你曾经关注过 :) This Week in Rust 421: https:/
「更快、更高、更强」的 mold 是的,既然是链接器的问题,那么最简单的办法就是换一个。 该如何与 Rust 工具链结合使用呢,有这么两种方法: mold -run 采用这种模式,可以帮助我们快速体验 mold ,这得益于内置的拦截机制,可以将指向 ld ,ld.lld ,ld.gold 的命令转向 mold 自身。 # 结合 Make mold -run make <make-options-if-any> # 或者针对于 Cargo mold -run cargo <cargo-options-if-any> 编辑 .cargo/config.toml 添加下面的内容即可,如果是按 sudo make install 安装的,path/to/mold 大概率会指向 /usr/local/bin/mold 。
ReadMore: https://kerkour.com/rust-projects-maintenance-and-supply-chain-security mold 一个比 llvm linker 快数倍的链接器 mold是现有Unix链接器的一个更快的直接替代者。 LLVM lld是第二快的开源链接器,mold 比其链接速度快数倍。 下面是GNU gold、LLVM lld和mold在模拟的8核16线程机器上连接主要大型程序的最终调试信息可执行文件的性能比较。 "] ReadMore: https://github.com/rui314/mold ---- From 日报小组 Koalr 社区学习交流平台订阅: Rustcc论坛: 支持rss 微信公众号:Rust