btf: Replace / in DATASEC before load to kernel

This replaces the / character with a . which is allowed in the kernel
names. Not allowing a forward slash is perhaps a kernel bug, but lets
fix it up here as it's commonly used for Aya

Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
pull/179/head
Dave Tucker 3 years ago
parent 1904aeaef9
commit 825bb3ad20

@ -453,23 +453,29 @@ impl Btf {
// Start DataSec Fixups
let sec_name = self.string_at(ty.name_off)?;
let name = sec_name.to_string();
// There are some cases when the compiler does indeed populate the
// size
if unsafe { ty.__bindgen_anon_1.size > 0 } {
debug!("{} {}: fixup not required", kind, name);
continue;
}
let mut fixed_ty = *ty;
let mut fixed_data = data.clone();
// Handle any "/" characters in section names
// Example: "maps/hashmap"
let fixed_name = name.replace('/', ".");
if fixed_name != name {
fixed_ty.name_off = self.add_string(fixed_name);
}
// There are some cases when the compiler does indeed populate the
// size
if unsafe { ty.__bindgen_anon_1.size > 0 } {
debug!("{} {}: size fixup not required", kind, name);
} else {
// We need to get the size of the section from the ELF file
// Fortunately, we cached these when parsing it initially
// and we can this up by name in section_sizes
let size =
section_sizes
.get(&name)
.ok_or_else(|| BtfError::UnknownSectionSize {
let size = section_sizes.get(&name).ok_or_else(|| {
BtfError::UnknownSectionSize {
section_name: name.clone(),
}
})?;
debug!("{} {}: fixup size to {}", kind, name, size);
fixed_ty.__bindgen_anon_1.size = *size as u32;
@ -506,6 +512,7 @@ impl Btf {
return Err(BtfError::InvalidDatasec);
}
}
}
types.types[i] = BtfType::DataSec(fixed_ty, fixed_data);
}
// Fixup FUNC_PROTO
@ -1097,7 +1104,7 @@ mod tests {
BTF_VAR_GLOBAL_EXTERN,
));
let name_offset = btf.add_string(".data".to_string());
let name_offset = btf.add_string(".data/foo".to_string());
let variables = vec![btf_var_secinfo {
type_: var_type_id,
offset: 0,
@ -1111,14 +1118,14 @@ mod tests {
};
btf.fixup_and_sanitize(
&HashMap::from([(".data".to_string(), 32u64)]),
&HashMap::from([(".data/foo".to_string(), 32u64)]),
&HashMap::from([("foo".to_string(), 64u64)]),
&features,
)
.unwrap();
if let BtfType::DataSec(fixed, sec_info) = btf.type_by_id(datasec_type_id).unwrap() {
assert!(fixed.name_off == name_offset);
assert!(fixed.name_off != name_offset);
assert!(unsafe { fixed.__bindgen_anon_1.size } == 32);
assert!(sec_info.len() == 1);
assert!(sec_info[0].type_ == var_type_id);
@ -1126,7 +1133,8 @@ mod tests {
sec_info[0].offset == 64,
"expected 64, got {}",
sec_info[0].offset
)
);
assert!(btf.string_at(fixed.name_off).unwrap() == ".data.foo")
} else {
panic!("not a datasec")
}

Loading…
Cancel
Save