types.rs 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850
  1. #![allow(missing_docs)]
  2. use alloc::{string::ToString, vec, vec::Vec};
  3. use core::{fmt::Display, mem, ptr};
  4. use object::Endianness;
  5. use crate::btf::{Btf, BtfError, MAX_RESOLVE_DEPTH};
  6. #[derive(Clone, Debug)]
  7. pub enum BtfType {
  8. Unknown,
  9. Fwd(Fwd),
  10. Const(Const),
  11. Volatile(Volatile),
  12. Restrict(Restrict),
  13. Ptr(Ptr),
  14. Typedef(Typedef),
  15. Func(Func),
  16. Int(Int),
  17. Float(Float),
  18. Enum(Enum),
  19. Array(Array),
  20. Struct(Struct),
  21. Union(Union),
  22. FuncProto(FuncProto),
  23. Var(Var),
  24. DataSec(DataSec),
  25. DeclTag(DeclTag),
  26. TypeTag(TypeTag),
  27. Enum64(Enum64),
  28. }
  29. #[repr(C)]
  30. #[derive(Clone, Debug)]
  31. pub struct Fwd {
  32. pub(crate) name_offset: u32,
  33. info: u32,
  34. _unused: u32,
  35. }
  36. impl Fwd {
  37. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  38. bytes_of::<Fwd>(self).to_vec()
  39. }
  40. pub(crate) fn kind(&self) -> BtfKind {
  41. BtfKind::Fwd
  42. }
  43. pub(crate) fn type_info_size(&self) -> usize {
  44. mem::size_of::<Self>()
  45. }
  46. }
  47. #[repr(C)]
  48. #[derive(Clone, Debug)]
  49. pub struct Const {
  50. pub(crate) name_offset: u32,
  51. info: u32,
  52. pub(crate) btf_type: u32,
  53. }
  54. impl Const {
  55. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  56. bytes_of::<Const>(self).to_vec()
  57. }
  58. pub(crate) fn kind(&self) -> BtfKind {
  59. BtfKind::Const
  60. }
  61. pub(crate) fn type_info_size(&self) -> usize {
  62. mem::size_of::<Self>()
  63. }
  64. pub(crate) fn new(btf_type: u32) -> Self {
  65. let info = (BtfKind::Const as u32) << 24;
  66. Self {
  67. name_offset: 0,
  68. info,
  69. btf_type,
  70. }
  71. }
  72. }
  73. #[repr(C)]
  74. #[derive(Clone, Debug)]
  75. pub struct Volatile {
  76. pub(crate) name_offset: u32,
  77. info: u32,
  78. pub(crate) btf_type: u32,
  79. }
  80. impl Volatile {
  81. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  82. bytes_of::<Volatile>(self).to_vec()
  83. }
  84. pub(crate) fn kind(&self) -> BtfKind {
  85. BtfKind::Volatile
  86. }
  87. pub(crate) fn type_info_size(&self) -> usize {
  88. mem::size_of::<Self>()
  89. }
  90. }
  91. #[derive(Clone, Debug)]
  92. pub struct Restrict {
  93. pub(crate) name_offset: u32,
  94. _info: u32,
  95. pub(crate) btf_type: u32,
  96. }
  97. impl Restrict {
  98. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  99. bytes_of::<Restrict>(self).to_vec()
  100. }
  101. pub(crate) fn kind(&self) -> BtfKind {
  102. BtfKind::Restrict
  103. }
  104. pub(crate) fn type_info_size(&self) -> usize {
  105. mem::size_of::<Self>()
  106. }
  107. }
  108. #[repr(C)]
  109. #[derive(Clone, Debug)]
  110. pub struct Ptr {
  111. pub(crate) name_offset: u32,
  112. info: u32,
  113. pub(crate) btf_type: u32,
  114. }
  115. impl Ptr {
  116. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  117. bytes_of::<Self>(self).to_vec()
  118. }
  119. pub(crate) fn kind(&self) -> BtfKind {
  120. BtfKind::Ptr
  121. }
  122. pub(crate) fn type_info_size(&self) -> usize {
  123. mem::size_of::<Self>()
  124. }
  125. pub fn new(name_offset: u32, btf_type: u32) -> Self {
  126. let info = (BtfKind::Ptr as u32) << 24;
  127. Self {
  128. name_offset,
  129. info,
  130. btf_type,
  131. }
  132. }
  133. }
  134. #[repr(C)]
  135. #[derive(Clone, Debug)]
  136. pub struct Typedef {
  137. pub(crate) name_offset: u32,
  138. info: u32,
  139. pub(crate) btf_type: u32,
  140. }
  141. impl Typedef {
  142. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  143. bytes_of::<Self>(self).to_vec()
  144. }
  145. pub(crate) fn kind(&self) -> BtfKind {
  146. BtfKind::Typedef
  147. }
  148. pub(crate) fn type_info_size(&self) -> usize {
  149. mem::size_of::<Self>()
  150. }
  151. pub(crate) fn new(name_offset: u32, btf_type: u32) -> Self {
  152. let info = (BtfKind::Typedef as u32) << 24;
  153. Self {
  154. name_offset,
  155. info,
  156. btf_type,
  157. }
  158. }
  159. }
  160. #[repr(C)]
  161. #[derive(Clone, Debug)]
  162. pub struct Float {
  163. pub(crate) name_offset: u32,
  164. info: u32,
  165. pub(crate) size: u32,
  166. }
  167. impl Float {
  168. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  169. bytes_of::<Self>(self).to_vec()
  170. }
  171. pub(crate) fn kind(&self) -> BtfKind {
  172. BtfKind::Float
  173. }
  174. pub(crate) fn type_info_size(&self) -> usize {
  175. mem::size_of::<Self>()
  176. }
  177. pub fn new(name_offset: u32, size: u32) -> Self {
  178. let info = (BtfKind::Float as u32) << 24;
  179. Self {
  180. name_offset,
  181. info,
  182. size,
  183. }
  184. }
  185. }
  186. #[repr(C)]
  187. #[derive(Clone, Debug)]
  188. pub struct Func {
  189. pub(crate) name_offset: u32,
  190. info: u32,
  191. pub(crate) btf_type: u32,
  192. }
  193. #[repr(u32)]
  194. #[derive(Clone, Debug, PartialEq, Eq)]
  195. pub enum FuncLinkage {
  196. Static = 0,
  197. Global = 1,
  198. Extern = 2,
  199. Unknown,
  200. }
  201. impl From<u32> for FuncLinkage {
  202. fn from(v: u32) -> Self {
  203. match v {
  204. 0 => FuncLinkage::Static,
  205. 1 => FuncLinkage::Global,
  206. 2 => FuncLinkage::Extern,
  207. _ => FuncLinkage::Unknown,
  208. }
  209. }
  210. }
  211. impl Func {
  212. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  213. bytes_of::<Self>(self).to_vec()
  214. }
  215. pub(crate) fn kind(&self) -> BtfKind {
  216. BtfKind::Func
  217. }
  218. pub(crate) fn type_info_size(&self) -> usize {
  219. mem::size_of::<Self>()
  220. }
  221. pub fn new(name_offset: u32, proto: u32, linkage: FuncLinkage) -> Self {
  222. let mut info = (BtfKind::Func as u32) << 24;
  223. info |= (linkage as u32) & 0xFFFF;
  224. Self {
  225. name_offset,
  226. info,
  227. btf_type: proto,
  228. }
  229. }
  230. pub(crate) fn linkage(&self) -> FuncLinkage {
  231. (self.info & 0xFFF).into()
  232. }
  233. pub(crate) fn set_linkage(&mut self, linkage: FuncLinkage) {
  234. self.info = (self.info & 0xFFFF0000) | (linkage as u32) & 0xFFFF;
  235. }
  236. }
  237. #[repr(C)]
  238. #[derive(Clone, Debug)]
  239. pub struct TypeTag {
  240. pub(crate) name_offset: u32,
  241. info: u32,
  242. pub(crate) btf_type: u32,
  243. }
  244. impl TypeTag {
  245. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  246. bytes_of::<Self>(self).to_vec()
  247. }
  248. pub(crate) fn kind(&self) -> BtfKind {
  249. BtfKind::TypeTag
  250. }
  251. pub(crate) fn type_info_size(&self) -> usize {
  252. mem::size_of::<Self>()
  253. }
  254. pub fn new(name_offset: u32, btf_type: u32) -> Self {
  255. let info = (BtfKind::TypeTag as u32) << 24;
  256. Self {
  257. name_offset,
  258. info,
  259. btf_type,
  260. }
  261. }
  262. }
  263. #[repr(u32)]
  264. #[derive(Clone, Debug, Eq, PartialEq)]
  265. pub enum IntEncoding {
  266. None,
  267. Signed = 1,
  268. Char = 2,
  269. Bool = 4,
  270. Unknown,
  271. }
  272. impl From<u32> for IntEncoding {
  273. fn from(v: u32) -> Self {
  274. match v {
  275. 0 => IntEncoding::None,
  276. 1 => IntEncoding::Signed,
  277. 2 => IntEncoding::Char,
  278. 4 => IntEncoding::Bool,
  279. _ => IntEncoding::Unknown,
  280. }
  281. }
  282. }
  283. #[repr(C)]
  284. #[derive(Clone, Debug)]
  285. pub struct Int {
  286. pub(crate) name_offset: u32,
  287. info: u32,
  288. pub(crate) size: u32,
  289. pub(crate) data: u32,
  290. }
  291. impl Int {
  292. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  293. let Self {
  294. name_offset,
  295. info,
  296. size,
  297. data,
  298. } = self;
  299. [
  300. bytes_of::<u32>(name_offset),
  301. bytes_of::<u32>(info),
  302. bytes_of::<u32>(size),
  303. bytes_of::<u32>(data),
  304. ]
  305. .concat()
  306. }
  307. pub(crate) fn kind(&self) -> BtfKind {
  308. BtfKind::Int
  309. }
  310. pub(crate) fn type_info_size(&self) -> usize {
  311. mem::size_of::<Self>()
  312. }
  313. pub fn new(name_offset: u32, size: u32, encoding: IntEncoding, offset: u32) -> Self {
  314. let info = (BtfKind::Int as u32) << 24;
  315. let mut data = 0u32;
  316. data |= (encoding as u32 & 0x0f) << 24;
  317. data |= (offset & 0xff) << 16;
  318. data |= (size * 8) & 0xff;
  319. Self {
  320. name_offset,
  321. info,
  322. size,
  323. data,
  324. }
  325. }
  326. pub(crate) fn encoding(&self) -> IntEncoding {
  327. ((self.data & 0x0f000000) >> 24).into()
  328. }
  329. pub(crate) fn offset(&self) -> u32 {
  330. (self.data & 0x00ff0000) >> 16
  331. }
  332. // TODO: Remove directive this when this crate is pub
  333. #[cfg(test)]
  334. pub(crate) fn bits(&self) -> u32 {
  335. self.data & 0x000000ff
  336. }
  337. }
  338. #[repr(C)]
  339. #[derive(Debug, Clone)]
  340. pub struct BtfEnum {
  341. pub name_offset: u32,
  342. pub value: u32,
  343. }
  344. impl BtfEnum {
  345. pub fn new(name_offset: u32, value: u32) -> Self {
  346. Self { name_offset, value }
  347. }
  348. }
  349. #[repr(C)]
  350. #[derive(Clone, Debug)]
  351. pub struct Enum {
  352. pub(crate) name_offset: u32,
  353. info: u32,
  354. pub(crate) size: u32,
  355. pub(crate) variants: Vec<BtfEnum>,
  356. }
  357. impl Enum {
  358. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  359. let Self {
  360. name_offset,
  361. info,
  362. size,
  363. variants,
  364. } = self;
  365. [
  366. bytes_of::<u32>(name_offset),
  367. bytes_of::<u32>(info),
  368. bytes_of::<u32>(size),
  369. ]
  370. .into_iter()
  371. .chain(variants.iter().flat_map(|BtfEnum { name_offset, value }| {
  372. [bytes_of::<u32>(name_offset), bytes_of::<u32>(value)]
  373. }))
  374. .flatten()
  375. .copied()
  376. .collect()
  377. }
  378. pub(crate) fn kind(&self) -> BtfKind {
  379. BtfKind::Enum
  380. }
  381. pub(crate) fn type_info_size(&self) -> usize {
  382. mem::size_of::<Fwd>() + mem::size_of::<BtfEnum>() * self.variants.len()
  383. }
  384. pub fn new(name_offset: u32, signed: bool, variants: Vec<BtfEnum>) -> Self {
  385. let mut info = (BtfKind::Enum as u32) << 24;
  386. info |= (variants.len() as u32) & 0xFFFF;
  387. if signed {
  388. info |= 1 << 31;
  389. }
  390. Self {
  391. name_offset,
  392. info,
  393. size: 4,
  394. variants,
  395. }
  396. }
  397. pub(crate) fn is_signed(&self) -> bool {
  398. self.info >> 31 == 1
  399. }
  400. pub(crate) fn set_signed(&mut self, signed: bool) {
  401. if signed {
  402. self.info |= 1 << 31;
  403. } else {
  404. self.info &= !(1 << 31);
  405. }
  406. }
  407. }
  408. #[repr(C)]
  409. #[derive(Debug, Clone)]
  410. pub struct BtfEnum64 {
  411. pub(crate) name_offset: u32,
  412. pub(crate) value_low: u32,
  413. pub(crate) value_high: u32,
  414. }
  415. impl BtfEnum64 {
  416. pub fn new(name_offset: u32, value: u64) -> Self {
  417. Self {
  418. name_offset,
  419. value_low: value as u32,
  420. value_high: (value >> 32) as u32,
  421. }
  422. }
  423. }
  424. #[repr(C)]
  425. #[derive(Clone, Debug)]
  426. pub struct Enum64 {
  427. pub(crate) name_offset: u32,
  428. info: u32,
  429. pub(crate) size: u32,
  430. pub(crate) variants: Vec<BtfEnum64>,
  431. }
  432. impl Enum64 {
  433. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  434. let Self {
  435. name_offset,
  436. info,
  437. size,
  438. variants,
  439. } = self;
  440. [
  441. bytes_of::<u32>(name_offset),
  442. bytes_of::<u32>(info),
  443. bytes_of::<u32>(size),
  444. ]
  445. .into_iter()
  446. .chain(variants.iter().flat_map(
  447. |BtfEnum64 {
  448. name_offset,
  449. value_low,
  450. value_high,
  451. }| {
  452. [
  453. bytes_of::<u32>(name_offset),
  454. bytes_of::<u32>(value_low),
  455. bytes_of::<u32>(value_high),
  456. ]
  457. },
  458. ))
  459. .flatten()
  460. .copied()
  461. .collect()
  462. }
  463. pub(crate) fn kind(&self) -> BtfKind {
  464. BtfKind::Enum64
  465. }
  466. pub(crate) fn type_info_size(&self) -> usize {
  467. mem::size_of::<Fwd>() + mem::size_of::<BtfEnum64>() * self.variants.len()
  468. }
  469. pub(crate) fn is_signed(&self) -> bool {
  470. self.info >> 31 == 1
  471. }
  472. pub fn new(name_offset: u32, signed: bool, variants: Vec<BtfEnum64>) -> Self {
  473. let mut info = (BtfKind::Enum64 as u32) << 24;
  474. if signed {
  475. info |= 1 << 31
  476. };
  477. info |= (variants.len() as u32) & 0xFFFF;
  478. Enum64 {
  479. name_offset,
  480. info,
  481. // According to the documentation:
  482. //
  483. // https://www.kernel.org/doc/html/next/bpf/btf.html
  484. //
  485. // The size may be 1/2/4/8. Since BtfEnum64::new() takes a u64, we
  486. // can assume that the size is 8.
  487. size: 8,
  488. variants,
  489. }
  490. }
  491. }
  492. #[repr(C)]
  493. #[derive(Clone, Debug)]
  494. pub(crate) struct BtfMember {
  495. pub(crate) name_offset: u32,
  496. pub(crate) btf_type: u32,
  497. pub(crate) offset: u32,
  498. }
  499. #[repr(C)]
  500. #[derive(Clone, Debug)]
  501. pub struct Struct {
  502. pub(crate) name_offset: u32,
  503. info: u32,
  504. pub(crate) size: u32,
  505. pub(crate) members: Vec<BtfMember>,
  506. }
  507. impl Struct {
  508. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  509. let Self {
  510. name_offset,
  511. info,
  512. size,
  513. members,
  514. } = self;
  515. [
  516. bytes_of::<u32>(name_offset),
  517. bytes_of::<u32>(info),
  518. bytes_of::<u32>(size),
  519. ]
  520. .into_iter()
  521. .chain(members.iter().flat_map(
  522. |BtfMember {
  523. name_offset,
  524. btf_type,
  525. offset,
  526. }| {
  527. [
  528. bytes_of::<u32>(name_offset),
  529. bytes_of::<u32>(btf_type),
  530. bytes_of::<u32>(offset),
  531. ]
  532. },
  533. ))
  534. .flatten()
  535. .copied()
  536. .collect()
  537. }
  538. pub(crate) fn kind(&self) -> BtfKind {
  539. BtfKind::Struct
  540. }
  541. pub(crate) fn type_info_size(&self) -> usize {
  542. mem::size_of::<Fwd>() + mem::size_of::<BtfMember>() * self.members.len()
  543. }
  544. pub(crate) fn new(name_offset: u32, members: Vec<BtfMember>, size: u32) -> Self {
  545. let mut info = (BtfKind::Struct as u32) << 24;
  546. info |= (members.len() as u32) & 0xFFFF;
  547. Self {
  548. name_offset,
  549. info,
  550. size,
  551. members,
  552. }
  553. }
  554. pub(crate) fn member_bit_offset(&self, member: &BtfMember) -> usize {
  555. let k_flag = self.info >> 31 == 1;
  556. let bit_offset = if k_flag {
  557. member.offset & 0xFFFFFF
  558. } else {
  559. member.offset
  560. };
  561. bit_offset as usize
  562. }
  563. pub(crate) fn member_bit_field_size(&self, member: &BtfMember) -> usize {
  564. let k_flag = (self.info >> 31) == 1;
  565. let size = if k_flag { member.offset >> 24 } else { 0 };
  566. size as usize
  567. }
  568. }
  569. #[repr(C)]
  570. #[derive(Clone, Debug)]
  571. pub struct Union {
  572. pub(crate) name_offset: u32,
  573. info: u32,
  574. pub(crate) size: u32,
  575. pub(crate) members: Vec<BtfMember>,
  576. }
  577. impl Union {
  578. pub(crate) fn new(name_offset: u32, size: u32, members: Vec<BtfMember>) -> Self {
  579. let mut info = (BtfKind::Union as u32) << 24;
  580. info |= (members.len() as u32) & 0xFFFF;
  581. Self {
  582. name_offset,
  583. info,
  584. size,
  585. members,
  586. }
  587. }
  588. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  589. let Self {
  590. name_offset,
  591. info,
  592. size,
  593. members,
  594. } = self;
  595. [
  596. bytes_of::<u32>(name_offset),
  597. bytes_of::<u32>(info),
  598. bytes_of::<u32>(size),
  599. ]
  600. .into_iter()
  601. .chain(members.iter().flat_map(
  602. |BtfMember {
  603. name_offset,
  604. btf_type,
  605. offset,
  606. }| {
  607. [
  608. bytes_of::<u32>(name_offset),
  609. bytes_of::<u32>(btf_type),
  610. bytes_of::<u32>(offset),
  611. ]
  612. },
  613. ))
  614. .flatten()
  615. .copied()
  616. .collect()
  617. }
  618. pub(crate) fn kind(&self) -> BtfKind {
  619. BtfKind::Union
  620. }
  621. pub(crate) fn type_info_size(&self) -> usize {
  622. mem::size_of::<Fwd>() + mem::size_of::<BtfMember>() * self.members.len()
  623. }
  624. pub(crate) fn member_bit_offset(&self, member: &BtfMember) -> usize {
  625. let k_flag = self.info >> 31 == 1;
  626. let bit_offset = if k_flag {
  627. member.offset & 0xFFFFFF
  628. } else {
  629. member.offset
  630. };
  631. bit_offset as usize
  632. }
  633. pub(crate) fn member_bit_field_size(&self, member: &BtfMember) -> usize {
  634. let k_flag = (self.info >> 31) == 1;
  635. let size = if k_flag { member.offset >> 24 } else { 0 };
  636. size as usize
  637. }
  638. }
  639. #[repr(C)]
  640. #[derive(Clone, Debug)]
  641. pub(crate) struct BtfArray {
  642. pub(crate) element_type: u32,
  643. pub(crate) index_type: u32,
  644. pub(crate) len: u32,
  645. }
  646. #[repr(C)]
  647. #[derive(Clone, Debug)]
  648. pub struct Array {
  649. pub(crate) name_offset: u32,
  650. info: u32,
  651. _unused: u32,
  652. pub(crate) array: BtfArray,
  653. }
  654. impl Array {
  655. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  656. let Self {
  657. name_offset,
  658. info,
  659. _unused,
  660. array,
  661. } = self;
  662. [
  663. bytes_of::<u32>(name_offset),
  664. bytes_of::<u32>(info),
  665. bytes_of::<u32>(_unused),
  666. bytes_of::<BtfArray>(array),
  667. ]
  668. .concat()
  669. }
  670. pub(crate) fn kind(&self) -> BtfKind {
  671. BtfKind::Array
  672. }
  673. pub(crate) fn type_info_size(&self) -> usize {
  674. mem::size_of::<Self>()
  675. }
  676. #[cfg(test)]
  677. pub(crate) fn new(name_offset: u32, element_type: u32, index_type: u32, len: u32) -> Self {
  678. let info = (BtfKind::Array as u32) << 24;
  679. Self {
  680. name_offset,
  681. info,
  682. _unused: 0,
  683. array: BtfArray {
  684. element_type,
  685. index_type,
  686. len,
  687. },
  688. }
  689. }
  690. }
  691. #[repr(C)]
  692. #[derive(Clone, Debug)]
  693. pub struct BtfParam {
  694. pub name_offset: u32,
  695. pub btf_type: u32,
  696. }
  697. #[repr(C)]
  698. #[derive(Clone, Debug)]
  699. pub struct FuncProto {
  700. pub(crate) name_offset: u32,
  701. info: u32,
  702. pub(crate) return_type: u32,
  703. pub(crate) params: Vec<BtfParam>,
  704. }
  705. impl FuncProto {
  706. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  707. let Self {
  708. name_offset,
  709. info,
  710. return_type,
  711. params,
  712. } = self;
  713. [
  714. bytes_of::<u32>(name_offset),
  715. bytes_of::<u32>(info),
  716. bytes_of::<u32>(return_type),
  717. ]
  718. .into_iter()
  719. .chain(params.iter().flat_map(
  720. |BtfParam {
  721. name_offset,
  722. btf_type,
  723. }| { [bytes_of::<u32>(name_offset), bytes_of::<u32>(btf_type)] },
  724. ))
  725. .flatten()
  726. .copied()
  727. .collect()
  728. }
  729. pub(crate) fn kind(&self) -> BtfKind {
  730. BtfKind::FuncProto
  731. }
  732. pub(crate) fn type_info_size(&self) -> usize {
  733. mem::size_of::<Fwd>() + mem::size_of::<BtfParam>() * self.params.len()
  734. }
  735. pub fn new(params: Vec<BtfParam>, return_type: u32) -> Self {
  736. let mut info = (BtfKind::FuncProto as u32) << 24;
  737. info |= (params.len() as u32) & 0xFFFF;
  738. Self {
  739. name_offset: 0,
  740. info,
  741. return_type,
  742. params,
  743. }
  744. }
  745. }
  746. #[repr(u32)]
  747. #[derive(Clone, Debug, PartialEq, Eq)]
  748. pub enum VarLinkage {
  749. Static,
  750. Global,
  751. Extern,
  752. Unknown,
  753. }
  754. impl From<u32> for VarLinkage {
  755. fn from(v: u32) -> Self {
  756. match v {
  757. 0 => VarLinkage::Static,
  758. 1 => VarLinkage::Global,
  759. 2 => VarLinkage::Extern,
  760. _ => VarLinkage::Unknown,
  761. }
  762. }
  763. }
  764. #[repr(C)]
  765. #[derive(Clone, Debug)]
  766. pub struct Var {
  767. pub(crate) name_offset: u32,
  768. info: u32,
  769. pub(crate) btf_type: u32,
  770. pub(crate) linkage: VarLinkage,
  771. }
  772. impl Var {
  773. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  774. let Self {
  775. name_offset,
  776. info,
  777. btf_type,
  778. linkage,
  779. } = self;
  780. [
  781. bytes_of::<u32>(name_offset),
  782. bytes_of::<u32>(info),
  783. bytes_of::<u32>(btf_type),
  784. bytes_of::<VarLinkage>(linkage),
  785. ]
  786. .concat()
  787. }
  788. pub(crate) fn kind(&self) -> BtfKind {
  789. BtfKind::Var
  790. }
  791. pub(crate) fn type_info_size(&self) -> usize {
  792. mem::size_of::<Self>()
  793. }
  794. pub fn new(name_offset: u32, btf_type: u32, linkage: VarLinkage) -> Self {
  795. let info = (BtfKind::Var as u32) << 24;
  796. Self {
  797. name_offset,
  798. info,
  799. btf_type,
  800. linkage,
  801. }
  802. }
  803. }
  804. #[repr(C)]
  805. #[derive(Clone, Debug)]
  806. pub struct DataSecEntry {
  807. pub btf_type: u32,
  808. pub offset: u32,
  809. pub size: u32,
  810. }
  811. #[repr(C)]
  812. #[derive(Clone, Debug)]
  813. pub struct DataSec {
  814. pub(crate) name_offset: u32,
  815. info: u32,
  816. pub(crate) size: u32,
  817. pub(crate) entries: Vec<DataSecEntry>,
  818. }
  819. impl DataSec {
  820. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  821. let Self {
  822. name_offset,
  823. info,
  824. size,
  825. entries,
  826. } = self;
  827. [
  828. bytes_of::<u32>(name_offset),
  829. bytes_of::<u32>(info),
  830. bytes_of::<u32>(size),
  831. ]
  832. .into_iter()
  833. .chain(entries.iter().flat_map(
  834. |DataSecEntry {
  835. btf_type,
  836. offset,
  837. size,
  838. }| {
  839. [
  840. bytes_of::<u32>(btf_type),
  841. bytes_of::<u32>(offset),
  842. bytes_of::<u32>(size),
  843. ]
  844. },
  845. ))
  846. .flatten()
  847. .copied()
  848. .collect()
  849. }
  850. pub(crate) fn kind(&self) -> BtfKind {
  851. BtfKind::DataSec
  852. }
  853. pub(crate) fn type_info_size(&self) -> usize {
  854. mem::size_of::<Fwd>() + mem::size_of::<DataSecEntry>() * self.entries.len()
  855. }
  856. pub fn new(name_offset: u32, entries: Vec<DataSecEntry>, size: u32) -> Self {
  857. let mut info = (BtfKind::DataSec as u32) << 24;
  858. info |= (entries.len() as u32) & 0xFFFF;
  859. Self {
  860. name_offset,
  861. info,
  862. size,
  863. entries,
  864. }
  865. }
  866. }
  867. #[repr(C)]
  868. #[derive(Clone, Debug)]
  869. pub struct DeclTag {
  870. pub(crate) name_offset: u32,
  871. info: u32,
  872. pub(crate) btf_type: u32,
  873. pub(crate) component_index: i32,
  874. }
  875. impl DeclTag {
  876. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  877. let Self {
  878. name_offset,
  879. info,
  880. btf_type,
  881. component_index,
  882. } = self;
  883. [
  884. bytes_of::<u32>(name_offset),
  885. bytes_of::<u32>(info),
  886. bytes_of::<u32>(btf_type),
  887. bytes_of::<i32>(component_index),
  888. ]
  889. .concat()
  890. }
  891. pub(crate) fn kind(&self) -> BtfKind {
  892. BtfKind::DeclTag
  893. }
  894. pub(crate) fn type_info_size(&self) -> usize {
  895. mem::size_of::<Self>()
  896. }
  897. pub fn new(name_offset: u32, btf_type: u32, component_index: i32) -> Self {
  898. let info = (BtfKind::DeclTag as u32) << 24;
  899. Self {
  900. name_offset,
  901. info,
  902. btf_type,
  903. component_index,
  904. }
  905. }
  906. }
  907. #[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
  908. #[repr(u32)]
  909. pub enum BtfKind {
  910. #[default]
  911. Unknown = 0,
  912. Int = 1,
  913. Ptr = 2,
  914. Array = 3,
  915. Struct = 4,
  916. Union = 5,
  917. Enum = 6,
  918. Fwd = 7,
  919. Typedef = 8,
  920. Volatile = 9,
  921. Const = 10,
  922. Restrict = 11,
  923. Func = 12,
  924. FuncProto = 13,
  925. Var = 14,
  926. DataSec = 15,
  927. Float = 16,
  928. DeclTag = 17,
  929. TypeTag = 18,
  930. Enum64 = 19,
  931. }
  932. impl TryFrom<u32> for BtfKind {
  933. type Error = BtfError;
  934. fn try_from(v: u32) -> Result<Self, Self::Error> {
  935. use BtfKind::*;
  936. Ok(match v {
  937. 0 => Unknown,
  938. 1 => Int,
  939. 2 => Ptr,
  940. 3 => Array,
  941. 4 => Struct,
  942. 5 => Union,
  943. 6 => Enum,
  944. 7 => Fwd,
  945. 8 => Typedef,
  946. 9 => Volatile,
  947. 10 => Const,
  948. 11 => Restrict,
  949. 12 => Func,
  950. 13 => FuncProto,
  951. 14 => Var,
  952. 15 => DataSec,
  953. 16 => Float,
  954. 17 => DeclTag,
  955. 18 => TypeTag,
  956. 19 => Enum64,
  957. kind => return Err(BtfError::InvalidTypeKind { kind }),
  958. })
  959. }
  960. }
  961. impl Display for BtfKind {
  962. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  963. match self {
  964. BtfKind::Unknown => write!(f, "[UNKNOWN]"),
  965. BtfKind::Int => write!(f, "[INT]"),
  966. BtfKind::Float => write!(f, "[FLOAT]"),
  967. BtfKind::Ptr => write!(f, "[PTR]"),
  968. BtfKind::Array => write!(f, "[ARRAY]"),
  969. BtfKind::Struct => write!(f, "[STRUCT]"),
  970. BtfKind::Union => write!(f, "[UNION]"),
  971. BtfKind::Enum => write!(f, "[ENUM]"),
  972. BtfKind::Fwd => write!(f, "[FWD]"),
  973. BtfKind::Typedef => write!(f, "[TYPEDEF]"),
  974. BtfKind::Volatile => write!(f, "[VOLATILE]"),
  975. BtfKind::Const => write!(f, "[CONST]"),
  976. BtfKind::Restrict => write!(f, "[RESTRICT]"),
  977. BtfKind::Func => write!(f, "[FUNC]"),
  978. BtfKind::FuncProto => write!(f, "[FUNC_PROTO]"),
  979. BtfKind::Var => write!(f, "[VAR]"),
  980. BtfKind::DataSec => write!(f, "[DATASEC]"),
  981. BtfKind::DeclTag => write!(f, "[DECL_TAG]"),
  982. BtfKind::TypeTag => write!(f, "[TYPE_TAG]"),
  983. BtfKind::Enum64 => write!(f, "[ENUM64]"),
  984. }
  985. }
  986. }
  987. unsafe fn read<T>(data: &[u8]) -> Result<T, BtfError> {
  988. if mem::size_of::<T>() > data.len() {
  989. return Err(BtfError::InvalidTypeInfo);
  990. }
  991. Ok(ptr::read_unaligned::<T>(data.as_ptr() as *const T))
  992. }
  993. unsafe fn read_array<T>(data: &[u8], len: usize) -> Result<Vec<T>, BtfError> {
  994. if mem::size_of::<T>() * len > data.len() {
  995. return Err(BtfError::InvalidTypeInfo);
  996. }
  997. let data = &data[0..mem::size_of::<T>() * len];
  998. let r = data
  999. .chunks(mem::size_of::<T>())
  1000. .map(|chunk| ptr::read_unaligned(chunk.as_ptr() as *const T))
  1001. .collect();
  1002. Ok(r)
  1003. }
  1004. impl BtfType {
  1005. #[allow(unused_unsafe)]
  1006. pub(crate) unsafe fn read(data: &[u8], endianness: Endianness) -> Result<BtfType, BtfError> {
  1007. let ty = unsafe { read_array::<u32>(data, 3)? };
  1008. let data = &data[mem::size_of::<u32>() * 3..];
  1009. let vlen = type_vlen(ty[1]);
  1010. Ok(match type_kind(ty[1])? {
  1011. BtfKind::Unknown => BtfType::Unknown,
  1012. BtfKind::Fwd => BtfType::Fwd(Fwd {
  1013. name_offset: ty[0],
  1014. info: ty[1],
  1015. _unused: 0,
  1016. }),
  1017. BtfKind::Const => BtfType::Const(Const {
  1018. name_offset: ty[0],
  1019. info: ty[1],
  1020. btf_type: ty[2],
  1021. }),
  1022. BtfKind::Volatile => BtfType::Volatile(Volatile {
  1023. name_offset: ty[0],
  1024. info: ty[1],
  1025. btf_type: ty[2],
  1026. }),
  1027. BtfKind::Restrict => BtfType::Restrict(Restrict {
  1028. name_offset: ty[0],
  1029. _info: ty[1],
  1030. btf_type: ty[2],
  1031. }),
  1032. BtfKind::Ptr => BtfType::Ptr(Ptr {
  1033. name_offset: ty[0],
  1034. info: ty[1],
  1035. btf_type: ty[2],
  1036. }),
  1037. BtfKind::Typedef => BtfType::Typedef(Typedef {
  1038. name_offset: ty[0],
  1039. info: ty[1],
  1040. btf_type: ty[2],
  1041. }),
  1042. BtfKind::Func => BtfType::Func(Func {
  1043. name_offset: ty[0],
  1044. info: ty[1],
  1045. btf_type: ty[2],
  1046. }),
  1047. BtfKind::Int => {
  1048. if mem::size_of::<u32>() > data.len() {
  1049. return Err(BtfError::InvalidTypeInfo);
  1050. }
  1051. let read_u32 = if endianness == Endianness::Little {
  1052. u32::from_le_bytes
  1053. } else {
  1054. u32::from_be_bytes
  1055. };
  1056. BtfType::Int(Int {
  1057. name_offset: ty[0],
  1058. info: ty[1],
  1059. size: ty[2],
  1060. data: read_u32(data[..mem::size_of::<u32>()].try_into().unwrap()),
  1061. })
  1062. }
  1063. BtfKind::Float => BtfType::Float(Float {
  1064. name_offset: ty[0],
  1065. info: ty[1],
  1066. size: ty[2],
  1067. }),
  1068. BtfKind::Enum => BtfType::Enum(Enum {
  1069. name_offset: ty[0],
  1070. info: ty[1],
  1071. size: ty[2],
  1072. variants: unsafe { read_array::<BtfEnum>(data, vlen)? },
  1073. }),
  1074. BtfKind::Enum64 => BtfType::Enum64(Enum64 {
  1075. name_offset: ty[0],
  1076. info: ty[1],
  1077. size: ty[2],
  1078. variants: unsafe { read_array::<BtfEnum64>(data, vlen)? },
  1079. }),
  1080. BtfKind::Array => BtfType::Array(Array {
  1081. name_offset: ty[0],
  1082. info: ty[1],
  1083. _unused: 0,
  1084. array: unsafe { read(data)? },
  1085. }),
  1086. BtfKind::Struct => BtfType::Struct(Struct {
  1087. name_offset: ty[0],
  1088. info: ty[1],
  1089. size: ty[2],
  1090. members: unsafe { read_array::<BtfMember>(data, vlen)? },
  1091. }),
  1092. BtfKind::Union => BtfType::Union(Union {
  1093. name_offset: ty[0],
  1094. info: ty[1],
  1095. size: ty[2],
  1096. members: unsafe { read_array::<BtfMember>(data, vlen)? },
  1097. }),
  1098. BtfKind::FuncProto => BtfType::FuncProto(FuncProto {
  1099. name_offset: ty[0],
  1100. info: ty[1],
  1101. return_type: ty[2],
  1102. params: unsafe { read_array::<BtfParam>(data, vlen)? },
  1103. }),
  1104. BtfKind::Var => BtfType::Var(Var {
  1105. name_offset: ty[0],
  1106. info: ty[1],
  1107. btf_type: ty[2],
  1108. linkage: unsafe { read(data)? },
  1109. }),
  1110. BtfKind::DataSec => BtfType::DataSec(DataSec {
  1111. name_offset: ty[0],
  1112. info: ty[1],
  1113. size: ty[2],
  1114. entries: unsafe { read_array::<DataSecEntry>(data, vlen)? },
  1115. }),
  1116. BtfKind::DeclTag => BtfType::DeclTag(DeclTag {
  1117. name_offset: ty[0],
  1118. info: ty[1],
  1119. btf_type: ty[2],
  1120. component_index: unsafe { read(data)? },
  1121. }),
  1122. BtfKind::TypeTag => BtfType::TypeTag(TypeTag {
  1123. name_offset: ty[0],
  1124. info: ty[1],
  1125. btf_type: ty[2],
  1126. }),
  1127. })
  1128. }
  1129. pub(crate) fn to_bytes(&self) -> Vec<u8> {
  1130. match self {
  1131. BtfType::Unknown => vec![],
  1132. BtfType::Fwd(t) => t.to_bytes(),
  1133. BtfType::Const(t) => t.to_bytes(),
  1134. BtfType::Volatile(t) => t.to_bytes(),
  1135. BtfType::Restrict(t) => t.to_bytes(),
  1136. BtfType::Ptr(t) => t.to_bytes(),
  1137. BtfType::Typedef(t) => t.to_bytes(),
  1138. BtfType::Func(t) => t.to_bytes(),
  1139. BtfType::Int(t) => t.to_bytes(),
  1140. BtfType::Float(t) => t.to_bytes(),
  1141. BtfType::Enum(t) => t.to_bytes(),
  1142. BtfType::Enum64(t) => t.to_bytes(),
  1143. BtfType::Array(t) => t.to_bytes(),
  1144. BtfType::Struct(t) => t.to_bytes(),
  1145. BtfType::Union(t) => t.to_bytes(),
  1146. BtfType::FuncProto(t) => t.to_bytes(),
  1147. BtfType::Var(t) => t.to_bytes(),
  1148. BtfType::DataSec(t) => t.to_bytes(),
  1149. BtfType::DeclTag(t) => t.to_bytes(),
  1150. BtfType::TypeTag(t) => t.to_bytes(),
  1151. }
  1152. }
  1153. pub(crate) fn size(&self) -> Option<u32> {
  1154. match self {
  1155. BtfType::Int(t) => Some(t.size),
  1156. BtfType::Float(t) => Some(t.size),
  1157. BtfType::Enum(t) => Some(t.size),
  1158. BtfType::Enum64(t) => Some(t.size),
  1159. BtfType::Struct(t) => Some(t.size),
  1160. BtfType::Union(t) => Some(t.size),
  1161. BtfType::DataSec(t) => Some(t.size),
  1162. BtfType::Ptr(_) => Some(mem::size_of::<&()>() as u32),
  1163. _ => None,
  1164. }
  1165. }
  1166. pub(crate) fn btf_type(&self) -> Option<u32> {
  1167. match self {
  1168. BtfType::Const(t) => Some(t.btf_type),
  1169. BtfType::Volatile(t) => Some(t.btf_type),
  1170. BtfType::Restrict(t) => Some(t.btf_type),
  1171. BtfType::Ptr(t) => Some(t.btf_type),
  1172. BtfType::Typedef(t) => Some(t.btf_type),
  1173. // FuncProto contains the return type here, and doesn't directly reference another type
  1174. BtfType::FuncProto(t) => Some(t.return_type),
  1175. BtfType::Var(t) => Some(t.btf_type),
  1176. BtfType::DeclTag(t) => Some(t.btf_type),
  1177. BtfType::TypeTag(t) => Some(t.btf_type),
  1178. _ => None,
  1179. }
  1180. }
  1181. pub(crate) fn type_info_size(&self) -> usize {
  1182. match self {
  1183. BtfType::Unknown => mem::size_of::<Fwd>(),
  1184. BtfType::Fwd(t) => t.type_info_size(),
  1185. BtfType::Const(t) => t.type_info_size(),
  1186. BtfType::Volatile(t) => t.type_info_size(),
  1187. BtfType::Restrict(t) => t.type_info_size(),
  1188. BtfType::Ptr(t) => t.type_info_size(),
  1189. BtfType::Typedef(t) => t.type_info_size(),
  1190. BtfType::Func(t) => t.type_info_size(),
  1191. BtfType::Int(t) => t.type_info_size(),
  1192. BtfType::Float(t) => t.type_info_size(),
  1193. BtfType::Enum(t) => t.type_info_size(),
  1194. BtfType::Enum64(t) => t.type_info_size(),
  1195. BtfType::Array(t) => t.type_info_size(),
  1196. BtfType::Struct(t) => t.type_info_size(),
  1197. BtfType::Union(t) => t.type_info_size(),
  1198. BtfType::FuncProto(t) => t.type_info_size(),
  1199. BtfType::Var(t) => t.type_info_size(),
  1200. BtfType::DataSec(t) => t.type_info_size(),
  1201. BtfType::DeclTag(t) => t.type_info_size(),
  1202. BtfType::TypeTag(t) => t.type_info_size(),
  1203. }
  1204. }
  1205. pub(crate) fn name_offset(&self) -> u32 {
  1206. match self {
  1207. BtfType::Unknown => 0,
  1208. BtfType::Fwd(t) => t.name_offset,
  1209. BtfType::Const(t) => t.name_offset,
  1210. BtfType::Volatile(t) => t.name_offset,
  1211. BtfType::Restrict(t) => t.name_offset,
  1212. BtfType::Ptr(t) => t.name_offset,
  1213. BtfType::Typedef(t) => t.name_offset,
  1214. BtfType::Func(t) => t.name_offset,
  1215. BtfType::Int(t) => t.name_offset,
  1216. BtfType::Float(t) => t.name_offset,
  1217. BtfType::Enum(t) => t.name_offset,
  1218. BtfType::Enum64(t) => t.name_offset,
  1219. BtfType::Array(t) => t.name_offset,
  1220. BtfType::Struct(t) => t.name_offset,
  1221. BtfType::Union(t) => t.name_offset,
  1222. BtfType::FuncProto(t) => t.name_offset,
  1223. BtfType::Var(t) => t.name_offset,
  1224. BtfType::DataSec(t) => t.name_offset,
  1225. BtfType::DeclTag(t) => t.name_offset,
  1226. BtfType::TypeTag(t) => t.name_offset,
  1227. }
  1228. }
  1229. pub(crate) fn kind(&self) -> BtfKind {
  1230. match self {
  1231. BtfType::Unknown => BtfKind::Unknown,
  1232. BtfType::Fwd(t) => t.kind(),
  1233. BtfType::Const(t) => t.kind(),
  1234. BtfType::Volatile(t) => t.kind(),
  1235. BtfType::Restrict(t) => t.kind(),
  1236. BtfType::Ptr(t) => t.kind(),
  1237. BtfType::Typedef(t) => t.kind(),
  1238. BtfType::Func(t) => t.kind(),
  1239. BtfType::Int(t) => t.kind(),
  1240. BtfType::Float(t) => t.kind(),
  1241. BtfType::Enum(t) => t.kind(),
  1242. BtfType::Enum64(t) => t.kind(),
  1243. BtfType::Array(t) => t.kind(),
  1244. BtfType::Struct(t) => t.kind(),
  1245. BtfType::Union(t) => t.kind(),
  1246. BtfType::FuncProto(t) => t.kind(),
  1247. BtfType::Var(t) => t.kind(),
  1248. BtfType::DataSec(t) => t.kind(),
  1249. BtfType::DeclTag(t) => t.kind(),
  1250. BtfType::TypeTag(t) => t.kind(),
  1251. }
  1252. }
  1253. pub(crate) fn is_composite(&self) -> bool {
  1254. matches!(self, BtfType::Struct(_) | BtfType::Union(_))
  1255. }
  1256. pub(crate) fn members(&self) -> Option<impl Iterator<Item = &BtfMember>> {
  1257. match self {
  1258. BtfType::Struct(t) => Some(t.members.iter()),
  1259. BtfType::Union(t) => Some(t.members.iter()),
  1260. _ => None,
  1261. }
  1262. }
  1263. pub(crate) fn member_bit_field_size(&self, member: &BtfMember) -> Option<usize> {
  1264. match self {
  1265. BtfType::Struct(t) => Some(t.member_bit_field_size(member)),
  1266. BtfType::Union(t) => Some(t.member_bit_field_size(member)),
  1267. _ => None,
  1268. }
  1269. }
  1270. pub(crate) fn member_bit_offset(&self, member: &BtfMember) -> Option<usize> {
  1271. match self {
  1272. BtfType::Struct(t) => Some(t.member_bit_offset(member)),
  1273. BtfType::Union(t) => Some(t.member_bit_offset(member)),
  1274. _ => None,
  1275. }
  1276. }
  1277. pub(crate) fn is_compatible(&self, other: &BtfType) -> bool {
  1278. if self.kind() == other.kind() {
  1279. return true;
  1280. }
  1281. matches!(
  1282. (self.kind(), other.kind()),
  1283. (BtfKind::Enum, BtfKind::Enum64) | (BtfKind::Enum64, BtfKind::Enum)
  1284. )
  1285. }
  1286. }
  1287. fn type_kind(info: u32) -> Result<BtfKind, BtfError> {
  1288. ((info >> 24) & 0x1F).try_into()
  1289. }
  1290. fn type_vlen(info: u32) -> usize {
  1291. (info & 0xFFFF) as usize
  1292. }
  1293. pub(crate) fn types_are_compatible(
  1294. local_btf: &Btf,
  1295. root_local_id: u32,
  1296. target_btf: &Btf,
  1297. root_target_id: u32,
  1298. ) -> Result<bool, BtfError> {
  1299. let mut local_id = root_local_id;
  1300. let mut target_id = root_target_id;
  1301. let local_ty = local_btf.type_by_id(local_id)?;
  1302. let target_ty = target_btf.type_by_id(target_id)?;
  1303. if !local_ty.is_compatible(target_ty) {
  1304. return Ok(false);
  1305. }
  1306. for () in core::iter::repeat_n((), MAX_RESOLVE_DEPTH) {
  1307. local_id = local_btf.resolve_type(local_id)?;
  1308. target_id = target_btf.resolve_type(target_id)?;
  1309. let local_ty = local_btf.type_by_id(local_id)?;
  1310. let target_ty = target_btf.type_by_id(target_id)?;
  1311. if !local_ty.is_compatible(target_ty) {
  1312. return Ok(false);
  1313. }
  1314. match local_ty {
  1315. BtfType::Unknown
  1316. | BtfType::Struct(_)
  1317. | BtfType::Union(_)
  1318. | BtfType::Enum(_)
  1319. | BtfType::Enum64(_)
  1320. | BtfType::Fwd(_)
  1321. | BtfType::Float(_) => return Ok(true),
  1322. BtfType::Int(local) => {
  1323. if let BtfType::Int(target) = target_ty {
  1324. return Ok(local.offset() == 0 && target.offset() == 0);
  1325. }
  1326. }
  1327. BtfType::Ptr(local) => {
  1328. if let BtfType::Ptr(target) = target_ty {
  1329. local_id = local.btf_type;
  1330. target_id = target.btf_type;
  1331. continue;
  1332. }
  1333. }
  1334. BtfType::Array(Array { array: local, .. }) => {
  1335. if let BtfType::Array(Array { array: target, .. }) = target_ty {
  1336. local_id = local.element_type;
  1337. target_id = target.element_type;
  1338. continue;
  1339. }
  1340. }
  1341. BtfType::FuncProto(local) => {
  1342. if let BtfType::FuncProto(target) = target_ty {
  1343. if local.params.len() != target.params.len() {
  1344. return Ok(false);
  1345. }
  1346. for (l_param, t_param) in local.params.iter().zip(target.params.iter()) {
  1347. let local_id = local_btf.resolve_type(l_param.btf_type)?;
  1348. let target_id = target_btf.resolve_type(t_param.btf_type)?;
  1349. if !types_are_compatible(local_btf, local_id, target_btf, target_id)? {
  1350. return Ok(false);
  1351. }
  1352. }
  1353. local_id = local.return_type;
  1354. target_id = target.return_type;
  1355. continue;
  1356. }
  1357. }
  1358. local_ty => panic!("unexpected type {:?}", local_ty),
  1359. }
  1360. }
  1361. Err(BtfError::MaximumTypeDepthReached { type_id: local_id })
  1362. }
  1363. pub(crate) fn fields_are_compatible(
  1364. local_btf: &Btf,
  1365. mut local_id: u32,
  1366. target_btf: &Btf,
  1367. mut target_id: u32,
  1368. ) -> Result<bool, BtfError> {
  1369. for () in core::iter::repeat_n((), MAX_RESOLVE_DEPTH) {
  1370. local_id = local_btf.resolve_type(local_id)?;
  1371. target_id = target_btf.resolve_type(target_id)?;
  1372. let local_ty = local_btf.type_by_id(local_id)?;
  1373. let target_ty = target_btf.type_by_id(target_id)?;
  1374. if local_ty.is_composite() && target_ty.is_composite() {
  1375. return Ok(true);
  1376. }
  1377. if !local_ty.is_compatible(target_ty) {
  1378. return Ok(false);
  1379. }
  1380. match local_ty {
  1381. BtfType::Fwd(_) | BtfType::Enum(_) | BtfType::Enum64(_) => {
  1382. let flavorless_name =
  1383. |name: &str| name.split_once("___").map_or(name, |x| x.0).to_string();
  1384. let local_name = flavorless_name(&local_btf.type_name(local_ty)?);
  1385. let target_name = flavorless_name(&target_btf.type_name(target_ty)?);
  1386. return Ok(local_name == target_name);
  1387. }
  1388. BtfType::Int(local) => {
  1389. if let BtfType::Int(target) = target_ty {
  1390. return Ok(local.offset() == 0 && target.offset() == 0);
  1391. }
  1392. }
  1393. BtfType::Float(_) => return Ok(true),
  1394. BtfType::Ptr(_) => return Ok(true),
  1395. BtfType::Array(Array { array: local, .. }) => {
  1396. if let BtfType::Array(Array { array: target, .. }) = target_ty {
  1397. local_id = local.element_type;
  1398. target_id = target.element_type;
  1399. continue;
  1400. }
  1401. }
  1402. local_ty => panic!("unexpected type {:?}", local_ty),
  1403. }
  1404. }
  1405. Err(BtfError::MaximumTypeDepthReached { type_id: local_id })
  1406. }
  1407. fn bytes_of<T>(val: &T) -> &[u8] {
  1408. // Safety: all btf types are POD
  1409. unsafe { crate::util::bytes_of(val) }
  1410. }
  1411. #[cfg(test)]
  1412. mod tests {
  1413. use assert_matches::assert_matches;
  1414. use super::*;
  1415. #[test]
  1416. fn test_read_btf_type_int() {
  1417. let endianness = Endianness::default();
  1418. let bpf_type = BtfType::Int(Int::new(1, 8, IntEncoding::None, 0));
  1419. let data: &[u8] = &bpf_type.to_bytes();
  1420. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Int(new @ Int {
  1421. name_offset,
  1422. info: _,
  1423. size,
  1424. data: _,
  1425. }) => {
  1426. assert_eq!(name_offset, 1);
  1427. assert_eq!(size, 8);
  1428. assert_eq!(new.bits(), 64);
  1429. assert_eq!(new.to_bytes(), data);
  1430. });
  1431. }
  1432. #[test]
  1433. fn test_read_btf_type_ptr() {
  1434. let endianness = Endianness::default();
  1435. let bpf_type = BtfType::Ptr(Ptr::new(0, 0x06));
  1436. let data: &[u8] = &bpf_type.to_bytes();
  1437. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Ptr(got) => {
  1438. assert_eq!(got.to_bytes(), data);
  1439. });
  1440. }
  1441. #[test]
  1442. fn test_read_btf_type_array() {
  1443. let endianness = Endianness::default();
  1444. let bpf_type = BtfType::Array(Array::new(0, 1, 0x12, 2));
  1445. let data: &[u8] = &bpf_type.to_bytes();
  1446. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Array(got) => {
  1447. assert_eq!(got.to_bytes(), data);
  1448. });
  1449. }
  1450. #[test]
  1451. fn test_read_btf_type_struct() {
  1452. let endianness = Endianness::default();
  1453. let members = vec![BtfMember {
  1454. name_offset: 0x0247,
  1455. btf_type: 0x12,
  1456. offset: 0,
  1457. }];
  1458. let bpf_type = BtfType::Struct(Struct::new(0, members, 4));
  1459. let data: &[u8] = &bpf_type.to_bytes();
  1460. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Struct(got) => {
  1461. assert_eq!(got.to_bytes(), data);
  1462. });
  1463. }
  1464. #[test]
  1465. fn test_read_btf_type_union() {
  1466. let endianness = Endianness::default();
  1467. let members = vec![BtfMember {
  1468. name_offset: 0x040d,
  1469. btf_type: 0x68,
  1470. offset: 0,
  1471. }];
  1472. let bpf_type = BtfType::Union(Union::new(0, 4, members));
  1473. let data: &[u8] = &bpf_type.to_bytes();
  1474. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Union(got) => {
  1475. assert_eq!(got.to_bytes(), data);
  1476. });
  1477. }
  1478. #[test]
  1479. fn test_read_btf_type_enum() {
  1480. let endianness = Endianness::default();
  1481. let enum1 = BtfEnum::new(0xc9, 0);
  1482. let enum2 = BtfEnum::new(0xcf, 1);
  1483. let variants = vec![enum1, enum2];
  1484. let bpf_type = BtfType::Enum(Enum::new(0, false, variants));
  1485. let data: &[u8] = &bpf_type.to_bytes();
  1486. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Enum(got) => {
  1487. assert_eq!(got.to_bytes(), data);
  1488. });
  1489. }
  1490. #[test]
  1491. fn test_read_btf_type_fwd() {
  1492. let endianness = Endianness::default();
  1493. let info = (BtfKind::Fwd as u32) << 24;
  1494. let bpf_type = BtfType::Fwd(Fwd {
  1495. name_offset: 0x550b,
  1496. info,
  1497. _unused: 0,
  1498. });
  1499. let data: &[u8] = &bpf_type.to_bytes();
  1500. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Fwd(got) => {
  1501. assert_eq!(got.to_bytes(), data);
  1502. });
  1503. }
  1504. #[test]
  1505. fn test_read_btf_type_typedef() {
  1506. let endianness = Endianness::default();
  1507. let bpf_type = BtfType::Typedef(Typedef::new(0x31, 0x0b));
  1508. let data: &[u8] = &bpf_type.to_bytes();
  1509. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Typedef(got) => {
  1510. assert_eq!(got.to_bytes(), data);
  1511. });
  1512. }
  1513. #[test]
  1514. fn test_read_btf_type_volatile() {
  1515. let endianness = Endianness::default();
  1516. let info = (BtfKind::Volatile as u32) << 24;
  1517. let bpf_type = BtfType::Volatile(Volatile {
  1518. name_offset: 0,
  1519. info,
  1520. btf_type: 0x24,
  1521. });
  1522. let data: &[u8] = &bpf_type.to_bytes();
  1523. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Volatile(got) => {
  1524. assert_eq!(got.to_bytes(), data);
  1525. });
  1526. }
  1527. #[test]
  1528. fn test_read_btf_type_const() {
  1529. let endianness = Endianness::default();
  1530. let bpf_type = BtfType::Const(Const::new(1));
  1531. let data: &[u8] = &bpf_type.to_bytes();
  1532. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Const(got) => {
  1533. assert_eq!(got.to_bytes(), data);
  1534. });
  1535. }
  1536. #[test]
  1537. fn test_read_btf_type_restrict() {
  1538. let endianness = Endianness::default();
  1539. let info = (BtfKind::Restrict as u32) << 24;
  1540. let bpf_type = BtfType::Restrict(Restrict {
  1541. name_offset: 0,
  1542. _info: info,
  1543. btf_type: 4,
  1544. });
  1545. let data: &[u8] = &bpf_type.to_bytes();
  1546. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Restrict(got) => {
  1547. assert_eq!(got.to_bytes(), data);
  1548. });
  1549. }
  1550. #[test]
  1551. fn test_read_btf_type_func() {
  1552. let endianness = Endianness::default();
  1553. let bpf_type = BtfType::Func(Func::new(0x000f8b17, 0xe4f0, FuncLinkage::Global));
  1554. let data: &[u8] = &bpf_type.to_bytes();
  1555. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Func(got) => {
  1556. assert_eq!(got.to_bytes(), data);
  1557. });
  1558. }
  1559. #[test]
  1560. fn test_read_btf_type_func_proto() {
  1561. let endianness = Endianness::default();
  1562. let params = vec![BtfParam {
  1563. name_offset: 0,
  1564. btf_type: 0x12,
  1565. }];
  1566. let bpf_type = BtfType::FuncProto(FuncProto::new(params, 0));
  1567. let data: &[u8] = &bpf_type.to_bytes();
  1568. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::FuncProto(got) => {
  1569. assert_eq!(got.to_bytes(), data);
  1570. });
  1571. }
  1572. #[test]
  1573. fn test_read_btf_type_func_var() {
  1574. let endianness = Endianness::default();
  1575. // NOTE: There was no data in /sys/kernell/btf/vmlinux for this type
  1576. let bpf_type = BtfType::Var(Var::new(0, 0xf0, VarLinkage::Static));
  1577. let data: &[u8] = &bpf_type.to_bytes();
  1578. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Var(got) => {
  1579. assert_eq!(got.to_bytes(), data);
  1580. });
  1581. }
  1582. #[test]
  1583. fn test_read_btf_type_func_datasec() {
  1584. let endianness = Endianness::default();
  1585. let entries = vec![DataSecEntry {
  1586. btf_type: 11,
  1587. offset: 0,
  1588. size: 4,
  1589. }];
  1590. let bpf_type = BtfType::DataSec(DataSec::new(0xd9, entries, 0));
  1591. let data: &[u8] = &bpf_type.to_bytes();
  1592. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::DataSec(DataSec {
  1593. name_offset: _,
  1594. info: _,
  1595. size,
  1596. entries,
  1597. }) => {
  1598. assert_eq!(size, 0);
  1599. assert_matches!(*entries, [
  1600. DataSecEntry {
  1601. btf_type: 11,
  1602. offset: 0,
  1603. size: 4,
  1604. }
  1605. ]);
  1606. }
  1607. );
  1608. }
  1609. #[test]
  1610. fn test_read_btf_type_float() {
  1611. let endianness = Endianness::default();
  1612. let bpf_type = BtfType::Float(Float::new(0x02fd, 8));
  1613. let data: &[u8] = &bpf_type.to_bytes();
  1614. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Float(got) => {
  1615. assert_eq!(got.to_bytes(), data);
  1616. });
  1617. }
  1618. #[test]
  1619. fn test_write_btf_func_proto() {
  1620. let params = vec![
  1621. BtfParam {
  1622. name_offset: 1,
  1623. btf_type: 1,
  1624. },
  1625. BtfParam {
  1626. name_offset: 3,
  1627. btf_type: 1,
  1628. },
  1629. ];
  1630. let func_proto = FuncProto::new(params, 2);
  1631. let data = func_proto.to_bytes();
  1632. assert_matches!(unsafe { BtfType::read(&data, Endianness::default()) }.unwrap(), BtfType::FuncProto(FuncProto {
  1633. name_offset: _,
  1634. info: _,
  1635. return_type: _,
  1636. params,
  1637. }) => {
  1638. assert_matches!(*params, [
  1639. _,
  1640. _,
  1641. ])
  1642. });
  1643. }
  1644. #[test]
  1645. fn test_types_are_compatible() {
  1646. let mut btf = Btf::new();
  1647. let name_offset = btf.add_string("u32");
  1648. let u32t = btf.add_type(BtfType::Int(Int::new(name_offset, 4, IntEncoding::None, 0)));
  1649. let name_offset = btf.add_string("u64");
  1650. let u64t = btf.add_type(BtfType::Int(Int::new(name_offset, 8, IntEncoding::None, 0)));
  1651. let name_offset = btf.add_string("widgets");
  1652. let array_type = btf.add_type(BtfType::Array(Array::new(name_offset, u64t, u32t, 16)));
  1653. assert!(types_are_compatible(&btf, u32t, &btf, u32t).unwrap());
  1654. // int types are compatible if offsets match. size and encoding aren't compared
  1655. assert!(types_are_compatible(&btf, u32t, &btf, u64t).unwrap());
  1656. assert!(types_are_compatible(&btf, array_type, &btf, array_type).unwrap());
  1657. }
  1658. #[test]
  1659. pub fn test_read_btf_type_enum64() {
  1660. let endianness = Endianness::default();
  1661. let variants = vec![BtfEnum64::new(0, 0xbbbbbbbbaaaaaaaau64)];
  1662. let bpf_type = BtfType::Enum64(Enum64::new(0, false, variants));
  1663. let data: &[u8] = &bpf_type.to_bytes();
  1664. assert_matches!(unsafe { BtfType::read(data, endianness) }.unwrap(), BtfType::Enum64(got) => {
  1665. assert_eq!(got.to_bytes(), data);
  1666. });
  1667. }
  1668. }