|
|
@ -475,7 +475,7 @@ impl Btf {
|
|
|
|
) -> Result<(), BtfError> {
|
|
|
|
) -> Result<(), BtfError> {
|
|
|
|
let mut types = mem::take(&mut self.types);
|
|
|
|
let mut types = mem::take(&mut self.types);
|
|
|
|
for i in 0..types.types.len() {
|
|
|
|
for i in 0..types.types.len() {
|
|
|
|
let t = &types.types[i];
|
|
|
|
let t = &mut types.types[i];
|
|
|
|
let kind = t.kind();
|
|
|
|
let kind = t.kind();
|
|
|
|
match t {
|
|
|
|
match t {
|
|
|
|
// Fixup PTR for Rust
|
|
|
|
// Fixup PTR for Rust
|
|
|
@ -483,9 +483,7 @@ impl Btf {
|
|
|
|
// While I figure out if this needs fixing in the Kernel or LLVM, we'll
|
|
|
|
// While I figure out if this needs fixing in the Kernel or LLVM, we'll
|
|
|
|
// do a fixup here
|
|
|
|
// do a fixup here
|
|
|
|
BtfType::Ptr(ptr) => {
|
|
|
|
BtfType::Ptr(ptr) => {
|
|
|
|
let mut fixed_ty = ptr.clone();
|
|
|
|
ptr.name_offset = 0;
|
|
|
|
fixed_ty.name_offset = 0;
|
|
|
|
|
|
|
|
types.types[i] = BtfType::Ptr(fixed_ty)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Sanitize VAR if they are not supported
|
|
|
|
// Sanitize VAR if they are not supported
|
|
|
|
BtfType::Var(v) if !features.btf_datasec => {
|
|
|
|
BtfType::Var(v) if !features.btf_datasec => {
|
|
|
@ -496,7 +494,7 @@ impl Btf {
|
|
|
|
debug!("{}: not supported. replacing with STRUCT", kind);
|
|
|
|
debug!("{}: not supported. replacing with STRUCT", kind);
|
|
|
|
|
|
|
|
|
|
|
|
// STRUCT aren't allowed to have "." in their name, fixup this if needed.
|
|
|
|
// STRUCT aren't allowed to have "." in their name, fixup this if needed.
|
|
|
|
let mut name_offset = t.name_offset();
|
|
|
|
let mut name_offset = d.name_offset;
|
|
|
|
let name = self.string_at(name_offset)?;
|
|
|
|
let name = self.string_at(name_offset)?;
|
|
|
|
|
|
|
|
|
|
|
|
// Handle any "." characters in struct names
|
|
|
|
// Handle any "." characters in struct names
|
|
|
@ -506,18 +504,22 @@ impl Btf {
|
|
|
|
name_offset = self.add_string(&fixed_name);
|
|
|
|
name_offset = self.add_string(&fixed_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let mut members = vec![];
|
|
|
|
let entries = std::mem::take(&mut d.entries);
|
|
|
|
for member in d.entries.iter() {
|
|
|
|
|
|
|
|
let mt = types.type_by_id(member.btf_type).unwrap();
|
|
|
|
let members = entries
|
|
|
|
members.push(BtfMember {
|
|
|
|
.iter()
|
|
|
|
name_offset: mt.name_offset(),
|
|
|
|
.map(|e| {
|
|
|
|
btf_type: member.btf_type,
|
|
|
|
let mt = types.type_by_id(e.btf_type).unwrap();
|
|
|
|
offset: member.offset * 8,
|
|
|
|
BtfMember {
|
|
|
|
|
|
|
|
name_offset: mt.name_offset(),
|
|
|
|
|
|
|
|
btf_type: e.btf_type,
|
|
|
|
|
|
|
|
offset: e.offset * 8,
|
|
|
|
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
|
|
|
|
types.types[i] =
|
|
|
|
types.types[i] =
|
|
|
|
BtfType::Struct(Struct::new(name_offset, members, d.entries.len() as u32));
|
|
|
|
BtfType::Struct(Struct::new(name_offset, members, entries.len() as u32));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Fixup DATASEC
|
|
|
|
// Fixup DATASEC
|
|
|
|
// DATASEC sizes aren't always set by LLVM
|
|
|
|
// DATASEC sizes aren't always set by LLVM
|
|
|
@ -527,18 +529,16 @@ impl Btf {
|
|
|
|
let name = self.string_at(d.name_offset)?;
|
|
|
|
let name = self.string_at(d.name_offset)?;
|
|
|
|
let name = name.into_owned();
|
|
|
|
let name = name.into_owned();
|
|
|
|
|
|
|
|
|
|
|
|
let mut fixed_ty = d.clone();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Handle any "/" characters in section names
|
|
|
|
// Handle any "/" characters in section names
|
|
|
|
// Example: "maps/hashmap"
|
|
|
|
// Example: "maps/hashmap"
|
|
|
|
let fixed_name = name.replace('/', ".");
|
|
|
|
let fixed_name = name.replace('/', ".");
|
|
|
|
if fixed_name != name {
|
|
|
|
if fixed_name != name {
|
|
|
|
fixed_ty.name_offset = self.add_string(&fixed_name);
|
|
|
|
d.name_offset = self.add_string(&fixed_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// There are some cases when the compiler does indeed populate the
|
|
|
|
// There are some cases when the compiler does indeed populate the
|
|
|
|
// size
|
|
|
|
// size
|
|
|
|
if t.size().unwrap() > 0 {
|
|
|
|
if d.size > 0 {
|
|
|
|
debug!("{} {}: size fixup not required", kind, name);
|
|
|
|
debug!("{} {}: size fixup not required", kind, name);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
// We need to get the size of the section from the ELF file
|
|
|
|
// We need to get the size of the section from the ELF file
|
|
|
@ -551,22 +551,23 @@ impl Btf {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
debug!("{} {}: fixup size to {}", kind, name, size);
|
|
|
|
debug!("{} {}: fixup size to {}", kind, name, size);
|
|
|
|
fixed_ty.size = *size as u32;
|
|
|
|
d.size = *size as u32;
|
|
|
|
|
|
|
|
|
|
|
|
// The Vec<btf_var_secinfo> contains BTF_KIND_VAR sections
|
|
|
|
// The Vec<btf_var_secinfo> contains BTF_KIND_VAR sections
|
|
|
|
// that need to have their offsets adjusted. To do this,
|
|
|
|
// that need to have their offsets adjusted. To do this,
|
|
|
|
// we need to get the offset from the ELF file.
|
|
|
|
// we need to get the offset from the ELF file.
|
|
|
|
// This was also cached during initial parsing and
|
|
|
|
// This was also cached during initial parsing and
|
|
|
|
// we can query by name in symbol_offsets
|
|
|
|
// we can query by name in symbol_offsets
|
|
|
|
for d in &mut fixed_ty.entries.iter_mut() {
|
|
|
|
let mut entries = mem::take(&mut d.entries);
|
|
|
|
let var_type = types.type_by_id(d.btf_type)?;
|
|
|
|
let mut fixed_section = d.clone();
|
|
|
|
let var_kind = var_type.kind();
|
|
|
|
|
|
|
|
if let BtfType::Var(var) = var_type {
|
|
|
|
for e in entries.iter_mut() {
|
|
|
|
|
|
|
|
if let BtfType::Var(var) = types.type_by_id(e.btf_type)? {
|
|
|
|
let var_name = self.string_at(var.name_offset)?;
|
|
|
|
let var_name = self.string_at(var.name_offset)?;
|
|
|
|
if var.linkage == VarLinkage::Static {
|
|
|
|
if var.linkage == VarLinkage::Static {
|
|
|
|
debug!(
|
|
|
|
debug!(
|
|
|
|
"{} {}: {} {}: fixup not required",
|
|
|
|
"{} {}: VAR {}: fixup not required",
|
|
|
|
kind, name, var_kind, var_name
|
|
|
|
kind, name, var_name
|
|
|
|
);
|
|
|
|
);
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -579,27 +580,26 @@ impl Btf {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
d.offset = *offset as u32;
|
|
|
|
e.offset = *offset as u32;
|
|
|
|
debug!(
|
|
|
|
debug!(
|
|
|
|
"{} {}: {} {}: fixup offset {}",
|
|
|
|
"{} {}: VAR {}: fixup offset {}",
|
|
|
|
kind, name, var_kind, var_name, offset
|
|
|
|
kind, name, var_name, offset
|
|
|
|
);
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
return Err(BtfError::InvalidDatasec);
|
|
|
|
return Err(BtfError::InvalidDatasec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fixed_section.entries = entries;
|
|
|
|
|
|
|
|
types.types[i] = BtfType::DataSec(fixed_section);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
types.types[i] = BtfType::DataSec(fixed_ty);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Fixup FUNC_PROTO
|
|
|
|
// Fixup FUNC_PROTO
|
|
|
|
BtfType::FuncProto(ty) if features.btf_func => {
|
|
|
|
BtfType::FuncProto(ty) if features.btf_func => {
|
|
|
|
let mut ty = ty.clone();
|
|
|
|
|
|
|
|
for (i, param) in ty.params.iter_mut().enumerate() {
|
|
|
|
for (i, param) in ty.params.iter_mut().enumerate() {
|
|
|
|
if param.name_offset == 0 && param.btf_type != 0 {
|
|
|
|
if param.name_offset == 0 && param.btf_type != 0 {
|
|
|
|
param.name_offset = self.add_string(&format!("param{i}"));
|
|
|
|
param.name_offset = self.add_string(&format!("param{i}"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
types.types[i] = BtfType::FuncProto(ty);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Sanitize FUNC_PROTO
|
|
|
|
// Sanitize FUNC_PROTO
|
|
|
|
BtfType::FuncProto(ty) if !features.btf_func => {
|
|
|
|
BtfType::FuncProto(ty) if !features.btf_func => {
|
|
|
@ -635,7 +635,6 @@ impl Btf {
|
|
|
|
// and verified separately from their callers, while instead we
|
|
|
|
// and verified separately from their callers, while instead we
|
|
|
|
// want tracking info (eg bound checks) to be propagated to the
|
|
|
|
// want tracking info (eg bound checks) to be propagated to the
|
|
|
|
// memory builtins.
|
|
|
|
// memory builtins.
|
|
|
|
let mut fixed_ty = ty.clone();
|
|
|
|
|
|
|
|
if ty.linkage() == FuncLinkage::Global {
|
|
|
|
if ty.linkage() == FuncLinkage::Global {
|
|
|
|
if !features.btf_func_global {
|
|
|
|
if !features.btf_func_global {
|
|
|
|
debug!(
|
|
|
|
debug!(
|
|
|
@ -645,9 +644,8 @@ impl Btf {
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
debug!("changing FUNC {name} linkage to BTF_FUNC_STATIC");
|
|
|
|
debug!("changing FUNC {name} linkage to BTF_FUNC_STATIC");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fixed_ty.set_linkage(FuncLinkage::Static);
|
|
|
|
ty.set_linkage(FuncLinkage::Static);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
types.types[i] = BtfType::Func(fixed_ty);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Sanitize FLOAT
|
|
|
|
// Sanitize FLOAT
|
|
|
@ -1244,9 +1242,9 @@ mod tests {
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
)));
|
|
|
|
)));
|
|
|
|
|
|
|
|
|
|
|
|
let name_offset = btf.add_string("foo");
|
|
|
|
let var_name_offset = btf.add_string("foo");
|
|
|
|
let var_type_id = btf.add_type(BtfType::Var(Var::new(
|
|
|
|
let var_type_id = btf.add_type(BtfType::Var(Var::new(
|
|
|
|
name_offset,
|
|
|
|
var_name_offset,
|
|
|
|
int_type_id,
|
|
|
|
int_type_id,
|
|
|
|
VarLinkage::Static,
|
|
|
|
VarLinkage::Static,
|
|
|
|
)));
|
|
|
|
)));
|
|
|
@ -1271,11 +1269,14 @@ mod tests {
|
|
|
|
assert_eq!(fixed.name_offset , name_offset);
|
|
|
|
assert_eq!(fixed.name_offset , name_offset);
|
|
|
|
assert_matches!(*fixed.members, [
|
|
|
|
assert_matches!(*fixed.members, [
|
|
|
|
BtfMember {
|
|
|
|
BtfMember {
|
|
|
|
name_offset: _,
|
|
|
|
name_offset: name_offset1,
|
|
|
|
btf_type,
|
|
|
|
btf_type,
|
|
|
|
offset: 0,
|
|
|
|
offset: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
] => assert_eq!(btf_type, var_type_id));
|
|
|
|
] => {
|
|
|
|
|
|
|
|
assert_eq!(name_offset1, var_name_offset);
|
|
|
|
|
|
|
|
assert_eq!(btf_type, var_type_id);
|
|
|
|
|
|
|
|
})
|
|
|
|
});
|
|
|
|
});
|
|
|
|
// Ensure we can convert to bytes and back again
|
|
|
|
// Ensure we can convert to bytes and back again
|
|
|
|
let raw = btf.to_bytes();
|
|
|
|
let raw = btf.to_bytes();
|
|
|
|