Skip to content

Commit

Permalink
capi: Hook up support for PROCMAP_QUERY ioctl to normalize APIs
Browse files Browse the repository at this point in the history
Hook up support for the PROCMAP_QUERY ioctl to the normalize APIs, to
make this functionality accessible from blazesym-c.

Signed-off-by: Daniel Müller <[email protected]>
  • Loading branch information
d-e-s-o committed Aug 8, 2024
1 parent b22e572 commit 225f88e
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 7 deletions.
1 change: 1 addition & 0 deletions capi/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
18 changes: 17 additions & 1 deletion capi/include/blazesym.h
Original file line number Diff line number Diff line change
Expand Up @@ -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/<pid>/maps` for getting available VMA ranges.
*
* # Notes
*
* Support for this ioctl is only present in very recent kernels
* (likely: 6.11+). See <https://lwn.net/Articles/979931/> 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/<pid>/maps` contents.
*
Expand All @@ -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;

/**
Expand Down
45 changes: 39 additions & 6 deletions capi/src/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ pub struct blaze_normalizer_opts {
/// Make sure to initialize it to `sizeof(<type>)`. 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/<pid>/maps` for getting available VMA ranges.
///
/// # Notes
///
/// Support for this ioctl is only present in very recent kernels
/// (likely: 6.11+). See <https://lwn.net/Articles/979931/> 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/<pid>/maps` contents.
///
/// Setting this flag to `true` is not generally recommended, because it
Expand All @@ -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::<Self>(),
procmap_query_ioctl: false,
cache_vmas: false,
build_ids: false,
cache_build_ids: false,
reserved: [0; 5],
reserved: [0; 4],
}
}
}
Expand Down Expand Up @@ -180,13 +195,15 @@ 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,
reserved: _,
} = 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)
Expand Down Expand Up @@ -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,
Expand All @@ -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 {
Expand All @@ -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]
Expand Down

0 comments on commit 225f88e

Please sign in to comment.