test_btf.c 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /* Copyright (c) 2018 Facebook */
  3. #include <linux/bpf.h>
  4. #include <linux/btf.h>
  5. #include <linux/err.h>
  6. #include <bpf/bpf.h>
  7. #include <sys/resource.h>
  8. #include <libelf.h>
  9. #include <gelf.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <stdarg.h>
  14. #include <unistd.h>
  15. #include <fcntl.h>
  16. #include <errno.h>
  17. #include <bpf/libbpf.h>
  18. #include <bpf/btf.h>
  19. #include "bpf_rlimit.h"
  20. static uint32_t pass_cnt;
  21. static uint32_t error_cnt;
  22. static uint32_t skip_cnt;
  23. #define CHECK(condition, format...) ({ \
  24. int __ret = !!(condition); \
  25. if (__ret) { \
  26. fprintf(stderr, "%s:%d:FAIL ", __func__, __LINE__); \
  27. fprintf(stderr, format); \
  28. } \
  29. __ret; \
  30. })
  31. static int count_result(int err)
  32. {
  33. if (err)
  34. error_cnt++;
  35. else
  36. pass_cnt++;
  37. fprintf(stderr, "\n");
  38. return err;
  39. }
  40. #define min(a, b) ((a) < (b) ? (a) : (b))
  41. #define __printf(a, b) __attribute__((format(printf, a, b)))
  42. __printf(1, 2)
  43. static int __base_pr(const char *format, ...)
  44. {
  45. va_list args;
  46. int err;
  47. va_start(args, format);
  48. err = vfprintf(stderr, format, args);
  49. va_end(args);
  50. return err;
  51. }
  52. #define BTF_INFO_ENC(kind, root, vlen) \
  53. ((!!(root) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
  54. #define BTF_TYPE_ENC(name, info, size_or_type) \
  55. (name), (info), (size_or_type)
  56. #define BTF_INT_ENC(encoding, bits_offset, nr_bits) \
  57. ((encoding) << 24 | (bits_offset) << 16 | (nr_bits))
  58. #define BTF_TYPE_INT_ENC(name, encoding, bits_offset, bits, sz) \
  59. BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), sz), \
  60. BTF_INT_ENC(encoding, bits_offset, bits)
  61. #define BTF_ARRAY_ENC(type, index_type, nr_elems) \
  62. (type), (index_type), (nr_elems)
  63. #define BTF_TYPE_ARRAY_ENC(type, index_type, nr_elems) \
  64. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 0), \
  65. BTF_ARRAY_ENC(type, index_type, nr_elems)
  66. #define BTF_MEMBER_ENC(name, type, bits_offset) \
  67. (name), (type), (bits_offset)
  68. #define BTF_ENUM_ENC(name, val) (name), (val)
  69. #define BTF_TYPEDEF_ENC(name, type) \
  70. BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), type)
  71. #define BTF_PTR_ENC(name, type) \
  72. BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), type)
  73. #define BTF_END_RAW 0xdeadbeef
  74. #define NAME_TBD 0xdeadb33f
  75. #define MAX_NR_RAW_TYPES 1024
  76. #define BTF_LOG_BUF_SIZE 65535
  77. #ifndef ARRAY_SIZE
  78. # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
  79. #endif
  80. static struct args {
  81. unsigned int raw_test_num;
  82. unsigned int file_test_num;
  83. unsigned int get_info_test_num;
  84. bool raw_test;
  85. bool file_test;
  86. bool get_info_test;
  87. bool pprint_test;
  88. bool always_log;
  89. } args;
  90. static char btf_log_buf[BTF_LOG_BUF_SIZE];
  91. static struct btf_header hdr_tmpl = {
  92. .magic = BTF_MAGIC,
  93. .version = BTF_VERSION,
  94. .hdr_len = sizeof(struct btf_header),
  95. };
  96. struct btf_raw_test {
  97. const char *descr;
  98. const char *str_sec;
  99. const char *map_name;
  100. const char *err_str;
  101. __u32 raw_types[MAX_NR_RAW_TYPES];
  102. __u32 str_sec_size;
  103. enum bpf_map_type map_type;
  104. __u32 key_size;
  105. __u32 value_size;
  106. __u32 key_type_id;
  107. __u32 value_type_id;
  108. __u32 max_entries;
  109. bool btf_load_err;
  110. bool map_create_err;
  111. int hdr_len_delta;
  112. int type_off_delta;
  113. int str_off_delta;
  114. int str_len_delta;
  115. };
  116. static struct btf_raw_test raw_tests[] = {
  117. /* enum E {
  118. * E0,
  119. * E1,
  120. * };
  121. *
  122. * struct A {
  123. * unsigned long long m;
  124. * int n;
  125. * char o;
  126. * [3 bytes hole]
  127. * int p[8];
  128. * int q[4][8];
  129. * enum E r;
  130. * };
  131. */
  132. {
  133. .descr = "struct test #1",
  134. .raw_types = {
  135. /* int */
  136. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
  137. /* unsigned long long */
  138. BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */
  139. /* char */
  140. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */
  141. /* int[8] */
  142. BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */
  143. /* struct A { */ /* [5] */
  144. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 6), 180),
  145. BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/
  146. BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */
  147. BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */
  148. BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */
  149. BTF_MEMBER_ENC(NAME_TBD, 6, 384),/* int q[4][8] */
  150. BTF_MEMBER_ENC(NAME_TBD, 7, 1408), /* enum E r */
  151. /* } */
  152. /* int[4][8] */
  153. BTF_TYPE_ARRAY_ENC(4, 1, 4), /* [6] */
  154. /* enum E */ /* [7] */
  155. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
  156. BTF_ENUM_ENC(NAME_TBD, 0),
  157. BTF_ENUM_ENC(NAME_TBD, 1),
  158. BTF_END_RAW,
  159. },
  160. .str_sec = "\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1",
  161. .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1"),
  162. .map_type = BPF_MAP_TYPE_ARRAY,
  163. .map_name = "struct_test1_map",
  164. .key_size = sizeof(int),
  165. .value_size = 180,
  166. .key_type_id = 1,
  167. .value_type_id = 5,
  168. .max_entries = 4,
  169. },
  170. /* typedef struct b Struct_B;
  171. *
  172. * struct A {
  173. * int m;
  174. * struct b n[4];
  175. * const Struct_B o[4];
  176. * };
  177. *
  178. * struct B {
  179. * int m;
  180. * int n;
  181. * };
  182. */
  183. {
  184. .descr = "struct test #2",
  185. .raw_types = {
  186. /* int */ /* [1] */
  187. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  188. /* struct b [4] */ /* [2] */
  189. BTF_TYPE_ARRAY_ENC(4, 1, 4),
  190. /* struct A { */ /* [3] */
  191. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 3), 68),
  192. BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
  193. BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct B n[4] */
  194. BTF_MEMBER_ENC(NAME_TBD, 8, 288),/* const Struct_B o[4];*/
  195. /* } */
  196. /* struct B { */ /* [4] */
  197. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
  198. BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
  199. BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
  200. /* } */
  201. /* const int */ /* [5] */
  202. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
  203. /* typedef struct b Struct_B */ /* [6] */
  204. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), 4),
  205. /* const Struct_B */ /* [7] */
  206. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 6),
  207. /* const Struct_B [4] */ /* [8] */
  208. BTF_TYPE_ARRAY_ENC(7, 1, 4),
  209. BTF_END_RAW,
  210. },
  211. .str_sec = "\0A\0m\0n\0o\0B\0m\0n\0Struct_B",
  212. .str_sec_size = sizeof("\0A\0m\0n\0o\0B\0m\0n\0Struct_B"),
  213. .map_type = BPF_MAP_TYPE_ARRAY,
  214. .map_name = "struct_test2_map",
  215. .key_size = sizeof(int),
  216. .value_size = 68,
  217. .key_type_id = 1,
  218. .value_type_id = 3,
  219. .max_entries = 4,
  220. },
  221. /* Test member exceeds the size of struct.
  222. *
  223. * struct A {
  224. * int m;
  225. * int n;
  226. * };
  227. */
  228. {
  229. .descr = "size check test #1",
  230. .raw_types = {
  231. /* int */ /* [1] */
  232. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  233. /* struct A { */ /* [2] */
  234. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1),
  235. BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
  236. BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
  237. /* } */
  238. BTF_END_RAW,
  239. },
  240. .str_sec = "\0A\0m\0n",
  241. .str_sec_size = sizeof("\0A\0m\0n"),
  242. .map_type = BPF_MAP_TYPE_ARRAY,
  243. .map_name = "size_check1_map",
  244. .key_size = sizeof(int),
  245. .value_size = 1,
  246. .key_type_id = 1,
  247. .value_type_id = 2,
  248. .max_entries = 4,
  249. .btf_load_err = true,
  250. .err_str = "Member exceeds struct_size",
  251. },
  252. /* Test member exeeds the size of struct
  253. *
  254. * struct A {
  255. * int m;
  256. * int n[2];
  257. * };
  258. */
  259. {
  260. .descr = "size check test #2",
  261. .raw_types = {
  262. /* int */ /* [1] */
  263. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
  264. /* int[2] */ /* [2] */
  265. BTF_TYPE_ARRAY_ENC(1, 1, 2),
  266. /* struct A { */ /* [3] */
  267. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 3 - 1),
  268. BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
  269. BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* int n[2]; */
  270. /* } */
  271. BTF_END_RAW,
  272. },
  273. .str_sec = "\0A\0m\0n",
  274. .str_sec_size = sizeof("\0A\0m\0n"),
  275. .map_type = BPF_MAP_TYPE_ARRAY,
  276. .map_name = "size_check2_map",
  277. .key_size = sizeof(int),
  278. .value_size = 1,
  279. .key_type_id = 1,
  280. .value_type_id = 3,
  281. .max_entries = 4,
  282. .btf_load_err = true,
  283. .err_str = "Member exceeds struct_size",
  284. },
  285. /* Test member exeeds the size of struct
  286. *
  287. * struct A {
  288. * int m;
  289. * void *n;
  290. * };
  291. */
  292. {
  293. .descr = "size check test #3",
  294. .raw_types = {
  295. /* int */ /* [1] */
  296. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
  297. /* void* */ /* [2] */
  298. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
  299. /* struct A { */ /* [3] */
  300. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) + sizeof(void *) - 1),
  301. BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
  302. BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* void *n; */
  303. /* } */
  304. BTF_END_RAW,
  305. },
  306. .str_sec = "\0A\0m\0n",
  307. .str_sec_size = sizeof("\0A\0m\0n"),
  308. .map_type = BPF_MAP_TYPE_ARRAY,
  309. .map_name = "size_check3_map",
  310. .key_size = sizeof(int),
  311. .value_size = 1,
  312. .key_type_id = 1,
  313. .value_type_id = 3,
  314. .max_entries = 4,
  315. .btf_load_err = true,
  316. .err_str = "Member exceeds struct_size",
  317. },
  318. /* Test member exceeds the size of struct
  319. *
  320. * enum E {
  321. * E0,
  322. * E1,
  323. * };
  324. *
  325. * struct A {
  326. * int m;
  327. * enum E n;
  328. * };
  329. */
  330. {
  331. .descr = "size check test #4",
  332. .raw_types = {
  333. /* int */ /* [1] */
  334. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
  335. /* enum E { */ /* [2] */
  336. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
  337. BTF_ENUM_ENC(NAME_TBD, 0),
  338. BTF_ENUM_ENC(NAME_TBD, 1),
  339. /* } */
  340. /* struct A { */ /* [3] */
  341. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1),
  342. BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */
  343. BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* enum E n; */
  344. /* } */
  345. BTF_END_RAW,
  346. },
  347. .str_sec = "\0E\0E0\0E1\0A\0m\0n",
  348. .str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"),
  349. .map_type = BPF_MAP_TYPE_ARRAY,
  350. .map_name = "size_check4_map",
  351. .key_size = sizeof(int),
  352. .value_size = 1,
  353. .key_type_id = 1,
  354. .value_type_id = 3,
  355. .max_entries = 4,
  356. .btf_load_err = true,
  357. .err_str = "Member exceeds struct_size",
  358. },
  359. /* typedef const void * const_void_ptr;
  360. * struct A {
  361. * const_void_ptr m;
  362. * };
  363. */
  364. {
  365. .descr = "void test #1",
  366. .raw_types = {
  367. /* int */ /* [1] */
  368. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  369. /* const void */ /* [2] */
  370. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
  371. /* const void* */ /* [3] */
  372. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
  373. /* typedef const void * const_void_ptr */
  374. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
  375. /* struct A { */ /* [4] */
  376. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
  377. /* const_void_ptr m; */
  378. BTF_MEMBER_ENC(NAME_TBD, 3, 0),
  379. /* } */
  380. BTF_END_RAW,
  381. },
  382. .str_sec = "\0const_void_ptr\0A\0m",
  383. .str_sec_size = sizeof("\0const_void_ptr\0A\0m"),
  384. .map_type = BPF_MAP_TYPE_ARRAY,
  385. .map_name = "void_test1_map",
  386. .key_size = sizeof(int),
  387. .value_size = sizeof(void *),
  388. .key_type_id = 1,
  389. .value_type_id = 4,
  390. .max_entries = 4,
  391. },
  392. /* struct A {
  393. * const void m;
  394. * };
  395. */
  396. {
  397. .descr = "void test #2",
  398. .raw_types = {
  399. /* int */ /* [1] */
  400. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  401. /* const void */ /* [2] */
  402. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
  403. /* struct A { */ /* [3] */
  404. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 8),
  405. /* const void m; */
  406. BTF_MEMBER_ENC(NAME_TBD, 2, 0),
  407. /* } */
  408. BTF_END_RAW,
  409. },
  410. .str_sec = "\0A\0m",
  411. .str_sec_size = sizeof("\0A\0m"),
  412. .map_type = BPF_MAP_TYPE_ARRAY,
  413. .map_name = "void_test2_map",
  414. .key_size = sizeof(int),
  415. .value_size = sizeof(void *),
  416. .key_type_id = 1,
  417. .value_type_id = 3,
  418. .max_entries = 4,
  419. .btf_load_err = true,
  420. .err_str = "Invalid member",
  421. },
  422. /* typedef const void * const_void_ptr;
  423. * const_void_ptr[4]
  424. */
  425. {
  426. .descr = "void test #3",
  427. .raw_types = {
  428. /* int */ /* [1] */
  429. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  430. /* const void */ /* [2] */
  431. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
  432. /* const void* */ /* [3] */
  433. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
  434. /* typedef const void * const_void_ptr */ /* [4] */
  435. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
  436. /* const_void_ptr[4] */ /* [5] */
  437. BTF_TYPE_ARRAY_ENC(3, 1, 4),
  438. BTF_END_RAW,
  439. },
  440. .str_sec = "\0const_void_ptr",
  441. .str_sec_size = sizeof("\0const_void_ptr"),
  442. .map_type = BPF_MAP_TYPE_ARRAY,
  443. .map_name = "void_test3_map",
  444. .key_size = sizeof(int),
  445. .value_size = sizeof(void *) * 4,
  446. .key_type_id = 1,
  447. .value_type_id = 4,
  448. .max_entries = 4,
  449. },
  450. /* const void[4] */
  451. {
  452. .descr = "void test #4",
  453. .raw_types = {
  454. /* int */ /* [1] */
  455. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  456. /* const void */ /* [2] */
  457. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
  458. /* const void[4] */ /* [3] */
  459. BTF_TYPE_ARRAY_ENC(2, 1, 4),
  460. BTF_END_RAW,
  461. },
  462. .str_sec = "\0A\0m",
  463. .str_sec_size = sizeof("\0A\0m"),
  464. .map_type = BPF_MAP_TYPE_ARRAY,
  465. .map_name = "void_test4_map",
  466. .key_size = sizeof(int),
  467. .value_size = sizeof(void *) * 4,
  468. .key_type_id = 1,
  469. .value_type_id = 3,
  470. .max_entries = 4,
  471. .btf_load_err = true,
  472. .err_str = "Invalid elem",
  473. },
  474. /* Array_A <------------------+
  475. * elem_type == Array_B |
  476. * | |
  477. * | |
  478. * Array_B <-------- + |
  479. * elem_type == Array A --+
  480. */
  481. {
  482. .descr = "loop test #1",
  483. .raw_types = {
  484. /* int */ /* [1] */
  485. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  486. /* Array_A */ /* [2] */
  487. BTF_TYPE_ARRAY_ENC(3, 1, 8),
  488. /* Array_B */ /* [3] */
  489. BTF_TYPE_ARRAY_ENC(2, 1, 8),
  490. BTF_END_RAW,
  491. },
  492. .str_sec = "",
  493. .str_sec_size = sizeof(""),
  494. .map_type = BPF_MAP_TYPE_ARRAY,
  495. .map_name = "loop_test1_map",
  496. .key_size = sizeof(int),
  497. .value_size = sizeof(sizeof(int) * 8),
  498. .key_type_id = 1,
  499. .value_type_id = 2,
  500. .max_entries = 4,
  501. .btf_load_err = true,
  502. .err_str = "Loop detected",
  503. },
  504. /* typedef is _before_ the BTF type of Array_A and Array_B
  505. *
  506. * typedef Array_B int_array;
  507. *
  508. * Array_A <------------------+
  509. * elem_type == int_array |
  510. * | |
  511. * | |
  512. * Array_B <-------- + |
  513. * elem_type == Array_A --+
  514. */
  515. {
  516. .descr = "loop test #2",
  517. .raw_types = {
  518. /* int */
  519. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
  520. /* typedef Array_B int_array */
  521. BTF_TYPEDEF_ENC(1, 4), /* [2] */
  522. /* Array_A */
  523. BTF_TYPE_ARRAY_ENC(2, 1, 8), /* [3] */
  524. /* Array_B */
  525. BTF_TYPE_ARRAY_ENC(3, 1, 8), /* [4] */
  526. BTF_END_RAW,
  527. },
  528. .str_sec = "\0int_array\0",
  529. .str_sec_size = sizeof("\0int_array"),
  530. .map_type = BPF_MAP_TYPE_ARRAY,
  531. .map_name = "loop_test2_map",
  532. .key_size = sizeof(int),
  533. .value_size = sizeof(sizeof(int) * 8),
  534. .key_type_id = 1,
  535. .value_type_id = 2,
  536. .max_entries = 4,
  537. .btf_load_err = true,
  538. .err_str = "Loop detected",
  539. },
  540. /* Array_A <------------------+
  541. * elem_type == Array_B |
  542. * | |
  543. * | |
  544. * Array_B <-------- + |
  545. * elem_type == Array_A --+
  546. */
  547. {
  548. .descr = "loop test #3",
  549. .raw_types = {
  550. /* int */ /* [1] */
  551. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  552. /* Array_A */ /* [2] */
  553. BTF_TYPE_ARRAY_ENC(3, 1, 8),
  554. /* Array_B */ /* [3] */
  555. BTF_TYPE_ARRAY_ENC(2, 1, 8),
  556. BTF_END_RAW,
  557. },
  558. .str_sec = "",
  559. .str_sec_size = sizeof(""),
  560. .map_type = BPF_MAP_TYPE_ARRAY,
  561. .map_name = "loop_test3_map",
  562. .key_size = sizeof(int),
  563. .value_size = sizeof(sizeof(int) * 8),
  564. .key_type_id = 1,
  565. .value_type_id = 2,
  566. .max_entries = 4,
  567. .btf_load_err = true,
  568. .err_str = "Loop detected",
  569. },
  570. /* typedef is _between_ the BTF type of Array_A and Array_B
  571. *
  572. * typedef Array_B int_array;
  573. *
  574. * Array_A <------------------+
  575. * elem_type == int_array |
  576. * | |
  577. * | |
  578. * Array_B <-------- + |
  579. * elem_type == Array_A --+
  580. */
  581. {
  582. .descr = "loop test #4",
  583. .raw_types = {
  584. /* int */ /* [1] */
  585. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  586. /* Array_A */ /* [2] */
  587. BTF_TYPE_ARRAY_ENC(3, 1, 8),
  588. /* typedef Array_B int_array */ /* [3] */
  589. BTF_TYPEDEF_ENC(NAME_TBD, 4),
  590. /* Array_B */ /* [4] */
  591. BTF_TYPE_ARRAY_ENC(2, 1, 8),
  592. BTF_END_RAW,
  593. },
  594. .str_sec = "\0int_array\0",
  595. .str_sec_size = sizeof("\0int_array"),
  596. .map_type = BPF_MAP_TYPE_ARRAY,
  597. .map_name = "loop_test4_map",
  598. .key_size = sizeof(int),
  599. .value_size = sizeof(sizeof(int) * 8),
  600. .key_type_id = 1,
  601. .value_type_id = 2,
  602. .max_entries = 4,
  603. .btf_load_err = true,
  604. .err_str = "Loop detected",
  605. },
  606. /* typedef struct B Struct_B
  607. *
  608. * struct A {
  609. * int x;
  610. * Struct_B y;
  611. * };
  612. *
  613. * struct B {
  614. * int x;
  615. * struct A y;
  616. * };
  617. */
  618. {
  619. .descr = "loop test #5",
  620. .raw_types = {
  621. /* int */
  622. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
  623. /* struct A */ /* [2] */
  624. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
  625. BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x; */
  626. BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* Struct_B y; */
  627. /* typedef struct B Struct_B */
  628. BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */
  629. /* struct B */ /* [4] */
  630. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
  631. BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x; */
  632. BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A y; */
  633. BTF_END_RAW,
  634. },
  635. .str_sec = "\0A\0x\0y\0Struct_B\0B\0x\0y",
  636. .str_sec_size = sizeof("\0A\0x\0y\0Struct_B\0B\0x\0y"),
  637. .map_type = BPF_MAP_TYPE_ARRAY,
  638. .map_name = "loop_test5_map",
  639. .key_size = sizeof(int),
  640. .value_size = 8,
  641. .key_type_id = 1,
  642. .value_type_id = 2,
  643. .max_entries = 4,
  644. .btf_load_err = true,
  645. .err_str = "Loop detected",
  646. },
  647. /* struct A {
  648. * int x;
  649. * struct A array_a[4];
  650. * };
  651. */
  652. {
  653. .descr = "loop test #6",
  654. .raw_types = {
  655. /* int */
  656. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
  657. BTF_TYPE_ARRAY_ENC(3, 1, 4), /* [2] */
  658. /* struct A */ /* [3] */
  659. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
  660. BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x; */
  661. BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A array_a[4]; */
  662. BTF_END_RAW,
  663. },
  664. .str_sec = "\0A\0x\0y",
  665. .str_sec_size = sizeof("\0A\0x\0y"),
  666. .map_type = BPF_MAP_TYPE_ARRAY,
  667. .map_name = "loop_test6_map",
  668. .key_size = sizeof(int),
  669. .value_size = 8,
  670. .key_type_id = 1,
  671. .value_type_id = 2,
  672. .max_entries = 4,
  673. .btf_load_err = true,
  674. .err_str = "Loop detected",
  675. },
  676. {
  677. .descr = "loop test #7",
  678. .raw_types = {
  679. /* int */ /* [1] */
  680. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  681. /* struct A { */ /* [2] */
  682. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
  683. /* const void *m; */
  684. BTF_MEMBER_ENC(NAME_TBD, 3, 0),
  685. /* CONST type_id=3 */ /* [3] */
  686. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
  687. /* PTR type_id=2 */ /* [4] */
  688. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
  689. BTF_END_RAW,
  690. },
  691. .str_sec = "\0A\0m",
  692. .str_sec_size = sizeof("\0A\0m"),
  693. .map_type = BPF_MAP_TYPE_ARRAY,
  694. .map_name = "loop_test7_map",
  695. .key_size = sizeof(int),
  696. .value_size = sizeof(void *),
  697. .key_type_id = 1,
  698. .value_type_id = 2,
  699. .max_entries = 4,
  700. .btf_load_err = true,
  701. .err_str = "Loop detected",
  702. },
  703. {
  704. .descr = "loop test #8",
  705. .raw_types = {
  706. /* int */ /* [1] */
  707. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  708. /* struct A { */ /* [2] */
  709. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
  710. /* const void *m; */
  711. BTF_MEMBER_ENC(NAME_TBD, 4, 0),
  712. /* struct B { */ /* [3] */
  713. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
  714. /* const void *n; */
  715. BTF_MEMBER_ENC(NAME_TBD, 6, 0),
  716. /* CONST type_id=5 */ /* [4] */
  717. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 5),
  718. /* PTR type_id=6 */ /* [5] */
  719. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 6),
  720. /* CONST type_id=7 */ /* [6] */
  721. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 7),
  722. /* PTR type_id=4 */ /* [7] */
  723. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 4),
  724. BTF_END_RAW,
  725. },
  726. .str_sec = "\0A\0m\0B\0n",
  727. .str_sec_size = sizeof("\0A\0m\0B\0n"),
  728. .map_type = BPF_MAP_TYPE_ARRAY,
  729. .map_name = "loop_test8_map",
  730. .key_size = sizeof(int),
  731. .value_size = sizeof(void *),
  732. .key_type_id = 1,
  733. .value_type_id = 2,
  734. .max_entries = 4,
  735. .btf_load_err = true,
  736. .err_str = "Loop detected",
  737. },
  738. {
  739. .descr = "string section does not end with null",
  740. .raw_types = {
  741. /* int */ /* [1] */
  742. BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
  743. BTF_END_RAW,
  744. },
  745. .str_sec = "\0int",
  746. .str_sec_size = sizeof("\0int") - 1,
  747. .map_type = BPF_MAP_TYPE_ARRAY,
  748. .map_name = "hdr_test_map",
  749. .key_size = sizeof(int),
  750. .value_size = sizeof(int),
  751. .key_type_id = 1,
  752. .value_type_id = 1,
  753. .max_entries = 4,
  754. .btf_load_err = true,
  755. .err_str = "Invalid string section",
  756. },
  757. {
  758. .descr = "empty string section",
  759. .raw_types = {
  760. /* int */ /* [1] */
  761. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  762. BTF_END_RAW,
  763. },
  764. .str_sec = "",
  765. .str_sec_size = 0,
  766. .map_type = BPF_MAP_TYPE_ARRAY,
  767. .map_name = "hdr_test_map",
  768. .key_size = sizeof(int),
  769. .value_size = sizeof(int),
  770. .key_type_id = 1,
  771. .value_type_id = 1,
  772. .max_entries = 4,
  773. .btf_load_err = true,
  774. .err_str = "Invalid string section",
  775. },
  776. {
  777. .descr = "empty type section",
  778. .raw_types = {
  779. BTF_END_RAW,
  780. },
  781. .str_sec = "\0int",
  782. .str_sec_size = sizeof("\0int"),
  783. .map_type = BPF_MAP_TYPE_ARRAY,
  784. .map_name = "hdr_test_map",
  785. .key_size = sizeof(int),
  786. .value_size = sizeof(int),
  787. .key_type_id = 1,
  788. .value_type_id = 1,
  789. .max_entries = 4,
  790. .btf_load_err = true,
  791. .err_str = "No type found",
  792. },
  793. {
  794. .descr = "btf_header test. Longer hdr_len",
  795. .raw_types = {
  796. /* int */ /* [1] */
  797. BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
  798. BTF_END_RAW,
  799. },
  800. .str_sec = "\0int",
  801. .str_sec_size = sizeof("\0int"),
  802. .map_type = BPF_MAP_TYPE_ARRAY,
  803. .map_name = "hdr_test_map",
  804. .key_size = sizeof(int),
  805. .value_size = sizeof(int),
  806. .key_type_id = 1,
  807. .value_type_id = 1,
  808. .max_entries = 4,
  809. .btf_load_err = true,
  810. .hdr_len_delta = 4,
  811. .err_str = "Unsupported btf_header",
  812. },
  813. {
  814. .descr = "btf_header test. Gap between hdr and type",
  815. .raw_types = {
  816. /* int */ /* [1] */
  817. BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
  818. BTF_END_RAW,
  819. },
  820. .str_sec = "\0int",
  821. .str_sec_size = sizeof("\0int"),
  822. .map_type = BPF_MAP_TYPE_ARRAY,
  823. .map_name = "hdr_test_map",
  824. .key_size = sizeof(int),
  825. .value_size = sizeof(int),
  826. .key_type_id = 1,
  827. .value_type_id = 1,
  828. .max_entries = 4,
  829. .btf_load_err = true,
  830. .type_off_delta = 4,
  831. .err_str = "Unsupported section found",
  832. },
  833. {
  834. .descr = "btf_header test. Gap between type and str",
  835. .raw_types = {
  836. /* int */ /* [1] */
  837. BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
  838. BTF_END_RAW,
  839. },
  840. .str_sec = "\0int",
  841. .str_sec_size = sizeof("\0int"),
  842. .map_type = BPF_MAP_TYPE_ARRAY,
  843. .map_name = "hdr_test_map",
  844. .key_size = sizeof(int),
  845. .value_size = sizeof(int),
  846. .key_type_id = 1,
  847. .value_type_id = 1,
  848. .max_entries = 4,
  849. .btf_load_err = true,
  850. .str_off_delta = 4,
  851. .err_str = "Unsupported section found",
  852. },
  853. {
  854. .descr = "btf_header test. Overlap between type and str",
  855. .raw_types = {
  856. /* int */ /* [1] */
  857. BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
  858. BTF_END_RAW,
  859. },
  860. .str_sec = "\0int",
  861. .str_sec_size = sizeof("\0int"),
  862. .map_type = BPF_MAP_TYPE_ARRAY,
  863. .map_name = "hdr_test_map",
  864. .key_size = sizeof(int),
  865. .value_size = sizeof(int),
  866. .key_type_id = 1,
  867. .value_type_id = 1,
  868. .max_entries = 4,
  869. .btf_load_err = true,
  870. .str_off_delta = -4,
  871. .err_str = "Section overlap found",
  872. },
  873. {
  874. .descr = "btf_header test. Larger BTF size",
  875. .raw_types = {
  876. /* int */ /* [1] */
  877. BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
  878. BTF_END_RAW,
  879. },
  880. .str_sec = "\0int",
  881. .str_sec_size = sizeof("\0int"),
  882. .map_type = BPF_MAP_TYPE_ARRAY,
  883. .map_name = "hdr_test_map",
  884. .key_size = sizeof(int),
  885. .value_size = sizeof(int),
  886. .key_type_id = 1,
  887. .value_type_id = 1,
  888. .max_entries = 4,
  889. .btf_load_err = true,
  890. .str_len_delta = -4,
  891. .err_str = "Unsupported section found",
  892. },
  893. {
  894. .descr = "btf_header test. Smaller BTF size",
  895. .raw_types = {
  896. /* int */ /* [1] */
  897. BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
  898. BTF_END_RAW,
  899. },
  900. .str_sec = "\0int",
  901. .str_sec_size = sizeof("\0int"),
  902. .map_type = BPF_MAP_TYPE_ARRAY,
  903. .map_name = "hdr_test_map",
  904. .key_size = sizeof(int),
  905. .value_size = sizeof(int),
  906. .key_type_id = 1,
  907. .value_type_id = 1,
  908. .max_entries = 4,
  909. .btf_load_err = true,
  910. .str_len_delta = 4,
  911. .err_str = "Total section length too long",
  912. },
  913. {
  914. .descr = "array test. index_type/elem_type \"int\"",
  915. .raw_types = {
  916. /* int */ /* [1] */
  917. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  918. /* int[16] */ /* [2] */
  919. BTF_TYPE_ARRAY_ENC(1, 1, 16),
  920. BTF_END_RAW,
  921. },
  922. .str_sec = "",
  923. .str_sec_size = sizeof(""),
  924. .map_type = BPF_MAP_TYPE_ARRAY,
  925. .map_name = "array_test_map",
  926. .key_size = sizeof(int),
  927. .value_size = sizeof(int),
  928. .key_type_id = 1,
  929. .value_type_id = 1,
  930. .max_entries = 4,
  931. },
  932. {
  933. .descr = "array test. index_type/elem_type \"const int\"",
  934. .raw_types = {
  935. /* int */ /* [1] */
  936. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  937. /* int[16] */ /* [2] */
  938. BTF_TYPE_ARRAY_ENC(3, 3, 16),
  939. /* CONST type_id=1 */ /* [3] */
  940. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
  941. BTF_END_RAW,
  942. },
  943. .str_sec = "",
  944. .str_sec_size = sizeof(""),
  945. .map_type = BPF_MAP_TYPE_ARRAY,
  946. .map_name = "array_test_map",
  947. .key_size = sizeof(int),
  948. .value_size = sizeof(int),
  949. .key_type_id = 1,
  950. .value_type_id = 1,
  951. .max_entries = 4,
  952. },
  953. {
  954. .descr = "array test. index_type \"const int:31\"",
  955. .raw_types = {
  956. /* int */ /* [1] */
  957. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  958. /* int:31 */ /* [2] */
  959. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
  960. /* int[16] */ /* [3] */
  961. BTF_TYPE_ARRAY_ENC(1, 4, 16),
  962. /* CONST type_id=2 */ /* [4] */
  963. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
  964. BTF_END_RAW,
  965. },
  966. .str_sec = "",
  967. .str_sec_size = sizeof(""),
  968. .map_type = BPF_MAP_TYPE_ARRAY,
  969. .map_name = "array_test_map",
  970. .key_size = sizeof(int),
  971. .value_size = sizeof(int),
  972. .key_type_id = 1,
  973. .value_type_id = 1,
  974. .max_entries = 4,
  975. .btf_load_err = true,
  976. .err_str = "Invalid index",
  977. },
  978. {
  979. .descr = "array test. elem_type \"const int:31\"",
  980. .raw_types = {
  981. /* int */ /* [1] */
  982. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  983. /* int:31 */ /* [2] */
  984. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
  985. /* int[16] */ /* [3] */
  986. BTF_TYPE_ARRAY_ENC(4, 1, 16),
  987. /* CONST type_id=2 */ /* [4] */
  988. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
  989. BTF_END_RAW,
  990. },
  991. .str_sec = "",
  992. .str_sec_size = sizeof(""),
  993. .map_type = BPF_MAP_TYPE_ARRAY,
  994. .map_name = "array_test_map",
  995. .key_size = sizeof(int),
  996. .value_size = sizeof(int),
  997. .key_type_id = 1,
  998. .value_type_id = 1,
  999. .max_entries = 4,
  1000. .btf_load_err = true,
  1001. .err_str = "Invalid array of int",
  1002. },
  1003. {
  1004. .descr = "array test. index_type \"void\"",
  1005. .raw_types = {
  1006. /* int */ /* [1] */
  1007. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  1008. /* int[16] */ /* [2] */
  1009. BTF_TYPE_ARRAY_ENC(1, 0, 16),
  1010. BTF_END_RAW,
  1011. },
  1012. .str_sec = "",
  1013. .str_sec_size = sizeof(""),
  1014. .map_type = BPF_MAP_TYPE_ARRAY,
  1015. .map_name = "array_test_map",
  1016. .key_size = sizeof(int),
  1017. .value_size = sizeof(int),
  1018. .key_type_id = 1,
  1019. .value_type_id = 1,
  1020. .max_entries = 4,
  1021. .btf_load_err = true,
  1022. .err_str = "Invalid index",
  1023. },
  1024. {
  1025. .descr = "array test. index_type \"const void\"",
  1026. .raw_types = {
  1027. /* int */ /* [1] */
  1028. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  1029. /* int[16] */ /* [2] */
  1030. BTF_TYPE_ARRAY_ENC(1, 3, 16),
  1031. /* CONST type_id=0 (void) */ /* [3] */
  1032. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
  1033. BTF_END_RAW,
  1034. },
  1035. .str_sec = "",
  1036. .str_sec_size = sizeof(""),
  1037. .map_type = BPF_MAP_TYPE_ARRAY,
  1038. .map_name = "array_test_map",
  1039. .key_size = sizeof(int),
  1040. .value_size = sizeof(int),
  1041. .key_type_id = 1,
  1042. .value_type_id = 1,
  1043. .max_entries = 4,
  1044. .btf_load_err = true,
  1045. .err_str = "Invalid index",
  1046. },
  1047. {
  1048. .descr = "array test. elem_type \"const void\"",
  1049. .raw_types = {
  1050. /* int */ /* [1] */
  1051. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  1052. /* int[16] */ /* [2] */
  1053. BTF_TYPE_ARRAY_ENC(3, 1, 16),
  1054. /* CONST type_id=0 (void) */ /* [3] */
  1055. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
  1056. BTF_END_RAW,
  1057. },
  1058. .str_sec = "",
  1059. .str_sec_size = sizeof(""),
  1060. .map_type = BPF_MAP_TYPE_ARRAY,
  1061. .map_name = "array_test_map",
  1062. .key_size = sizeof(int),
  1063. .value_size = sizeof(int),
  1064. .key_type_id = 1,
  1065. .value_type_id = 1,
  1066. .max_entries = 4,
  1067. .btf_load_err = true,
  1068. .err_str = "Invalid elem",
  1069. },
  1070. {
  1071. .descr = "array test. elem_type \"const void *\"",
  1072. .raw_types = {
  1073. /* int */ /* [1] */
  1074. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  1075. /* const void *[16] */ /* [2] */
  1076. BTF_TYPE_ARRAY_ENC(3, 1, 16),
  1077. /* CONST type_id=4 */ /* [3] */
  1078. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
  1079. /* void* */ /* [4] */
  1080. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
  1081. BTF_END_RAW,
  1082. },
  1083. .str_sec = "",
  1084. .str_sec_size = sizeof(""),
  1085. .map_type = BPF_MAP_TYPE_ARRAY,
  1086. .map_name = "array_test_map",
  1087. .key_size = sizeof(int),
  1088. .value_size = sizeof(int),
  1089. .key_type_id = 1,
  1090. .value_type_id = 1,
  1091. .max_entries = 4,
  1092. },
  1093. {
  1094. .descr = "array test. index_type \"const void *\"",
  1095. .raw_types = {
  1096. /* int */ /* [1] */
  1097. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  1098. /* const void *[16] */ /* [2] */
  1099. BTF_TYPE_ARRAY_ENC(3, 3, 16),
  1100. /* CONST type_id=4 */ /* [3] */
  1101. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
  1102. /* void* */ /* [4] */
  1103. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
  1104. BTF_END_RAW,
  1105. },
  1106. .str_sec = "",
  1107. .str_sec_size = sizeof(""),
  1108. .map_type = BPF_MAP_TYPE_ARRAY,
  1109. .map_name = "array_test_map",
  1110. .key_size = sizeof(int),
  1111. .value_size = sizeof(int),
  1112. .key_type_id = 1,
  1113. .value_type_id = 1,
  1114. .max_entries = 4,
  1115. .btf_load_err = true,
  1116. .err_str = "Invalid index",
  1117. },
  1118. {
  1119. .descr = "array test. t->size != 0\"",
  1120. .raw_types = {
  1121. /* int */ /* [1] */
  1122. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  1123. /* int[16] */ /* [2] */
  1124. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 1),
  1125. BTF_ARRAY_ENC(1, 1, 16),
  1126. BTF_END_RAW,
  1127. },
  1128. .str_sec = "",
  1129. .str_sec_size = sizeof(""),
  1130. .map_type = BPF_MAP_TYPE_ARRAY,
  1131. .map_name = "array_test_map",
  1132. .key_size = sizeof(int),
  1133. .value_size = sizeof(int),
  1134. .key_type_id = 1,
  1135. .value_type_id = 1,
  1136. .max_entries = 4,
  1137. .btf_load_err = true,
  1138. .err_str = "size != 0",
  1139. },
  1140. {
  1141. .descr = "int test. invalid int_data",
  1142. .raw_types = {
  1143. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), 4),
  1144. 0x10000000,
  1145. BTF_END_RAW,
  1146. },
  1147. .str_sec = "",
  1148. .str_sec_size = sizeof(""),
  1149. .map_type = BPF_MAP_TYPE_ARRAY,
  1150. .map_name = "array_test_map",
  1151. .key_size = sizeof(int),
  1152. .value_size = sizeof(int),
  1153. .key_type_id = 1,
  1154. .value_type_id = 1,
  1155. .max_entries = 4,
  1156. .btf_load_err = true,
  1157. .err_str = "Invalid int_data",
  1158. },
  1159. {
  1160. .descr = "invalid BTF_INFO",
  1161. .raw_types = {
  1162. /* int */ /* [1] */
  1163. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  1164. BTF_TYPE_ENC(0, 0x10000000, 4),
  1165. BTF_END_RAW,
  1166. },
  1167. .str_sec = "",
  1168. .str_sec_size = sizeof(""),
  1169. .map_type = BPF_MAP_TYPE_ARRAY,
  1170. .map_name = "array_test_map",
  1171. .key_size = sizeof(int),
  1172. .value_size = sizeof(int),
  1173. .key_type_id = 1,
  1174. .value_type_id = 1,
  1175. .max_entries = 4,
  1176. .btf_load_err = true,
  1177. .err_str = "Invalid btf_info",
  1178. },
  1179. {
  1180. .descr = "fwd test. t->type != 0\"",
  1181. .raw_types = {
  1182. /* int */ /* [1] */
  1183. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  1184. /* fwd type */ /* [2] */
  1185. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 1),
  1186. BTF_END_RAW,
  1187. },
  1188. .str_sec = "",
  1189. .str_sec_size = sizeof(""),
  1190. .map_type = BPF_MAP_TYPE_ARRAY,
  1191. .map_name = "fwd_test_map",
  1192. .key_size = sizeof(int),
  1193. .value_size = sizeof(int),
  1194. .key_type_id = 1,
  1195. .value_type_id = 1,
  1196. .max_entries = 4,
  1197. .btf_load_err = true,
  1198. .err_str = "type != 0",
  1199. },
  1200. }; /* struct btf_raw_test raw_tests[] */
  1201. static const char *get_next_str(const char *start, const char *end)
  1202. {
  1203. return start < end - 1 ? start + 1 : NULL;
  1204. }
  1205. static int get_type_sec_size(const __u32 *raw_types)
  1206. {
  1207. int i;
  1208. for (i = MAX_NR_RAW_TYPES - 1;
  1209. i >= 0 && raw_types[i] != BTF_END_RAW;
  1210. i--)
  1211. ;
  1212. return i < 0 ? i : i * sizeof(raw_types[0]);
  1213. }
  1214. static void *btf_raw_create(const struct btf_header *hdr,
  1215. const __u32 *raw_types,
  1216. const char *str,
  1217. unsigned int str_sec_size,
  1218. unsigned int *btf_size)
  1219. {
  1220. const char *next_str = str, *end_str = str + str_sec_size;
  1221. unsigned int size_needed, offset;
  1222. struct btf_header *ret_hdr;
  1223. int i, type_sec_size;
  1224. uint32_t *ret_types;
  1225. void *raw_btf;
  1226. type_sec_size = get_type_sec_size(raw_types);
  1227. if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types"))
  1228. return NULL;
  1229. size_needed = sizeof(*hdr) + type_sec_size + str_sec_size;
  1230. raw_btf = malloc(size_needed);
  1231. if (CHECK(!raw_btf, "Cannot allocate memory for raw_btf"))
  1232. return NULL;
  1233. /* Copy header */
  1234. memcpy(raw_btf, hdr, sizeof(*hdr));
  1235. offset = sizeof(*hdr);
  1236. /* Copy type section */
  1237. ret_types = raw_btf + offset;
  1238. for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) {
  1239. if (raw_types[i] == NAME_TBD) {
  1240. next_str = get_next_str(next_str, end_str);
  1241. if (CHECK(!next_str, "Error in getting next_str")) {
  1242. free(raw_btf);
  1243. return NULL;
  1244. }
  1245. ret_types[i] = next_str - str;
  1246. next_str += strlen(next_str);
  1247. } else {
  1248. ret_types[i] = raw_types[i];
  1249. }
  1250. }
  1251. offset += type_sec_size;
  1252. /* Copy string section */
  1253. memcpy(raw_btf + offset, str, str_sec_size);
  1254. ret_hdr = (struct btf_header *)raw_btf;
  1255. ret_hdr->type_len = type_sec_size;
  1256. ret_hdr->str_off = type_sec_size;
  1257. ret_hdr->str_len = str_sec_size;
  1258. *btf_size = size_needed;
  1259. return raw_btf;
  1260. }
  1261. static int do_test_raw(unsigned int test_num)
  1262. {
  1263. struct btf_raw_test *test = &raw_tests[test_num - 1];
  1264. struct bpf_create_map_attr create_attr = {};
  1265. int map_fd = -1, btf_fd = -1;
  1266. unsigned int raw_btf_size;
  1267. struct btf_header *hdr;
  1268. void *raw_btf;
  1269. int err;
  1270. fprintf(stderr, "BTF raw test[%u] (%s): ", test_num, test->descr);
  1271. raw_btf = btf_raw_create(&hdr_tmpl,
  1272. test->raw_types,
  1273. test->str_sec,
  1274. test->str_sec_size,
  1275. &raw_btf_size);
  1276. if (!raw_btf)
  1277. return -1;
  1278. hdr = raw_btf;
  1279. hdr->hdr_len = (int)hdr->hdr_len + test->hdr_len_delta;
  1280. hdr->type_off = (int)hdr->type_off + test->type_off_delta;
  1281. hdr->str_off = (int)hdr->str_off + test->str_off_delta;
  1282. hdr->str_len = (int)hdr->str_len + test->str_len_delta;
  1283. *btf_log_buf = '\0';
  1284. btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
  1285. btf_log_buf, BTF_LOG_BUF_SIZE,
  1286. args.always_log);
  1287. free(raw_btf);
  1288. err = ((btf_fd == -1) != test->btf_load_err);
  1289. if (CHECK(err, "btf_fd:%d test->btf_load_err:%u",
  1290. btf_fd, test->btf_load_err) ||
  1291. CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
  1292. "expected err_str:%s", test->err_str)) {
  1293. err = -1;
  1294. goto done;
  1295. }
  1296. if (err || btf_fd == -1)
  1297. goto done;
  1298. create_attr.name = test->map_name;
  1299. create_attr.map_type = test->map_type;
  1300. create_attr.key_size = test->key_size;
  1301. create_attr.value_size = test->value_size;
  1302. create_attr.max_entries = test->max_entries;
  1303. create_attr.btf_fd = btf_fd;
  1304. create_attr.btf_key_type_id = test->key_type_id;
  1305. create_attr.btf_value_type_id = test->value_type_id;
  1306. map_fd = bpf_create_map_xattr(&create_attr);
  1307. err = ((map_fd == -1) != test->map_create_err);
  1308. CHECK(err, "map_fd:%d test->map_create_err:%u",
  1309. map_fd, test->map_create_err);
  1310. done:
  1311. if (!err)
  1312. fprintf(stderr, "OK");
  1313. if (*btf_log_buf && (err || args.always_log))
  1314. fprintf(stderr, "\n%s", btf_log_buf);
  1315. if (btf_fd != -1)
  1316. close(btf_fd);
  1317. if (map_fd != -1)
  1318. close(map_fd);
  1319. return err;
  1320. }
  1321. static int test_raw(void)
  1322. {
  1323. unsigned int i;
  1324. int err = 0;
  1325. if (args.raw_test_num)
  1326. return count_result(do_test_raw(args.raw_test_num));
  1327. for (i = 1; i <= ARRAY_SIZE(raw_tests); i++)
  1328. err |= count_result(do_test_raw(i));
  1329. return err;
  1330. }
  1331. struct btf_get_info_test {
  1332. const char *descr;
  1333. const char *str_sec;
  1334. __u32 raw_types[MAX_NR_RAW_TYPES];
  1335. __u32 str_sec_size;
  1336. int btf_size_delta;
  1337. int (*special_test)(unsigned int test_num);
  1338. };
  1339. static int test_big_btf_info(unsigned int test_num);
  1340. static int test_btf_id(unsigned int test_num);
  1341. const struct btf_get_info_test get_info_tests[] = {
  1342. {
  1343. .descr = "== raw_btf_size+1",
  1344. .raw_types = {
  1345. /* int */ /* [1] */
  1346. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  1347. BTF_END_RAW,
  1348. },
  1349. .str_sec = "",
  1350. .str_sec_size = sizeof(""),
  1351. .btf_size_delta = 1,
  1352. },
  1353. {
  1354. .descr = "== raw_btf_size-3",
  1355. .raw_types = {
  1356. /* int */ /* [1] */
  1357. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  1358. BTF_END_RAW,
  1359. },
  1360. .str_sec = "",
  1361. .str_sec_size = sizeof(""),
  1362. .btf_size_delta = -3,
  1363. },
  1364. {
  1365. .descr = "Large bpf_btf_info",
  1366. .raw_types = {
  1367. /* int */ /* [1] */
  1368. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  1369. BTF_END_RAW,
  1370. },
  1371. .str_sec = "",
  1372. .str_sec_size = sizeof(""),
  1373. .special_test = test_big_btf_info,
  1374. },
  1375. {
  1376. .descr = "BTF ID",
  1377. .raw_types = {
  1378. /* int */ /* [1] */
  1379. BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
  1380. /* unsigned int */ /* [2] */
  1381. BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
  1382. BTF_END_RAW,
  1383. },
  1384. .str_sec = "",
  1385. .str_sec_size = sizeof(""),
  1386. .special_test = test_btf_id,
  1387. },
  1388. };
  1389. static inline __u64 ptr_to_u64(const void *ptr)
  1390. {
  1391. return (__u64)(unsigned long)ptr;
  1392. }
  1393. static int test_big_btf_info(unsigned int test_num)
  1394. {
  1395. const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
  1396. uint8_t *raw_btf = NULL, *user_btf = NULL;
  1397. unsigned int raw_btf_size;
  1398. struct {
  1399. struct bpf_btf_info info;
  1400. uint64_t garbage;
  1401. } info_garbage;
  1402. struct bpf_btf_info *info;
  1403. int btf_fd = -1, err;
  1404. uint32_t info_len;
  1405. raw_btf = btf_raw_create(&hdr_tmpl,
  1406. test->raw_types,
  1407. test->str_sec,
  1408. test->str_sec_size,
  1409. &raw_btf_size);
  1410. if (!raw_btf)
  1411. return -1;
  1412. *btf_log_buf = '\0';
  1413. user_btf = malloc(raw_btf_size);
  1414. if (CHECK(!user_btf, "!user_btf")) {
  1415. err = -1;
  1416. goto done;
  1417. }
  1418. btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
  1419. btf_log_buf, BTF_LOG_BUF_SIZE,
  1420. args.always_log);
  1421. if (CHECK(btf_fd == -1, "errno:%d", errno)) {
  1422. err = -1;
  1423. goto done;
  1424. }
  1425. /*
  1426. * GET_INFO should error out if the userspace info
  1427. * has non zero tailing bytes.
  1428. */
  1429. info = &info_garbage.info;
  1430. memset(info, 0, sizeof(*info));
  1431. info_garbage.garbage = 0xdeadbeef;
  1432. info_len = sizeof(info_garbage);
  1433. info->btf = ptr_to_u64(user_btf);
  1434. info->btf_size = raw_btf_size;
  1435. err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
  1436. if (CHECK(!err, "!err")) {
  1437. err = -1;
  1438. goto done;
  1439. }
  1440. /*
  1441. * GET_INFO should succeed even info_len is larger than
  1442. * the kernel supported as long as tailing bytes are zero.
  1443. * The kernel supported info len should also be returned
  1444. * to userspace.
  1445. */
  1446. info_garbage.garbage = 0;
  1447. err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
  1448. if (CHECK(err || info_len != sizeof(*info),
  1449. "err:%d errno:%d info_len:%u sizeof(*info):%lu",
  1450. err, errno, info_len, sizeof(*info))) {
  1451. err = -1;
  1452. goto done;
  1453. }
  1454. fprintf(stderr, "OK");
  1455. done:
  1456. if (*btf_log_buf && (err || args.always_log))
  1457. fprintf(stderr, "\n%s", btf_log_buf);
  1458. free(raw_btf);
  1459. free(user_btf);
  1460. if (btf_fd != -1)
  1461. close(btf_fd);
  1462. return err;
  1463. }
  1464. static int test_btf_id(unsigned int test_num)
  1465. {
  1466. const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
  1467. struct bpf_create_map_attr create_attr = {};
  1468. uint8_t *raw_btf = NULL, *user_btf[2] = {};
  1469. int btf_fd[2] = {-1, -1}, map_fd = -1;
  1470. struct bpf_map_info map_info = {};
  1471. struct bpf_btf_info info[2] = {};
  1472. unsigned int raw_btf_size;
  1473. uint32_t info_len;
  1474. int err, i, ret;
  1475. raw_btf = btf_raw_create(&hdr_tmpl,
  1476. test->raw_types,
  1477. test->str_sec,
  1478. test->str_sec_size,
  1479. &raw_btf_size);
  1480. if (!raw_btf)
  1481. return -1;
  1482. *btf_log_buf = '\0';
  1483. for (i = 0; i < 2; i++) {
  1484. user_btf[i] = malloc(raw_btf_size);
  1485. if (CHECK(!user_btf[i], "!user_btf[%d]", i)) {
  1486. err = -1;
  1487. goto done;
  1488. }
  1489. info[i].btf = ptr_to_u64(user_btf[i]);
  1490. info[i].btf_size = raw_btf_size;
  1491. }
  1492. btf_fd[0] = bpf_load_btf(raw_btf, raw_btf_size,
  1493. btf_log_buf, BTF_LOG_BUF_SIZE,
  1494. args.always_log);
  1495. if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
  1496. err = -1;
  1497. goto done;
  1498. }
  1499. /* Test BPF_OBJ_GET_INFO_BY_ID on btf_id */
  1500. info_len = sizeof(info[0]);
  1501. err = bpf_obj_get_info_by_fd(btf_fd[0], &info[0], &info_len);
  1502. if (CHECK(err, "errno:%d", errno)) {
  1503. err = -1;
  1504. goto done;
  1505. }
  1506. btf_fd[1] = bpf_btf_get_fd_by_id(info[0].id);
  1507. if (CHECK(btf_fd[1] == -1, "errno:%d", errno)) {
  1508. err = -1;
  1509. goto done;
  1510. }
  1511. ret = 0;
  1512. err = bpf_obj_get_info_by_fd(btf_fd[1], &info[1], &info_len);
  1513. if (CHECK(err || info[0].id != info[1].id ||
  1514. info[0].btf_size != info[1].btf_size ||
  1515. (ret = memcmp(user_btf[0], user_btf[1], info[0].btf_size)),
  1516. "err:%d errno:%d id0:%u id1:%u btf_size0:%u btf_size1:%u memcmp:%d",
  1517. err, errno, info[0].id, info[1].id,
  1518. info[0].btf_size, info[1].btf_size, ret)) {
  1519. err = -1;
  1520. goto done;
  1521. }
  1522. /* Test btf members in struct bpf_map_info */
  1523. create_attr.name = "test_btf_id";
  1524. create_attr.map_type = BPF_MAP_TYPE_ARRAY;
  1525. create_attr.key_size = sizeof(int);
  1526. create_attr.value_size = sizeof(unsigned int);
  1527. create_attr.max_entries = 4;
  1528. create_attr.btf_fd = btf_fd[0];
  1529. create_attr.btf_key_type_id = 1;
  1530. create_attr.btf_value_type_id = 2;
  1531. map_fd = bpf_create_map_xattr(&create_attr);
  1532. if (CHECK(map_fd == -1, "errno:%d", errno)) {
  1533. err = -1;
  1534. goto done;
  1535. }
  1536. info_len = sizeof(map_info);
  1537. err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len);
  1538. if (CHECK(err || map_info.btf_id != info[0].id ||
  1539. map_info.btf_key_type_id != 1 || map_info.btf_value_type_id != 2,
  1540. "err:%d errno:%d info.id:%u btf_id:%u btf_key_type_id:%u btf_value_type_id:%u",
  1541. err, errno, info[0].id, map_info.btf_id, map_info.btf_key_type_id,
  1542. map_info.btf_value_type_id)) {
  1543. err = -1;
  1544. goto done;
  1545. }
  1546. for (i = 0; i < 2; i++) {
  1547. close(btf_fd[i]);
  1548. btf_fd[i] = -1;
  1549. }
  1550. /* Test BTF ID is removed from the kernel */
  1551. btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
  1552. if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
  1553. err = -1;
  1554. goto done;
  1555. }
  1556. close(btf_fd[0]);
  1557. btf_fd[0] = -1;
  1558. /* The map holds the last ref to BTF and its btf_id */
  1559. close(map_fd);
  1560. map_fd = -1;
  1561. btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
  1562. if (CHECK(btf_fd[0] != -1, "BTF lingers")) {
  1563. err = -1;
  1564. goto done;
  1565. }
  1566. fprintf(stderr, "OK");
  1567. done:
  1568. if (*btf_log_buf && (err || args.always_log))
  1569. fprintf(stderr, "\n%s", btf_log_buf);
  1570. free(raw_btf);
  1571. if (map_fd != -1)
  1572. close(map_fd);
  1573. for (i = 0; i < 2; i++) {
  1574. free(user_btf[i]);
  1575. if (btf_fd[i] != -1)
  1576. close(btf_fd[i]);
  1577. }
  1578. return err;
  1579. }
  1580. static int do_test_get_info(unsigned int test_num)
  1581. {
  1582. const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
  1583. unsigned int raw_btf_size, user_btf_size, expected_nbytes;
  1584. uint8_t *raw_btf = NULL, *user_btf = NULL;
  1585. struct bpf_btf_info info = {};
  1586. int btf_fd = -1, err, ret;
  1587. uint32_t info_len;
  1588. fprintf(stderr, "BTF GET_INFO test[%u] (%s): ",
  1589. test_num, test->descr);
  1590. if (test->special_test)
  1591. return test->special_test(test_num);
  1592. raw_btf = btf_raw_create(&hdr_tmpl,
  1593. test->raw_types,
  1594. test->str_sec,
  1595. test->str_sec_size,
  1596. &raw_btf_size);
  1597. if (!raw_btf)
  1598. return -1;
  1599. *btf_log_buf = '\0';
  1600. user_btf = malloc(raw_btf_size);
  1601. if (CHECK(!user_btf, "!user_btf")) {
  1602. err = -1;
  1603. goto done;
  1604. }
  1605. btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
  1606. btf_log_buf, BTF_LOG_BUF_SIZE,
  1607. args.always_log);
  1608. if (CHECK(btf_fd == -1, "errno:%d", errno)) {
  1609. err = -1;
  1610. goto done;
  1611. }
  1612. user_btf_size = (int)raw_btf_size + test->btf_size_delta;
  1613. expected_nbytes = min(raw_btf_size, user_btf_size);
  1614. if (raw_btf_size > expected_nbytes)
  1615. memset(user_btf + expected_nbytes, 0xff,
  1616. raw_btf_size - expected_nbytes);
  1617. info_len = sizeof(info);
  1618. info.btf = ptr_to_u64(user_btf);
  1619. info.btf_size = user_btf_size;
  1620. ret = 0;
  1621. err = bpf_obj_get_info_by_fd(btf_fd, &info, &info_len);
  1622. if (CHECK(err || !info.id || info_len != sizeof(info) ||
  1623. info.btf_size != raw_btf_size ||
  1624. (ret = memcmp(raw_btf, user_btf, expected_nbytes)),
  1625. "err:%d errno:%d info.id:%u info_len:%u sizeof(info):%lu raw_btf_size:%u info.btf_size:%u expected_nbytes:%u memcmp:%d",
  1626. err, errno, info.id, info_len, sizeof(info),
  1627. raw_btf_size, info.btf_size, expected_nbytes, ret)) {
  1628. err = -1;
  1629. goto done;
  1630. }
  1631. while (expected_nbytes < raw_btf_size) {
  1632. fprintf(stderr, "%u...", expected_nbytes);
  1633. if (CHECK(user_btf[expected_nbytes++] != 0xff,
  1634. "user_btf[%u]:%x != 0xff", expected_nbytes - 1,
  1635. user_btf[expected_nbytes - 1])) {
  1636. err = -1;
  1637. goto done;
  1638. }
  1639. }
  1640. fprintf(stderr, "OK");
  1641. done:
  1642. if (*btf_log_buf && (err || args.always_log))
  1643. fprintf(stderr, "\n%s", btf_log_buf);
  1644. free(raw_btf);
  1645. free(user_btf);
  1646. if (btf_fd != -1)
  1647. close(btf_fd);
  1648. return err;
  1649. }
  1650. static int test_get_info(void)
  1651. {
  1652. unsigned int i;
  1653. int err = 0;
  1654. if (args.get_info_test_num)
  1655. return count_result(do_test_get_info(args.get_info_test_num));
  1656. for (i = 1; i <= ARRAY_SIZE(get_info_tests); i++)
  1657. err |= count_result(do_test_get_info(i));
  1658. return err;
  1659. }
  1660. struct btf_file_test {
  1661. const char *file;
  1662. bool btf_kv_notfound;
  1663. };
  1664. static struct btf_file_test file_tests[] = {
  1665. {
  1666. .file = "test_btf_haskv.o",
  1667. },
  1668. {
  1669. .file = "test_btf_nokv.o",
  1670. .btf_kv_notfound = true,
  1671. },
  1672. };
  1673. static int file_has_btf_elf(const char *fn)
  1674. {
  1675. Elf_Scn *scn = NULL;
  1676. GElf_Ehdr ehdr;
  1677. int elf_fd;
  1678. Elf *elf;
  1679. int ret;
  1680. if (CHECK(elf_version(EV_CURRENT) == EV_NONE,
  1681. "elf_version(EV_CURRENT) == EV_NONE"))
  1682. return -1;
  1683. elf_fd = open(fn, O_RDONLY);
  1684. if (CHECK(elf_fd == -1, "open(%s): errno:%d", fn, errno))
  1685. return -1;
  1686. elf = elf_begin(elf_fd, ELF_C_READ, NULL);
  1687. if (CHECK(!elf, "elf_begin(%s): %s", fn, elf_errmsg(elf_errno()))) {
  1688. ret = -1;
  1689. goto done;
  1690. }
  1691. if (CHECK(!gelf_getehdr(elf, &ehdr), "!gelf_getehdr(%s)", fn)) {
  1692. ret = -1;
  1693. goto done;
  1694. }
  1695. while ((scn = elf_nextscn(elf, scn))) {
  1696. const char *sh_name;
  1697. GElf_Shdr sh;
  1698. if (CHECK(gelf_getshdr(scn, &sh) != &sh,
  1699. "file:%s gelf_getshdr != &sh", fn)) {
  1700. ret = -1;
  1701. goto done;
  1702. }
  1703. sh_name = elf_strptr(elf, ehdr.e_shstrndx, sh.sh_name);
  1704. if (!strcmp(sh_name, BTF_ELF_SEC)) {
  1705. ret = 1;
  1706. goto done;
  1707. }
  1708. }
  1709. ret = 0;
  1710. done:
  1711. close(elf_fd);
  1712. elf_end(elf);
  1713. return ret;
  1714. }
  1715. static int do_test_file(unsigned int test_num)
  1716. {
  1717. const struct btf_file_test *test = &file_tests[test_num - 1];
  1718. struct bpf_object *obj = NULL;
  1719. struct bpf_program *prog;
  1720. struct bpf_map *map;
  1721. int err;
  1722. fprintf(stderr, "BTF libbpf test[%u] (%s): ", test_num,
  1723. test->file);
  1724. err = file_has_btf_elf(test->file);
  1725. if (err == -1)
  1726. return err;
  1727. if (err == 0) {
  1728. fprintf(stderr, "SKIP. No ELF %s found", BTF_ELF_SEC);
  1729. skip_cnt++;
  1730. return 0;
  1731. }
  1732. obj = bpf_object__open(test->file);
  1733. if (CHECK(IS_ERR(obj), "obj: %ld", PTR_ERR(obj)))
  1734. return PTR_ERR(obj);
  1735. err = bpf_object__btf_fd(obj);
  1736. if (CHECK(err == -1, "bpf_object__btf_fd: -1"))
  1737. goto done;
  1738. prog = bpf_program__next(NULL, obj);
  1739. if (CHECK(!prog, "Cannot find bpf_prog")) {
  1740. err = -1;
  1741. goto done;
  1742. }
  1743. bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
  1744. err = bpf_object__load(obj);
  1745. if (CHECK(err < 0, "bpf_object__load: %d", err))
  1746. goto done;
  1747. map = bpf_object__find_map_by_name(obj, "btf_map");
  1748. if (CHECK(!map, "btf_map not found")) {
  1749. err = -1;
  1750. goto done;
  1751. }
  1752. err = (bpf_map__btf_key_type_id(map) == 0 || bpf_map__btf_value_type_id(map) == 0)
  1753. != test->btf_kv_notfound;
  1754. if (CHECK(err, "btf_key_type_id:%u btf_value_type_id:%u test->btf_kv_notfound:%u",
  1755. bpf_map__btf_key_type_id(map), bpf_map__btf_value_type_id(map),
  1756. test->btf_kv_notfound))
  1757. goto done;
  1758. fprintf(stderr, "OK");
  1759. done:
  1760. bpf_object__close(obj);
  1761. return err;
  1762. }
  1763. static int test_file(void)
  1764. {
  1765. unsigned int i;
  1766. int err = 0;
  1767. if (args.file_test_num)
  1768. return count_result(do_test_file(args.file_test_num));
  1769. for (i = 1; i <= ARRAY_SIZE(file_tests); i++)
  1770. err |= count_result(do_test_file(i));
  1771. return err;
  1772. }
  1773. const char *pprint_enum_str[] = {
  1774. "ENUM_ZERO",
  1775. "ENUM_ONE",
  1776. "ENUM_TWO",
  1777. "ENUM_THREE",
  1778. };
  1779. struct pprint_mapv {
  1780. uint32_t ui32;
  1781. uint16_t ui16;
  1782. /* 2 bytes hole */
  1783. int32_t si32;
  1784. uint32_t unused_bits2a:2,
  1785. bits28:28,
  1786. unused_bits2b:2;
  1787. union {
  1788. uint64_t ui64;
  1789. uint8_t ui8a[8];
  1790. };
  1791. enum {
  1792. ENUM_ZERO,
  1793. ENUM_ONE,
  1794. ENUM_TWO,
  1795. ENUM_THREE,
  1796. } aenum;
  1797. };
  1798. static struct btf_raw_test pprint_test = {
  1799. .descr = "BTF pretty print test #1",
  1800. .raw_types = {
  1801. /* unsighed char */ /* [1] */
  1802. BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
  1803. /* unsigned short */ /* [2] */
  1804. BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
  1805. /* unsigned int */ /* [3] */
  1806. BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
  1807. /* int */ /* [4] */
  1808. BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
  1809. /* unsigned long long */ /* [5] */
  1810. BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
  1811. /* 2 bits */ /* [6] */
  1812. BTF_TYPE_INT_ENC(0, 0, 0, 2, 2),
  1813. /* 28 bits */ /* [7] */
  1814. BTF_TYPE_INT_ENC(0, 0, 0, 28, 4),
  1815. /* uint8_t[8] */ /* [8] */
  1816. BTF_TYPE_ARRAY_ENC(9, 1, 8),
  1817. /* typedef unsigned char uint8_t */ /* [9] */
  1818. BTF_TYPEDEF_ENC(NAME_TBD, 1),
  1819. /* typedef unsigned short uint16_t */ /* [10] */
  1820. BTF_TYPEDEF_ENC(NAME_TBD, 2),
  1821. /* typedef unsigned int uint32_t */ /* [11] */
  1822. BTF_TYPEDEF_ENC(NAME_TBD, 3),
  1823. /* typedef int int32_t */ /* [12] */
  1824. BTF_TYPEDEF_ENC(NAME_TBD, 4),
  1825. /* typedef unsigned long long uint64_t *//* [13] */
  1826. BTF_TYPEDEF_ENC(NAME_TBD, 5),
  1827. /* union (anon) */ /* [14] */
  1828. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
  1829. BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
  1830. BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
  1831. /* enum (anon) */ /* [15] */
  1832. BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
  1833. BTF_ENUM_ENC(NAME_TBD, 0),
  1834. BTF_ENUM_ENC(NAME_TBD, 1),
  1835. BTF_ENUM_ENC(NAME_TBD, 2),
  1836. BTF_ENUM_ENC(NAME_TBD, 3),
  1837. /* struct pprint_mapv */ /* [16] */
  1838. BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 8), 28),
  1839. BTF_MEMBER_ENC(NAME_TBD, 11, 0), /* uint32_t ui32 */
  1840. BTF_MEMBER_ENC(NAME_TBD, 10, 32), /* uint16_t ui16 */
  1841. BTF_MEMBER_ENC(NAME_TBD, 12, 64), /* int32_t si32 */
  1842. BTF_MEMBER_ENC(NAME_TBD, 6, 96), /* unused_bits2a */
  1843. BTF_MEMBER_ENC(NAME_TBD, 7, 98), /* bits28 */
  1844. BTF_MEMBER_ENC(NAME_TBD, 6, 126), /* unused_bits2b */
  1845. BTF_MEMBER_ENC(0, 14, 128), /* union (anon) */
  1846. BTF_MEMBER_ENC(NAME_TBD, 15, 192), /* aenum */
  1847. BTF_END_RAW,
  1848. },
  1849. .str_sec = "\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum",
  1850. .str_sec_size = sizeof("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum"),
  1851. .map_type = BPF_MAP_TYPE_ARRAY,
  1852. .map_name = "pprint_test",
  1853. .key_size = sizeof(unsigned int),
  1854. .value_size = sizeof(struct pprint_mapv),
  1855. .key_type_id = 3, /* unsigned int */
  1856. .value_type_id = 16, /* struct pprint_mapv */
  1857. .max_entries = 128 * 1024,
  1858. };
  1859. static void set_pprint_mapv(struct pprint_mapv *v, uint32_t i)
  1860. {
  1861. v->ui32 = i;
  1862. v->si32 = -i;
  1863. v->unused_bits2a = 3;
  1864. v->bits28 = i;
  1865. v->unused_bits2b = 3;
  1866. v->ui64 = i;
  1867. v->aenum = i & 0x03;
  1868. }
  1869. static int test_pprint(void)
  1870. {
  1871. const struct btf_raw_test *test = &pprint_test;
  1872. struct bpf_create_map_attr create_attr = {};
  1873. int map_fd = -1, btf_fd = -1;
  1874. struct pprint_mapv mapv = {};
  1875. unsigned int raw_btf_size;
  1876. char expected_line[255];
  1877. FILE *pin_file = NULL;
  1878. char pin_path[255];
  1879. size_t line_len = 0;
  1880. char *line = NULL;
  1881. unsigned int key;
  1882. uint8_t *raw_btf;
  1883. ssize_t nread;
  1884. int err, ret;
  1885. fprintf(stderr, "%s......", test->descr);
  1886. raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
  1887. test->str_sec, test->str_sec_size,
  1888. &raw_btf_size);
  1889. if (!raw_btf)
  1890. return -1;
  1891. *btf_log_buf = '\0';
  1892. btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
  1893. btf_log_buf, BTF_LOG_BUF_SIZE,
  1894. args.always_log);
  1895. free(raw_btf);
  1896. if (CHECK(btf_fd == -1, "errno:%d", errno)) {
  1897. err = -1;
  1898. goto done;
  1899. }
  1900. create_attr.name = test->map_name;
  1901. create_attr.map_type = test->map_type;
  1902. create_attr.key_size = test->key_size;
  1903. create_attr.value_size = test->value_size;
  1904. create_attr.max_entries = test->max_entries;
  1905. create_attr.btf_fd = btf_fd;
  1906. create_attr.btf_key_type_id = test->key_type_id;
  1907. create_attr.btf_value_type_id = test->value_type_id;
  1908. map_fd = bpf_create_map_xattr(&create_attr);
  1909. if (CHECK(map_fd == -1, "errno:%d", errno)) {
  1910. err = -1;
  1911. goto done;
  1912. }
  1913. ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
  1914. "/sys/fs/bpf", test->map_name);
  1915. if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long",
  1916. "/sys/fs/bpf", test->map_name)) {
  1917. err = -1;
  1918. goto done;
  1919. }
  1920. err = bpf_obj_pin(map_fd, pin_path);
  1921. if (CHECK(err, "bpf_obj_pin(%s): errno:%d.", pin_path, errno))
  1922. goto done;
  1923. for (key = 0; key < test->max_entries; key++) {
  1924. set_pprint_mapv(&mapv, key);
  1925. bpf_map_update_elem(map_fd, &key, &mapv, 0);
  1926. }
  1927. pin_file = fopen(pin_path, "r");
  1928. if (CHECK(!pin_file, "fopen(%s): errno:%d", pin_path, errno)) {
  1929. err = -1;
  1930. goto done;
  1931. }
  1932. /* Skip lines start with '#' */
  1933. while ((nread = getline(&line, &line_len, pin_file)) > 0 &&
  1934. *line == '#')
  1935. ;
  1936. if (CHECK(nread <= 0, "Unexpected EOF")) {
  1937. err = -1;
  1938. goto done;
  1939. }
  1940. key = 0;
  1941. do {
  1942. ssize_t nexpected_line;
  1943. set_pprint_mapv(&mapv, key);
  1944. nexpected_line = snprintf(expected_line, sizeof(expected_line),
  1945. "%u: {%u,0,%d,0x%x,0x%x,0x%x,{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s}\n",
  1946. key,
  1947. mapv.ui32, mapv.si32,
  1948. mapv.unused_bits2a, mapv.bits28, mapv.unused_bits2b,
  1949. mapv.ui64,
  1950. mapv.ui8a[0], mapv.ui8a[1], mapv.ui8a[2], mapv.ui8a[3],
  1951. mapv.ui8a[4], mapv.ui8a[5], mapv.ui8a[6], mapv.ui8a[7],
  1952. pprint_enum_str[mapv.aenum]);
  1953. if (CHECK(nexpected_line == sizeof(expected_line),
  1954. "expected_line is too long")) {
  1955. err = -1;
  1956. goto done;
  1957. }
  1958. if (strcmp(expected_line, line)) {
  1959. err = -1;
  1960. fprintf(stderr, "unexpected pprint output\n");
  1961. fprintf(stderr, "expected: %s", expected_line);
  1962. fprintf(stderr, " read: %s", line);
  1963. goto done;
  1964. }
  1965. nread = getline(&line, &line_len, pin_file);
  1966. } while (++key < test->max_entries && nread > 0);
  1967. if (CHECK(key < test->max_entries,
  1968. "Unexpected EOF. key:%u test->max_entries:%u",
  1969. key, test->max_entries)) {
  1970. err = -1;
  1971. goto done;
  1972. }
  1973. if (CHECK(nread > 0, "Unexpected extra pprint output: %s", line)) {
  1974. err = -1;
  1975. goto done;
  1976. }
  1977. err = 0;
  1978. done:
  1979. if (!err)
  1980. fprintf(stderr, "OK");
  1981. if (*btf_log_buf && (err || args.always_log))
  1982. fprintf(stderr, "\n%s", btf_log_buf);
  1983. if (btf_fd != -1)
  1984. close(btf_fd);
  1985. if (map_fd != -1)
  1986. close(map_fd);
  1987. if (pin_file)
  1988. fclose(pin_file);
  1989. unlink(pin_path);
  1990. free(line);
  1991. return err;
  1992. }
  1993. static void usage(const char *cmd)
  1994. {
  1995. fprintf(stderr, "Usage: %s [-l] [[-r test_num (1 - %zu)] | [-g test_num (1 - %zu)] | [-f test_num (1 - %zu)] | [-p]]\n",
  1996. cmd, ARRAY_SIZE(raw_tests), ARRAY_SIZE(get_info_tests),
  1997. ARRAY_SIZE(file_tests));
  1998. }
  1999. static int parse_args(int argc, char **argv)
  2000. {
  2001. const char *optstr = "lpf:r:g:";
  2002. int opt;
  2003. while ((opt = getopt(argc, argv, optstr)) != -1) {
  2004. switch (opt) {
  2005. case 'l':
  2006. args.always_log = true;
  2007. break;
  2008. case 'f':
  2009. args.file_test_num = atoi(optarg);
  2010. args.file_test = true;
  2011. break;
  2012. case 'r':
  2013. args.raw_test_num = atoi(optarg);
  2014. args.raw_test = true;
  2015. break;
  2016. case 'g':
  2017. args.get_info_test_num = atoi(optarg);
  2018. args.get_info_test = true;
  2019. break;
  2020. case 'p':
  2021. args.pprint_test = true;
  2022. break;
  2023. case 'h':
  2024. usage(argv[0]);
  2025. exit(0);
  2026. default:
  2027. usage(argv[0]);
  2028. return -1;
  2029. }
  2030. }
  2031. if (args.raw_test_num &&
  2032. (args.raw_test_num < 1 ||
  2033. args.raw_test_num > ARRAY_SIZE(raw_tests))) {
  2034. fprintf(stderr, "BTF raw test number must be [1 - %zu]\n",
  2035. ARRAY_SIZE(raw_tests));
  2036. return -1;
  2037. }
  2038. if (args.file_test_num &&
  2039. (args.file_test_num < 1 ||
  2040. args.file_test_num > ARRAY_SIZE(file_tests))) {
  2041. fprintf(stderr, "BTF file test number must be [1 - %zu]\n",
  2042. ARRAY_SIZE(file_tests));
  2043. return -1;
  2044. }
  2045. if (args.get_info_test_num &&
  2046. (args.get_info_test_num < 1 ||
  2047. args.get_info_test_num > ARRAY_SIZE(get_info_tests))) {
  2048. fprintf(stderr, "BTF get info test number must be [1 - %zu]\n",
  2049. ARRAY_SIZE(get_info_tests));
  2050. return -1;
  2051. }
  2052. return 0;
  2053. }
  2054. static void print_summary(void)
  2055. {
  2056. fprintf(stderr, "PASS:%u SKIP:%u FAIL:%u\n",
  2057. pass_cnt - skip_cnt, skip_cnt, error_cnt);
  2058. }
  2059. int main(int argc, char **argv)
  2060. {
  2061. int err = 0;
  2062. err = parse_args(argc, argv);
  2063. if (err)
  2064. return err;
  2065. if (args.always_log)
  2066. libbpf_set_print(__base_pr, __base_pr, __base_pr);
  2067. if (args.raw_test)
  2068. err |= test_raw();
  2069. if (args.get_info_test)
  2070. err |= test_get_info();
  2071. if (args.file_test)
  2072. err |= test_file();
  2073. if (args.pprint_test)
  2074. err |= count_result(test_pprint());
  2075. if (args.raw_test || args.get_info_test || args.file_test ||
  2076. args.pprint_test)
  2077. goto done;
  2078. err |= test_raw();
  2079. err |= test_get_info();
  2080. err |= test_file();
  2081. done:
  2082. print_summary();
  2083. return err;
  2084. }