lib.rs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #![no_std]
  2. pub extern crate ufmt;
  3. mod macros;
  4. use core::{cmp, mem, ptr};
  5. use aya_bpf::{
  6. macros::map,
  7. maps::{PerCpuArray, PerfEventByteArray},
  8. };
  9. pub use aya_log_common::Level;
  10. use aya_log_common::RecordField;
  11. pub use aya_log_common::LOG_BUF_CAPACITY;
  12. #[doc(hidden)]
  13. #[repr(C)]
  14. pub struct LogBuf {
  15. pub buf: [u8; LOG_BUF_CAPACITY],
  16. }
  17. #[doc(hidden)]
  18. #[map]
  19. pub static mut AYA_LOG_BUF: PerCpuArray<LogBuf> = PerCpuArray::with_max_entries(1, 0);
  20. #[doc(hidden)]
  21. #[map]
  22. pub static mut AYA_LOGS: PerfEventByteArray = PerfEventByteArray::new(0);
  23. #[doc(hidden)]
  24. pub struct LogBufWriter<'a> {
  25. pos: usize,
  26. data: &'a mut [u8],
  27. }
  28. impl<'a> LogBufWriter<'a> {
  29. pub fn new(data: &mut [u8]) -> LogBufWriter<'_> {
  30. LogBufWriter {
  31. pos: mem::size_of::<RecordField>() + mem::size_of::<usize>(),
  32. data,
  33. }
  34. }
  35. pub fn finish(self) -> usize {
  36. let mut buf = self.data;
  37. unsafe { ptr::write_unaligned(buf.as_mut_ptr() as *mut _, RecordField::Log) };
  38. buf = &mut buf[mem::size_of::<RecordField>()..];
  39. let len = self.pos - mem::size_of::<RecordField>() - mem::size_of::<usize>();
  40. unsafe { ptr::write_unaligned(buf.as_mut_ptr() as *mut _, len) };
  41. self.pos
  42. }
  43. }
  44. impl<'a> ufmt::uWrite for LogBufWriter<'a> {
  45. type Error = ();
  46. fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
  47. let bytes = s.as_bytes();
  48. let len = bytes.len();
  49. // this is to make sure the verifier knows about the upper bound
  50. if len > LOG_BUF_CAPACITY {
  51. return Err(());
  52. }
  53. let available = self.data.len() - self.pos;
  54. if available < len {
  55. return Err(());
  56. }
  57. self.data[self.pos..self.pos + len].copy_from_slice(&bytes[..len]);
  58. self.pos += len;
  59. Ok(())
  60. }
  61. }
  62. struct TagLenValue<'a> {
  63. tag: RecordField,
  64. value: &'a [u8],
  65. }
  66. impl<'a> TagLenValue<'a> {
  67. #[inline(always)]
  68. pub(crate) fn new(tag: RecordField, value: &'a [u8]) -> TagLenValue<'a> {
  69. TagLenValue { tag, value }
  70. }
  71. pub(crate) fn try_write(&self, mut buf: &mut [u8]) -> Result<usize, ()> {
  72. let size = mem::size_of::<RecordField>() + mem::size_of::<usize>() + self.value.len();
  73. if buf.len() < size {
  74. return Err(());
  75. }
  76. unsafe { ptr::write_unaligned(buf.as_mut_ptr() as *mut _, self.tag) };
  77. buf = &mut buf[mem::size_of::<RecordField>()..];
  78. unsafe { ptr::write_unaligned(buf.as_mut_ptr() as *mut _, self.value.len()) };
  79. buf = &mut buf[mem::size_of::<usize>()..];
  80. let len = cmp::min(buf.len(), self.value.len());
  81. buf[..len].copy_from_slice(&self.value[..len]);
  82. Ok(size)
  83. }
  84. }
  85. #[doc(hidden)]
  86. pub fn write_record_header(
  87. buf: &mut [u8],
  88. target: &str,
  89. level: Level,
  90. module: &str,
  91. file: &str,
  92. line: u32,
  93. ) -> Result<usize, ()> {
  94. let mut size = 0;
  95. for attr in [
  96. TagLenValue::new(RecordField::Target, target.as_bytes()),
  97. TagLenValue::new(RecordField::Level, &(level as usize).to_ne_bytes()),
  98. TagLenValue::new(RecordField::Module, module.as_bytes()),
  99. TagLenValue::new(RecordField::File, file.as_bytes()),
  100. TagLenValue::new(RecordField::Line, &line.to_ne_bytes()),
  101. ] {
  102. size += attr.try_write(&mut buf[size..])?;
  103. }
  104. Ok(size)
  105. }