跳转至

HIC ABI 兼容性规范

本文档定义了HIC系统的ABI(Application Binary Interface)兼容性规范,确保二进制兼容性和跨版本稳定性

一、ABI 设计原则

重要: 关于接口分类和官方接口维护原则的详细信息,请参阅: - 接口分类与维护原则

1.1 核心原则

  • 类型稳定: 所有公开类型的布局和大小在ABI版本内不变
  • 调用约定: 使用标准平台调用约定
  • 对齐要求: 遵循平台默认对齐
  • 返回值: 所有函数返回统一的错误码类型
  • 参数传递: 使用寄存器传递小参数,栈传递大参数

1.2 版本兼容性

版本 发布日期 兼容性 变更
1.0 2026-02-26 - 初始版本

二、类型定义规范

2.1 基本类型

所有公开类型必须使用固定大小的整数类型:

typedef u8  u8;   /* 8位无符号 */
typedef u16 u16;  /* 16位无符号 */
typedef u32 u32;  /* 32位无符号 */
typedef u64 u64;  /* 64位无符号 */
typedef s8  s8;   /* 8位有符号 */
typedef s16 s16;  /* 16位有符号 */
typedef s32 s32;  /* 32位有符号 */
typedef s64 s64;  /* 64位有符号 */

ABI保证: 这些类型的大小和符号性永不改变。

2.2 句柄类型

所有句柄类型使用64位无符号整数:

typedef u64 hic_domain_t;    /* 域ID */
typedef u64 hic_cap_t;       /* 能力句柄 */
typedef u64 hic_thread_t;    /* 线程句柄 */
typedef u64 hic_shmem_t;     /* 共享内存句柄 */

ABI保证: - 大小永远64位 - 无效值固定为 ~0ULL (0xFFFFFFFFFFFFFFFF) - 值0永远保留用于特殊用途

2.3 枚举类型

枚举类型使用32位有符号整数:

typedef s32 hic_error_t;

enum {
    HIC_OK = 0,
    HIC_ERR_INVALID_PARAM = 1,
    /* ... */
};

ABI保证: - 枚举值永不改变 - 新枚举值可以添加,但不能删除或重命名 - 枚举类型大小固定为32位

2.4 结构体类型

所有公开结构体必须满足:

  1. 固定大小: 结构体大小在ABI版本内不变
  2. 固定对齐: 使用默认对齐,不使用packed
  3. 填充规则: 遵循平台默认填充规则
  4. 尾随填充: 确保结构体大小是最大对齐的倍数

示例:

typedef struct {
    char name[64];        /* 64字节,偏移0 */
    u32 api_version_major; /* 4字节,偏移64 */
    u32 api_version_minor; /* 4字节,偏移68 */
    u32 api_version_patch; /* 4字节,偏移72 */
    u32 syscall_num;       /* 4字节,偏移76 */
    /* 填充到8字节对齐 */
    u32 padding1;          /* 4字节,偏移80 */
    u64 call_count;        /* 8字节,偏移88 */
    u64 total_time_ns;     /* 8字节,偏移96 */
    /* 总大小: 104字节 */
} hic_endpoint_info_t;

ABI保证: - 现有字段永不移动或删除 - 新字段只能添加到结构体末尾 - 字段大小永不改变 - 字段对齐永不改变


三、函数调用约定

3.1 x86-64 (System V AMD64 ABI)

参数位置 寄存器
参数1 RDI -
参数2 RSI -
参数3 RDX -
参数4 RCX -
参数5 R8 -
参数6 R9 -
参数7+ - 从右到左压栈

返回值: - 整数/指针: RAX - 大结构体: 通过隐藏指针(RDI作为第一个参数)

被调用者保存: - RBX, RBP, R12-R15 - 栈指针(RSP) - 对齐栈(16字节对齐)

调用者保存: - RAX, RCX, RDX, RSI, RDI, R8-R11 - XMM0-XMM15

3.2 ARM64 (AAPCS64)

参数位置 寄存器
参数1 X0 -
参数2 X1 -
参数3 X2 -
参数4 X3 -
参数5 X4 -
参数6 X5 -
参数7 X6 -
参数8 X7 -
参数9+ - 从右到左压栈

返回值: - 整数/指针: X0 - 大结构体: 通过隐藏指针(X8作为第一个参数)

被调用者保存: - X19-X29 - SP(栈指针) - 16字节栈对齐

调用者保存: - X0-X18 - V0-V31(浮点/向量)

3.3 RISC-V (RV64I)

参数位置 寄存器
参数1 a0 (x10) -
参数2 a1 (x11) -
参数3 a2 (x12) -
参数4 a3 (x13) -
参数5 a4 (x14) -
参数6 a5 (x15) -
参数7 a6 (x16) -
参数8 a7 (x17) -
参数9+ - 从右到左压栈

返回值: - 整数/指针: a0 (x10) - 大结构体: 通过隐藏指针(a0作为第一个参数)

被调用者保存: - s0-s11 (x8-x9, x18-x27) - sp (x2) - 16字节栈对齐

调用者保存: - t0-t6 (x5-x7, x28-x31) - a0-a7 (x10-x17)


四、系统调用接口

4.1 系统调用约定

HIC使用统一的系统调用接口,通过 syscall 指令(x86-64)或 svc 指令(ARM64)进入内核。

x86-64系统调用寄存器约定:

RAX: 系统调用号
RDI: 参数1
RSI: 参数2
RDX: 参数3
RCX: 用户空间返回地址(由syscall自动保存)
R11: RFLAGS(由syscall自动保存)

返回值: - 成功: 0(在RAX中) - 失败: 错误码(在RAX中)

4.2 系统调用号映射

系统调用号 函数 参数 返回值
0 SYSCALL_IPC_CALL endpoint_cap, message hic_error_t
1 SYSCALL_CAP_TRANSFER to_domain, cap hic_error_t
2 SYSCALL_CAP_DERIVE parent, sub_rights, out_cap hic_error_t
3 SYSCALL_CAP_REVOKE cap hic_error_t
4 SYSCALL_DOMAIN_CREATE config, out_domain hic_error_t
5 SYSCALL_DOMAIN_DESTROY domain hic_error_t
6 SYSCALL_THREAD_CREATE domain, config, out_thread hic_error_t
7 SYSCALL_THREAD_YIELD - hic_error_t
8 SYSCALL_SHMEM_ALLOC size, flags, out_shmem hic_error_t
9 SYSCALL_SHMEM_MAP shmem, offset, size, out_addr hic_error_t

ABI保证: - 系统调用号永不改变 - 参数类型和顺序永不改变 - 返回值类型永不改变


五、内存布局规范

5.1 共享内存布局

共享内存必须满足:

  1. 对齐: 起始地址至少8字节对齐
  2. 大小: 必须是页面大小的倍数(4KB)
  3. 访问权限: 通过能力系统控制

5.2 域内存布局

每个域的内存布局:

+------------------+ 0x00000000
| 代码段          | 只读,可执行
+------------------+
| 只读数据        | 只读
+------------------+
| 数据段          | 读写
+------------------+
| BSS段           | 读写,零初始化
+------------------+
| 栈              | 读写,向下增长
+------------------+
| 堆              | 读写,向上增长
+------------------+
| 共享内存映射    | 读写,能力控制
+------------------+
| MMIO映射        | 读写,能力控制
+------------------+
| 保留            |
+------------------+

ABI保证: - 内存布局顺序永不改变 - 每个段的起始对齐至少8字节 - 栈向下增长,堆向上增长


六、兼容性检查清单

6.1 类型兼容性

  • [ ] 所有公开类型的大小固定
  • [ ] 所有枚举值固定
  • [ ] 所有结构体字段固定
  • [ ] 所有对齐要求固定

6.2 函数兼容性

  • [ ] 函数签名不变
  • [ ] 参数类型不变
  • [ ] 返回值类型不变
  • [ ] 调用约定不变

6.3 系统调用兼容性

  • [ ] 系统调用号不变
  • [ ] 参数顺序不变
  • [ ] 返回值约定不变

6.4 内存兼容性

  • [ ] 共享内存布局不变
  • [ ] 域内存布局不变
  • [ ] 对齐要求不变

七、版本演进规则

7.1 官方接口的特殊原则

HIC官方接口遵循以下严格原则

7.1.1 官方接口的向后兼容保证

绝对禁止的操作(官方接口): - ❌ 永不删除任何公开API、函数、结构体字段或枚举值 - ❌ 永不修改任何公开API的签名、参数类型或返回值类型 - ❌ 永不改变任何公开结构体的字段布局或大小 - ❌ 永不废弃任何现有功能

允许的操作(官方接口): - ✅ 只添加新的公开API - ✅ 只添加新的枚举值 - ✅ 只在结构体末尾添加新字段 - ✅ 只添加新的系统调用

7.1.2 官方接口的版本承诺

主版本(Major): - 主版本号增加仅当必须进行破坏性变更 - 破坏性变更包括:删除API、修改签名、改变结构体布局 - 主版本更新极少发生,必须有重大技术理由 - 必须提供完整的迁移路径和文档 - 维护旧版本至少1个发布周期

次版本(Minor): - 次版本号增加用于添加新功能 - 必须保持所有现有API完全兼容 - 不能修改任何现有API - 新增API不能影响现有功能

补丁版本(Patch): - 补丁版本号增加用于bug修复和优化 - 必须保持完全的二进制兼容性 - 不能改变任何公开接口 - 可以包含性能优化和安全修复

7.1.3 官方接口的扩展规则

系统调用扩展: - 系统调用号只能单调递增 - 已分配的系统调用号永不重用 - 系统调用签名永不改变

服务端点扩展: - 端点ID只能单调递增 - 已分配的端点ID永不重用 - 端点功能永不改变

类型扩展: - 可以在结构体末尾添加新字段 - 不能修改或删除现有字段 - 不能改变字段类型或大小

7.2 第三方接口的版本演进

第三方接口的版本管理由各自开发者决定,但必须遵循以下基本规则:

7.2.1 基本要求

  • 必须提供版本号(major.minor.patch)
  • 必须提供API文档
  • 必须明确兼容性声明

7.2.2 版本变更通知

  • 主版本变更必须通知所有用户
  • 必须提供迁移指南
  • 建议维护旧版本一段时间

7.3 主版本更新(破坏性变更)

主版本号增加(例如:1.0 → 2.0)仅当:

  1. 删除公开API
  2. 改变公开API签名
  3. 改变公开结构体布局
  4. 改变系统调用约定

必须: - 更新所有客户端 - 提供迁移指南 - 维护旧版本至少1个发布周期

注意: 官方接口极少进行主版本更新。

7.4 次版本更新(向后兼容)

次版本号增加(例如:1.0 → 1.1)可以:

  1. 添加新的公开API
  2. 添加新的枚举值
  3. 在结构体末尾添加新字段
  4. 添加新的系统调用

必须: - 保持所有现有API不变 - 保持二进制兼容性 - 提供新功能的文档 - 保持二进制兼容性 - 提供新功能的文档

7.3 补丁版本更新(修复)

补丁版本号增加(例如:1.0.0 → 1.0.1)可以:

  1. 修复bug
  2. 性能优化
  3. 文档更新

必须: - 不改变任何公开API - 不改变任何公开结构体 - 保持完全的二进制兼容性


八、实现要求

8.1 编译器兼容性

HIC ABI必须与以下编译器兼容:

  • GCC: 7.0+
  • Clang: 5.0+
  • MSVC: 2017+(仅x86-64)

8.2 链接器兼容性

HIC ABI必须与以下链接器兼容:

  • GNU ld: 2.26+
  • LLVM lld: 6.0+
  • gold: 1.12+

8.3 测试要求

所有ABI变更必须通过以下测试:

  1. 类型大小测试: 验证所有类型的大小
  2. 对齐测试: 验证所有类型的对齐
  3. 调用约定测试: 验证函数调用
  4. 系统调用测试: 验证系统调用接口
  5. 跨版本测试: 验证不同版本的兼容性

九、参考文档


附录

A. 类型大小表

类型 大小 对齐 平台
u8 1字节 1字节 通用
u16 2字节 2字节 通用
u32 4字节 4字节 通用
u64 8字节 8字节 通用
hic_domain_t 8字节 8字节 通用
hic_cap_t 8字节 8字节 通用
hic_thread_t 8字节 8字节 通用
hic_shmem_t 8字节 8字节 通用
hic_error_t 4字节 4字节 通用

B. 系统调用开销表

操作 理论开销 实际开销 方法
系统调用 20-30ns ~25ns syscall/sysret
IPC调用 20-30ns ~25ns 同级函数调用
能力检查 ~50ns ~50ns 只读查表

C. 对齐要求表

类型 x86-64 ARM64 RISC-V
u8 1字节 1字节 1字节
u16 2字节 2字节 2字节
u32 4字节 4字节 4字节
u64 8字节 8字节 8字节
指针 8字节 8字节 8字节
结构体 最大对齐 最大对齐 最大对齐