|
|
@ -364,7 +364,7 @@ fn match_candidate<'target>(
|
|
|
|
| RelocationKind::FieldLShift64
|
|
|
|
| RelocationKind::FieldLShift64
|
|
|
|
| RelocationKind::FieldRShift64 => {
|
|
|
|
| RelocationKind::FieldRShift64 => {
|
|
|
|
let mut target_id = candidate.type_id;
|
|
|
|
let mut target_id = candidate.type_id;
|
|
|
|
for accessor in &local_spec.accessors {
|
|
|
|
for (i, accessor) in local_spec.accessors.iter().enumerate() {
|
|
|
|
target_id = candidate.btf.resolve_type(target_id)?;
|
|
|
|
target_id = candidate.btf.resolve_type(target_id)?;
|
|
|
|
|
|
|
|
|
|
|
|
if accessor.name.is_some() {
|
|
|
|
if accessor.name.is_some() {
|
|
|
@ -381,7 +381,29 @@ fn match_candidate<'target>(
|
|
|
|
return Ok(None);
|
|
|
|
return Ok(None);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
// array access
|
|
|
|
// i = 0 is the base struct. for i > 0, we need to potentially do bounds checking
|
|
|
|
|
|
|
|
if i > 0 {
|
|
|
|
|
|
|
|
let target_ty = candidate.btf.type_by_id(target_id)?;
|
|
|
|
|
|
|
|
let array = match target_ty {
|
|
|
|
|
|
|
|
BtfType::Array(_, array) => array,
|
|
|
|
|
|
|
|
_ => return Ok(None),
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let var_len = array.nelems == 0 && {
|
|
|
|
|
|
|
|
// an array is potentially variable length if it's the last field
|
|
|
|
|
|
|
|
// of the parent struct and has 0 elements
|
|
|
|
|
|
|
|
let parent = target_spec.accessors.last().unwrap();
|
|
|
|
|
|
|
|
let parent_ty = candidate.btf.type_by_id(parent.type_id)?;
|
|
|
|
|
|
|
|
match parent_ty {
|
|
|
|
|
|
|
|
BtfType::Struct(_, members) => parent.index == members.len() - 1,
|
|
|
|
|
|
|
|
_ => false,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
if !var_len && accessor.index >= array.nelems as usize {
|
|
|
|
|
|
|
|
return Ok(None);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
target_id = candidate.btf.resolve_type(array.type_)?;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if target_spec.parts.len() == MAX_SPEC_LEN {
|
|
|
|
if target_spec.parts.len() == MAX_SPEC_LEN {
|
|
|
|
return Err(BtfRelocationError::MaximumNestingLevelReached {
|
|
|
|
return Err(BtfRelocationError::MaximumNestingLevelReached {
|
|
|
|