The short version
I'm working on a BPF program that is loaded via tc which requires the ELF to be in a particular format. Rust (or LLVM?) utilize relocations for local literal variables, as well as some common local variables which trips up the tc loader because it doesn't know how to handle these relocations.
How is Rust making these determinations / is there a way to control this behavior?
The Longer Version
Specifically, the tc BPF loader it requires the ELF binary use the following format:
- all BPF map declarations be in an ELF section called
maps - any
tcactions/classifiers be in their own ELF sections (names can be arbitrary, as you telltcwhich sections to use at runtime) - Relocations can only point to sections
.text,maps, or the sections containing your classifier/actions (<-- This is the problem)
Placing maps in a maps sections easy, and works flawlessly with Rust's #[link_section = "maps"]. So that isn't the issue.
For a simplified example, assume there is a well defined map like a HashMap<K,V> (meaning assume things like HashMap::init already work as intended) which is declared in a manner like:
#[link_section = "maps"]
static mut my_map: HashMap<i32, u64> = HashMap::init();
The problem is within user code, such as a function my_action() if I do something like my_map.set(&1, &count) (assuming count is defined as some u64 I'm trying to update). Rust will place the &1 in its own section of something like .Lalloc52 with a value of 0x1, and a relocation pointing to .Lalloc52. Because the relocation points to .Lalloc52 and not one of the valid relocation sections listed above, tc loading fails.
However, I change out &1 to some valid memory location (assuming type i32 is correct), such as my_map.set(&some_i32, &count), the relocation is gone and everything works.
If I try to make my own local variable binding, something like:
let one = 1;
my_map.set(&one, &count);
The relocation is now to .rodata instead of .Lalloc52, but still causing tc to fail loading.
I know this probably difficult to follow and a niche problem, but any help is much appreciated!