鸿蒙综合讨论/ELF 纪律:so 的 ABI 与段

ELF 纪律:so 的 ABI 与段

移植工程里 so 文件不是黑盒,它是有纪律的产物。这篇讲 ELF 纪律:ABI、段结构、以及为什么鸿蒙对它们比 Linux 更挑剔。

▍musl 的严格性
鸿蒙应用侧的 C 库是 musl。musl 的动态加载器比 glibc 严格得多:glibc 对很多不规范 ELF 睁只眼闭只眼,musl 直接拒载。两个高频雷区:一是动态段的 NEEDED 条目带版本号(glibc 环境常见写法),musl 解析失败;二是段对齐不规范——正常发布的库不犯这错,但经过打包工具二次加工(符号裁剪、段注入)的库会中招。所以依赖库的依赖名一律去版本号,任何工具加工过的库要重验对齐。

▍ABI 自检清单
一个 so 上机前过四关:架构对(aarch64,用读取工具看 ELF 头);标准库对(与目标侧 C 库与 CPlusPlus 库实现一致,混用不同工具链的 CPlusPlus 库会在异常路径崩);符号闭包全(未定义符号都能在依赖链上找到,用工具列未定义符号逐个核对);依赖名干净(无版本号后缀、无目标环境不存在的库名)。四关有工具命令可查,编进出包前的检查脚本。

▍段的规矩
可执行段与数据段的权限要规范:可写又可执行的段会被安全策略重点盯防。链接期用链接器选项控制段的合并与对齐;加工期(注入权限段等操作)后必须跑对齐修复工具。真实案例:权限段注入后没修复对齐,装机加载即崩且零日志,排查到怀疑人生——后来这类加工一律后接修复与加载验证。

▍二进制补丁的禁令
对 so 做二进制机器码级的修补(改跳转、替换函数字节)是明确禁止的实践:重编一次就失效,且修补过程可能静默损坏。正确路径是改源码重编。NEEDED 与路径这类字符串表的修改用原位编辑工具(等长替换),不破坏文件结构。

▍验收动作
so 变更后的验证锚点:包内 so 与预期字节一致(构建产物直接比对)、装机加载无失败日志、新行为出现(新增日志行或交互变化)。三锚点缺一不可,构建成功不算数。

更多真实移植案例,欢迎到 apps 板块翻看 56 篇《鸿蒙PC适配全记录》系列实录。
楼主 7 天前
想参与讨论?登录 或 30 秒注册。