ABI stability in Kernel
Motivation
In the FreeBSD, while Application Binary Interface (ABI) stability is not guaranteed across major versions, there is no explicit specification regarding ABI stability within minor versions. This lack of clarity can lead to challenges for third-party kernel developers, such as those working on projects like VirtualBox and Direct Rendering Manager (DRM). It makes distributing package for different minor version may have some problem in current pkg system. Frequent changes in the Kernel Binary Interface (KBI) within minor versions can disrupt development and compatibility, creating significant obstacles for maintaining third-party kernel modules.
The primary goal of this project is to ensure KBI stability across FreeBSD minor versions. This will be achieved by introducing a mechanism to verify and maintain consistency in the ABI between releases. As a foundational step, we propose the development of a tool capable of detecting differences in the ABI of two binaries.
Tool: CTFDiff
Differential: D48199
A tool that input two binary and compare their .SUNW_ctf section to check if their ABI is different.
Usage
In Base
Since all components in based is compiled with CTF, we can use the following command to check if two binary have different ABI
ctfdiff /boot/kernel/kernel /boot/kernel.old/kernel
Other
To use ctfdiff outside the base, we have to generate the .SUNW_ctf section manually:
First, compile your code with -g -c to generate dwarf information:
Notice that ctfconvert only support in single compile unit (e.g. relocatable file). So -c is needed
Here are two example code you can try:
# a.c int var_a_have; int var_both_same; int var_both_diff; int func_a_have() { return (0); } int func_both_diff() { return (0); } int func_both_same(int a, int b) { return (0); } int func_const_diff(int a) { return (0); }
# b.c int var_b_have; int var_both_same; double var_both_diff; int func_b_have() { return (0); } int func_both_diff(int val) { return (0); } int func_both_same(int a, int b) { return (0); } int func_const_diff(const int a) { return (0); }
clang -g -c a.c -o a.o clang -g -c b.c -o b.o
Second, conver the dwarf to ctf with ctfconvert.
You have to provide a label name for the abi.
ctfconvert -l abi -o a a.o ctfconvert -l abi -o b b.o
Last, Use ctfdiff to compare two files
ctfdiff a b
An example output is as following:
< means this symbol is from file at left hand side, > means this symbol is from file at right hand side.
< [0] func_a_have > [0] func_b_have < [1] func_both_diff > [1] func_both_diff < [3] func_const_diff > [3] func_const_diff < [0] var_a_have > [0] var_b_have < [2] var_both_diff > [2] var_both_diff
Reasons:
< [0] func_a_have # Only lhs has this symbol > [0] func_b_have # Only rhs has this symbol < [1] func_both_diff # Both have this symbol but symbol signature is different > [1] func_both_diff # same as previous < [3] func_const_diff # Both have this symbol but symbol signature is different > [3] func_const_diff # Same as previous < [0] var_a_have # Only lhs has this symbol > [0] var_b_have # Only rhs has this symbol < [2] var_both_diff # Both have this symbol but symbol signature is different > [2] var_both_diff # Same as previous
Script
This script enable us to fetch the tarball from web and use ctfdiff to get ABI difference between the local compiled one and extracted tarball: