obj.rs 77 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390
  1. //! Object file loading, parsing, and relocation.
  2. use alloc::{
  3. borrow::ToOwned,
  4. ffi::CString,
  5. string::{String, ToString},
  6. vec::Vec,
  7. };
  8. use core::{ffi::CStr, mem, ptr, str::FromStr};
  9. use log::debug;
  10. use object::{
  11. read::{Object as ElfObject, ObjectSection, Section as ObjSection},
  12. Endianness, ObjectSymbol, ObjectSymbolTable, RelocationTarget, SectionIndex, SectionKind,
  13. SymbolKind,
  14. };
  15. use crate::{
  16. btf::BtfFeatures,
  17. generated::{BPF_CALL, BPF_JMP, BPF_K},
  18. maps::{BtfMap, LegacyMap, Map, MINIMUM_MAP_SIZE},
  19. relocation::*,
  20. util::HashMap,
  21. };
  22. #[cfg(not(feature = "std"))]
  23. use crate::std;
  24. use crate::{
  25. btf::{Btf, BtfError, BtfExt, BtfType},
  26. generated::{bpf_insn, bpf_map_info, bpf_map_type::BPF_MAP_TYPE_ARRAY, BPF_F_RDONLY_PROG},
  27. maps::{bpf_map_def, BtfMapDef, PinningType},
  28. programs::{CgroupSockAddrAttachType, CgroupSockAttachType, CgroupSockoptAttachType},
  29. };
  30. use core::slice::from_raw_parts_mut;
  31. use crate::btf::{Array, DataSecEntry, FuncSecInfo, LineSecInfo};
  32. const KERNEL_VERSION_ANY: u32 = 0xFFFF_FFFE;
  33. /// Features implements BPF and BTF feature detection
  34. #[derive(Default, Debug)]
  35. #[allow(missing_docs)]
  36. pub struct Features {
  37. pub bpf_name: bool,
  38. pub bpf_probe_read_kernel: bool,
  39. pub bpf_perf_link: bool,
  40. pub btf: Option<BtfFeatures>,
  41. }
  42. /// The loaded object file representation
  43. #[derive(Clone)]
  44. pub struct Object {
  45. /// The endianness
  46. pub endianness: Endianness,
  47. /// Program license
  48. pub license: CString,
  49. /// Kernel version
  50. pub kernel_version: KernelVersion,
  51. /// Program BTF
  52. pub btf: Option<Btf>,
  53. /// Program BTF.ext
  54. pub btf_ext: Option<BtfExt>,
  55. /// Referenced maps
  56. pub maps: HashMap<String, Map>,
  57. /// A hash map of programs, using the program names parsed
  58. /// in [ProgramSection]s as keys.
  59. pub programs: HashMap<String, Program>,
  60. /// Functions
  61. pub functions: HashMap<(usize, u64), Function>,
  62. pub(crate) relocations: HashMap<SectionIndex, HashMap<u64, Relocation>>,
  63. pub(crate) symbol_table: HashMap<usize, Symbol>,
  64. pub(crate) section_sizes: HashMap<String, u64>,
  65. // symbol_offset_by_name caches symbols that could be referenced from a
  66. // BTF VAR type so the offsets can be fixed up
  67. pub(crate) symbol_offset_by_name: HashMap<String, u64>,
  68. }
  69. /// An eBPF program
  70. #[derive(Debug, Clone)]
  71. pub struct Program {
  72. /// The license
  73. pub license: CString,
  74. /// The kernel version
  75. pub kernel_version: KernelVersion,
  76. /// The section containing the program
  77. pub section: ProgramSection,
  78. /// The function
  79. pub function: Function,
  80. }
  81. /// An eBPF function
  82. #[derive(Debug, Clone)]
  83. pub struct Function {
  84. /// The address
  85. pub address: u64,
  86. /// The function name
  87. pub name: String,
  88. /// The section index
  89. pub section_index: SectionIndex,
  90. /// The section offset
  91. pub section_offset: usize,
  92. /// The eBPF byte code instructions
  93. pub instructions: Vec<bpf_insn>,
  94. /// The function info
  95. pub func_info: FuncSecInfo,
  96. /// The line info
  97. pub line_info: LineSecInfo,
  98. /// Function info record size
  99. pub func_info_rec_size: usize,
  100. /// Line info record size
  101. pub line_info_rec_size: usize,
  102. }
  103. /// Section types containing eBPF programs
  104. ///
  105. /// # Section Name Parsing
  106. ///
  107. /// Section types are parsed from the section name strings.
  108. ///
  109. /// In order for Aya to treat a section as a [ProgramSection],
  110. /// there are a few requirements:
  111. /// - The section must be an executable code section.
  112. /// - The section name must conform to [Program Types and ELF Sections].
  113. ///
  114. /// [Program Types and ELF Sections]: https://docs.kernel.org/bpf/libbpf/program_types.html
  115. ///
  116. /// ## Program Name
  117. ///
  118. /// Each section name is parsed into a section type and a program name.
  119. ///
  120. /// Generally speaking,
  121. /// - if the section name does not contain any slashes,
  122. /// then the program name is just that section name;
  123. /// - if there are some slashes, the name is `section_name.rsplitn(2, '/')[0]`,
  124. /// - except for tracepoint programs, for which the name is
  125. /// `section_name.splitn(2, '/')[1]`.
  126. ///
  127. /// ```rust
  128. /// use aya_obj::ProgramSection;
  129. /// use std::str::FromStr;
  130. ///
  131. /// assert_eq!(
  132. /// ProgramSection::from_str("kprobe/do_unlinkat")
  133. /// .unwrap().name(),
  134. /// "do_unlinkat",
  135. /// );
  136. /// assert_eq!(
  137. /// ProgramSection::from_str("tracepoint/syscalls/sys_enter_openat")
  138. /// .unwrap().name(),
  139. /// "syscalls/sys_enter_openat",
  140. /// );
  141. /// ```
  142. ///
  143. /// The program name will be used in [Object] as references to each program.
  144. ///
  145. /// # Unsupported Sections
  146. ///
  147. /// Currently, the following section names are not supported yet:
  148. /// - `flow_dissector`: `BPF_PROG_TYPE_FLOW_DISSECTOR`
  149. /// - `ksyscall+` or `kretsyscall+`
  150. /// - `uprobe.s+` or `uretprobe.s+`
  151. /// - `usdt+`
  152. /// - `kprobe.multi+` or `kretprobe.multi+`: `BPF_TRACE_KPROBE_MULTI`
  153. /// - `lsm_cgroup+` or `lsm.s+`
  154. /// - `lwt_in`, `lwt_out`, `lwt_seg6local`, `lwt_xmit`
  155. /// - `raw_tp.w+`, `raw_tracepoint.w+`
  156. /// - `action`
  157. /// - `sk_reuseport/migrate`, `sk_reuseport`
  158. /// - `syscall`
  159. /// - `struct_ops+`
  160. /// - `fmod_ret+`, `fmod_ret.s+`
  161. /// - `fentry.s+`, `fexit.s+`
  162. /// - `iter+`, `iter.s+`
  163. /// - `xdp.frags/cpumap`, `xdp/cpumap`
  164. /// - `xdp.frags/devmap`, `xdp/devmap`
  165. #[derive(Debug, Clone)]
  166. #[allow(missing_docs)]
  167. pub enum ProgramSection {
  168. KRetProbe {
  169. name: String,
  170. },
  171. KProbe {
  172. name: String,
  173. },
  174. UProbe {
  175. name: String,
  176. },
  177. URetProbe {
  178. name: String,
  179. },
  180. TracePoint {
  181. name: String,
  182. },
  183. SocketFilter {
  184. name: String,
  185. },
  186. Xdp {
  187. name: String,
  188. frags_supported: bool,
  189. },
  190. SkMsg {
  191. name: String,
  192. },
  193. SkSkbStreamParser {
  194. name: String,
  195. },
  196. SkSkbStreamVerdict {
  197. name: String,
  198. },
  199. SockOps {
  200. name: String,
  201. },
  202. SchedClassifier {
  203. name: String,
  204. },
  205. CgroupSkb {
  206. name: String,
  207. },
  208. CgroupSkbIngress {
  209. name: String,
  210. },
  211. CgroupSkbEgress {
  212. name: String,
  213. },
  214. CgroupSockAddr {
  215. name: String,
  216. attach_type: CgroupSockAddrAttachType,
  217. },
  218. CgroupSysctl {
  219. name: String,
  220. },
  221. CgroupSockopt {
  222. name: String,
  223. attach_type: CgroupSockoptAttachType,
  224. },
  225. LircMode2 {
  226. name: String,
  227. },
  228. PerfEvent {
  229. name: String,
  230. },
  231. RawTracePoint {
  232. name: String,
  233. },
  234. Lsm {
  235. name: String,
  236. },
  237. BtfTracePoint {
  238. name: String,
  239. },
  240. FEntry {
  241. name: String,
  242. },
  243. FExit {
  244. name: String,
  245. },
  246. Extension {
  247. name: String,
  248. },
  249. SkLookup {
  250. name: String,
  251. },
  252. CgroupSock {
  253. name: String,
  254. attach_type: CgroupSockAttachType,
  255. },
  256. CgroupDevice {
  257. name: String,
  258. },
  259. }
  260. impl ProgramSection {
  261. /// Returns the program name
  262. pub fn name(&self) -> &str {
  263. match self {
  264. ProgramSection::KRetProbe { name } => name,
  265. ProgramSection::KProbe { name } => name,
  266. ProgramSection::UProbe { name } => name,
  267. ProgramSection::URetProbe { name } => name,
  268. ProgramSection::TracePoint { name } => name,
  269. ProgramSection::SocketFilter { name } => name,
  270. ProgramSection::Xdp { name, .. } => name,
  271. ProgramSection::SkMsg { name } => name,
  272. ProgramSection::SkSkbStreamParser { name } => name,
  273. ProgramSection::SkSkbStreamVerdict { name } => name,
  274. ProgramSection::SockOps { name } => name,
  275. ProgramSection::SchedClassifier { name } => name,
  276. ProgramSection::CgroupSkb { name, .. } => name,
  277. ProgramSection::CgroupSkbIngress { name, .. } => name,
  278. ProgramSection::CgroupSkbEgress { name, .. } => name,
  279. ProgramSection::CgroupSockAddr { name, .. } => name,
  280. ProgramSection::CgroupSysctl { name } => name,
  281. ProgramSection::CgroupSockopt { name, .. } => name,
  282. ProgramSection::LircMode2 { name } => name,
  283. ProgramSection::PerfEvent { name } => name,
  284. ProgramSection::RawTracePoint { name } => name,
  285. ProgramSection::Lsm { name } => name,
  286. ProgramSection::BtfTracePoint { name } => name,
  287. ProgramSection::FEntry { name } => name,
  288. ProgramSection::FExit { name } => name,
  289. ProgramSection::Extension { name } => name,
  290. ProgramSection::SkLookup { name } => name,
  291. ProgramSection::CgroupSock { name, .. } => name,
  292. ProgramSection::CgroupDevice { name } => name,
  293. }
  294. }
  295. }
  296. impl FromStr for ProgramSection {
  297. type Err = ParseError;
  298. fn from_str(section: &str) -> Result<ProgramSection, ParseError> {
  299. use ProgramSection::*;
  300. // parse the common case, eg "xdp/program_name" or
  301. // "sk_skb/stream_verdict/program_name"
  302. let mut parts = section.rsplitn(2, '/').collect::<Vec<_>>();
  303. if parts.len() == 1 {
  304. parts.push(parts[0]);
  305. }
  306. let kind = parts[1];
  307. let name = parts[0].to_owned();
  308. Ok(match kind {
  309. "kprobe" => KProbe { name },
  310. "kretprobe" => KRetProbe { name },
  311. "uprobe" => UProbe { name },
  312. "uretprobe" => URetProbe { name },
  313. "xdp" => Xdp {
  314. name,
  315. frags_supported: false,
  316. },
  317. "xdp.frags" => Xdp {
  318. name,
  319. frags_supported: true,
  320. },
  321. "tp_btf" => BtfTracePoint { name },
  322. _ if kind.starts_with("tracepoint") || kind.starts_with("tp") => {
  323. // tracepoint sections are named `tracepoint/category/event_name`,
  324. // and we want to parse the name as "category/event_name"
  325. let name = section.splitn(2, '/').last().unwrap().to_owned();
  326. TracePoint { name }
  327. }
  328. "socket" => SocketFilter { name },
  329. "sk_msg" => SkMsg { name },
  330. "sk_skb" => match &*name {
  331. "stream_parser" => SkSkbStreamParser { name },
  332. "stream_verdict" => SkSkbStreamVerdict { name },
  333. _ => {
  334. return Err(ParseError::InvalidProgramSection {
  335. section: section.to_owned(),
  336. })
  337. }
  338. },
  339. "sk_skb/stream_parser" => SkSkbStreamParser { name },
  340. "sk_skb/stream_verdict" => SkSkbStreamVerdict { name },
  341. "sockops" => SockOps { name },
  342. "classifier" => SchedClassifier { name },
  343. "cgroup_skb" => match &*name {
  344. "ingress" => CgroupSkbIngress { name },
  345. "egress" => CgroupSkbEgress { name },
  346. _ => {
  347. return Err(ParseError::InvalidProgramSection {
  348. section: section.to_owned(),
  349. })
  350. }
  351. },
  352. "cgroup_skb/ingress" => CgroupSkbIngress { name },
  353. "cgroup_skb/egress" => CgroupSkbEgress { name },
  354. "cgroup/skb" => CgroupSkb { name },
  355. "cgroup/sock" => CgroupSock {
  356. name,
  357. attach_type: CgroupSockAttachType::default(),
  358. },
  359. "cgroup/sysctl" => CgroupSysctl { name },
  360. "cgroup/dev" => CgroupDevice { name },
  361. "cgroup/getsockopt" => CgroupSockopt {
  362. name,
  363. attach_type: CgroupSockoptAttachType::Get,
  364. },
  365. "cgroup/setsockopt" => CgroupSockopt {
  366. name,
  367. attach_type: CgroupSockoptAttachType::Set,
  368. },
  369. "cgroup" => match &*name {
  370. "skb" => CgroupSkb { name },
  371. "sysctl" => CgroupSysctl { name },
  372. "dev" => CgroupDevice { name },
  373. "getsockopt" | "setsockopt" => {
  374. if let Ok(attach_type) = CgroupSockoptAttachType::try_from(name.as_str()) {
  375. CgroupSockopt { name, attach_type }
  376. } else {
  377. return Err(ParseError::InvalidProgramSection {
  378. section: section.to_owned(),
  379. });
  380. }
  381. }
  382. "sock" => CgroupSock {
  383. name,
  384. attach_type: CgroupSockAttachType::default(),
  385. },
  386. "post_bind4" | "post_bind6" | "sock_create" | "sock_release" => {
  387. if let Ok(attach_type) = CgroupSockAttachType::try_from(name.as_str()) {
  388. CgroupSock { name, attach_type }
  389. } else {
  390. return Err(ParseError::InvalidProgramSection {
  391. section: section.to_owned(),
  392. });
  393. }
  394. }
  395. _ => {
  396. if let Ok(attach_type) = CgroupSockAddrAttachType::try_from(name.as_str()) {
  397. CgroupSockAddr { name, attach_type }
  398. } else {
  399. return Err(ParseError::InvalidProgramSection {
  400. section: section.to_owned(),
  401. });
  402. }
  403. }
  404. },
  405. "cgroup/post_bind4" => CgroupSock {
  406. name,
  407. attach_type: CgroupSockAttachType::PostBind4,
  408. },
  409. "cgroup/post_bind6" => CgroupSock {
  410. name,
  411. attach_type: CgroupSockAttachType::PostBind6,
  412. },
  413. "cgroup/sock_create" => CgroupSock {
  414. name,
  415. attach_type: CgroupSockAttachType::SockCreate,
  416. },
  417. "cgroup/sock_release" => CgroupSock {
  418. name,
  419. attach_type: CgroupSockAttachType::SockRelease,
  420. },
  421. "cgroup/bind4" => CgroupSockAddr {
  422. name,
  423. attach_type: CgroupSockAddrAttachType::Bind4,
  424. },
  425. "cgroup/bind6" => CgroupSockAddr {
  426. name,
  427. attach_type: CgroupSockAddrAttachType::Bind6,
  428. },
  429. "cgroup/connect4" => CgroupSockAddr {
  430. name,
  431. attach_type: CgroupSockAddrAttachType::Connect4,
  432. },
  433. "cgroup/connect6" => CgroupSockAddr {
  434. name,
  435. attach_type: CgroupSockAddrAttachType::Connect6,
  436. },
  437. "cgroup/getpeername4" => CgroupSockAddr {
  438. name,
  439. attach_type: CgroupSockAddrAttachType::GetPeerName4,
  440. },
  441. "cgroup/getpeername6" => CgroupSockAddr {
  442. name,
  443. attach_type: CgroupSockAddrAttachType::GetPeerName6,
  444. },
  445. "cgroup/getsockname4" => CgroupSockAddr {
  446. name,
  447. attach_type: CgroupSockAddrAttachType::GetSockName4,
  448. },
  449. "cgroup/getsockname6" => CgroupSockAddr {
  450. name,
  451. attach_type: CgroupSockAddrAttachType::GetSockName6,
  452. },
  453. "cgroup/sendmsg4" => CgroupSockAddr {
  454. name,
  455. attach_type: CgroupSockAddrAttachType::UDPSendMsg4,
  456. },
  457. "cgroup/sendmsg6" => CgroupSockAddr {
  458. name,
  459. attach_type: CgroupSockAddrAttachType::UDPSendMsg6,
  460. },
  461. "cgroup/recvmsg4" => CgroupSockAddr {
  462. name,
  463. attach_type: CgroupSockAddrAttachType::UDPRecvMsg4,
  464. },
  465. "cgroup/recvmsg6" => CgroupSockAddr {
  466. name,
  467. attach_type: CgroupSockAddrAttachType::UDPRecvMsg6,
  468. },
  469. "lirc_mode2" => LircMode2 { name },
  470. "perf_event" => PerfEvent { name },
  471. "raw_tp" | "raw_tracepoint" => RawTracePoint { name },
  472. "lsm" => Lsm { name },
  473. "fentry" => FEntry { name },
  474. "fexit" => FExit { name },
  475. "freplace" => Extension { name },
  476. "sk_lookup" => SkLookup { name },
  477. _ => {
  478. return Err(ParseError::InvalidProgramSection {
  479. section: section.to_owned(),
  480. })
  481. }
  482. })
  483. }
  484. }
  485. impl Object {
  486. /// Parses the binary data as an object file into an [Object]
  487. pub fn parse(data: &[u8]) -> Result<Object, ParseError> {
  488. let obj = object::read::File::parse(data).map_err(ParseError::ElfError)?;
  489. let endianness = obj.endianness();
  490. let license = if let Some(section) = obj.section_by_name("license") {
  491. parse_license(Section::try_from(&section)?.data)?
  492. } else {
  493. CString::new("GPL").unwrap()
  494. };
  495. let kernel_version = if let Some(section) = obj.section_by_name("version") {
  496. parse_version(Section::try_from(&section)?.data, endianness)?
  497. } else {
  498. KernelVersion::Any
  499. };
  500. let mut bpf_obj = Object::new(endianness, license, kernel_version);
  501. if let Some(symbol_table) = obj.symbol_table() {
  502. for symbol in symbol_table.symbols() {
  503. let name = symbol
  504. .name()
  505. .ok()
  506. .map(String::from)
  507. .ok_or(BtfError::InvalidSymbolName)?;
  508. let sym = Symbol {
  509. index: symbol.index().0,
  510. name: Some(name.clone()),
  511. section_index: symbol.section().index().map(|i| i.0),
  512. address: symbol.address(),
  513. size: symbol.size(),
  514. is_definition: symbol.is_definition(),
  515. kind: symbol.kind(),
  516. };
  517. bpf_obj.symbol_table.insert(symbol.index().0, sym);
  518. if symbol.is_global() || symbol.kind() == SymbolKind::Data {
  519. bpf_obj.symbol_offset_by_name.insert(name, symbol.address());
  520. }
  521. }
  522. }
  523. // .BTF and .BTF.ext sections must be parsed first
  524. // as they're required to prepare function and line information
  525. // when parsing program sections
  526. if let Some(s) = obj.section_by_name(".BTF") {
  527. bpf_obj.parse_section(Section::try_from(&s)?)?;
  528. if let Some(s) = obj.section_by_name(".BTF.ext") {
  529. bpf_obj.parse_section(Section::try_from(&s)?)?;
  530. }
  531. }
  532. for s in obj.sections() {
  533. if let Ok(name) = s.name() {
  534. if name == ".BTF" || name == ".BTF.ext" {
  535. continue;
  536. }
  537. }
  538. bpf_obj.parse_section(Section::try_from(&s)?)?;
  539. }
  540. Ok(bpf_obj)
  541. }
  542. fn new(endianness: Endianness, license: CString, kernel_version: KernelVersion) -> Object {
  543. Object {
  544. endianness,
  545. license,
  546. kernel_version,
  547. btf: None,
  548. btf_ext: None,
  549. maps: HashMap::new(),
  550. programs: HashMap::new(),
  551. functions: HashMap::new(),
  552. relocations: HashMap::new(),
  553. symbol_table: HashMap::new(),
  554. section_sizes: HashMap::new(),
  555. symbol_offset_by_name: HashMap::new(),
  556. }
  557. }
  558. /// Patches map data
  559. pub fn patch_map_data(&mut self, globals: HashMap<&str, &[u8]>) -> Result<(), ParseError> {
  560. let symbols: HashMap<String, &Symbol> = self
  561. .symbol_table
  562. .iter()
  563. .filter(|(_, s)| s.name.is_some())
  564. .map(|(_, s)| (s.name.as_ref().unwrap().clone(), s))
  565. .collect();
  566. for (name, data) in globals {
  567. if let Some(symbol) = symbols.get(name) {
  568. if data.len() as u64 != symbol.size {
  569. return Err(ParseError::InvalidGlobalData {
  570. name: name.to_string(),
  571. sym_size: symbol.size,
  572. data_size: data.len(),
  573. });
  574. }
  575. let (_, map) = self
  576. .maps
  577. .iter_mut()
  578. // assumption: there is only one map created per section where we're trying to
  579. // patch data. this assumption holds true for the .rodata section at least
  580. .find(|(_, m)| symbol.section_index == Some(m.section_index()))
  581. .ok_or_else(|| ParseError::MapNotFound {
  582. index: symbol.section_index.unwrap_or(0),
  583. })?;
  584. let start = symbol.address as usize;
  585. let end = start + symbol.size as usize;
  586. if start > end || end > map.data().len() {
  587. return Err(ParseError::InvalidGlobalData {
  588. name: name.to_string(),
  589. sym_size: symbol.size,
  590. data_size: data.len(),
  591. });
  592. }
  593. map.data_mut().splice(start..end, data.iter().cloned());
  594. } else {
  595. return Err(ParseError::SymbolNotFound {
  596. name: name.to_owned(),
  597. });
  598. }
  599. }
  600. Ok(())
  601. }
  602. fn parse_btf(&mut self, section: &Section) -> Result<(), BtfError> {
  603. self.btf = Some(Btf::parse(section.data, self.endianness)?);
  604. Ok(())
  605. }
  606. fn parse_btf_ext(&mut self, section: &Section) -> Result<(), BtfError> {
  607. self.btf_ext = Some(BtfExt::parse(
  608. section.data,
  609. self.endianness,
  610. self.btf.as_ref().unwrap(),
  611. )?);
  612. Ok(())
  613. }
  614. fn parse_program(&self, section: &Section) -> Result<Program, ParseError> {
  615. let prog_sec = ProgramSection::from_str(section.name)?;
  616. let name = prog_sec.name().to_owned();
  617. let (func_info, line_info, func_info_rec_size, line_info_rec_size) =
  618. if let Some(btf_ext) = &self.btf_ext {
  619. let func_info = btf_ext.func_info.get(section.name);
  620. let line_info = btf_ext.line_info.get(section.name);
  621. (
  622. func_info,
  623. line_info,
  624. btf_ext.func_info_rec_size(),
  625. btf_ext.line_info_rec_size(),
  626. )
  627. } else {
  628. (FuncSecInfo::default(), LineSecInfo::default(), 0, 0)
  629. };
  630. Ok(Program {
  631. license: self.license.clone(),
  632. kernel_version: self.kernel_version,
  633. section: prog_sec,
  634. function: Function {
  635. name,
  636. address: section.address,
  637. section_index: section.index,
  638. section_offset: 0,
  639. instructions: copy_instructions(section.data)?,
  640. func_info,
  641. line_info,
  642. func_info_rec_size,
  643. line_info_rec_size,
  644. },
  645. })
  646. }
  647. fn parse_text_section(&mut self, section: Section) -> Result<(), ParseError> {
  648. let mut symbols_by_address = HashMap::new();
  649. for sym in self.symbol_table.values() {
  650. if sym.is_definition
  651. && sym.kind == SymbolKind::Text
  652. && sym.section_index == Some(section.index.0)
  653. {
  654. if symbols_by_address.contains_key(&sym.address) {
  655. return Err(ParseError::SymbolTableConflict {
  656. section_index: section.index.0,
  657. address: sym.address,
  658. });
  659. }
  660. symbols_by_address.insert(sym.address, sym);
  661. }
  662. }
  663. let mut offset = 0;
  664. while offset < section.data.len() {
  665. let address = section.address + offset as u64;
  666. let sym = symbols_by_address
  667. .get(&address)
  668. .ok_or(ParseError::UnknownSymbol {
  669. section_index: section.index.0,
  670. address,
  671. })?;
  672. if sym.size == 0 {
  673. return Err(ParseError::InvalidSymbol {
  674. index: sym.index,
  675. name: sym.name.clone(),
  676. });
  677. }
  678. let (func_info, line_info, func_info_rec_size, line_info_rec_size) =
  679. if let Some(btf_ext) = &self.btf_ext {
  680. let bytes_offset = offset as u32 / INS_SIZE as u32;
  681. let section_size_bytes = sym.size as u32 / INS_SIZE as u32;
  682. let mut func_info = btf_ext.func_info.get(section.name);
  683. func_info.func_info.retain(|f| f.insn_off == bytes_offset);
  684. let mut line_info = btf_ext.line_info.get(section.name);
  685. line_info.line_info.retain(|l| {
  686. l.insn_off >= bytes_offset
  687. && l.insn_off < (bytes_offset + section_size_bytes)
  688. });
  689. (
  690. func_info,
  691. line_info,
  692. btf_ext.func_info_rec_size(),
  693. btf_ext.line_info_rec_size(),
  694. )
  695. } else {
  696. (FuncSecInfo::default(), LineSecInfo::default(), 0, 0)
  697. };
  698. self.functions.insert(
  699. (section.index.0, sym.address),
  700. Function {
  701. address,
  702. name: sym.name.clone().unwrap(),
  703. section_index: section.index,
  704. section_offset: offset,
  705. instructions: copy_instructions(
  706. &section.data[offset..offset + sym.size as usize],
  707. )?,
  708. func_info,
  709. line_info,
  710. func_info_rec_size,
  711. line_info_rec_size,
  712. },
  713. );
  714. offset += sym.size as usize;
  715. }
  716. if !section.relocations.is_empty() {
  717. self.relocations.insert(
  718. section.index,
  719. section
  720. .relocations
  721. .into_iter()
  722. .map(|rel| (rel.offset, rel))
  723. .collect(),
  724. );
  725. }
  726. Ok(())
  727. }
  728. fn parse_btf_maps(
  729. &mut self,
  730. section: &Section,
  731. symbols: HashMap<String, Symbol>,
  732. ) -> Result<(), ParseError> {
  733. if self.btf.is_none() {
  734. return Err(ParseError::NoBTF);
  735. }
  736. let btf = self.btf.as_ref().unwrap();
  737. for t in btf.types() {
  738. if let BtfType::DataSec(datasec) = &t {
  739. let type_name = match btf.type_name(t) {
  740. Ok(name) => name,
  741. _ => continue,
  742. };
  743. if type_name == section.name {
  744. // each btf_var_secinfo contains a map
  745. for info in &datasec.entries {
  746. let (map_name, def) = parse_btf_map_def(btf, info)?;
  747. let symbol_index = symbols
  748. .get(&map_name)
  749. .ok_or_else(|| ParseError::SymbolNotFound {
  750. name: map_name.to_string(),
  751. })?
  752. .index;
  753. self.maps.insert(
  754. map_name,
  755. Map::Btf(BtfMap {
  756. def,
  757. section_index: section.index.0,
  758. symbol_index,
  759. data: Vec::new(),
  760. }),
  761. );
  762. }
  763. }
  764. }
  765. }
  766. Ok(())
  767. }
  768. fn parse_section(&mut self, section: Section) -> Result<(), ParseError> {
  769. let mut parts = section.name.rsplitn(2, '/').collect::<Vec<_>>();
  770. parts.reverse();
  771. if parts.len() == 1
  772. && (parts[0] == "xdp"
  773. || parts[0] == "sk_msg"
  774. || parts[0] == "sockops"
  775. || parts[0] == "classifier")
  776. {
  777. parts.push(parts[0]);
  778. }
  779. self.section_sizes
  780. .insert(section.name.to_owned(), section.size);
  781. match section.kind {
  782. BpfSectionKind::Data | BpfSectionKind::Rodata | BpfSectionKind::Bss => {
  783. self.maps
  784. .insert(section.name.to_string(), parse_data_map_section(&section)?);
  785. }
  786. BpfSectionKind::Text => self.parse_text_section(section)?,
  787. BpfSectionKind::Btf => self.parse_btf(&section)?,
  788. BpfSectionKind::BtfExt => self.parse_btf_ext(&section)?,
  789. BpfSectionKind::BtfMaps => {
  790. let symbols: HashMap<String, Symbol> = self
  791. .symbol_table
  792. .values()
  793. .filter(|s| {
  794. if let Some(idx) = s.section_index {
  795. idx == section.index.0 && s.name.is_some()
  796. } else {
  797. false
  798. }
  799. })
  800. .cloned()
  801. .map(|s| (s.name.as_ref().unwrap().to_string(), s))
  802. .collect();
  803. self.parse_btf_maps(&section, symbols)?
  804. }
  805. BpfSectionKind::Maps => {
  806. // take out self.maps so we can borrow the iterator below
  807. // without cloning or collecting
  808. let mut maps = mem::take(&mut self.maps);
  809. // extract the symbols for the .maps section, we'll need them
  810. // during parsing
  811. let symbols = self.symbol_table.values().filter(|s| {
  812. s.section_index
  813. .map(|idx| idx == section.index.0)
  814. .unwrap_or(false)
  815. });
  816. let res = parse_maps_section(&mut maps, &section, symbols);
  817. // put the maps back
  818. self.maps = maps;
  819. res?
  820. }
  821. BpfSectionKind::Program => {
  822. let program = self.parse_program(&section)?;
  823. self.programs
  824. .insert(program.section.name().to_owned(), program);
  825. if !section.relocations.is_empty() {
  826. self.relocations.insert(
  827. section.index,
  828. section
  829. .relocations
  830. .into_iter()
  831. .map(|rel| (rel.offset, rel))
  832. .collect(),
  833. );
  834. }
  835. }
  836. BpfSectionKind::Undefined | BpfSectionKind::License | BpfSectionKind::Version => {}
  837. }
  838. Ok(())
  839. }
  840. /// Sanitize BPF programs.
  841. pub fn sanitize_programs(&mut self, features: &Features) {
  842. for program in self.programs.values_mut() {
  843. program.sanitize(features);
  844. }
  845. }
  846. }
  847. fn insn_is_helper_call(ins: &bpf_insn) -> bool {
  848. let klass = (ins.code & 0x07) as u32;
  849. let op = (ins.code & 0xF0) as u32;
  850. let src = (ins.code & 0x08) as u32;
  851. klass == BPF_JMP && op == BPF_CALL && src == BPF_K && ins.src_reg() == 0 && ins.dst_reg() == 0
  852. }
  853. const BPF_FUNC_PROBE_READ: i32 = 4;
  854. const BPF_FUNC_PROBE_READ_STR: i32 = 45;
  855. const BPF_FUNC_PROBE_READ_USER: i32 = 112;
  856. const BPF_FUNC_PROBE_READ_KERNEL: i32 = 113;
  857. const BPF_FUNC_PROBE_READ_USER_STR: i32 = 114;
  858. const BPF_FUNC_PROBE_READ_KERNEL_STR: i32 = 115;
  859. impl Program {
  860. fn sanitize(&mut self, features: &Features) {
  861. for inst in &mut self.function.instructions {
  862. if !insn_is_helper_call(inst) {
  863. continue;
  864. }
  865. match inst.imm {
  866. BPF_FUNC_PROBE_READ_USER | BPF_FUNC_PROBE_READ_KERNEL
  867. if !features.bpf_probe_read_kernel =>
  868. {
  869. inst.imm = BPF_FUNC_PROBE_READ;
  870. }
  871. BPF_FUNC_PROBE_READ_USER_STR | BPF_FUNC_PROBE_READ_KERNEL_STR
  872. if !features.bpf_probe_read_kernel =>
  873. {
  874. inst.imm = BPF_FUNC_PROBE_READ_STR;
  875. }
  876. _ => {}
  877. }
  878. }
  879. }
  880. }
  881. // Parses multiple map definition contained in a single `maps` section (which is
  882. // different from `.maps` which is used for BTF). We can tell where each map is
  883. // based on the symbol table.
  884. fn parse_maps_section<'a, I: Iterator<Item = &'a Symbol>>(
  885. maps: &mut HashMap<String, Map>,
  886. section: &Section,
  887. symbols: I,
  888. ) -> Result<(), ParseError> {
  889. let mut have_symbols = false;
  890. // each symbol in the section is a separate map
  891. for (i, sym) in symbols.enumerate() {
  892. let start = sym.address as usize;
  893. let end = start + sym.size as usize;
  894. let data = &section.data[start..end];
  895. let name = sym
  896. .name
  897. .as_ref()
  898. .ok_or(ParseError::MapSymbolNameNotFound { i })?;
  899. let def = parse_map_def(name, data)?;
  900. maps.insert(
  901. name.to_string(),
  902. Map::Legacy(LegacyMap {
  903. section_index: section.index.0,
  904. section_kind: section.kind,
  905. symbol_index: Some(sym.index),
  906. def,
  907. data: Vec::new(),
  908. }),
  909. );
  910. have_symbols = true;
  911. }
  912. if !have_symbols {
  913. return Err(ParseError::NoSymbolsForMapsSection);
  914. }
  915. Ok(())
  916. }
  917. /// Errors caught during parsing the object file
  918. #[derive(Debug, thiserror::Error)]
  919. #[allow(missing_docs)]
  920. pub enum ParseError {
  921. #[error("error parsing ELF data")]
  922. ElfError(object::read::Error),
  923. /// Error parsing BTF object
  924. #[error("BTF error")]
  925. BtfError(#[from] BtfError),
  926. #[error("invalid license `{data:?}`: missing NULL terminator")]
  927. MissingLicenseNullTerminator { data: Vec<u8> },
  928. #[error("invalid license `{data:?}`")]
  929. InvalidLicense { data: Vec<u8> },
  930. #[error("invalid kernel version `{data:?}`")]
  931. InvalidKernelVersion { data: Vec<u8> },
  932. #[error("error parsing section with index {index}")]
  933. SectionError {
  934. index: usize,
  935. error: object::read::Error,
  936. },
  937. #[error("unsupported relocation target")]
  938. UnsupportedRelocationTarget,
  939. #[error("invalid program section `{section}`")]
  940. InvalidProgramSection { section: String },
  941. #[error("invalid program code")]
  942. InvalidProgramCode,
  943. #[error("error parsing map `{name}`")]
  944. InvalidMapDefinition { name: String },
  945. #[error("two or more symbols in section `{section_index}` have the same address {address:#X}")]
  946. SymbolTableConflict { section_index: usize, address: u64 },
  947. #[error("unknown symbol in section `{section_index}` at address {address:#X}")]
  948. UnknownSymbol { section_index: usize, address: u64 },
  949. #[error("invalid symbol, index `{index}` name: {}", .name.as_ref().unwrap_or(&"[unknown]".into()))]
  950. InvalidSymbol { index: usize, name: Option<String> },
  951. #[error("symbol {name} has size `{sym_size}`, but provided data is of size `{data_size}`")]
  952. InvalidGlobalData {
  953. name: String,
  954. sym_size: u64,
  955. data_size: usize,
  956. },
  957. #[error("symbol with name {name} not found in the symbols table")]
  958. SymbolNotFound { name: String },
  959. #[error("map for section with index {index} not found")]
  960. MapNotFound { index: usize },
  961. #[error("the map number {i} in the `maps` section doesn't have a symbol name")]
  962. MapSymbolNameNotFound { i: usize },
  963. #[error("no symbols for `maps` section, can't parse maps")]
  964. NoSymbolsForMapsSection,
  965. /// No BTF parsed for object
  966. #[error("no BTF parsed for object")]
  967. NoBTF,
  968. }
  969. /// The kind of an ELF section.
  970. #[derive(Debug, Copy, Clone, Eq, PartialEq)]
  971. pub enum BpfSectionKind {
  972. /// Undefined
  973. Undefined,
  974. /// `maps`
  975. Maps,
  976. /// `.maps`
  977. BtfMaps,
  978. /// A program section
  979. Program,
  980. /// `.data`
  981. Data,
  982. /// `.rodata`
  983. Rodata,
  984. /// `.bss`
  985. Bss,
  986. /// `.text`
  987. Text,
  988. /// `.BTF`
  989. Btf,
  990. /// `.BTF.ext`
  991. BtfExt,
  992. /// `license`
  993. License,
  994. /// `version`
  995. Version,
  996. }
  997. impl BpfSectionKind {
  998. fn from_name(name: &str) -> BpfSectionKind {
  999. if name.starts_with("license") {
  1000. BpfSectionKind::License
  1001. } else if name.starts_with("version") {
  1002. BpfSectionKind::Version
  1003. } else if name.starts_with("maps") {
  1004. BpfSectionKind::Maps
  1005. } else if name.starts_with(".maps") {
  1006. BpfSectionKind::BtfMaps
  1007. } else if name.starts_with(".text") {
  1008. BpfSectionKind::Text
  1009. } else if name.starts_with(".bss")
  1010. || name.starts_with(".data")
  1011. || name.starts_with(".rodata")
  1012. {
  1013. BpfSectionKind::Data
  1014. } else if name == ".BTF" {
  1015. BpfSectionKind::Btf
  1016. } else if name == ".BTF.ext" {
  1017. BpfSectionKind::BtfExt
  1018. } else {
  1019. BpfSectionKind::Undefined
  1020. }
  1021. }
  1022. }
  1023. #[derive(Debug)]
  1024. struct Section<'a> {
  1025. index: SectionIndex,
  1026. kind: BpfSectionKind,
  1027. address: u64,
  1028. name: &'a str,
  1029. data: &'a [u8],
  1030. size: u64,
  1031. relocations: Vec<Relocation>,
  1032. }
  1033. impl<'data, 'file, 'a> TryFrom<&'a ObjSection<'data, 'file>> for Section<'a> {
  1034. type Error = ParseError;
  1035. fn try_from(section: &'a ObjSection) -> Result<Section<'a>, ParseError> {
  1036. let index = section.index();
  1037. let map_err = |error| ParseError::SectionError {
  1038. index: index.0,
  1039. error,
  1040. };
  1041. let name = section.name().map_err(map_err)?;
  1042. let kind = match BpfSectionKind::from_name(name) {
  1043. BpfSectionKind::Undefined => {
  1044. if section.kind() == SectionKind::Text && section.size() > 0 {
  1045. BpfSectionKind::Program
  1046. } else {
  1047. BpfSectionKind::Undefined
  1048. }
  1049. }
  1050. k => k,
  1051. };
  1052. Ok(Section {
  1053. index,
  1054. kind,
  1055. address: section.address(),
  1056. name,
  1057. data: section.data().map_err(map_err)?,
  1058. size: section.size(),
  1059. relocations: section
  1060. .relocations()
  1061. .map(|(offset, r)| {
  1062. Ok(Relocation {
  1063. symbol_index: match r.target() {
  1064. RelocationTarget::Symbol(index) => index.0,
  1065. _ => return Err(ParseError::UnsupportedRelocationTarget),
  1066. },
  1067. offset,
  1068. size: r.size(),
  1069. })
  1070. })
  1071. .collect::<Result<Vec<_>, _>>()?,
  1072. })
  1073. }
  1074. }
  1075. fn parse_license(data: &[u8]) -> Result<CString, ParseError> {
  1076. if data.len() < 2 {
  1077. return Err(ParseError::InvalidLicense {
  1078. data: data.to_vec(),
  1079. });
  1080. }
  1081. if data[data.len() - 1] != 0 {
  1082. return Err(ParseError::MissingLicenseNullTerminator {
  1083. data: data.to_vec(),
  1084. });
  1085. }
  1086. Ok(CStr::from_bytes_with_nul(data)
  1087. .map_err(|_| ParseError::InvalidLicense {
  1088. data: data.to_vec(),
  1089. })?
  1090. .to_owned())
  1091. }
  1092. fn parse_version(data: &[u8], endianness: object::Endianness) -> Result<KernelVersion, ParseError> {
  1093. let data = match data.len() {
  1094. 4 => data.try_into().unwrap(),
  1095. _ => {
  1096. return Err(ParseError::InvalidKernelVersion {
  1097. data: data.to_vec(),
  1098. })
  1099. }
  1100. };
  1101. let v = match endianness {
  1102. object::Endianness::Big => u32::from_be_bytes(data),
  1103. object::Endianness::Little => u32::from_le_bytes(data),
  1104. };
  1105. Ok(match v {
  1106. KERNEL_VERSION_ANY => KernelVersion::Any,
  1107. v => KernelVersion::Version(v),
  1108. })
  1109. }
  1110. // Gets an integer value from a BTF map defintion K/V pair.
  1111. // type_id should be a PTR to an ARRAY.
  1112. // the value is encoded in the array nr_elems field.
  1113. fn get_map_field(btf: &Btf, type_id: u32) -> Result<u32, BtfError> {
  1114. let pty = match &btf.type_by_id(type_id)? {
  1115. BtfType::Ptr(pty) => pty,
  1116. other => {
  1117. return Err(BtfError::UnexpectedBtfType {
  1118. type_id: other.btf_type().unwrap_or(0),
  1119. })
  1120. }
  1121. };
  1122. // Safety: union
  1123. let arr = match &btf.type_by_id(pty.btf_type)? {
  1124. BtfType::Array(Array { array, .. }) => array,
  1125. other => {
  1126. return Err(BtfError::UnexpectedBtfType {
  1127. type_id: other.btf_type().unwrap_or(0),
  1128. })
  1129. }
  1130. };
  1131. Ok(arr.len)
  1132. }
  1133. /// The parsed kernel version
  1134. #[derive(Copy, Clone, Debug, PartialEq, Eq)]
  1135. pub enum KernelVersion {
  1136. /// Specified version
  1137. Version(u32),
  1138. /// Any version
  1139. Any,
  1140. }
  1141. impl From<KernelVersion> for u32 {
  1142. fn from(version: KernelVersion) -> u32 {
  1143. match version {
  1144. KernelVersion::Any => KERNEL_VERSION_ANY,
  1145. KernelVersion::Version(v) => v,
  1146. }
  1147. }
  1148. }
  1149. // Parsed '.bss' '.data' and '.rodata' sections. These sections are arrays of
  1150. // bytes and are relocated based on their section index.
  1151. fn parse_data_map_section(section: &Section) -> Result<Map, ParseError> {
  1152. let (def, data) = match section.kind {
  1153. BpfSectionKind::Bss | BpfSectionKind::Data | BpfSectionKind::Rodata => {
  1154. let def = bpf_map_def {
  1155. map_type: BPF_MAP_TYPE_ARRAY as u32,
  1156. key_size: mem::size_of::<u32>() as u32,
  1157. // We need to use section.size here since
  1158. // .bss will always have data.len() == 0
  1159. value_size: section.size as u32,
  1160. max_entries: 1,
  1161. map_flags: if section.kind == BpfSectionKind::Rodata {
  1162. BPF_F_RDONLY_PROG
  1163. } else {
  1164. 0
  1165. },
  1166. ..Default::default()
  1167. };
  1168. (def, section.data.to_vec())
  1169. }
  1170. _ => unreachable!(),
  1171. };
  1172. Ok(Map::Legacy(LegacyMap {
  1173. section_index: section.index.0,
  1174. section_kind: section.kind,
  1175. // Data maps don't require symbols to be relocated
  1176. symbol_index: None,
  1177. def,
  1178. data,
  1179. }))
  1180. }
  1181. fn parse_map_def(name: &str, data: &[u8]) -> Result<bpf_map_def, ParseError> {
  1182. if data.len() < MINIMUM_MAP_SIZE {
  1183. return Err(ParseError::InvalidMapDefinition {
  1184. name: name.to_owned(),
  1185. });
  1186. }
  1187. if data.len() < mem::size_of::<bpf_map_def>() {
  1188. let mut map_def = bpf_map_def::default();
  1189. unsafe {
  1190. let map_def_ptr =
  1191. from_raw_parts_mut(&mut map_def as *mut bpf_map_def as *mut u8, data.len());
  1192. map_def_ptr.copy_from_slice(data);
  1193. }
  1194. Ok(map_def)
  1195. } else {
  1196. Ok(unsafe { ptr::read_unaligned(data.as_ptr() as *const bpf_map_def) })
  1197. }
  1198. }
  1199. fn parse_btf_map_def(btf: &Btf, info: &DataSecEntry) -> Result<(String, BtfMapDef), BtfError> {
  1200. let ty = match btf.type_by_id(info.btf_type)? {
  1201. BtfType::Var(var) => var,
  1202. other => {
  1203. return Err(BtfError::UnexpectedBtfType {
  1204. type_id: other.btf_type().unwrap_or(0),
  1205. })
  1206. }
  1207. };
  1208. let map_name = btf.string_at(ty.name_offset)?;
  1209. let mut map_def = BtfMapDef::default();
  1210. // Safety: union
  1211. let root_type = btf.resolve_type(ty.btf_type)?;
  1212. let s = match btf.type_by_id(root_type)? {
  1213. BtfType::Struct(s) => s,
  1214. other => {
  1215. return Err(BtfError::UnexpectedBtfType {
  1216. type_id: other.btf_type().unwrap_or(0),
  1217. })
  1218. }
  1219. };
  1220. for m in &s.members {
  1221. match btf.string_at(m.name_offset)?.as_ref() {
  1222. "type" => {
  1223. map_def.map_type = get_map_field(btf, m.btf_type)?;
  1224. }
  1225. "key" => {
  1226. if let BtfType::Ptr(pty) = btf.type_by_id(m.btf_type)? {
  1227. // Safety: union
  1228. let t = pty.btf_type;
  1229. map_def.key_size = btf.type_size(t)? as u32;
  1230. map_def.btf_key_type_id = t;
  1231. } else {
  1232. return Err(BtfError::UnexpectedBtfType {
  1233. type_id: m.btf_type,
  1234. });
  1235. }
  1236. }
  1237. "key_size" => {
  1238. map_def.key_size = get_map_field(btf, m.btf_type)?;
  1239. }
  1240. "value" => {
  1241. if let BtfType::Ptr(pty) = btf.type_by_id(m.btf_type)? {
  1242. let t = pty.btf_type;
  1243. map_def.value_size = btf.type_size(t)? as u32;
  1244. map_def.btf_value_type_id = t;
  1245. } else {
  1246. return Err(BtfError::UnexpectedBtfType {
  1247. type_id: m.btf_type,
  1248. });
  1249. }
  1250. }
  1251. "value_size" => {
  1252. map_def.value_size = get_map_field(btf, m.btf_type)?;
  1253. }
  1254. "max_entries" => {
  1255. map_def.max_entries = get_map_field(btf, m.btf_type)?;
  1256. }
  1257. "map_flags" => {
  1258. map_def.map_flags = get_map_field(btf, m.btf_type)?;
  1259. }
  1260. "pinning" => {
  1261. let pinning = get_map_field(btf, m.btf_type)?;
  1262. map_def.pinning = PinningType::try_from(pinning).unwrap_or_else(|_| {
  1263. debug!("{} is not a valid pin type. using PIN_NONE", pinning);
  1264. PinningType::None
  1265. });
  1266. }
  1267. other => {
  1268. debug!("skipping unknown map section: {}", other);
  1269. continue;
  1270. }
  1271. }
  1272. }
  1273. Ok((map_name.to_string(), map_def))
  1274. }
  1275. /// Parses a [bpf_map_info] into a [Map].
  1276. pub fn parse_map_info(info: bpf_map_info, pinned: PinningType) -> Map {
  1277. if info.btf_key_type_id != 0 {
  1278. Map::Btf(BtfMap {
  1279. def: BtfMapDef {
  1280. map_type: info.type_,
  1281. key_size: info.key_size,
  1282. value_size: info.value_size,
  1283. max_entries: info.max_entries,
  1284. map_flags: info.map_flags,
  1285. pinning: pinned,
  1286. btf_key_type_id: info.btf_key_type_id,
  1287. btf_value_type_id: info.btf_value_type_id,
  1288. },
  1289. section_index: 0,
  1290. symbol_index: 0,
  1291. data: Vec::new(),
  1292. })
  1293. } else {
  1294. Map::Legacy(LegacyMap {
  1295. def: bpf_map_def {
  1296. map_type: info.type_,
  1297. key_size: info.key_size,
  1298. value_size: info.value_size,
  1299. max_entries: info.max_entries,
  1300. map_flags: info.map_flags,
  1301. pinning: pinned,
  1302. id: info.id,
  1303. },
  1304. section_index: 0,
  1305. symbol_index: None,
  1306. section_kind: BpfSectionKind::Undefined,
  1307. data: Vec::new(),
  1308. })
  1309. }
  1310. }
  1311. /// Copies a block of eBPF instructions
  1312. pub fn copy_instructions(data: &[u8]) -> Result<Vec<bpf_insn>, ParseError> {
  1313. if data.len() % mem::size_of::<bpf_insn>() > 0 {
  1314. return Err(ParseError::InvalidProgramCode);
  1315. }
  1316. let instructions = data
  1317. .chunks_exact(mem::size_of::<bpf_insn>())
  1318. .map(|d| unsafe { ptr::read_unaligned(d.as_ptr() as *const bpf_insn) })
  1319. .collect::<Vec<_>>();
  1320. Ok(instructions)
  1321. }
  1322. #[cfg(test)]
  1323. mod tests {
  1324. use alloc::vec;
  1325. use matches::assert_matches;
  1326. use object::Endianness;
  1327. use super::*;
  1328. use crate::maps::PinningType;
  1329. fn fake_section<'a>(kind: BpfSectionKind, name: &'a str, data: &'a [u8]) -> Section<'a> {
  1330. Section {
  1331. index: SectionIndex(0),
  1332. kind,
  1333. address: 0,
  1334. name,
  1335. data,
  1336. size: data.len() as u64,
  1337. relocations: Vec::new(),
  1338. }
  1339. }
  1340. fn fake_ins() -> bpf_insn {
  1341. bpf_insn {
  1342. code: 0,
  1343. _bitfield_align_1: [],
  1344. _bitfield_1: bpf_insn::new_bitfield_1(0, 0),
  1345. off: 0,
  1346. imm: 0,
  1347. }
  1348. }
  1349. fn fake_sym(obj: &mut Object, section_index: usize, address: u64, name: &str, size: u64) {
  1350. let idx = obj.symbol_table.len();
  1351. obj.symbol_table.insert(
  1352. idx + 1,
  1353. Symbol {
  1354. index: idx + 1,
  1355. section_index: Some(section_index),
  1356. name: Some(name.to_string()),
  1357. address,
  1358. size,
  1359. is_definition: false,
  1360. kind: SymbolKind::Data,
  1361. },
  1362. );
  1363. }
  1364. fn bytes_of<T>(val: &T) -> &[u8] {
  1365. // Safety: This is for testing only
  1366. unsafe { crate::util::bytes_of(val) }
  1367. }
  1368. #[test]
  1369. fn test_parse_generic_error() {
  1370. assert!(matches!(
  1371. Object::parse(&b"foo"[..]),
  1372. Err(ParseError::ElfError(_))
  1373. ))
  1374. }
  1375. #[test]
  1376. fn test_parse_license() {
  1377. assert!(matches!(
  1378. parse_license(b""),
  1379. Err(ParseError::InvalidLicense { .. })
  1380. ));
  1381. assert!(matches!(
  1382. parse_license(b"\0"),
  1383. Err(ParseError::InvalidLicense { .. })
  1384. ));
  1385. assert!(matches!(
  1386. parse_license(b"GPL"),
  1387. Err(ParseError::MissingLicenseNullTerminator { .. })
  1388. ));
  1389. assert_eq!(parse_license(b"GPL\0").unwrap().to_str().unwrap(), "GPL");
  1390. }
  1391. #[test]
  1392. fn test_parse_version() {
  1393. assert!(matches!(
  1394. parse_version(b"", Endianness::Little),
  1395. Err(ParseError::InvalidKernelVersion { .. })
  1396. ));
  1397. assert!(matches!(
  1398. parse_version(b"123", Endianness::Little),
  1399. Err(ParseError::InvalidKernelVersion { .. })
  1400. ));
  1401. assert_eq!(
  1402. parse_version(&0xFFFF_FFFEu32.to_le_bytes(), Endianness::Little)
  1403. .expect("failed to parse magic version"),
  1404. KernelVersion::Any
  1405. );
  1406. assert_eq!(
  1407. parse_version(&0xFFFF_FFFEu32.to_be_bytes(), Endianness::Big)
  1408. .expect("failed to parse magic version"),
  1409. KernelVersion::Any
  1410. );
  1411. assert_eq!(
  1412. parse_version(&1234u32.to_le_bytes(), Endianness::Little)
  1413. .expect("failed to parse magic version"),
  1414. KernelVersion::Version(1234)
  1415. );
  1416. }
  1417. #[test]
  1418. fn test_parse_map_def_error() {
  1419. assert!(matches!(
  1420. parse_map_def("foo", &[]),
  1421. Err(ParseError::InvalidMapDefinition { .. })
  1422. ));
  1423. }
  1424. #[test]
  1425. fn test_parse_map_short() {
  1426. let def = bpf_map_def {
  1427. map_type: 1,
  1428. key_size: 2,
  1429. value_size: 3,
  1430. max_entries: 4,
  1431. map_flags: 5,
  1432. id: 0,
  1433. pinning: PinningType::None,
  1434. };
  1435. assert_eq!(
  1436. parse_map_def("foo", &bytes_of(&def)[..MINIMUM_MAP_SIZE]).unwrap(),
  1437. def
  1438. );
  1439. }
  1440. #[test]
  1441. fn test_parse_map_def() {
  1442. let def = bpf_map_def {
  1443. map_type: 1,
  1444. key_size: 2,
  1445. value_size: 3,
  1446. max_entries: 4,
  1447. map_flags: 5,
  1448. id: 6,
  1449. pinning: PinningType::ByName,
  1450. };
  1451. assert_eq!(parse_map_def("foo", bytes_of(&def)).unwrap(), def);
  1452. }
  1453. #[test]
  1454. fn test_parse_map_def_with_padding() {
  1455. let def = bpf_map_def {
  1456. map_type: 1,
  1457. key_size: 2,
  1458. value_size: 3,
  1459. max_entries: 4,
  1460. map_flags: 5,
  1461. id: 6,
  1462. pinning: PinningType::ByName,
  1463. };
  1464. let mut buf = [0u8; 128];
  1465. unsafe { ptr::write_unaligned(buf.as_mut_ptr() as *mut _, def) };
  1466. assert_eq!(parse_map_def("foo", &buf).unwrap(), def);
  1467. }
  1468. #[test]
  1469. fn test_parse_map_data() {
  1470. let map_data = b"map data";
  1471. assert!(matches!(
  1472. parse_data_map_section(
  1473. &fake_section(
  1474. BpfSectionKind::Data,
  1475. ".bss",
  1476. map_data,
  1477. ),
  1478. ),
  1479. Ok(Map::Legacy(LegacyMap {
  1480. section_index: 0,
  1481. section_kind: BpfSectionKind::Data,
  1482. symbol_index: None,
  1483. def: bpf_map_def {
  1484. map_type: _map_type,
  1485. key_size: 4,
  1486. value_size,
  1487. max_entries: 1,
  1488. map_flags: 0,
  1489. id: 0,
  1490. pinning: PinningType::None,
  1491. },
  1492. data,
  1493. })) if data == map_data && value_size == map_data.len() as u32
  1494. ))
  1495. }
  1496. fn fake_obj() -> Object {
  1497. Object::new(
  1498. Endianness::Little,
  1499. CString::new("GPL").unwrap(),
  1500. KernelVersion::Any,
  1501. )
  1502. }
  1503. #[test]
  1504. fn test_parse_program_error() {
  1505. let obj = fake_obj();
  1506. assert_matches!(
  1507. obj.parse_program(&fake_section(
  1508. BpfSectionKind::Program,
  1509. "kprobe/foo",
  1510. &42u32.to_ne_bytes(),
  1511. )),
  1512. Err(ParseError::InvalidProgramCode)
  1513. );
  1514. }
  1515. #[test]
  1516. fn test_parse_program() {
  1517. let obj = fake_obj();
  1518. assert_matches!(
  1519. obj.parse_program(&fake_section(BpfSectionKind::Program,"kprobe/foo", bytes_of(&fake_ins()))),
  1520. Ok(Program {
  1521. license,
  1522. kernel_version: KernelVersion::Any,
  1523. section: ProgramSection::KProbe { .. },
  1524. function: Function {
  1525. name,
  1526. address: 0,
  1527. section_index: SectionIndex(0),
  1528. section_offset: 0,
  1529. instructions,
  1530. ..} }) if license.to_string_lossy() == "GPL" && name == "foo" && instructions.len() == 1
  1531. );
  1532. }
  1533. #[test]
  1534. fn test_parse_section_map() {
  1535. let mut obj = fake_obj();
  1536. fake_sym(&mut obj, 0, 0, "foo", mem::size_of::<bpf_map_def>() as u64);
  1537. assert_matches!(
  1538. obj.parse_section(fake_section(
  1539. BpfSectionKind::Maps,
  1540. "maps/foo",
  1541. bytes_of(&bpf_map_def {
  1542. map_type: 1,
  1543. key_size: 2,
  1544. value_size: 3,
  1545. max_entries: 4,
  1546. map_flags: 5,
  1547. ..Default::default()
  1548. })
  1549. )),
  1550. Ok(())
  1551. );
  1552. assert!(obj.maps.get("foo").is_some());
  1553. }
  1554. #[test]
  1555. fn test_parse_section_multiple_maps() {
  1556. let mut obj = fake_obj();
  1557. fake_sym(&mut obj, 0, 0, "foo", mem::size_of::<bpf_map_def>() as u64);
  1558. fake_sym(&mut obj, 0, 28, "bar", mem::size_of::<bpf_map_def>() as u64);
  1559. fake_sym(&mut obj, 0, 60, "baz", mem::size_of::<bpf_map_def>() as u64);
  1560. let def = &bpf_map_def {
  1561. map_type: 1,
  1562. key_size: 2,
  1563. value_size: 3,
  1564. max_entries: 4,
  1565. map_flags: 5,
  1566. ..Default::default()
  1567. };
  1568. let map_data = bytes_of(def).to_vec();
  1569. let mut buf = vec![];
  1570. buf.extend(&map_data);
  1571. buf.extend(&map_data);
  1572. // throw in some padding
  1573. buf.extend([0, 0, 0, 0]);
  1574. buf.extend(&map_data);
  1575. assert_matches!(
  1576. obj.parse_section(fake_section(BpfSectionKind::Maps, "maps", buf.as_slice(),)),
  1577. Ok(())
  1578. );
  1579. assert!(obj.maps.get("foo").is_some());
  1580. assert!(obj.maps.get("bar").is_some());
  1581. assert!(obj.maps.get("baz").is_some());
  1582. for map in obj.maps.values() {
  1583. if let Map::Legacy(m) = map {
  1584. assert_eq!(&m.def, def);
  1585. } else {
  1586. panic!("expected a BTF map")
  1587. }
  1588. }
  1589. }
  1590. #[test]
  1591. fn test_parse_section_data() {
  1592. let mut obj = fake_obj();
  1593. assert_matches!(
  1594. obj.parse_section(fake_section(BpfSectionKind::Data, ".bss", b"map data")),
  1595. Ok(())
  1596. );
  1597. assert!(obj.maps.get(".bss").is_some());
  1598. assert_matches!(
  1599. obj.parse_section(fake_section(BpfSectionKind::Data, ".rodata", b"map data")),
  1600. Ok(())
  1601. );
  1602. assert!(obj.maps.get(".rodata").is_some());
  1603. assert_matches!(
  1604. obj.parse_section(fake_section(
  1605. BpfSectionKind::Data,
  1606. ".rodata.boo",
  1607. b"map data"
  1608. )),
  1609. Ok(())
  1610. );
  1611. assert!(obj.maps.get(".rodata.boo").is_some());
  1612. assert_matches!(
  1613. obj.parse_section(fake_section(BpfSectionKind::Data, ".data", b"map data")),
  1614. Ok(())
  1615. );
  1616. assert!(obj.maps.get(".data").is_some());
  1617. assert_matches!(
  1618. obj.parse_section(fake_section(BpfSectionKind::Data, ".data.boo", b"map data")),
  1619. Ok(())
  1620. );
  1621. assert!(obj.maps.get(".data.boo").is_some());
  1622. }
  1623. #[test]
  1624. fn test_parse_section_kprobe() {
  1625. let mut obj = fake_obj();
  1626. assert_matches!(
  1627. obj.parse_section(fake_section(
  1628. BpfSectionKind::Program,
  1629. "kprobe/foo",
  1630. bytes_of(&fake_ins())
  1631. )),
  1632. Ok(())
  1633. );
  1634. assert_matches!(
  1635. obj.programs.get("foo"),
  1636. Some(Program {
  1637. section: ProgramSection::KProbe { .. },
  1638. ..
  1639. })
  1640. );
  1641. }
  1642. #[test]
  1643. fn test_parse_section_uprobe() {
  1644. let mut obj = fake_obj();
  1645. assert_matches!(
  1646. obj.parse_section(fake_section(
  1647. BpfSectionKind::Program,
  1648. "uprobe/foo",
  1649. bytes_of(&fake_ins())
  1650. )),
  1651. Ok(())
  1652. );
  1653. assert_matches!(
  1654. obj.programs.get("foo"),
  1655. Some(Program {
  1656. section: ProgramSection::UProbe { .. },
  1657. ..
  1658. })
  1659. );
  1660. }
  1661. #[test]
  1662. fn test_parse_section_trace_point() {
  1663. let mut obj = fake_obj();
  1664. assert_matches!(
  1665. obj.parse_section(fake_section(
  1666. BpfSectionKind::Program,
  1667. "tracepoint/foo",
  1668. bytes_of(&fake_ins())
  1669. )),
  1670. Ok(())
  1671. );
  1672. assert_matches!(
  1673. obj.programs.get("foo"),
  1674. Some(Program {
  1675. section: ProgramSection::TracePoint { .. },
  1676. ..
  1677. })
  1678. );
  1679. assert_matches!(
  1680. obj.parse_section(fake_section(
  1681. BpfSectionKind::Program,
  1682. "tp/foo/bar",
  1683. bytes_of(&fake_ins())
  1684. )),
  1685. Ok(())
  1686. );
  1687. assert_matches!(
  1688. obj.programs.get("foo/bar"),
  1689. Some(Program {
  1690. section: ProgramSection::TracePoint { .. },
  1691. ..
  1692. })
  1693. );
  1694. }
  1695. #[test]
  1696. fn test_parse_section_socket_filter() {
  1697. let mut obj = fake_obj();
  1698. assert_matches!(
  1699. obj.parse_section(fake_section(
  1700. BpfSectionKind::Program,
  1701. "socket/foo",
  1702. bytes_of(&fake_ins())
  1703. )),
  1704. Ok(())
  1705. );
  1706. assert_matches!(
  1707. obj.programs.get("foo"),
  1708. Some(Program {
  1709. section: ProgramSection::SocketFilter { .. },
  1710. ..
  1711. })
  1712. );
  1713. }
  1714. #[test]
  1715. fn test_parse_section_xdp() {
  1716. let mut obj = fake_obj();
  1717. assert_matches!(
  1718. obj.parse_section(fake_section(
  1719. BpfSectionKind::Program,
  1720. "xdp/foo",
  1721. bytes_of(&fake_ins())
  1722. )),
  1723. Ok(())
  1724. );
  1725. assert_matches!(
  1726. obj.programs.get("foo"),
  1727. Some(Program {
  1728. section: ProgramSection::Xdp { .. },
  1729. ..
  1730. })
  1731. );
  1732. }
  1733. #[test]
  1734. fn test_parse_section_xdp_frags() {
  1735. let mut obj = fake_obj();
  1736. assert_matches!(
  1737. obj.parse_section(fake_section(
  1738. BpfSectionKind::Program,
  1739. "xdp.frags/foo",
  1740. bytes_of(&fake_ins())
  1741. )),
  1742. Ok(())
  1743. );
  1744. assert_matches!(
  1745. obj.programs.get("foo"),
  1746. Some(Program {
  1747. section: ProgramSection::Xdp {
  1748. frags_supported: true,
  1749. ..
  1750. },
  1751. ..
  1752. })
  1753. );
  1754. }
  1755. #[test]
  1756. fn test_parse_section_raw_tp() {
  1757. let mut obj = fake_obj();
  1758. assert_matches!(
  1759. obj.parse_section(fake_section(
  1760. BpfSectionKind::Program,
  1761. "raw_tp/foo",
  1762. bytes_of(&fake_ins())
  1763. )),
  1764. Ok(())
  1765. );
  1766. assert_matches!(
  1767. obj.programs.get("foo"),
  1768. Some(Program {
  1769. section: ProgramSection::RawTracePoint { .. },
  1770. ..
  1771. })
  1772. );
  1773. assert_matches!(
  1774. obj.parse_section(fake_section(
  1775. BpfSectionKind::Program,
  1776. "raw_tracepoint/bar",
  1777. bytes_of(&fake_ins())
  1778. )),
  1779. Ok(())
  1780. );
  1781. assert_matches!(
  1782. obj.programs.get("bar"),
  1783. Some(Program {
  1784. section: ProgramSection::RawTracePoint { .. },
  1785. ..
  1786. })
  1787. );
  1788. }
  1789. #[test]
  1790. fn test_parse_section_lsm() {
  1791. let mut obj = fake_obj();
  1792. assert_matches!(
  1793. obj.parse_section(fake_section(
  1794. BpfSectionKind::Program,
  1795. "lsm/foo",
  1796. bytes_of(&fake_ins())
  1797. )),
  1798. Ok(())
  1799. );
  1800. assert_matches!(
  1801. obj.programs.get("foo"),
  1802. Some(Program {
  1803. section: ProgramSection::Lsm { .. },
  1804. ..
  1805. })
  1806. );
  1807. }
  1808. #[test]
  1809. fn test_parse_section_btf_tracepoint() {
  1810. let mut obj = fake_obj();
  1811. assert_matches!(
  1812. obj.parse_section(fake_section(
  1813. BpfSectionKind::Program,
  1814. "tp_btf/foo",
  1815. bytes_of(&fake_ins())
  1816. )),
  1817. Ok(())
  1818. );
  1819. assert_matches!(
  1820. obj.programs.get("foo"),
  1821. Some(Program {
  1822. section: ProgramSection::BtfTracePoint { .. },
  1823. ..
  1824. })
  1825. );
  1826. }
  1827. #[test]
  1828. fn test_parse_section_skskb_unnamed() {
  1829. let mut obj = fake_obj();
  1830. assert_matches!(
  1831. obj.parse_section(fake_section(
  1832. BpfSectionKind::Program,
  1833. "sk_skb/stream_parser",
  1834. bytes_of(&fake_ins())
  1835. )),
  1836. Ok(())
  1837. );
  1838. assert_matches!(
  1839. obj.programs.get("stream_parser"),
  1840. Some(Program {
  1841. section: ProgramSection::SkSkbStreamParser { .. },
  1842. ..
  1843. })
  1844. );
  1845. }
  1846. #[test]
  1847. fn test_parse_section_skskb_named() {
  1848. let mut obj = fake_obj();
  1849. assert_matches!(
  1850. obj.parse_section(fake_section(
  1851. BpfSectionKind::Program,
  1852. "sk_skb/stream_parser/my_parser",
  1853. bytes_of(&fake_ins())
  1854. )),
  1855. Ok(())
  1856. );
  1857. assert_matches!(
  1858. obj.programs.get("my_parser"),
  1859. Some(Program {
  1860. section: ProgramSection::SkSkbStreamParser { .. },
  1861. ..
  1862. })
  1863. );
  1864. }
  1865. #[test]
  1866. fn test_parse_section_fentry() {
  1867. let mut obj = fake_obj();
  1868. assert_matches!(
  1869. obj.parse_section(fake_section(
  1870. BpfSectionKind::Program,
  1871. "fentry/foo",
  1872. bytes_of(&fake_ins())
  1873. )),
  1874. Ok(())
  1875. );
  1876. assert_matches!(
  1877. obj.programs.get("foo"),
  1878. Some(Program {
  1879. section: ProgramSection::FEntry { .. },
  1880. ..
  1881. })
  1882. );
  1883. }
  1884. #[test]
  1885. fn test_parse_section_fexit() {
  1886. let mut obj = fake_obj();
  1887. assert_matches!(
  1888. obj.parse_section(fake_section(
  1889. BpfSectionKind::Program,
  1890. "fexit/foo",
  1891. bytes_of(&fake_ins())
  1892. )),
  1893. Ok(())
  1894. );
  1895. assert_matches!(
  1896. obj.programs.get("foo"),
  1897. Some(Program {
  1898. section: ProgramSection::FExit { .. },
  1899. ..
  1900. })
  1901. );
  1902. }
  1903. #[test]
  1904. fn test_parse_section_cgroup_skb_ingress_unnamed() {
  1905. let mut obj = fake_obj();
  1906. assert_matches!(
  1907. obj.parse_section(fake_section(
  1908. BpfSectionKind::Program,
  1909. "cgroup_skb/ingress",
  1910. bytes_of(&fake_ins())
  1911. )),
  1912. Ok(())
  1913. );
  1914. assert_matches!(
  1915. obj.programs.get("ingress"),
  1916. Some(Program {
  1917. section: ProgramSection::CgroupSkbIngress { .. },
  1918. ..
  1919. })
  1920. );
  1921. }
  1922. #[test]
  1923. fn test_parse_section_cgroup_skb_ingress_named() {
  1924. let mut obj = fake_obj();
  1925. assert_matches!(
  1926. obj.parse_section(fake_section(
  1927. BpfSectionKind::Program,
  1928. "cgroup_skb/ingress/foo",
  1929. bytes_of(&fake_ins())
  1930. )),
  1931. Ok(())
  1932. );
  1933. assert_matches!(
  1934. obj.programs.get("foo"),
  1935. Some(Program {
  1936. section: ProgramSection::CgroupSkbIngress { .. },
  1937. ..
  1938. })
  1939. );
  1940. }
  1941. #[test]
  1942. fn test_parse_section_cgroup_skb_no_direction_unamed() {
  1943. let mut obj = fake_obj();
  1944. assert_matches!(
  1945. obj.parse_section(fake_section(
  1946. BpfSectionKind::Program,
  1947. "cgroup/skb",
  1948. bytes_of(&fake_ins())
  1949. )),
  1950. Ok(())
  1951. );
  1952. assert_matches!(
  1953. obj.programs.get("skb"),
  1954. Some(Program {
  1955. section: ProgramSection::CgroupSkb { .. },
  1956. ..
  1957. })
  1958. );
  1959. }
  1960. #[test]
  1961. fn test_parse_section_cgroup_skb_no_direction_named() {
  1962. let mut obj = fake_obj();
  1963. assert_matches!(
  1964. obj.parse_section(fake_section(
  1965. BpfSectionKind::Program,
  1966. "cgroup/skb/foo",
  1967. bytes_of(&fake_ins())
  1968. )),
  1969. Ok(())
  1970. );
  1971. assert_matches!(
  1972. obj.programs.get("foo"),
  1973. Some(Program {
  1974. section: ProgramSection::CgroupSkb { .. },
  1975. ..
  1976. })
  1977. );
  1978. }
  1979. #[test]
  1980. fn test_parse_section_sock_addr_named() {
  1981. let mut obj = fake_obj();
  1982. assert_matches!(
  1983. obj.parse_section(fake_section(
  1984. BpfSectionKind::Program,
  1985. "cgroup/connect4/foo",
  1986. bytes_of(&fake_ins())
  1987. )),
  1988. Ok(())
  1989. );
  1990. assert_matches!(
  1991. obj.programs.get("foo"),
  1992. Some(Program {
  1993. section: ProgramSection::CgroupSockAddr {
  1994. attach_type: CgroupSockAddrAttachType::Connect4,
  1995. ..
  1996. },
  1997. ..
  1998. })
  1999. );
  2000. }
  2001. #[test]
  2002. fn test_parse_section_sock_addr_unnamed() {
  2003. let mut obj = fake_obj();
  2004. assert_matches!(
  2005. obj.parse_section(fake_section(
  2006. BpfSectionKind::Program,
  2007. "cgroup/connect4",
  2008. bytes_of(&fake_ins())
  2009. )),
  2010. Ok(())
  2011. );
  2012. assert_matches!(
  2013. obj.programs.get("connect4"),
  2014. Some(Program {
  2015. section: ProgramSection::CgroupSockAddr {
  2016. attach_type: CgroupSockAddrAttachType::Connect4,
  2017. ..
  2018. },
  2019. ..
  2020. })
  2021. );
  2022. }
  2023. #[test]
  2024. fn test_parse_section_sockopt_named() {
  2025. let mut obj = fake_obj();
  2026. assert_matches!(
  2027. obj.parse_section(fake_section(
  2028. BpfSectionKind::Program,
  2029. "cgroup/getsockopt/foo",
  2030. bytes_of(&fake_ins())
  2031. )),
  2032. Ok(())
  2033. );
  2034. assert_matches!(
  2035. obj.programs.get("foo"),
  2036. Some(Program {
  2037. section: ProgramSection::CgroupSockopt {
  2038. attach_type: CgroupSockoptAttachType::Get,
  2039. ..
  2040. },
  2041. ..
  2042. })
  2043. );
  2044. }
  2045. #[test]
  2046. fn test_parse_section_sockopt_unnamed() {
  2047. let mut obj = fake_obj();
  2048. assert_matches!(
  2049. obj.parse_section(fake_section(
  2050. BpfSectionKind::Program,
  2051. "cgroup/getsockopt",
  2052. bytes_of(&fake_ins())
  2053. )),
  2054. Ok(())
  2055. );
  2056. assert_matches!(
  2057. obj.programs.get("getsockopt"),
  2058. Some(Program {
  2059. section: ProgramSection::CgroupSockopt {
  2060. attach_type: CgroupSockoptAttachType::Get,
  2061. ..
  2062. },
  2063. ..
  2064. })
  2065. );
  2066. }
  2067. #[test]
  2068. fn test_patch_map_data() {
  2069. let mut obj = fake_obj();
  2070. obj.maps.insert(
  2071. ".rodata".to_string(),
  2072. Map::Legacy(LegacyMap {
  2073. def: bpf_map_def {
  2074. map_type: BPF_MAP_TYPE_ARRAY as u32,
  2075. key_size: mem::size_of::<u32>() as u32,
  2076. value_size: 3,
  2077. max_entries: 1,
  2078. map_flags: BPF_F_RDONLY_PROG,
  2079. id: 1,
  2080. pinning: PinningType::None,
  2081. },
  2082. section_index: 1,
  2083. section_kind: BpfSectionKind::Rodata,
  2084. symbol_index: Some(1),
  2085. data: vec![0, 0, 0],
  2086. }),
  2087. );
  2088. obj.symbol_table.insert(
  2089. 1,
  2090. Symbol {
  2091. index: 1,
  2092. section_index: Some(1),
  2093. name: Some("my_config".to_string()),
  2094. address: 0,
  2095. size: 3,
  2096. is_definition: true,
  2097. kind: SymbolKind::Data,
  2098. },
  2099. );
  2100. let test_data: &[u8] = &[1, 2, 3];
  2101. obj.patch_map_data(HashMap::from([("my_config", test_data)]))
  2102. .unwrap();
  2103. let map = obj.maps.get(".rodata").unwrap();
  2104. assert_eq!(test_data, map.data());
  2105. }
  2106. #[test]
  2107. fn test_parse_btf_map_section() {
  2108. let mut obj = fake_obj();
  2109. fake_sym(&mut obj, 0, 0, "map_1", 0);
  2110. fake_sym(&mut obj, 0, 0, "map_2", 0);
  2111. // generated from:
  2112. // objcopy --dump-section .BTF=test.btf ./target/bpfel-unknown-none/debug/multimap-btf.bpf.o
  2113. // hexdump -v -e '7/1 "0x%02X, " 1/1 " 0x%02X,\n"' test.btf
  2114. let data: &[u8] = &[
  2115. 0x9F, 0xEB, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x01,
  2116. 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xCC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2117. 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
  2118. 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
  2119. 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00,
  2120. 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
  2121. 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2122. 0x00, 0x02, 0x06, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
  2123. 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00,
  2124. 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
  2125. 0x09, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0A, 0x00,
  2126. 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00,
  2127. 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0C, 0x00,
  2128. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
  2129. 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
  2130. 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00,
  2131. 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x05, 0x00,
  2132. 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
  2133. 0x80, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0xC0, 0x00,
  2134. 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0D, 0x00, 0x00, 0x00,
  2135. 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x20, 0x00,
  2136. 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2137. 0x4A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x4E, 0x00,
  2138. 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
  2139. 0x0B, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,
  2140. 0x00, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2141. 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
  2142. 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
  2143. 0x70, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0C, 0x12, 0x00, 0x00, 0x00, 0xB0, 0x01,
  2144. 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01,
  2145. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
  2146. 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xB5, 0x01, 0x00, 0x00,
  2147. 0x00, 0x00, 0x00, 0x0E, 0x15, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xBE, 0x01,
  2148. 0x00, 0x00, 0x02, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,
  2149. 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
  2150. 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xC4, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0F,
  2151. 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
  2152. 0x00, 0x00, 0x00, 0x69, 0x6E, 0x74, 0x00, 0x5F, 0x5F, 0x41, 0x52, 0x52, 0x41, 0x59,
  2153. 0x5F, 0x53, 0x49, 0x5A, 0x45, 0x5F, 0x54, 0x59, 0x50, 0x45, 0x5F, 0x5F, 0x00, 0x5F,
  2154. 0x5F, 0x75, 0x33, 0x32, 0x00, 0x75, 0x6E, 0x73, 0x69, 0x67, 0x6E, 0x65, 0x64, 0x20,
  2155. 0x69, 0x6E, 0x74, 0x00, 0x5F, 0x5F, 0x75, 0x36, 0x34, 0x00, 0x75, 0x6E, 0x73, 0x69,
  2156. 0x67, 0x6E, 0x65, 0x64, 0x20, 0x6C, 0x6F, 0x6E, 0x67, 0x20, 0x6C, 0x6F, 0x6E, 0x67,
  2157. 0x00, 0x74, 0x79, 0x70, 0x65, 0x00, 0x6B, 0x65, 0x79, 0x00, 0x76, 0x61, 0x6C, 0x75,
  2158. 0x65, 0x00, 0x6D, 0x61, 0x78, 0x5F, 0x65, 0x6E, 0x74, 0x72, 0x69, 0x65, 0x73, 0x00,
  2159. 0x6D, 0x61, 0x70, 0x5F, 0x31, 0x00, 0x6D, 0x61, 0x70, 0x5F, 0x32, 0x00, 0x63, 0x74,
  2160. 0x78, 0x00, 0x62, 0x70, 0x66, 0x5F, 0x70, 0x72, 0x6F, 0x67, 0x00, 0x74, 0x72, 0x61,
  2161. 0x63, 0x65, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x00, 0x2F, 0x76, 0x61, 0x72, 0x2F, 0x68,
  2162. 0x6F, 0x6D, 0x65, 0x2F, 0x64, 0x61, 0x76, 0x65, 0x2F, 0x64, 0x65, 0x76, 0x2F, 0x61,
  2163. 0x79, 0x61, 0x2D, 0x72, 0x73, 0x2F, 0x61, 0x79, 0x61, 0x2F, 0x74, 0x65, 0x73, 0x74,
  2164. 0x2F, 0x69, 0x6E, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2D, 0x65,
  2165. 0x62, 0x70, 0x66, 0x2F, 0x73, 0x72, 0x63, 0x2F, 0x62, 0x70, 0x66, 0x2F, 0x6D, 0x75,
  2166. 0x6C, 0x74, 0x69, 0x6D, 0x61, 0x70, 0x2D, 0x62, 0x74, 0x66, 0x2E, 0x62, 0x70, 0x66,
  2167. 0x2E, 0x63, 0x00, 0x69, 0x6E, 0x74, 0x20, 0x62, 0x70, 0x66, 0x5F, 0x70, 0x72, 0x6F,
  2168. 0x67, 0x28, 0x76, 0x6F, 0x69, 0x64, 0x20, 0x2A, 0x63, 0x74, 0x78, 0x29, 0x00, 0x09,
  2169. 0x5F, 0x5F, 0x75, 0x33, 0x32, 0x20, 0x6B, 0x65, 0x79, 0x20, 0x3D, 0x20, 0x30, 0x3B,
  2170. 0x00, 0x09, 0x5F, 0x5F, 0x75, 0x36, 0x34, 0x20, 0x74, 0x77, 0x65, 0x6E, 0x74, 0x79,
  2171. 0x5F, 0x66, 0x6F, 0x75, 0x72, 0x20, 0x3D, 0x20, 0x32, 0x34, 0x3B, 0x00, 0x09, 0x5F,
  2172. 0x5F, 0x75, 0x36, 0x34, 0x20, 0x66, 0x6F, 0x72, 0x74, 0x79, 0x5F, 0x74, 0x77, 0x6F,
  2173. 0x20, 0x3D, 0x20, 0x34, 0x32, 0x3B, 0x00, 0x20, 0x20, 0x20, 0x20, 0x62, 0x70, 0x66,
  2174. 0x5F, 0x6D, 0x61, 0x70, 0x5F, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5F, 0x65, 0x6C,
  2175. 0x65, 0x6D, 0x28, 0x26, 0x6D, 0x61, 0x70, 0x5F, 0x31, 0x2C, 0x20, 0x26, 0x6B, 0x65,
  2176. 0x79, 0x2C, 0x20, 0x26, 0x74, 0x77, 0x65, 0x6E, 0x74, 0x79, 0x5F, 0x66, 0x6F, 0x75,
  2177. 0x72, 0x2C, 0x20, 0x42, 0x50, 0x46, 0x5F, 0x41, 0x4E, 0x59, 0x29, 0x3B, 0x00, 0x20,
  2178. 0x20, 0x20, 0x20, 0x62, 0x70, 0x66, 0x5F, 0x6D, 0x61, 0x70, 0x5F, 0x75, 0x70, 0x64,
  2179. 0x61, 0x74, 0x65, 0x5F, 0x65, 0x6C, 0x65, 0x6D, 0x28, 0x26, 0x6D, 0x61, 0x70, 0x5F,
  2180. 0x32, 0x2C, 0x20, 0x26, 0x6B, 0x65, 0x79, 0x2C, 0x20, 0x26, 0x66, 0x6F, 0x72, 0x74,
  2181. 0x79, 0x5F, 0x74, 0x77, 0x6F, 0x2C, 0x20, 0x42, 0x50, 0x46, 0x5F, 0x41, 0x4E, 0x59,
  2182. 0x29, 0x3B, 0x00, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, 0x20, 0x30, 0x3B, 0x00,
  2183. 0x63, 0x68, 0x61, 0x72, 0x00, 0x5F, 0x6C, 0x69, 0x63, 0x65, 0x6E, 0x73, 0x65, 0x00,
  2184. 0x2E, 0x6D, 0x61, 0x70, 0x73, 0x00, 0x6C, 0x69, 0x63, 0x65, 0x6E, 0x73, 0x65, 0x00,
  2185. ];
  2186. let btf_section = fake_section(BpfSectionKind::Btf, ".BTF", data);
  2187. obj.parse_section(btf_section).unwrap();
  2188. let map_section = fake_section(BpfSectionKind::BtfMaps, ".maps", &[]);
  2189. obj.parse_section(map_section).unwrap();
  2190. let map = obj.maps.get("map_1").unwrap();
  2191. if let Map::Btf(m) = map {
  2192. assert_eq!(m.def.key_size, 4);
  2193. assert_eq!(m.def.value_size, 8);
  2194. assert_eq!(m.def.max_entries, 1);
  2195. } else {
  2196. panic!("expected a BTF map")
  2197. }
  2198. }
  2199. }