4
0

lib.rs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #![no_std]
  2. use core::{cmp, mem, ptr};
  3. use aya_bpf::{
  4. macros::map,
  5. maps::{PerCpuArray, PerfEventByteArray},
  6. };
  7. use aya_log_common::{ArgType, RecordField};
  8. pub use aya_log_common::{Level, LOG_BUF_CAPACITY};
  9. pub use aya_log_ebpf_macros::{debug, error, info, log, trace, warn};
  10. #[doc(hidden)]
  11. #[repr(C)]
  12. pub struct LogBuf {
  13. pub buf: [u8; LOG_BUF_CAPACITY],
  14. }
  15. #[doc(hidden)]
  16. #[map]
  17. pub static mut AYA_LOG_BUF: PerCpuArray<LogBuf> = PerCpuArray::with_max_entries(1, 0);
  18. #[doc(hidden)]
  19. #[map]
  20. pub static mut AYA_LOGS: PerfEventByteArray = PerfEventByteArray::new(0);
  21. struct TagLenValue<'a, T> {
  22. tag: T,
  23. value: &'a [u8],
  24. }
  25. impl<'a, T> TagLenValue<'a, T>
  26. where
  27. T: Copy,
  28. {
  29. #[inline(always)]
  30. pub(crate) fn new(tag: T, value: &'a [u8]) -> TagLenValue<'a, T> {
  31. TagLenValue { tag, value }
  32. }
  33. pub(crate) fn write(&self, mut buf: &mut [u8]) -> Result<usize, ()> {
  34. let size = mem::size_of::<T>() + mem::size_of::<usize>() + self.value.len();
  35. if buf.len() < size {
  36. return Err(());
  37. }
  38. unsafe { ptr::write_unaligned(buf.as_mut_ptr() as *mut _, self.tag) };
  39. buf = &mut buf[mem::size_of::<T>()..];
  40. unsafe { ptr::write_unaligned(buf.as_mut_ptr() as *mut _, self.value.len()) };
  41. buf = &mut buf[mem::size_of::<usize>()..];
  42. let len = cmp::min(buf.len(), self.value.len());
  43. buf[..len].copy_from_slice(&self.value[..len]);
  44. Ok(size)
  45. }
  46. }
  47. pub trait WriteToBuf {
  48. #[allow(clippy::result_unit_err)]
  49. fn write(&self, buf: &mut [u8]) -> Result<usize, ()>;
  50. }
  51. macro_rules! impl_write_to_buf {
  52. ($type:ident, $arg_type:expr) => {
  53. impl WriteToBuf for $type {
  54. fn write(&self, buf: &mut [u8]) -> Result<usize, ()> {
  55. TagLenValue::<ArgType>::new($arg_type, &self.to_ne_bytes()).write(buf)
  56. }
  57. }
  58. };
  59. }
  60. impl_write_to_buf!(i8, ArgType::I8);
  61. impl_write_to_buf!(i16, ArgType::I16);
  62. impl_write_to_buf!(i32, ArgType::I32);
  63. impl_write_to_buf!(i64, ArgType::I64);
  64. impl_write_to_buf!(i128, ArgType::I128);
  65. impl_write_to_buf!(isize, ArgType::Isize);
  66. impl_write_to_buf!(u8, ArgType::U8);
  67. impl_write_to_buf!(u16, ArgType::U16);
  68. impl_write_to_buf!(u32, ArgType::U32);
  69. impl_write_to_buf!(u64, ArgType::U64);
  70. impl_write_to_buf!(u128, ArgType::U128);
  71. impl_write_to_buf!(usize, ArgType::Usize);
  72. impl_write_to_buf!(f32, ArgType::F32);
  73. impl_write_to_buf!(f64, ArgType::F64);
  74. impl WriteToBuf for str {
  75. fn write(&self, buf: &mut [u8]) -> Result<usize, ()> {
  76. TagLenValue::<ArgType>::new(ArgType::Str, self.as_bytes()).write(buf)
  77. }
  78. }
  79. #[allow(clippy::result_unit_err)]
  80. #[doc(hidden)]
  81. pub fn write_record_header(
  82. buf: &mut [u8],
  83. target: &str,
  84. level: Level,
  85. module: &str,
  86. file: &str,
  87. line: u32,
  88. num_args: usize,
  89. ) -> Result<usize, ()> {
  90. let mut size = 0;
  91. for attr in [
  92. TagLenValue::<RecordField>::new(RecordField::Target, target.as_bytes()),
  93. TagLenValue::<RecordField>::new(RecordField::Level, &(level as usize).to_ne_bytes()),
  94. TagLenValue::<RecordField>::new(RecordField::Module, module.as_bytes()),
  95. TagLenValue::<RecordField>::new(RecordField::File, file.as_bytes()),
  96. TagLenValue::<RecordField>::new(RecordField::Line, &line.to_ne_bytes()),
  97. TagLenValue::<RecordField>::new(RecordField::NumArgs, &num_args.to_ne_bytes()),
  98. ] {
  99. size += attr.write(&mut buf[size..])?;
  100. }
  101. Ok(size)
  102. }
  103. #[allow(clippy::result_unit_err)]
  104. #[doc(hidden)]
  105. pub fn write_record_message(buf: &mut [u8], msg: &str) -> Result<usize, ()> {
  106. TagLenValue::<RecordField>::new(RecordField::Log, msg.as_bytes()).write(buf)
  107. }
  108. #[doc(hidden)]
  109. pub mod macro_support {
  110. pub use aya_log_common::{Level, LOG_BUF_CAPACITY};
  111. pub use aya_log_ebpf_macros::log;
  112. }