BOLT Address Translation(BAT)详解:在已优化二进制上采集 Profile 并反译回输入二进制的原理与实践 BOLT Address TranslationBAT详解在已优化二进制上采集 Profile 并反译回输入二进制的原理与实践【免费下载链接】llvm-projectThe LLVM Project is a collection of modular and reusable compiler and toolchain technologies.项目地址: https://gitcode.com/GitHub_Trending/ll/llvm-projectBOLT Address TranslationBAT解决的是一个很实际的性能工程问题如果只能在生产环境部署已经过 BOLT 优化的二进制如何在其上采集采样 Profile再把这些样本地址翻译回优化前的输入二进制用于下一轮优化读完本文你将掌握 BAT 的端到端工作流--enable-bat生成翻译表、perf2bolt反译 Profile、.note.bolt_bat段的完整二进制编码格式函数表、地址翻译表、次入口点表的 delta/LEB128 编码细节以及BoltAddressTranslation类在 BOLT 源码中的构建、解析与查询链路。1. 背景为什么需要 BATBOLT 的常规 Profile 采集流程是在未优化的输入二进制上插桩或用 perf 采样得到基于输入二进制地址的 Profile再交给 BOLT 做函数重排、基本块重排、冷热拆分等优化。但在真实部署场景中往往只能部署已优化的二进制——也就是说采样只能发生在 BOLT 输出的二进制上。此时样本地址是输出地址空间中的地址而 BOLT 又不支持直接对已优化二进制再做二次优化。BAT 正是为此设计的BOLT 在输出二进制中额外插入一个名为.note.bolt_bat的 note 段其中保存地址翻译表和函数冷热拆分split functions的关联信息。有了这个段就可以把采集自优化二进制的 Profile 映射回原始输入二进制从而避免为了单纯采集数据而部署非 BOLT 版本。这一设计目标在头文件注释中写得很明确见 BoltAddressTranslation.h 的类注释We do not support reoptimizing a binary already processed by BOLT, but we do support collecting samples in a binary processed by BOLT. We then translate samples back to addresses from the input (original) binary, one that can be optimized. The goal is to avoid special deployments of non-bolted binaries just for the purposes of data collection.从源码结构看内存中的表示以函数为单位组织每个函数有一张自己的std::multimapuint32_t, uint32_t翻译表MapTy键为输出地址空间中区域的起点偏移值为输入地址空间中的偏移翻译时先在表中找到小于等于样本地址的最大键再据此换算出输入地址。此外只有会改变控制流的指令分支、调用才会作为分支源条目出现在表中而基本块起始位置被记录下来是因为它们可能是跳转目标LBR trace 中的 To 地址也用于重建函数内基本块布局以便根据 LBR 轨迹恢复 fall-through隐式顺序执行边。2. 使用方式从生成 BAT 段到反译 ProfileBAT 的完整使用流程分两步第一步启用 BAT 并运行 BOLT 优化。--enable-bat控制是否生成 BAT 段将采样的 Profile 与不含 BAT 的输入二进制一起交给llvm-bolt并在参数中加上--enable-bat。该选项定义于 CommandLineOpts.cpp默认值为false描述为 write BOLT Address Translation tablescl::optbool EnableBAT(enable-bat, cl::desc(write BOLT Address Translation tables), cl::init(false), cl::ZeroOrMore, cl::cat(BoltCategory));第二步在优化后的二进制上采集 Profile并用perf2bolt反译。将采到的采样 Profile如 perf 数据连同包含 BAT 段的优化二进制一起传给perf2bolt。perf2bolt会读取.note.bolt_bat段将其填充进BoltAddressTranslation对象随后在样本处理过程中由DataAggregator查询该对象把输出地址空间中的地址/偏移重建为输入二进制中的地址/偏移最终产出一份针对原始输入二进制的 Profile。在 DataAggregator.cpp 中可以观察到这一查询链路的具体调用点BAT-translate(Func.getAddress(), ...)负责地址反译普通样本与 LBR 样本各有一处、BAT-fetchParentAddress(...)用于把拆分出的冷片段样本归并回其父热函数、BAT-getFallthroughsInTrace(...)用于从 LBR 轨迹推断被取到的 fall-through 边。仓库中的端到端测试 bolt-address-translation.test 演示了--reorder-blocksnormal --split-functions --enable-bat的组合用法bolt-address-translation-yaml.test 则覆盖了--reorder-functionscdsort --enable-bat --dyno-stats场景下的 Profile 输出仓库还提供了 bat-dump 工具用于转储解析后的翻译表方便人工检查。需要注意的一个前提llvm-bolt在写入 BAT 段时会记录每个基本块/指令的输入-输出地址映射IO address mapBinaryFunction.cpp 中即有 accurate IO address map later (used for BAT, ...) 的相关逻辑当二进制没有重定位无 relocations且函数体未被修改时函数被视为simple无需翻译表见 BoltAddressTranslation.cpp 中write的跳过条件。3. BAT 段的内容组织.note.bolt_bat段整体组织如下Hot functions table 热函数表 └─ Address translation tables 各函数的地址翻译表 Cold functions table 冷函数表即先是一张热函数表每个函数附带自己的地址翻译表后跟一张冷函数表。热/冷两个表共享同一套编码差异在下方各小节单独标出。从实现角度看BoltAddressTranslation类由 BOLT linker 提供的地址翻译信息构建write遍历BinaryContext中的每个BinaryFunction通过writeEntriesForBB为每个基本块及其内部的控制流指令生成条目然后以 ELF note 段的形式编码进输出二进制。反过来perf2bolt处理 BAT 启用的二进制时parse方法从 note 段重建内存表示供DataAggregator在样本处理时查询。4. 编码格式详解编码的权威定义在 BoltAddressTranslation.h 与 BoltAddressTranslation.cpp 中。整体布局为Hot functions table Cold functions table Functions table: |------------------| | Function entry | | | | Address | | translation | | table | | | | Secondary entry | | points | |------------------|4.1 函数表Functions table热、冷函数表共享下述编码差异在各条目最后一列标出。表头只有一个字段条目编码说明NumFuncsULEB128该函数表中的函数数量表头之后是NumFuncs个函数条目。两个关键的压缩策略输出二进制地址采用 delta 编码只存储与上一个输出地址的差值地址隐含从 0 开始。输出地址在函数起始地址与函数内部偏移之间、以及热/冷片段之间都是连续的continuous这样差值更均匀能更好地省空间。热函数索引HotIndex同样 delta 编码隐含从 0 开始。各条目定义如下条目编码说明热/冷AddressContinuous, Delta, ULEB128函数在输出二进制中的地址两者HotIndexDelta, ULEB128对应热函数在热函数表中的索引冷FuncHash8b输入函数的哈希热NumBlocksULEB128原始函数中基本块的数量热NumSecEntryPointsULEB128原始函数中次入口点的数量热ColdInputSkewULEB128需要应用到所有输入偏移上的偏移量skew冷NumEntriesULEB128该函数地址翻译表中的条目数两者EqualElemsULEB128函数开头输入偏移等于输出偏移的条目数两者BranchEntriesBitmaskalignTo(EqualElems, 8)个 bit当EqualElems非零时标记哪些条目带BRANCHENTRY位的位图两者函数头部之后依次是含NumEntries个条目的地址翻译表以及仅热函数含NumSecEntryPoints个条目的次入口点表。其中HotIndex的作用可以从 BoltAddressTranslation.h 的成员ColdPartSourceLinks outlined cold blocks to their original function印证冷函数表条目通过HotIndex指向其父热函数perf2bolt侧的fetchParentAddress查询正是利用这份关联把冷片段上的样本归并到父函数FuncHash与NumBlocks则对应内存结构FuncHashesTy/BBHashMapTy用于在 BAT 模式下校验函数身份并重建输入二进制的基本块布局DataAggregator写 YAML Profile 时会调用getBFHash、getNumBasicBlocks、getBBHashMap填充这些元数据。4.2 地址翻译表Address translation tabledelta 编码的含义是只编码与上一个对应条目的差值输入偏移隐含从 0 开始。条目编码说明分支/BBOutputOffsetContinuous, Delta, ULEB128函数在输出二进制中的偏移两者InputOffsetOptional, Delta, SLEB128输入二进制中函数的偏移最低位LSB为BRANCHENTRY位两者BBHashOptional, 8b输入二进制中基本块的哈希BBBBIdxOptional, Delta, ULEB128输入二进制中基本块的索引BB格式上的三个要点等偏移省略表会省略函数开头EqualElems个输入偏移等于输出偏移的条目——因为这些位置本身就不需要翻译。BRANCHENTRY位的语义该位标记该偏移对是否为控制流源分支或调用指令未置位则表示控制流目标基本块偏移。这与 BoltAddressTranslation.h 中const static uint32_t BRANCHENTRY 0x1;一致也解释了为何InputOffset用 SLEB128 且值域左移一位。等偏移条目的输入地址省略当输入、输出函数中偏移相等时InputOffset字段整体省略此时BRANCHENTRY位单独编码在BranchEntries位向量中即上表 4.1 中的位图字段。在 BoltAddressTranslation.cpp 的writeEntriesForBB中可以看到条目生成的实际规则每个输出基本块至少产生一条 BB 起始条目Map.emplace(BBOutputOffset, BBInputOffset 1)左移一位即为BRANCHENTRY位留空随后遍历块内记录的位置符号为每个控制流指令追加一条(InputOffset 1) | BRANCHENTRY条目。对于被优化删除的基本块编码上输出其OutputOffset等于函数大小——这类条目不影响地址翻译只参与输入基本块映射DataAggregator中isInputBlock的判断正依赖完整的输入块映射。值得注意的工程细节当多个输入块映射到同一输出地址时例如只含 NOP 或跳转的块被删除与后继块共享地址编码策略是后写者胜出优先保留后继块successor的映射保证样本不会错误落到已删除块上。4.3 次入口点表Secondary Entry Points table该表仅对热片段输出包含NumSecEntryPoints个偏移表示次入口点函数体内允许从外部直接跳转进入的位置如跳表、尾调用目标等采用 delta 编码、隐含从 0 开始条目编码说明SecEntryPointDelta, ULEB128次入口点偏移write流程通过Function.forEachEntryPoint收集这些偏移并缓存到SecondaryEntryPointsMap查询侧的translateSymbol/getSecondaryEntryPointId则用于把优化二进制的符号引用翻译回父函数与对应入口点YAMLProfileWriter.cpp 在写被调方地址时即调用translateSymbol。5. 小结BAT 在 BOLT 工作流中的位置把前述内容串起来BAT 支撑的完整闭环是llvm-bolt --enable-bat ...优化输入二进制输出二进制中带有.note.bolt_bat段热函数表 翻译表 次入口点表冷函数表带HotIndex关联该优化二进制上线运行perf 采样得到基于输出地址的 Profileperf2bolt将采样数据与优化二进制一起处理BoltAddressTranslation::parse从 note 段重建翻译表DataAggregator在处理每个样本时调用translate/fetchParentAddress/getFallthroughsInTrace把地址反译、冷片段归并、fall-through 边补全产出输入二进制地址空间的 Profile该 Profile 回到步骤 1驱动下一轮 BOLT 优化。对使用者而言需要记住的约束BAT 面向采集而非二次优化——已 BOLT 过的二进制本身不能作为 BOLT 的输入再优化翻译表只覆盖会出现在 LBR 中的控制流点与基本块位置普通指令不占条目这正是编码能够保持紧凑的原因。【免费下载链接】llvm-projectThe LLVM Project is a collection of modular and reusable compiler and toolchain technologies.项目地址: https://gitcode.com/GitHub_Trending/ll/llvm-project创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

最新新闻

fuels-rs 调用其他合约实战:with_contracts 与 with_contract_ids 的输入输出准备机制

fuels-rs 调用其他合约实战:with_contracts 与 with_contract_ids 的输入输出准备机制

fuels-rs 调用其他合约实战:with_contracts 与 with_contract_ids 的输入输出准备机制 【免费下载链接】fuels-rs Fuel Network Rust SDK 项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-rs 当 Sway 合约的方法内部会调用其他合约时,交…

2026/9/6 19:17:11
Java校园二手置换系统:从匹配规则到订单状态机的完整设计

Java校园二手置换系统:从匹配规则到订单状态机的完整设计

简介:一份面向计算机相关专业毕业生的校园二手物品置换系统毕业设计文档,适用于需要完成Java Web方向课题、学习SpringBoot与MySQL整合开发的高校学生。文档基于B/S架构,从可行性分析、系统流程、性能评估到功能需求展开论述,完整…

2026/9/6 19:17:11
axios 贡献实战指南:代码风格、Conventional Commits、Vitest 测试体系与构建沙箱验证全流程

axios 贡献实战指南:代码风格、Conventional Commits、Vitest 测试体系与构建沙箱验证全流程

axios 贡献实战指南:代码风格、Conventional Commits、Vitest 测试体系与构建沙箱验证全流程 【免费下载链接】axios Promise based HTTP client for the browser and node.js 项目地址: https://gitcode.com/GitHub_Trending/ax/axios 本文以 axios 仓库的 …

2026/9/6 19:17:11
加权马尔可夫链修正ARIMA预测误差:原理、流程与实战

加权马尔可夫链修正ARIMA预测误差:原理、流程与实战

简介:这是一份面向算法、机器学习及人工智能领域研究者的学术论文PDF,聚焦设备状态参数预测问题。研究提出基于加权马尔可夫链修正的ARIMA组合预测模型,针对单一ARIMA模型存在偏差与不稳定性的不足,引入加权马尔可夫链对残差序列进…

2026/9/6 19:17:11
猫抓插件网页视频下载完整指南:从安装到 M3U8 解析

猫抓插件网页视频下载完整指南:从安装到 M3U8 解析

猫抓插件网页视频下载完整指南:从安装到 M3U8 解析 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 如果你遇到过这种情形:想…

2026/9/6 19:17:11
Opik 性能优化实战:每日数千万追踪记录的低成本稳定方案

Opik 性能优化实战:每日数千万追踪记录的低成本稳定方案

Opik 性能优化实战:每日数千万追踪记录的低成本稳定方案 【免费下载链接】comet-llm Debug, evaluate, and monitor your LLM applications, RAG systems, and agentic workflows with comprehensive tracing, automated evaluations, and production-ready dashboa…

2026/9/6 19:12:11