types.rs 48 KB

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