diff --git a/capi/CHANGELOG.md b/capi/CHANGELOG.md index 6c91b92dd..e88be26c2 100644 --- a/capi/CHANGELOG.md +++ b/capi/CHANGELOG.md @@ -1,5 +1,6 @@ Unreleased ---------- +- Added `procmap_query_ioctl` attribute to `blaze_normalizer_opts` - Renamed `blaze_result` to `blaze_syms` - Renamed `blaze_result_free` to `blaze_syms_free` - Renamed `cache_maps` attribute of `blaze_normalizer_opts` to diff --git a/capi/include/blazesym.h b/capi/include/blazesym.h index c5e1b69a7..94ae7d538 100644 --- a/capi/include/blazesym.h +++ b/capi/include/blazesym.h @@ -293,6 +293,22 @@ typedef struct blaze_normalizer_opts { * ensure compatibility in the presence of member additions. */ size_t type_size; + /** + * Whether or not to use the `PROCMAP_QUERY` ioctl instead of + * parsing `/proc//maps` for getting available VMA ranges. + * + * # Notes + * + * Support for this ioctl is only present in very recent kernels + * (likely: 6.11+). See for + * details. + * + * Furthermore, the ioctl will also be used for retrieving build + * IDs (if enabled). Build ID reading logic in the kernel is known + * to be incomplete, with a fix slated to be included only with + * 6.12. + */ + bool procmap_query_ioctl; /** * Whether or not to cache `/proc//maps` contents. * @@ -319,7 +335,7 @@ typedef struct blaze_normalizer_opts { * Unused member available for future expansion. Must be initialized * to zero. */ - uint8_t reserved[5]; + uint8_t reserved[4]; } blaze_normalizer_opts; /** diff --git a/capi/src/normalize.rs b/capi/src/normalize.rs index 3f02a2965..a834a134e 100644 --- a/capi/src/normalize.rs +++ b/capi/src/normalize.rs @@ -42,6 +42,20 @@ pub struct blaze_normalizer_opts { /// Make sure to initialize it to `sizeof()`. This member is used to /// ensure compatibility in the presence of member additions. pub type_size: usize, + /// Whether or not to use the `PROCMAP_QUERY` ioctl instead of + /// parsing `/proc//maps` for getting available VMA ranges. + /// + /// # Notes + /// + /// Support for this ioctl is only present in very recent kernels + /// (likely: 6.11+). See for + /// details. + /// + /// Furthermore, the ioctl will also be used for retrieving build + /// IDs (if enabled). Build ID reading logic in the kernel is known + /// to be incomplete, with a fix slated to be included only with + /// 6.12. + pub procmap_query_ioctl: bool, /// Whether or not to cache `/proc//maps` contents. /// /// Setting this flag to `true` is not generally recommended, because it @@ -60,17 +74,18 @@ pub struct blaze_normalizer_opts { pub cache_build_ids: bool, /// Unused member available for future expansion. Must be initialized /// to zero. - pub reserved: [u8; 5], + pub reserved: [u8; 4], } impl Default for blaze_normalizer_opts { fn default() -> Self { Self { type_size: size_of::(), + procmap_query_ioctl: false, cache_vmas: false, build_ids: false, cache_build_ids: false, - reserved: [0; 5], + reserved: [0; 4], } } } @@ -180,6 +195,7 @@ pub unsafe extern "C" fn blaze_normalizer_new_opts( let blaze_normalizer_opts { type_size: _, + procmap_query_ioctl, cache_vmas, build_ids, cache_build_ids, @@ -187,6 +203,7 @@ pub unsafe extern "C" fn blaze_normalizer_new_opts( } = opts; let normalizer = Normalizer::builder() + .enable_procmap_query_ioctl(procmap_query_ioctl) .enable_vma_caching(cache_vmas) .enable_build_ids(build_ids) .enable_build_id_caching(cache_build_ids) @@ -940,9 +957,7 @@ mod tests { let () = unsafe { blaze_normalizer_free(normalizer) }; } - /// Check that we can normalize sorted user space addresses. - #[test] - fn normalize_user_addrs_sorted() { + fn test_normalize_user_addrs_sorted(procmap_query_ioctl: bool) { let mut addrs = [ libc::atexit as Addr, libc::chdir as Addr, @@ -952,7 +967,11 @@ mod tests { ]; let () = addrs.sort(); - let normalizer = blaze_normalizer_new(); + let opts = blaze_normalizer_opts { + procmap_query_ioctl, + ..Default::default() + }; + let normalizer = unsafe { blaze_normalizer_new_opts(&opts) }; assert_ne!(normalizer, ptr::null_mut()); let opts = blaze_normalize_opts { @@ -978,6 +997,20 @@ mod tests { let () = unsafe { blaze_normalizer_free(normalizer) }; } + /// Check that we can normalize sorted user space addresses. + #[test] + fn normalize_user_addrs_sorted_proc_maps() { + test_normalize_user_addrs_sorted(false) + } + + /// Check that we can normalize sorted user space addresses using + /// the `PROCMAP_QUERY` ioctl. + #[test] + #[ignore = "test requires PROCMAP_QUERY ioctl kernel support"] + fn normalize_user_addrs_sorted_ioctl() { + test_normalize_user_addrs_sorted(true) + } + /// Check that we fail normalizing unsorted addresses with a function that /// requires them to be sorted. #[test]