1#[repr(C)]
8#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
9pub struct ProcModuleKey {
10 pub pid: u32,
11 pub pad: u32,
12 pub cookie_lo: u32,
13 pub cookie_hi: u32,
14}
15
16impl ProcModuleKey {
17 pub fn new(pid: u32, module_cookie: u64) -> Self {
18 Self {
19 pid,
20 pad: 0,
21 cookie_lo: module_cookie as u32,
22 cookie_hi: (module_cookie >> 32) as u32,
23 }
24 }
25}
26
27pub const PROC_MODULE_KEY_PID_OFFSET: usize = std::mem::offset_of!(ProcModuleKey, pid);
28pub const PROC_MODULE_KEY_PAD_OFFSET: usize = std::mem::offset_of!(ProcModuleKey, pad);
29pub const PROC_MODULE_KEY_COOKIE_LO_OFFSET: usize = std::mem::offset_of!(ProcModuleKey, cookie_lo);
30pub const PROC_MODULE_KEY_COOKIE_HI_OFFSET: usize = std::mem::offset_of!(ProcModuleKey, cookie_hi);
31pub const PROC_MODULE_KEY_SIZE: usize = std::mem::size_of::<ProcModuleKey>();
32
33#[repr(C)]
35#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
36pub struct ProcModuleOffsetsValue {
37 pub text: u64,
38 pub rodata: u64,
39 pub data: u64,
40 pub bss: u64,
41 pub base: u64,
42 pub size: u64,
43}
44
45impl ProcModuleOffsetsValue {
46 pub fn new(text: u64, rodata: u64, data: u64, bss: u64, base: u64, size: u64) -> Self {
47 Self {
48 text,
49 rodata,
50 data,
51 bss,
52 base,
53 size,
54 }
55 }
56}
57
58pub const PROC_MODULE_OFFSETS_VALUE_TEXT_OFFSET: usize =
59 std::mem::offset_of!(ProcModuleOffsetsValue, text);
60pub const PROC_MODULE_OFFSETS_VALUE_RODATA_OFFSET: usize =
61 std::mem::offset_of!(ProcModuleOffsetsValue, rodata);
62pub const PROC_MODULE_OFFSETS_VALUE_DATA_OFFSET: usize =
63 std::mem::offset_of!(ProcModuleOffsetsValue, data);
64pub const PROC_MODULE_OFFSETS_VALUE_BSS_OFFSET: usize =
65 std::mem::offset_of!(ProcModuleOffsetsValue, bss);
66pub const PROC_MODULE_OFFSETS_VALUE_BASE_OFFSET: usize =
67 std::mem::offset_of!(ProcModuleOffsetsValue, base);
68pub const PROC_MODULE_OFFSETS_VALUE_SIZE_OFFSET: usize =
69 std::mem::offset_of!(ProcModuleOffsetsValue, size);
70pub const PROC_MODULE_OFFSETS_VALUE_SIZE: usize = std::mem::size_of::<ProcModuleOffsetsValue>();
71
72#[repr(C)]
74#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
75pub struct ProcModuleRangeMeta {
76 pub active_slot: u32,
77 pub count: u32,
78}
79
80impl ProcModuleRangeMeta {
81 pub fn new(active_slot: u32, count: u32) -> Self {
82 Self { active_slot, count }
83 }
84}
85
86pub const PROC_MODULE_RANGE_META_ACTIVE_SLOT_OFFSET: usize =
87 std::mem::offset_of!(ProcModuleRangeMeta, active_slot);
88pub const PROC_MODULE_RANGE_META_COUNT_OFFSET: usize =
89 std::mem::offset_of!(ProcModuleRangeMeta, count);
90pub const PROC_MODULE_RANGE_META_SIZE: usize = std::mem::size_of::<ProcModuleRangeMeta>();
91
92#[repr(C)]
94#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
95pub struct ProcModuleRangeKey {
96 pub pid: u32,
97 pub slot: u32,
98 pub index: u32,
99 pub pad: u32,
100}
101
102impl ProcModuleRangeKey {
103 pub fn new(pid: u32, slot: u32, index: u32) -> Self {
104 Self {
105 pid,
106 slot,
107 index,
108 pad: 0,
109 }
110 }
111}
112
113pub const PROC_MODULE_RANGE_KEY_PID_OFFSET: usize = std::mem::offset_of!(ProcModuleRangeKey, pid);
114pub const PROC_MODULE_RANGE_KEY_SLOT_OFFSET: usize = std::mem::offset_of!(ProcModuleRangeKey, slot);
115pub const PROC_MODULE_RANGE_KEY_INDEX_OFFSET: usize =
116 std::mem::offset_of!(ProcModuleRangeKey, index);
117pub const PROC_MODULE_RANGE_KEY_PAD_OFFSET: usize = std::mem::offset_of!(ProcModuleRangeKey, pad);
118pub const PROC_MODULE_RANGE_KEY_SIZE: usize = std::mem::size_of::<ProcModuleRangeKey>();
119
120#[repr(C)]
122#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
123pub struct ProcModuleRangeValue {
124 pub base: u64,
125 pub end: u64,
126 pub text: u64,
127 pub cookie_lo: u32,
128 pub cookie_hi: u32,
129}
130
131impl ProcModuleRangeValue {
132 pub fn new(base: u64, end: u64, text: u64, module_cookie: u64) -> Self {
133 Self {
134 base,
135 end,
136 text,
137 cookie_lo: module_cookie as u32,
138 cookie_hi: (module_cookie >> 32) as u32,
139 }
140 }
141
142 pub fn module_cookie(self) -> u64 {
143 u64::from(self.cookie_lo) | (u64::from(self.cookie_hi) << 32)
144 }
145}
146
147pub const PROC_MODULE_RANGE_VALUE_BASE_OFFSET: usize =
148 std::mem::offset_of!(ProcModuleRangeValue, base);
149pub const PROC_MODULE_RANGE_VALUE_END_OFFSET: usize =
150 std::mem::offset_of!(ProcModuleRangeValue, end);
151pub const PROC_MODULE_RANGE_VALUE_TEXT_OFFSET: usize =
152 std::mem::offset_of!(ProcModuleRangeValue, text);
153pub const PROC_MODULE_RANGE_VALUE_COOKIE_LO_OFFSET: usize =
154 std::mem::offset_of!(ProcModuleRangeValue, cookie_lo);
155pub const PROC_MODULE_RANGE_VALUE_COOKIE_HI_OFFSET: usize =
156 std::mem::offset_of!(ProcModuleRangeValue, cookie_hi);
157pub const PROC_MODULE_RANGE_VALUE_SIZE: usize = std::mem::size_of::<ProcModuleRangeValue>();
158
159#[repr(C)]
161#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
162pub struct PidAliasValue {
163 pub proc_pid: u32,
164}
165
166pub const PID_ALIAS_VALUE_PROC_PID_OFFSET: usize = std::mem::offset_of!(PidAliasValue, proc_pid);
167pub const PID_ALIAS_VALUE_SIZE: usize = std::mem::size_of::<PidAliasValue>();
168
169#[repr(C)]
175#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
176pub struct BacktraceUnwindRow {
177 pub pc_start: u64,
178 pub pc_end: u64,
179 pub cfa_offset: i64,
180 pub ra_offset: i64,
181 pub rbp_offset: i64,
182 pub cfa_register: u16,
183 pub ra_register: u16,
184 pub rbp_register: u16,
185 pub ra_kind: u8,
186 pub rbp_kind: u8,
187 pub reserved: [u8; 2],
188}
189
190pub const BACKTRACE_UNWIND_ROW_PC_START_OFFSET: usize =
191 std::mem::offset_of!(BacktraceUnwindRow, pc_start);
192pub const BACKTRACE_UNWIND_ROW_PC_END_OFFSET: usize =
193 std::mem::offset_of!(BacktraceUnwindRow, pc_end);
194pub const BACKTRACE_UNWIND_ROW_CFA_OFFSET_OFFSET: usize =
195 std::mem::offset_of!(BacktraceUnwindRow, cfa_offset);
196pub const BACKTRACE_UNWIND_ROW_RA_OFFSET_OFFSET: usize =
197 std::mem::offset_of!(BacktraceUnwindRow, ra_offset);
198pub const BACKTRACE_UNWIND_ROW_RBP_OFFSET_OFFSET: usize =
199 std::mem::offset_of!(BacktraceUnwindRow, rbp_offset);
200pub const BACKTRACE_UNWIND_ROW_CFA_REGISTER_OFFSET: usize =
201 std::mem::offset_of!(BacktraceUnwindRow, cfa_register);
202pub const BACKTRACE_UNWIND_ROW_RA_REGISTER_OFFSET: usize =
203 std::mem::offset_of!(BacktraceUnwindRow, ra_register);
204pub const BACKTRACE_UNWIND_ROW_RBP_REGISTER_OFFSET: usize =
205 std::mem::offset_of!(BacktraceUnwindRow, rbp_register);
206pub const BACKTRACE_UNWIND_ROW_RA_KIND_OFFSET: usize =
207 std::mem::offset_of!(BacktraceUnwindRow, ra_kind);
208pub const BACKTRACE_UNWIND_ROW_RBP_KIND_OFFSET: usize =
209 std::mem::offset_of!(BacktraceUnwindRow, rbp_kind);
210pub const BACKTRACE_UNWIND_ROW_SIZE: usize = std::mem::size_of::<BacktraceUnwindRow>();
211
212pub const BACKTRACE_UNWIND_WORDS_PER_ROW: usize = 6;
213pub const BACKTRACE_UNWIND_WORD_PC_START: usize = 0;
214pub const BACKTRACE_UNWIND_WORD_PC_END: usize = 1;
215pub const BACKTRACE_UNWIND_WORD_CFA_OFFSET: usize = 2;
216pub const BACKTRACE_UNWIND_WORD_RA_OFFSET: usize = 3;
217pub const BACKTRACE_UNWIND_WORD_RBP_OFFSET: usize = 4;
218pub const BACKTRACE_UNWIND_WORD_REGISTERS: usize = 5;
219
220#[repr(C)]
226#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
227pub struct BacktraceModuleRowRange {
228 pub row_start: u32,
229 pub row_end: u32,
230}
231
232pub const BACKTRACE_MODULE_ROW_RANGE_ROW_START_OFFSET: usize =
233 std::mem::offset_of!(BacktraceModuleRowRange, row_start);
234pub const BACKTRACE_MODULE_ROW_RANGE_ROW_END_OFFSET: usize =
235 std::mem::offset_of!(BacktraceModuleRowRange, row_end);
236pub const BACKTRACE_MODULE_ROW_RANGE_SIZE: usize = std::mem::size_of::<BacktraceModuleRowRange>();
237
238pub fn backtrace_unwind_row_register_word(row: BacktraceUnwindRow) -> u64 {
239 u64::from(row.cfa_register)
240 | (u64::from(row.ra_register) << 16)
241 | (u64::from(row.rbp_register) << 32)
242 | (u64::from(row.ra_kind) << 48)
243 | (u64::from(row.rbp_kind) << 56)
244}
245
246pub fn backtrace_unwind_row_word(row: BacktraceUnwindRow, word: usize) -> u64 {
247 match word {
248 BACKTRACE_UNWIND_WORD_PC_START => row.pc_start,
249 BACKTRACE_UNWIND_WORD_PC_END => row.pc_end,
250 BACKTRACE_UNWIND_WORD_CFA_OFFSET => row.cfa_offset as u64,
251 BACKTRACE_UNWIND_WORD_RA_OFFSET => row.ra_offset as u64,
252 BACKTRACE_UNWIND_WORD_RBP_OFFSET => row.rbp_offset as u64,
253 BACKTRACE_UNWIND_WORD_REGISTERS => backtrace_unwind_row_register_word(row),
254 _ => 0,
255 }
256}
257
258pub fn backtrace_unwind_row_from_words(
259 words: [u64; BACKTRACE_UNWIND_WORDS_PER_ROW],
260) -> BacktraceUnwindRow {
261 let registers = words[BACKTRACE_UNWIND_WORD_REGISTERS];
262 BacktraceUnwindRow {
263 pc_start: words[BACKTRACE_UNWIND_WORD_PC_START],
264 pc_end: words[BACKTRACE_UNWIND_WORD_PC_END],
265 cfa_offset: words[BACKTRACE_UNWIND_WORD_CFA_OFFSET] as i64,
266 ra_offset: words[BACKTRACE_UNWIND_WORD_RA_OFFSET] as i64,
267 rbp_offset: words[BACKTRACE_UNWIND_WORD_RBP_OFFSET] as i64,
268 cfa_register: registers as u16,
269 ra_register: (registers >> 16) as u16,
270 rbp_register: (registers >> 32) as u16,
271 ra_kind: (registers >> 48) as u8,
272 rbp_kind: (registers >> 56) as u8,
273 reserved: [0, 0],
274 }
275}
276
277#[repr(C)]
279#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
280pub struct BacktraceTailCallState {
281 pub current_ip: u64,
282 pub current_rsp: u64,
283 pub current_rbp: u64,
284 pub module_bias: u64,
285 pub module_cookie: u64,
286 pub inst_offset: u32,
287 pub event_size: u32,
288 pub frame_count: u8,
289 pub requested_depth: u8,
290 pub offsets_found: u8,
291 pub tail_calls: u8,
292 pub flags: u8,
293 pub active_slot: u8,
294 pub error_code: u16,
295 pub next_slot: u8,
296}
297
298pub const BACKTRACE_TAIL_STATE_CURRENT_IP_OFFSET: usize =
299 std::mem::offset_of!(BacktraceTailCallState, current_ip);
300pub const BACKTRACE_TAIL_STATE_CURRENT_RSP_OFFSET: usize =
301 std::mem::offset_of!(BacktraceTailCallState, current_rsp);
302pub const BACKTRACE_TAIL_STATE_CURRENT_RBP_OFFSET: usize =
303 std::mem::offset_of!(BacktraceTailCallState, current_rbp);
304pub const BACKTRACE_TAIL_STATE_MODULE_BIAS_OFFSET: usize =
305 std::mem::offset_of!(BacktraceTailCallState, module_bias);
306pub const BACKTRACE_TAIL_STATE_MODULE_COOKIE_OFFSET: usize =
307 std::mem::offset_of!(BacktraceTailCallState, module_cookie);
308pub const BACKTRACE_TAIL_STATE_INST_OFFSET_OFFSET: usize =
309 std::mem::offset_of!(BacktraceTailCallState, inst_offset);
310pub const BACKTRACE_TAIL_STATE_EVENT_SIZE_OFFSET: usize =
311 std::mem::offset_of!(BacktraceTailCallState, event_size);
312pub const BACKTRACE_TAIL_STATE_FRAME_COUNT_OFFSET: usize =
313 std::mem::offset_of!(BacktraceTailCallState, frame_count);
314pub const BACKTRACE_TAIL_STATE_REQUESTED_DEPTH_OFFSET: usize =
315 std::mem::offset_of!(BacktraceTailCallState, requested_depth);
316pub const BACKTRACE_TAIL_STATE_OFFSETS_FOUND_OFFSET: usize =
317 std::mem::offset_of!(BacktraceTailCallState, offsets_found);
318pub const BACKTRACE_TAIL_STATE_TAIL_CALLS_OFFSET: usize =
319 std::mem::offset_of!(BacktraceTailCallState, tail_calls);
320pub const BACKTRACE_TAIL_STATE_FLAGS_OFFSET: usize =
321 std::mem::offset_of!(BacktraceTailCallState, flags);
322pub const BACKTRACE_TAIL_STATE_ACTIVE_SLOT_OFFSET: usize =
323 std::mem::offset_of!(BacktraceTailCallState, active_slot);
324pub const BACKTRACE_TAIL_STATE_ERROR_CODE_OFFSET: usize =
325 std::mem::offset_of!(BacktraceTailCallState, error_code);
326pub const BACKTRACE_TAIL_STATE_NEXT_SLOT_OFFSET: usize =
327 std::mem::offset_of!(BacktraceTailCallState, next_slot);
328pub const BACKTRACE_TAIL_STATE_SIZE: usize = std::mem::size_of::<BacktraceTailCallState>();
329pub const BACKTRACE_TAIL_NO_NEXT_SLOT: u8 = u8::MAX;
330
331pub const BACKTRACE_RECOVERY_UNDEFINED: u8 = 0;
332pub const BACKTRACE_RECOVERY_AT_CFA_OFFSET: u8 = 1;
333pub const BACKTRACE_RECOVERY_VAL_CFA_OFFSET: u8 = 2;
334pub const BACKTRACE_RECOVERY_REGISTER: u8 = 3;
335pub const BACKTRACE_RECOVERY_SAME_VALUE: u8 = 4;
336
337pub const BACKTRACE_RA_UNDEFINED: u8 = BACKTRACE_RECOVERY_UNDEFINED;
338pub const BACKTRACE_RA_AT_CFA_OFFSET: u8 = BACKTRACE_RECOVERY_AT_CFA_OFFSET;
339pub const BACKTRACE_RA_VAL_CFA_OFFSET: u8 = BACKTRACE_RECOVERY_VAL_CFA_OFFSET;
340pub const BACKTRACE_RA_REGISTER: u8 = BACKTRACE_RECOVERY_REGISTER;
341pub const BACKTRACE_RA_SAME_VALUE: u8 = BACKTRACE_RECOVERY_SAME_VALUE;
342
343#[cfg(feature = "aya-pod")]
344mod aya_pod {
345 use super::{
346 BacktraceModuleRowRange, BacktraceTailCallState, BacktraceUnwindRow, PidAliasValue,
347 ProcModuleKey, ProcModuleOffsetsValue, ProcModuleRangeKey, ProcModuleRangeMeta,
348 ProcModuleRangeValue,
349 };
350
351 unsafe impl aya::Pod for ProcModuleKey {}
354 unsafe impl aya::Pod for ProcModuleOffsetsValue {}
357 unsafe impl aya::Pod for PidAliasValue {}
360 unsafe impl aya::Pod for ProcModuleRangeMeta {}
363 unsafe impl aya::Pod for ProcModuleRangeKey {}
366 unsafe impl aya::Pod for ProcModuleRangeValue {}
369 unsafe impl aya::Pod for BacktraceUnwindRow {}
372 unsafe impl aya::Pod for BacktraceModuleRowRange {}
375 unsafe impl aya::Pod for BacktraceTailCallState {}
378}
379
380#[cfg(test)]
381mod tests {
382 use super::*;
383
384 #[test]
385 fn proc_module_offsets_layout_matches_bpf_maps() {
386 assert_eq!(PROC_MODULE_KEY_SIZE, 16);
387 assert_eq!(PROC_MODULE_KEY_PID_OFFSET, 0);
388 assert_eq!(PROC_MODULE_KEY_PAD_OFFSET, 4);
389 assert_eq!(PROC_MODULE_KEY_COOKIE_LO_OFFSET, 8);
390 assert_eq!(PROC_MODULE_KEY_COOKIE_HI_OFFSET, 12);
391
392 assert_eq!(PROC_MODULE_OFFSETS_VALUE_SIZE, 48);
393 assert_eq!(PROC_MODULE_OFFSETS_VALUE_TEXT_OFFSET, 0);
394 assert_eq!(PROC_MODULE_OFFSETS_VALUE_RODATA_OFFSET, 8);
395 assert_eq!(PROC_MODULE_OFFSETS_VALUE_DATA_OFFSET, 16);
396 assert_eq!(PROC_MODULE_OFFSETS_VALUE_BSS_OFFSET, 24);
397 assert_eq!(PROC_MODULE_OFFSETS_VALUE_BASE_OFFSET, 32);
398 assert_eq!(PROC_MODULE_OFFSETS_VALUE_SIZE_OFFSET, 40);
399
400 assert_eq!(PID_ALIAS_VALUE_SIZE, 4);
401 assert_eq!(PID_ALIAS_VALUE_PROC_PID_OFFSET, 0);
402
403 assert_eq!(PROC_MODULE_RANGE_META_SIZE, 8);
404 assert_eq!(PROC_MODULE_RANGE_META_ACTIVE_SLOT_OFFSET, 0);
405 assert_eq!(PROC_MODULE_RANGE_META_COUNT_OFFSET, 4);
406
407 assert_eq!(PROC_MODULE_RANGE_KEY_SIZE, 16);
408 assert_eq!(PROC_MODULE_RANGE_KEY_PID_OFFSET, 0);
409 assert_eq!(PROC_MODULE_RANGE_KEY_SLOT_OFFSET, 4);
410 assert_eq!(PROC_MODULE_RANGE_KEY_INDEX_OFFSET, 8);
411 assert_eq!(PROC_MODULE_RANGE_KEY_PAD_OFFSET, 12);
412
413 assert_eq!(PROC_MODULE_RANGE_VALUE_SIZE, 32);
414 assert_eq!(PROC_MODULE_RANGE_VALUE_BASE_OFFSET, 0);
415 assert_eq!(PROC_MODULE_RANGE_VALUE_END_OFFSET, 8);
416 assert_eq!(PROC_MODULE_RANGE_VALUE_TEXT_OFFSET, 16);
417 assert_eq!(PROC_MODULE_RANGE_VALUE_COOKIE_LO_OFFSET, 24);
418 assert_eq!(PROC_MODULE_RANGE_VALUE_COOKIE_HI_OFFSET, 28);
419 }
420
421 #[test]
422 fn backtrace_unwind_row_layout_matches_bpf_map_value() {
423 assert_eq!(BACKTRACE_UNWIND_ROW_SIZE, 56);
424 assert_eq!(BACKTRACE_UNWIND_ROW_PC_START_OFFSET, 0);
425 assert_eq!(BACKTRACE_UNWIND_ROW_PC_END_OFFSET, 8);
426 assert_eq!(BACKTRACE_UNWIND_ROW_CFA_OFFSET_OFFSET, 16);
427 assert_eq!(BACKTRACE_UNWIND_ROW_RA_OFFSET_OFFSET, 24);
428 assert_eq!(BACKTRACE_UNWIND_ROW_RBP_OFFSET_OFFSET, 32);
429 assert_eq!(BACKTRACE_UNWIND_ROW_CFA_REGISTER_OFFSET, 40);
430 assert_eq!(BACKTRACE_UNWIND_ROW_RA_REGISTER_OFFSET, 42);
431 assert_eq!(BACKTRACE_UNWIND_ROW_RBP_REGISTER_OFFSET, 44);
432 assert_eq!(BACKTRACE_UNWIND_ROW_RA_KIND_OFFSET, 46);
433 assert_eq!(BACKTRACE_UNWIND_ROW_RBP_KIND_OFFSET, 47);
434 assert_eq!(BACKTRACE_UNWIND_WORDS_PER_ROW, 6);
435
436 let row = BacktraceUnwindRow {
437 pc_start: 0x10,
438 pc_end: 0x20,
439 cfa_offset: 128,
440 ra_offset: -8,
441 rbp_offset: -16,
442 cfa_register: 7,
443 ra_register: 16,
444 rbp_register: 6,
445 ra_kind: BACKTRACE_RA_AT_CFA_OFFSET,
446 rbp_kind: BACKTRACE_RECOVERY_SAME_VALUE,
447 reserved: [0, 0],
448 };
449 let words = [
450 backtrace_unwind_row_word(row, BACKTRACE_UNWIND_WORD_PC_START),
451 backtrace_unwind_row_word(row, BACKTRACE_UNWIND_WORD_PC_END),
452 backtrace_unwind_row_word(row, BACKTRACE_UNWIND_WORD_CFA_OFFSET),
453 backtrace_unwind_row_word(row, BACKTRACE_UNWIND_WORD_RA_OFFSET),
454 backtrace_unwind_row_word(row, BACKTRACE_UNWIND_WORD_RBP_OFFSET),
455 backtrace_unwind_row_word(row, BACKTRACE_UNWIND_WORD_REGISTERS),
456 ];
457 assert_eq!(backtrace_unwind_row_from_words(words), row);
458 }
459
460 #[test]
461 fn backtrace_module_row_range_layout_matches_bpf_map_value() {
462 assert_eq!(BACKTRACE_MODULE_ROW_RANGE_SIZE, 8);
463 assert_eq!(BACKTRACE_MODULE_ROW_RANGE_ROW_START_OFFSET, 0);
464 assert_eq!(BACKTRACE_MODULE_ROW_RANGE_ROW_END_OFFSET, 4);
465 }
466
467 #[test]
468 fn backtrace_tail_call_state_layout_matches_bpf_accessors() {
469 assert_eq!(BACKTRACE_TAIL_STATE_SIZE, 64);
470 assert_eq!(BACKTRACE_TAIL_STATE_CURRENT_IP_OFFSET, 0);
471 assert_eq!(BACKTRACE_TAIL_STATE_CURRENT_RSP_OFFSET, 8);
472 assert_eq!(BACKTRACE_TAIL_STATE_CURRENT_RBP_OFFSET, 16);
473 assert_eq!(BACKTRACE_TAIL_STATE_MODULE_BIAS_OFFSET, 24);
474 assert_eq!(BACKTRACE_TAIL_STATE_MODULE_COOKIE_OFFSET, 32);
475 assert_eq!(BACKTRACE_TAIL_STATE_INST_OFFSET_OFFSET, 40);
476 assert_eq!(BACKTRACE_TAIL_STATE_EVENT_SIZE_OFFSET, 44);
477 assert_eq!(BACKTRACE_TAIL_STATE_FRAME_COUNT_OFFSET, 48);
478 assert_eq!(BACKTRACE_TAIL_STATE_REQUESTED_DEPTH_OFFSET, 49);
479 assert_eq!(BACKTRACE_TAIL_STATE_OFFSETS_FOUND_OFFSET, 50);
480 assert_eq!(BACKTRACE_TAIL_STATE_TAIL_CALLS_OFFSET, 51);
481 assert_eq!(BACKTRACE_TAIL_STATE_FLAGS_OFFSET, 52);
482 assert_eq!(BACKTRACE_TAIL_STATE_ACTIVE_SLOT_OFFSET, 53);
483 assert_eq!(BACKTRACE_TAIL_STATE_ERROR_CODE_OFFSET, 54);
484 assert_eq!(BACKTRACE_TAIL_STATE_NEXT_SLOT_OFFSET, 56);
485 }
486}