btf: fix match arms

Don't match on kind and use if let...
Match on the BtfType

Fixes: #178

Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
pull/175/head
Dave Tucker 3 years ago
parent 326825aab0
commit 99fa85eab8

@ -416,173 +416,159 @@ 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 kind = types.types.get(i).unwrap().kind()?.unwrap_or_default(); let t = &types.types[i];
match kind { let kind = t.kind()?.unwrap_or_default();
match t {
// Fixup PTR for Rust // Fixup PTR for Rust
// LLVM emits names for Rust pointer types, which the kernel doesn't like // LLVM emits names for Rust pointer types, which the kernel doesn't like
// 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
BtfKind::Ptr => { BtfType::Ptr(ty) => {
if let Some(BtfType::Ptr(ty)) = types.types.get_mut(i) { let mut fixed_ty = *ty;
ty.name_off = 0; fixed_ty.name_off = 0;
} types.types[i] = BtfType::Ptr(fixed_ty)
} }
// Sanitize VAR if they are not supported // Sanitize VAR if they are not supported
BtfKind::Var if !features.btf_datasec => { BtfType::Var(ty, _) if !features.btf_datasec => {
if let Some(BtfType::Var(ty, _)) = types.types.get(i) { types.types[i] = BtfType::new_int(ty.name_off, 1, 0, 0);
types.types[i] = BtfType::new_int(ty.name_off, 1, 0, 0);
}
} }
// Sanitize DATASEC if they are not supported // Sanitize DATASEC if they are not supported
BtfKind::DataSec if !features.btf_datasec => { BtfType::DataSec(ty, data) if !features.btf_datasec => {
if let Some(BtfType::DataSec(ty, data)) = types.types.get(i) { debug!("{}: not supported. replacing with STRUCT", kind);
debug!("{}: not supported. replacing with STRUCT", kind); let mut members = vec![];
let mut members = vec![]; for member in data {
for member in data { let mt = types.type_by_id(member.type_).unwrap();
let mt = types.type_by_id(member.type_).unwrap(); members.push(btf_member {
members.push(btf_member { name_off: mt.btf_type().unwrap().name_off,
name_off: mt.btf_type().unwrap().name_off, type_: member.type_,
type_: member.type_, offset: member.offset * 8,
offset: member.offset * 8, })
})
}
types.types[i] = BtfType::new_struct(ty.name_off, members, 0);
} }
types.types[i] = BtfType::new_struct(ty.name_off, members, 0);
} }
// Fixup DATASEC // Fixup DATASEC
// DATASEC sizes aren't always set by LLVM // DATASEC sizes aren't always set by LLVM
// we need to fix them here before loading the btf to the kernel // we need to fix them here before loading the btf to the kernel
BtfKind::DataSec if features.btf_datasec => { BtfType::DataSec(ty, data) if features.btf_datasec => {
if let Some(BtfType::DataSec(ty, data)) = types.types.get(i) { // Start DataSec Fixups
// Start DataSec Fixups let sec_name = self.string_at(ty.name_off)?;
let sec_name = self.string_at(ty.name_off)?; let name = sec_name.to_string();
let name = sec_name.to_string(); // 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 unsafe { ty.__bindgen_anon_1.size > 0 } {
if unsafe { ty.__bindgen_anon_1.size > 0 } { debug!("{} {}: fixup not required", kind, name);
debug!("{} {}: fixup not required", kind, name); continue;
continue; }
}
let mut fixed_ty = *ty; let mut fixed_ty = *ty;
let mut fixed_data = data.clone(); let mut fixed_data = data.clone();
// 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
// Fortunately, we cached these when parsing it initially // Fortunately, we cached these when parsing it initially
// and we can this up by name in section_sizes // and we can this up by name in section_sizes
let size = section_sizes.get(&name).ok_or_else(|| { let size =
BtfError::UnknownSectionSize { section_sizes
.get(&name)
.ok_or_else(|| BtfError::UnknownSectionSize {
section_name: name.clone(), section_name: name.clone(),
} })?;
})?; debug!("{} {}: fixup size to {}", kind, name, size);
debug!("{} {}: fixup size to {}", kind, name, size); fixed_ty.__bindgen_anon_1.size = *size as u32;
fixed_ty.__bindgen_anon_1.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_data {
for d in &mut fixed_data { let var_type = types.type_by_id(d.type_)?;
let var_type = types.type_by_id(d.type_)?; let var_kind = var_type.kind()?.unwrap();
let var_kind = var_type.kind()?.unwrap(); if let BtfType::Var(vty, var) = var_type {
if let BtfType::Var(vty, var) = var_type { let var_name = self.string_at(vty.name_off)?.to_string();
let var_name = self.string_at(vty.name_off)?.to_string(); if var.linkage == btf_func_linkage::BTF_FUNC_STATIC as u32 {
if var.linkage == btf_func_linkage::BTF_FUNC_STATIC as u32 {
debug!(
"{} {}: {} {}: fixup not required",
kind, name, var_kind, var_name
);
continue;
}
let offset = symbol_offsets.get(&var_name).ok_or(
BtfError::SymbolOffsetNotFound {
symbol_name: var_name.clone(),
},
)?;
d.offset = *offset as u32;
debug!( debug!(
"{} {}: {} {}: fixup offset {}", "{} {}: {} {}: fixup not required",
kind, name, var_kind, var_name, offset kind, name, var_kind, var_name
); );
} else { continue;
return Err(BtfError::InvalidDatasec);
} }
let offset = symbol_offsets.get(&var_name).ok_or(
BtfError::SymbolOffsetNotFound {
symbol_name: var_name.clone(),
},
)?;
d.offset = *offset as u32;
debug!(
"{} {}: {} {}: fixup offset {}",
kind, name, var_kind, var_name, offset
);
} else {
return Err(BtfError::InvalidDatasec);
} }
types.types[i] = BtfType::DataSec(fixed_ty, fixed_data);
} }
types.types[i] = BtfType::DataSec(fixed_ty, fixed_data);
} }
// Fixup FUNC_PROTO // Fixup FUNC_PROTO
BtfKind::FuncProto if features.btf_func => { BtfType::FuncProto(ty, params) if features.btf_func => {
if let Some(BtfType::FuncProto(_, params)) = types.types.get_mut(i) { let mut params = params.clone();
for (i, mut param) in params.iter_mut().enumerate() { for (i, mut param) in params.iter_mut().enumerate() {
if param.name_off == 0 && param.type_ != 0 { if param.name_off == 0 && param.type_ != 0 {
param.name_off = self.add_string(format!("param{}", i)); param.name_off = self.add_string(format!("param{}", i));
}
} }
} }
types.types[i] = BtfType::FuncProto(*ty, params);
} }
// Sanitize FUNC_PROTO // Sanitize FUNC_PROTO
BtfKind::FuncProto if !features.btf_func => { BtfType::FuncProto(ty, vars) if !features.btf_func => {
if let Some(BtfType::FuncProto(ty, vars)) = types.types.get(i) { debug!("{}: not supported. replacing with ENUM", kind);
debug!("{}: not supported. replacing with ENUM", kind); let members: Vec<btf_enum> = vars
let members: Vec<btf_enum> = vars .iter()
.iter() .map(|p| btf_enum {
.map(|p| btf_enum { name_off: p.name_off,
name_off: p.name_off, val: p.type_ as i32,
val: p.type_ as i32, })
}) .collect();
.collect(); let enum_type = BtfType::new_enum(ty.name_off, members);
let enum_type = BtfType::new_enum(ty.name_off, members); types.types[i] = enum_type;
types.types[i] = enum_type;
}
} }
// Sanitize FUNC // Sanitize FUNC
BtfKind::Func if !features.btf_func => { BtfType::Func(ty) if !features.btf_func => {
if let Some(BtfType::Func(ty)) = types.types.get(i) { debug!("{}: not supported. replacing with TYPEDEF", kind);
debug!("{}: not supported. replacing with TYPEDEF", kind); let typedef_type =
let typedef_type = BtfType::new_typedef(ty.name_off, unsafe { ty.__bindgen_anon_1.type_ });
BtfType::new_typedef(ty.name_off, unsafe { ty.__bindgen_anon_1.type_ }); types.types[i] = typedef_type;
types.types[i] = typedef_type;
}
} }
// Sanitize BTF_FUNC_GLOBAL // Sanitize BTF_FUNC_GLOBAL
BtfKind::Func if !features.btf_func_global => { BtfType::Func(ty) if !features.btf_func_global => {
if let Some(BtfType::Func(ty)) = types.types.get_mut(i) { let mut fixed_ty = *ty;
if type_vlen(ty) == btf_func_linkage::BTF_FUNC_GLOBAL as usize { if type_vlen(ty) == btf_func_linkage::BTF_FUNC_GLOBAL as usize {
debug!( debug!(
"{}: BTF_FUNC_GLOBAL not supported. replacing with BTF_FUNC_STATIC", "{}: BTF_FUNC_GLOBAL not supported. replacing with BTF_FUNC_STATIC",
kind kind
); );
ty.info = (ty.info & 0xFFFF0000) fixed_ty.info = (ty.info & 0xFFFF0000)
| (btf_func_linkage::BTF_FUNC_STATIC as u32) & 0xFFFF; | (btf_func_linkage::BTF_FUNC_STATIC as u32) & 0xFFFF;
}
} }
types.types[i] = BtfType::Func(fixed_ty);
} }
// Sanitize FLOAT // Sanitize FLOAT
BtfKind::Float if !features.btf_float => { BtfType::Float(ty) if !features.btf_float => {
if let Some(BtfType::Float(ty)) = types.types.get(i) { debug!("{}: not supported. replacing with STRUCT", kind);
debug!("{}: not supported. replacing with STRUCT", kind); let struct_ty =
let struct_ty = BtfType::new_struct(0, vec![], unsafe { ty.__bindgen_anon_1.size });
BtfType::new_struct(0, vec![], unsafe { ty.__bindgen_anon_1.size }); types.types[i] = struct_ty;
types.types[i] = struct_ty;
}
} }
// Sanitize DECL_TAG // Sanitize DECL_TAG
BtfKind::DeclTag if !features.btf_decl_tag => { BtfType::DeclTag(ty, _) if !features.btf_decl_tag => {
if let Some(BtfType::DeclTag(ty, _)) = types.types.get(i) { debug!("{}: not supported. replacing with INT", kind);
debug!("{}: not supported. replacing with INT", kind); let int_type = BtfType::new_int(ty.name_off, 1, 0, 0);
let int_type = BtfType::new_int(ty.name_off, 1, 0, 0); types.types[i] = int_type;
types.types[i] = int_type;
}
} }
// Sanitize TYPE_TAG // Sanitize TYPE_TAG
BtfKind::TypeTag if !features.btf_type_tag => { BtfType::TypeTag(ty) if !features.btf_type_tag => {
if let Some(BtfType::TypeTag(ty)) = types.types.get(i) { debug!("{}: not supported. replacing with CONST", kind);
debug!("{}: not supported. replacing with CONST", kind); let const_type = BtfType::new_const(unsafe { ty.__bindgen_anon_1.type_ });
let const_type = BtfType::new_const(unsafe { ty.__bindgen_anon_1.type_ }); types.types[i] = const_type;
types.types[i] = const_type;
}
} }
// The type does not need fixing up or sanitization // The type does not need fixing up or sanitization
_ => {} _ => {}

Loading…
Cancel
Save