btf: implement candidate matching for enums

pull/1/head
Alessandro Decina 4 years ago
parent 08d5fa6059
commit b49a627cac

@ -272,13 +272,15 @@ impl Object {
} }
} }
fn flavorless_name(name: &str) -> &str {
name.splitn(2, "___").next().unwrap()
}
fn find_candidates<'target>( fn find_candidates<'target>(
local_ty: &BtfType, local_ty: &BtfType,
local_name: &str, local_name: &str,
target_btf: &'target Btf, target_btf: &'target Btf,
) -> Result<Vec<Candidate<'target>>, BtfError> { ) -> Result<Vec<Candidate<'target>>, BtfError> {
let flavorless_name = |name: &str| name.splitn(2, "___").next().unwrap().to_string();
let mut candidates = Vec::new(); let mut candidates = Vec::new();
let local_name = flavorless_name(local_name); let local_name = flavorless_name(local_name);
for (type_id, ty) in target_btf.types().enumerate() { for (type_id, ty) in target_btf.types().enumerate() {
@ -330,7 +332,31 @@ fn match_candidate<'target>(
return Ok(None); return Ok(None);
} }
} }
RelocationKind::EnumVariantExists | RelocationKind::EnumVariantValue => todo!(), RelocationKind::EnumVariantExists | RelocationKind::EnumVariantValue => {
let target_id = candidate.btf.resolve_type(candidate.type_id)?;
let target_ty = candidate.btf.type_by_id(target_id)?;
// the first accessor is guaranteed to have a name by construction
let local_variant_name = local_spec.accessors[0].name.as_ref().unwrap();
match target_ty {
BtfType::Enum(_, members) => {
for (index, member) in members.iter().enumerate() {
let target_variant_name = candidate.btf.string_at(member.name_off)?;
if flavorless_name(local_variant_name)
== flavorless_name(&target_variant_name)
{
target_spec.parts.push(index);
target_spec.accessors.push(Accessor {
index,
type_id: target_id,
name: None,
});
return Ok(Some(target_spec));
}
}
}
_ => return Ok(None),
}
}
RelocationKind::FieldByteOffset RelocationKind::FieldByteOffset
| RelocationKind::FieldByteSize | RelocationKind::FieldByteSize
| RelocationKind::FieldExists | RelocationKind::FieldExists
@ -522,7 +548,7 @@ impl<'a> AccessSpec<'a> {
let accessors = vec![Accessor { let accessors = vec![Accessor {
type_id, type_id,
index, index,
name: btf.type_name(ty)?.map(String::from), name: Some(btf.string_at(members[index].name_off)?.to_string()),
}]; }];
AccessSpec { AccessSpec {

Loading…
Cancel
Save