BPFAbstractMemberAccess.cpp 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125
  1. //===------ BPFAbstractMemberAccess.cpp - Abstracting Member Accesses -----===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This pass abstracted struct/union member accesses in order to support
  10. // compile-once run-everywhere (CO-RE). The CO-RE intends to compile the program
  11. // which can run on different kernels. In particular, if bpf program tries to
  12. // access a particular kernel data structure member, the details of the
  13. // intermediate member access will be remembered so bpf loader can do
  14. // necessary adjustment right before program loading.
  15. //
  16. // For example,
  17. //
  18. // struct s {
  19. // int a;
  20. // int b;
  21. // };
  22. // struct t {
  23. // struct s c;
  24. // int d;
  25. // };
  26. // struct t e;
  27. //
  28. // For the member access e.c.b, the compiler will generate code
  29. // &e + 4
  30. //
  31. // The compile-once run-everywhere instead generates the following code
  32. // r = 4
  33. // &e + r
  34. // The "4" in "r = 4" can be changed based on a particular kernel version.
  35. // For example, on a particular kernel version, if struct s is changed to
  36. //
  37. // struct s {
  38. // int new_field;
  39. // int a;
  40. // int b;
  41. // }
  42. //
  43. // By repeating the member access on the host, the bpf loader can
  44. // adjust "r = 4" as "r = 8".
  45. //
  46. // This feature relies on the following three intrinsic calls:
  47. // addr = preserve_array_access_index(base, dimension, index)
  48. // addr = preserve_union_access_index(base, di_index)
  49. // !llvm.preserve.access.index <union_ditype>
  50. // addr = preserve_struct_access_index(base, gep_index, di_index)
  51. // !llvm.preserve.access.index <struct_ditype>
  52. //
  53. // Bitfield member access needs special attention. User cannot take the
  54. // address of a bitfield acceess. To facilitate kernel verifier
  55. // for easy bitfield code optimization, a new clang intrinsic is introduced:
  56. // uint32_t __builtin_preserve_field_info(member_access, info_kind)
  57. // In IR, a chain with two (or more) intrinsic calls will be generated:
  58. // ...
  59. // addr = preserve_struct_access_index(base, 1, 1) !struct s
  60. // uint32_t result = bpf_preserve_field_info(addr, info_kind)
  61. //
  62. // Suppose the info_kind is FIELD_SIGNEDNESS,
  63. // The above two IR intrinsics will be replaced with
  64. // a relocatable insn:
  65. // signness = /* signness of member_access */
  66. // and signness can be changed by bpf loader based on the
  67. // types on the host.
  68. //
  69. // User can also test whether a field exists or not with
  70. // uint32_t result = bpf_preserve_field_info(member_access, FIELD_EXISTENCE)
  71. // The field will be always available (result = 1) during initial
  72. // compilation, but bpf loader can patch with the correct value
  73. // on the target host where the member_access may or may not be available
  74. //
  75. //===----------------------------------------------------------------------===//
  76. #include "BPF.h"
  77. #include "BPFCORE.h"
  78. #include "BPFTargetMachine.h"
  79. #include "llvm/IR/DebugInfoMetadata.h"
  80. #include "llvm/IR/GlobalVariable.h"
  81. #include "llvm/IR/Instruction.h"
  82. #include "llvm/IR/Instructions.h"
  83. #include "llvm/IR/IntrinsicsBPF.h"
  84. #include "llvm/IR/Module.h"
  85. #include "llvm/IR/PassManager.h"
  86. #include "llvm/IR/Type.h"
  87. #include "llvm/IR/User.h"
  88. #include "llvm/IR/Value.h"
  89. #include "llvm/Pass.h"
  90. #include "llvm/Transforms/Utils/BasicBlockUtils.h"
  91. #include <stack>
  92. #define DEBUG_TYPE "bpf-abstract-member-access"
  93. namespace llvm {
  94. constexpr StringRef BPFCoreSharedInfo::AmaAttr;
  95. uint32_t BPFCoreSharedInfo::SeqNum;
  96. Instruction *BPFCoreSharedInfo::insertPassThrough(Module *M, BasicBlock *BB,
  97. Instruction *Input,
  98. Instruction *Before) {
  99. Function *Fn = Intrinsic::getDeclaration(
  100. M, Intrinsic::bpf_passthrough, {Input->getType(), Input->getType()});
  101. Constant *SeqNumVal = ConstantInt::get(Type::getInt32Ty(BB->getContext()),
  102. BPFCoreSharedInfo::SeqNum++);
  103. auto *NewInst = CallInst::Create(Fn, {SeqNumVal, Input});
  104. BB->getInstList().insert(Before->getIterator(), NewInst);
  105. return NewInst;
  106. }
  107. } // namespace llvm
  108. using namespace llvm;
  109. namespace {
  110. class BPFAbstractMemberAccess final {
  111. public:
  112. BPFAbstractMemberAccess(BPFTargetMachine *TM) : TM(TM) {}
  113. bool run(Function &F);
  114. struct CallInfo {
  115. uint32_t Kind;
  116. uint32_t AccessIndex;
  117. Align RecordAlignment;
  118. MDNode *Metadata;
  119. Value *Base;
  120. };
  121. typedef std::stack<std::pair<CallInst *, CallInfo>> CallInfoStack;
  122. private:
  123. enum : uint32_t {
  124. BPFPreserveArrayAI = 1,
  125. BPFPreserveUnionAI = 2,
  126. BPFPreserveStructAI = 3,
  127. BPFPreserveFieldInfoAI = 4,
  128. };
  129. TargetMachine *TM;
  130. const DataLayout *DL = nullptr;
  131. Module *M = nullptr;
  132. static std::map<std::string, GlobalVariable *> GEPGlobals;
  133. // A map to link preserve_*_access_index instrinsic calls.
  134. std::map<CallInst *, std::pair<CallInst *, CallInfo>> AIChain;
  135. // A map to hold all the base preserve_*_access_index instrinsic calls.
  136. // The base call is not an input of any other preserve_*
  137. // intrinsics.
  138. std::map<CallInst *, CallInfo> BaseAICalls;
  139. bool doTransformation(Function &F);
  140. void traceAICall(CallInst *Call, CallInfo &ParentInfo);
  141. void traceBitCast(BitCastInst *BitCast, CallInst *Parent,
  142. CallInfo &ParentInfo);
  143. void traceGEP(GetElementPtrInst *GEP, CallInst *Parent,
  144. CallInfo &ParentInfo);
  145. void collectAICallChains(Function &F);
  146. bool IsPreserveDIAccessIndexCall(const CallInst *Call, CallInfo &Cinfo);
  147. bool IsValidAIChain(const MDNode *ParentMeta, uint32_t ParentAI,
  148. const MDNode *ChildMeta);
  149. bool removePreserveAccessIndexIntrinsic(Function &F);
  150. void replaceWithGEP(std::vector<CallInst *> &CallList,
  151. uint32_t NumOfZerosIndex, uint32_t DIIndex);
  152. bool HasPreserveFieldInfoCall(CallInfoStack &CallStack);
  153. void GetStorageBitRange(DIDerivedType *MemberTy, Align RecordAlignment,
  154. uint32_t &StartBitOffset, uint32_t &EndBitOffset);
  155. uint32_t GetFieldInfo(uint32_t InfoKind, DICompositeType *CTy,
  156. uint32_t AccessIndex, uint32_t PatchImm,
  157. Align RecordAlignment);
  158. Value *computeBaseAndAccessKey(CallInst *Call, CallInfo &CInfo,
  159. std::string &AccessKey, MDNode *&BaseMeta);
  160. MDNode *computeAccessKey(CallInst *Call, CallInfo &CInfo,
  161. std::string &AccessKey, bool &IsInt32Ret);
  162. uint64_t getConstant(const Value *IndexValue);
  163. bool transformGEPChain(CallInst *Call, CallInfo &CInfo);
  164. };
  165. std::map<std::string, GlobalVariable *> BPFAbstractMemberAccess::GEPGlobals;
  166. class BPFAbstractMemberAccessLegacyPass final : public FunctionPass {
  167. BPFTargetMachine *TM;
  168. bool runOnFunction(Function &F) override {
  169. return BPFAbstractMemberAccess(TM).run(F);
  170. }
  171. public:
  172. static char ID;
  173. // Add optional BPFTargetMachine parameter so that BPF backend can add the
  174. // phase with target machine to find out the endianness. The default
  175. // constructor (without parameters) is used by the pass manager for managing
  176. // purposes.
  177. BPFAbstractMemberAccessLegacyPass(BPFTargetMachine *TM = nullptr)
  178. : FunctionPass(ID), TM(TM) {}
  179. };
  180. } // End anonymous namespace
  181. char BPFAbstractMemberAccessLegacyPass::ID = 0;
  182. INITIALIZE_PASS(BPFAbstractMemberAccessLegacyPass, DEBUG_TYPE,
  183. "BPF Abstract Member Access", false, false)
  184. FunctionPass *llvm::createBPFAbstractMemberAccess(BPFTargetMachine *TM) {
  185. return new BPFAbstractMemberAccessLegacyPass(TM);
  186. }
  187. bool BPFAbstractMemberAccess::run(Function &F) {
  188. LLVM_DEBUG(dbgs() << "********** Abstract Member Accesses **********\n");
  189. M = F.getParent();
  190. if (!M)
  191. return false;
  192. // Bail out if no debug info.
  193. if (M->debug_compile_units().empty())
  194. return false;
  195. DL = &M->getDataLayout();
  196. return doTransformation(F);
  197. }
  198. static bool SkipDIDerivedTag(unsigned Tag, bool skipTypedef) {
  199. if (Tag != dwarf::DW_TAG_typedef && Tag != dwarf::DW_TAG_const_type &&
  200. Tag != dwarf::DW_TAG_volatile_type &&
  201. Tag != dwarf::DW_TAG_restrict_type &&
  202. Tag != dwarf::DW_TAG_member)
  203. return false;
  204. if (Tag == dwarf::DW_TAG_typedef && !skipTypedef)
  205. return false;
  206. return true;
  207. }
  208. static DIType * stripQualifiers(DIType *Ty, bool skipTypedef = true) {
  209. while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
  210. if (!SkipDIDerivedTag(DTy->getTag(), skipTypedef))
  211. break;
  212. Ty = DTy->getBaseType();
  213. }
  214. return Ty;
  215. }
  216. static const DIType * stripQualifiers(const DIType *Ty) {
  217. while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
  218. if (!SkipDIDerivedTag(DTy->getTag(), true))
  219. break;
  220. Ty = DTy->getBaseType();
  221. }
  222. return Ty;
  223. }
  224. static uint32_t calcArraySize(const DICompositeType *CTy, uint32_t StartDim) {
  225. DINodeArray Elements = CTy->getElements();
  226. uint32_t DimSize = 1;
  227. for (uint32_t I = StartDim; I < Elements.size(); ++I) {
  228. if (auto *Element = dyn_cast_or_null<DINode>(Elements[I]))
  229. if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
  230. const DISubrange *SR = cast<DISubrange>(Element);
  231. auto *CI = SR->getCount().dyn_cast<ConstantInt *>();
  232. DimSize *= CI->getSExtValue();
  233. }
  234. }
  235. return DimSize;
  236. }
  237. static Type *getBaseElementType(const CallInst *Call) {
  238. // Element type is stored in an elementtype() attribute on the first param.
  239. return Call->getAttributes().getParamElementType(0);
  240. }
  241. /// Check whether a call is a preserve_*_access_index intrinsic call or not.
  242. bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call,
  243. CallInfo &CInfo) {
  244. if (!Call)
  245. return false;
  246. const auto *GV = dyn_cast<GlobalValue>(Call->getCalledOperand());
  247. if (!GV)
  248. return false;
  249. if (GV->getName().startswith("llvm.preserve.array.access.index")) {
  250. CInfo.Kind = BPFPreserveArrayAI;
  251. CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
  252. if (!CInfo.Metadata)
  253. report_fatal_error("Missing metadata for llvm.preserve.array.access.index intrinsic");
  254. CInfo.AccessIndex = getConstant(Call->getArgOperand(2));
  255. CInfo.Base = Call->getArgOperand(0);
  256. CInfo.RecordAlignment = DL->getABITypeAlign(getBaseElementType(Call));
  257. return true;
  258. }
  259. if (GV->getName().startswith("llvm.preserve.union.access.index")) {
  260. CInfo.Kind = BPFPreserveUnionAI;
  261. CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
  262. if (!CInfo.Metadata)
  263. report_fatal_error("Missing metadata for llvm.preserve.union.access.index intrinsic");
  264. CInfo.AccessIndex = getConstant(Call->getArgOperand(1));
  265. CInfo.Base = Call->getArgOperand(0);
  266. CInfo.RecordAlignment =
  267. DL->getABITypeAlign(CInfo.Base->getType()->getPointerElementType());
  268. return true;
  269. }
  270. if (GV->getName().startswith("llvm.preserve.struct.access.index")) {
  271. CInfo.Kind = BPFPreserveStructAI;
  272. CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
  273. if (!CInfo.Metadata)
  274. report_fatal_error("Missing metadata for llvm.preserve.struct.access.index intrinsic");
  275. CInfo.AccessIndex = getConstant(Call->getArgOperand(2));
  276. CInfo.Base = Call->getArgOperand(0);
  277. CInfo.RecordAlignment = DL->getABITypeAlign(getBaseElementType(Call));
  278. return true;
  279. }
  280. if (GV->getName().startswith("llvm.bpf.preserve.field.info")) {
  281. CInfo.Kind = BPFPreserveFieldInfoAI;
  282. CInfo.Metadata = nullptr;
  283. // Check validity of info_kind as clang did not check this.
  284. uint64_t InfoKind = getConstant(Call->getArgOperand(1));
  285. if (InfoKind >= BPFCoreSharedInfo::MAX_FIELD_RELOC_KIND)
  286. report_fatal_error("Incorrect info_kind for llvm.bpf.preserve.field.info intrinsic");
  287. CInfo.AccessIndex = InfoKind;
  288. return true;
  289. }
  290. if (GV->getName().startswith("llvm.bpf.preserve.type.info")) {
  291. CInfo.Kind = BPFPreserveFieldInfoAI;
  292. CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
  293. if (!CInfo.Metadata)
  294. report_fatal_error("Missing metadata for llvm.preserve.type.info intrinsic");
  295. uint64_t Flag = getConstant(Call->getArgOperand(1));
  296. if (Flag >= BPFCoreSharedInfo::MAX_PRESERVE_TYPE_INFO_FLAG)
  297. report_fatal_error("Incorrect flag for llvm.bpf.preserve.type.info intrinsic");
  298. if (Flag == BPFCoreSharedInfo::PRESERVE_TYPE_INFO_EXISTENCE)
  299. CInfo.AccessIndex = BPFCoreSharedInfo::TYPE_EXISTENCE;
  300. else
  301. CInfo.AccessIndex = BPFCoreSharedInfo::TYPE_SIZE;
  302. return true;
  303. }
  304. if (GV->getName().startswith("llvm.bpf.preserve.enum.value")) {
  305. CInfo.Kind = BPFPreserveFieldInfoAI;
  306. CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
  307. if (!CInfo.Metadata)
  308. report_fatal_error("Missing metadata for llvm.preserve.enum.value intrinsic");
  309. uint64_t Flag = getConstant(Call->getArgOperand(2));
  310. if (Flag >= BPFCoreSharedInfo::MAX_PRESERVE_ENUM_VALUE_FLAG)
  311. report_fatal_error("Incorrect flag for llvm.bpf.preserve.enum.value intrinsic");
  312. if (Flag == BPFCoreSharedInfo::PRESERVE_ENUM_VALUE_EXISTENCE)
  313. CInfo.AccessIndex = BPFCoreSharedInfo::ENUM_VALUE_EXISTENCE;
  314. else
  315. CInfo.AccessIndex = BPFCoreSharedInfo::ENUM_VALUE;
  316. return true;
  317. }
  318. return false;
  319. }
  320. void BPFAbstractMemberAccess::replaceWithGEP(std::vector<CallInst *> &CallList,
  321. uint32_t DimensionIndex,
  322. uint32_t GEPIndex) {
  323. for (auto Call : CallList) {
  324. uint32_t Dimension = 1;
  325. if (DimensionIndex > 0)
  326. Dimension = getConstant(Call->getArgOperand(DimensionIndex));
  327. Constant *Zero =
  328. ConstantInt::get(Type::getInt32Ty(Call->getParent()->getContext()), 0);
  329. SmallVector<Value *, 4> IdxList;
  330. for (unsigned I = 0; I < Dimension; ++I)
  331. IdxList.push_back(Zero);
  332. IdxList.push_back(Call->getArgOperand(GEPIndex));
  333. auto *GEP = GetElementPtrInst::CreateInBounds(
  334. getBaseElementType(Call), Call->getArgOperand(0), IdxList, "", Call);
  335. Call->replaceAllUsesWith(GEP);
  336. Call->eraseFromParent();
  337. }
  338. }
  339. bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(Function &F) {
  340. std::vector<CallInst *> PreserveArrayIndexCalls;
  341. std::vector<CallInst *> PreserveUnionIndexCalls;
  342. std::vector<CallInst *> PreserveStructIndexCalls;
  343. bool Found = false;
  344. for (auto &BB : F)
  345. for (auto &I : BB) {
  346. auto *Call = dyn_cast<CallInst>(&I);
  347. CallInfo CInfo;
  348. if (!IsPreserveDIAccessIndexCall(Call, CInfo))
  349. continue;
  350. Found = true;
  351. if (CInfo.Kind == BPFPreserveArrayAI)
  352. PreserveArrayIndexCalls.push_back(Call);
  353. else if (CInfo.Kind == BPFPreserveUnionAI)
  354. PreserveUnionIndexCalls.push_back(Call);
  355. else
  356. PreserveStructIndexCalls.push_back(Call);
  357. }
  358. // do the following transformation:
  359. // . addr = preserve_array_access_index(base, dimension, index)
  360. // is transformed to
  361. // addr = GEP(base, dimenion's zero's, index)
  362. // . addr = preserve_union_access_index(base, di_index)
  363. // is transformed to
  364. // addr = base, i.e., all usages of "addr" are replaced by "base".
  365. // . addr = preserve_struct_access_index(base, gep_index, di_index)
  366. // is transformed to
  367. // addr = GEP(base, 0, gep_index)
  368. replaceWithGEP(PreserveArrayIndexCalls, 1, 2);
  369. replaceWithGEP(PreserveStructIndexCalls, 0, 1);
  370. for (auto Call : PreserveUnionIndexCalls) {
  371. Call->replaceAllUsesWith(Call->getArgOperand(0));
  372. Call->eraseFromParent();
  373. }
  374. return Found;
  375. }
  376. /// Check whether the access index chain is valid. We check
  377. /// here because there may be type casts between two
  378. /// access indexes. We want to ensure memory access still valid.
  379. bool BPFAbstractMemberAccess::IsValidAIChain(const MDNode *ParentType,
  380. uint32_t ParentAI,
  381. const MDNode *ChildType) {
  382. if (!ChildType)
  383. return true; // preserve_field_info, no type comparison needed.
  384. const DIType *PType = stripQualifiers(cast<DIType>(ParentType));
  385. const DIType *CType = stripQualifiers(cast<DIType>(ChildType));
  386. // Child is a derived/pointer type, which is due to type casting.
  387. // Pointer type cannot be in the middle of chain.
  388. if (isa<DIDerivedType>(CType))
  389. return false;
  390. // Parent is a pointer type.
  391. if (const auto *PtrTy = dyn_cast<DIDerivedType>(PType)) {
  392. if (PtrTy->getTag() != dwarf::DW_TAG_pointer_type)
  393. return false;
  394. return stripQualifiers(PtrTy->getBaseType()) == CType;
  395. }
  396. // Otherwise, struct/union/array types
  397. const auto *PTy = dyn_cast<DICompositeType>(PType);
  398. const auto *CTy = dyn_cast<DICompositeType>(CType);
  399. assert(PTy && CTy && "ParentType or ChildType is null or not composite");
  400. uint32_t PTyTag = PTy->getTag();
  401. assert(PTyTag == dwarf::DW_TAG_array_type ||
  402. PTyTag == dwarf::DW_TAG_structure_type ||
  403. PTyTag == dwarf::DW_TAG_union_type);
  404. uint32_t CTyTag = CTy->getTag();
  405. assert(CTyTag == dwarf::DW_TAG_array_type ||
  406. CTyTag == dwarf::DW_TAG_structure_type ||
  407. CTyTag == dwarf::DW_TAG_union_type);
  408. // Multi dimensional arrays, base element should be the same
  409. if (PTyTag == dwarf::DW_TAG_array_type && PTyTag == CTyTag)
  410. return PTy->getBaseType() == CTy->getBaseType();
  411. DIType *Ty;
  412. if (PTyTag == dwarf::DW_TAG_array_type)
  413. Ty = PTy->getBaseType();
  414. else
  415. Ty = dyn_cast<DIType>(PTy->getElements()[ParentAI]);
  416. return dyn_cast<DICompositeType>(stripQualifiers(Ty)) == CTy;
  417. }
  418. void BPFAbstractMemberAccess::traceAICall(CallInst *Call,
  419. CallInfo &ParentInfo) {
  420. for (User *U : Call->users()) {
  421. Instruction *Inst = dyn_cast<Instruction>(U);
  422. if (!Inst)
  423. continue;
  424. if (auto *BI = dyn_cast<BitCastInst>(Inst)) {
  425. traceBitCast(BI, Call, ParentInfo);
  426. } else if (auto *CI = dyn_cast<CallInst>(Inst)) {
  427. CallInfo ChildInfo;
  428. if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
  429. IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
  430. ChildInfo.Metadata)) {
  431. AIChain[CI] = std::make_pair(Call, ParentInfo);
  432. traceAICall(CI, ChildInfo);
  433. } else {
  434. BaseAICalls[Call] = ParentInfo;
  435. }
  436. } else if (auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
  437. if (GI->hasAllZeroIndices())
  438. traceGEP(GI, Call, ParentInfo);
  439. else
  440. BaseAICalls[Call] = ParentInfo;
  441. } else {
  442. BaseAICalls[Call] = ParentInfo;
  443. }
  444. }
  445. }
  446. void BPFAbstractMemberAccess::traceBitCast(BitCastInst *BitCast,
  447. CallInst *Parent,
  448. CallInfo &ParentInfo) {
  449. for (User *U : BitCast->users()) {
  450. Instruction *Inst = dyn_cast<Instruction>(U);
  451. if (!Inst)
  452. continue;
  453. if (auto *BI = dyn_cast<BitCastInst>(Inst)) {
  454. traceBitCast(BI, Parent, ParentInfo);
  455. } else if (auto *CI = dyn_cast<CallInst>(Inst)) {
  456. CallInfo ChildInfo;
  457. if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
  458. IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
  459. ChildInfo.Metadata)) {
  460. AIChain[CI] = std::make_pair(Parent, ParentInfo);
  461. traceAICall(CI, ChildInfo);
  462. } else {
  463. BaseAICalls[Parent] = ParentInfo;
  464. }
  465. } else if (auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
  466. if (GI->hasAllZeroIndices())
  467. traceGEP(GI, Parent, ParentInfo);
  468. else
  469. BaseAICalls[Parent] = ParentInfo;
  470. } else {
  471. BaseAICalls[Parent] = ParentInfo;
  472. }
  473. }
  474. }
  475. void BPFAbstractMemberAccess::traceGEP(GetElementPtrInst *GEP, CallInst *Parent,
  476. CallInfo &ParentInfo) {
  477. for (User *U : GEP->users()) {
  478. Instruction *Inst = dyn_cast<Instruction>(U);
  479. if (!Inst)
  480. continue;
  481. if (auto *BI = dyn_cast<BitCastInst>(Inst)) {
  482. traceBitCast(BI, Parent, ParentInfo);
  483. } else if (auto *CI = dyn_cast<CallInst>(Inst)) {
  484. CallInfo ChildInfo;
  485. if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
  486. IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
  487. ChildInfo.Metadata)) {
  488. AIChain[CI] = std::make_pair(Parent, ParentInfo);
  489. traceAICall(CI, ChildInfo);
  490. } else {
  491. BaseAICalls[Parent] = ParentInfo;
  492. }
  493. } else if (auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
  494. if (GI->hasAllZeroIndices())
  495. traceGEP(GI, Parent, ParentInfo);
  496. else
  497. BaseAICalls[Parent] = ParentInfo;
  498. } else {
  499. BaseAICalls[Parent] = ParentInfo;
  500. }
  501. }
  502. }
  503. void BPFAbstractMemberAccess::collectAICallChains(Function &F) {
  504. AIChain.clear();
  505. BaseAICalls.clear();
  506. for (auto &BB : F)
  507. for (auto &I : BB) {
  508. CallInfo CInfo;
  509. auto *Call = dyn_cast<CallInst>(&I);
  510. if (!IsPreserveDIAccessIndexCall(Call, CInfo) ||
  511. AIChain.find(Call) != AIChain.end())
  512. continue;
  513. traceAICall(Call, CInfo);
  514. }
  515. }
  516. uint64_t BPFAbstractMemberAccess::getConstant(const Value *IndexValue) {
  517. const ConstantInt *CV = dyn_cast<ConstantInt>(IndexValue);
  518. assert(CV);
  519. return CV->getValue().getZExtValue();
  520. }
  521. /// Get the start and the end of storage offset for \p MemberTy.
  522. void BPFAbstractMemberAccess::GetStorageBitRange(DIDerivedType *MemberTy,
  523. Align RecordAlignment,
  524. uint32_t &StartBitOffset,
  525. uint32_t &EndBitOffset) {
  526. uint32_t MemberBitSize = MemberTy->getSizeInBits();
  527. uint32_t MemberBitOffset = MemberTy->getOffsetInBits();
  528. uint32_t AlignBits = RecordAlignment.value() * 8;
  529. if (RecordAlignment > 8 || MemberBitSize > AlignBits)
  530. report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info, "
  531. "requiring too big alignment");
  532. StartBitOffset = MemberBitOffset & ~(AlignBits - 1);
  533. if ((StartBitOffset + AlignBits) < (MemberBitOffset + MemberBitSize))
  534. report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info, "
  535. "cross alignment boundary");
  536. EndBitOffset = StartBitOffset + AlignBits;
  537. }
  538. uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind,
  539. DICompositeType *CTy,
  540. uint32_t AccessIndex,
  541. uint32_t PatchImm,
  542. Align RecordAlignment) {
  543. if (InfoKind == BPFCoreSharedInfo::FIELD_EXISTENCE)
  544. return 1;
  545. uint32_t Tag = CTy->getTag();
  546. if (InfoKind == BPFCoreSharedInfo::FIELD_BYTE_OFFSET) {
  547. if (Tag == dwarf::DW_TAG_array_type) {
  548. auto *EltTy = stripQualifiers(CTy->getBaseType());
  549. PatchImm += AccessIndex * calcArraySize(CTy, 1) *
  550. (EltTy->getSizeInBits() >> 3);
  551. } else if (Tag == dwarf::DW_TAG_structure_type) {
  552. auto *MemberTy = cast<DIDerivedType>(CTy->getElements()[AccessIndex]);
  553. if (!MemberTy->isBitField()) {
  554. PatchImm += MemberTy->getOffsetInBits() >> 3;
  555. } else {
  556. unsigned SBitOffset, NextSBitOffset;
  557. GetStorageBitRange(MemberTy, RecordAlignment, SBitOffset,
  558. NextSBitOffset);
  559. PatchImm += SBitOffset >> 3;
  560. }
  561. }
  562. return PatchImm;
  563. }
  564. if (InfoKind == BPFCoreSharedInfo::FIELD_BYTE_SIZE) {
  565. if (Tag == dwarf::DW_TAG_array_type) {
  566. auto *EltTy = stripQualifiers(CTy->getBaseType());
  567. return calcArraySize(CTy, 1) * (EltTy->getSizeInBits() >> 3);
  568. } else {
  569. auto *MemberTy = cast<DIDerivedType>(CTy->getElements()[AccessIndex]);
  570. uint32_t SizeInBits = MemberTy->getSizeInBits();
  571. if (!MemberTy->isBitField())
  572. return SizeInBits >> 3;
  573. unsigned SBitOffset, NextSBitOffset;
  574. GetStorageBitRange(MemberTy, RecordAlignment, SBitOffset, NextSBitOffset);
  575. SizeInBits = NextSBitOffset - SBitOffset;
  576. if (SizeInBits & (SizeInBits - 1))
  577. report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info");
  578. return SizeInBits >> 3;
  579. }
  580. }
  581. if (InfoKind == BPFCoreSharedInfo::FIELD_SIGNEDNESS) {
  582. const DIType *BaseTy;
  583. if (Tag == dwarf::DW_TAG_array_type) {
  584. // Signedness only checked when final array elements are accessed.
  585. if (CTy->getElements().size() != 1)
  586. report_fatal_error("Invalid array expression for llvm.bpf.preserve.field.info");
  587. BaseTy = stripQualifiers(CTy->getBaseType());
  588. } else {
  589. auto *MemberTy = cast<DIDerivedType>(CTy->getElements()[AccessIndex]);
  590. BaseTy = stripQualifiers(MemberTy->getBaseType());
  591. }
  592. // Only basic types and enum types have signedness.
  593. const auto *BTy = dyn_cast<DIBasicType>(BaseTy);
  594. while (!BTy) {
  595. const auto *CompTy = dyn_cast<DICompositeType>(BaseTy);
  596. // Report an error if the field expression does not have signedness.
  597. if (!CompTy || CompTy->getTag() != dwarf::DW_TAG_enumeration_type)
  598. report_fatal_error("Invalid field expression for llvm.bpf.preserve.field.info");
  599. BaseTy = stripQualifiers(CompTy->getBaseType());
  600. BTy = dyn_cast<DIBasicType>(BaseTy);
  601. }
  602. uint32_t Encoding = BTy->getEncoding();
  603. return (Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char);
  604. }
  605. if (InfoKind == BPFCoreSharedInfo::FIELD_LSHIFT_U64) {
  606. // The value is loaded into a value with FIELD_BYTE_SIZE size,
  607. // and then zero or sign extended to U64.
  608. // FIELD_LSHIFT_U64 and FIELD_RSHIFT_U64 are operations
  609. // to extract the original value.
  610. const Triple &Triple = TM->getTargetTriple();
  611. DIDerivedType *MemberTy = nullptr;
  612. bool IsBitField = false;
  613. uint32_t SizeInBits;
  614. if (Tag == dwarf::DW_TAG_array_type) {
  615. auto *EltTy = stripQualifiers(CTy->getBaseType());
  616. SizeInBits = calcArraySize(CTy, 1) * EltTy->getSizeInBits();
  617. } else {
  618. MemberTy = cast<DIDerivedType>(CTy->getElements()[AccessIndex]);
  619. SizeInBits = MemberTy->getSizeInBits();
  620. IsBitField = MemberTy->isBitField();
  621. }
  622. if (!IsBitField) {
  623. if (SizeInBits > 64)
  624. report_fatal_error("too big field size for llvm.bpf.preserve.field.info");
  625. return 64 - SizeInBits;
  626. }
  627. unsigned SBitOffset, NextSBitOffset;
  628. GetStorageBitRange(MemberTy, RecordAlignment, SBitOffset, NextSBitOffset);
  629. if (NextSBitOffset - SBitOffset > 64)
  630. report_fatal_error("too big field size for llvm.bpf.preserve.field.info");
  631. unsigned OffsetInBits = MemberTy->getOffsetInBits();
  632. if (Triple.getArch() == Triple::bpfel)
  633. return SBitOffset + 64 - OffsetInBits - SizeInBits;
  634. else
  635. return OffsetInBits + 64 - NextSBitOffset;
  636. }
  637. if (InfoKind == BPFCoreSharedInfo::FIELD_RSHIFT_U64) {
  638. DIDerivedType *MemberTy = nullptr;
  639. bool IsBitField = false;
  640. uint32_t SizeInBits;
  641. if (Tag == dwarf::DW_TAG_array_type) {
  642. auto *EltTy = stripQualifiers(CTy->getBaseType());
  643. SizeInBits = calcArraySize(CTy, 1) * EltTy->getSizeInBits();
  644. } else {
  645. MemberTy = cast<DIDerivedType>(CTy->getElements()[AccessIndex]);
  646. SizeInBits = MemberTy->getSizeInBits();
  647. IsBitField = MemberTy->isBitField();
  648. }
  649. if (!IsBitField) {
  650. if (SizeInBits > 64)
  651. report_fatal_error("too big field size for llvm.bpf.preserve.field.info");
  652. return 64 - SizeInBits;
  653. }
  654. unsigned SBitOffset, NextSBitOffset;
  655. GetStorageBitRange(MemberTy, RecordAlignment, SBitOffset, NextSBitOffset);
  656. if (NextSBitOffset - SBitOffset > 64)
  657. report_fatal_error("too big field size for llvm.bpf.preserve.field.info");
  658. return 64 - SizeInBits;
  659. }
  660. llvm_unreachable("Unknown llvm.bpf.preserve.field.info info kind");
  661. }
  662. bool BPFAbstractMemberAccess::HasPreserveFieldInfoCall(CallInfoStack &CallStack) {
  663. // This is called in error return path, no need to maintain CallStack.
  664. while (CallStack.size()) {
  665. auto StackElem = CallStack.top();
  666. if (StackElem.second.Kind == BPFPreserveFieldInfoAI)
  667. return true;
  668. CallStack.pop();
  669. }
  670. return false;
  671. }
  672. /// Compute the base of the whole preserve_* intrinsics chains, i.e., the base
  673. /// pointer of the first preserve_*_access_index call, and construct the access
  674. /// string, which will be the name of a global variable.
  675. Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(CallInst *Call,
  676. CallInfo &CInfo,
  677. std::string &AccessKey,
  678. MDNode *&TypeMeta) {
  679. Value *Base = nullptr;
  680. std::string TypeName;
  681. CallInfoStack CallStack;
  682. // Put the access chain into a stack with the top as the head of the chain.
  683. while (Call) {
  684. CallStack.push(std::make_pair(Call, CInfo));
  685. CInfo = AIChain[Call].second;
  686. Call = AIChain[Call].first;
  687. }
  688. // The access offset from the base of the head of chain is also
  689. // calculated here as all debuginfo types are available.
  690. // Get type name and calculate the first index.
  691. // We only want to get type name from typedef, structure or union.
  692. // If user wants a relocation like
  693. // int *p; ... __builtin_preserve_access_index(&p[4]) ...
  694. // or
  695. // int a[10][20]; ... __builtin_preserve_access_index(&a[2][3]) ...
  696. // we will skip them.
  697. uint32_t FirstIndex = 0;
  698. uint32_t PatchImm = 0; // AccessOffset or the requested field info
  699. uint32_t InfoKind = BPFCoreSharedInfo::FIELD_BYTE_OFFSET;
  700. while (CallStack.size()) {
  701. auto StackElem = CallStack.top();
  702. Call = StackElem.first;
  703. CInfo = StackElem.second;
  704. if (!Base)
  705. Base = CInfo.Base;
  706. DIType *PossibleTypeDef = stripQualifiers(cast<DIType>(CInfo.Metadata),
  707. false);
  708. DIType *Ty = stripQualifiers(PossibleTypeDef);
  709. if (CInfo.Kind == BPFPreserveUnionAI ||
  710. CInfo.Kind == BPFPreserveStructAI) {
  711. // struct or union type. If the typedef is in the metadata, always
  712. // use the typedef.
  713. TypeName = std::string(PossibleTypeDef->getName());
  714. TypeMeta = PossibleTypeDef;
  715. PatchImm += FirstIndex * (Ty->getSizeInBits() >> 3);
  716. break;
  717. }
  718. assert(CInfo.Kind == BPFPreserveArrayAI);
  719. // Array entries will always be consumed for accumulative initial index.
  720. CallStack.pop();
  721. // BPFPreserveArrayAI
  722. uint64_t AccessIndex = CInfo.AccessIndex;
  723. DIType *BaseTy = nullptr;
  724. bool CheckElemType = false;
  725. if (const auto *CTy = dyn_cast<DICompositeType>(Ty)) {
  726. // array type
  727. assert(CTy->getTag() == dwarf::DW_TAG_array_type);
  728. FirstIndex += AccessIndex * calcArraySize(CTy, 1);
  729. BaseTy = stripQualifiers(CTy->getBaseType());
  730. CheckElemType = CTy->getElements().size() == 1;
  731. } else {
  732. // pointer type
  733. auto *DTy = cast<DIDerivedType>(Ty);
  734. assert(DTy->getTag() == dwarf::DW_TAG_pointer_type);
  735. BaseTy = stripQualifiers(DTy->getBaseType());
  736. CTy = dyn_cast<DICompositeType>(BaseTy);
  737. if (!CTy) {
  738. CheckElemType = true;
  739. } else if (CTy->getTag() != dwarf::DW_TAG_array_type) {
  740. FirstIndex += AccessIndex;
  741. CheckElemType = true;
  742. } else {
  743. FirstIndex += AccessIndex * calcArraySize(CTy, 0);
  744. }
  745. }
  746. if (CheckElemType) {
  747. auto *CTy = dyn_cast<DICompositeType>(BaseTy);
  748. if (!CTy) {
  749. if (HasPreserveFieldInfoCall(CallStack))
  750. report_fatal_error("Invalid field access for llvm.preserve.field.info intrinsic");
  751. return nullptr;
  752. }
  753. unsigned CTag = CTy->getTag();
  754. if (CTag == dwarf::DW_TAG_structure_type || CTag == dwarf::DW_TAG_union_type) {
  755. TypeName = std::string(CTy->getName());
  756. } else {
  757. if (HasPreserveFieldInfoCall(CallStack))
  758. report_fatal_error("Invalid field access for llvm.preserve.field.info intrinsic");
  759. return nullptr;
  760. }
  761. TypeMeta = CTy;
  762. PatchImm += FirstIndex * (CTy->getSizeInBits() >> 3);
  763. break;
  764. }
  765. }
  766. assert(TypeName.size());
  767. AccessKey += std::to_string(FirstIndex);
  768. // Traverse the rest of access chain to complete offset calculation
  769. // and access key construction.
  770. while (CallStack.size()) {
  771. auto StackElem = CallStack.top();
  772. CInfo = StackElem.second;
  773. CallStack.pop();
  774. if (CInfo.Kind == BPFPreserveFieldInfoAI) {
  775. InfoKind = CInfo.AccessIndex;
  776. if (InfoKind == BPFCoreSharedInfo::FIELD_EXISTENCE)
  777. PatchImm = 1;
  778. break;
  779. }
  780. // If the next Call (the top of the stack) is a BPFPreserveFieldInfoAI,
  781. // the action will be extracting field info.
  782. if (CallStack.size()) {
  783. auto StackElem2 = CallStack.top();
  784. CallInfo CInfo2 = StackElem2.second;
  785. if (CInfo2.Kind == BPFPreserveFieldInfoAI) {
  786. InfoKind = CInfo2.AccessIndex;
  787. assert(CallStack.size() == 1);
  788. }
  789. }
  790. // Access Index
  791. uint64_t AccessIndex = CInfo.AccessIndex;
  792. AccessKey += ":" + std::to_string(AccessIndex);
  793. MDNode *MDN = CInfo.Metadata;
  794. // At this stage, it cannot be pointer type.
  795. auto *CTy = cast<DICompositeType>(stripQualifiers(cast<DIType>(MDN)));
  796. PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm,
  797. CInfo.RecordAlignment);
  798. }
  799. // Access key is the
  800. // "llvm." + type name + ":" + reloc type + ":" + patched imm + "$" +
  801. // access string,
  802. // uniquely identifying one relocation.
  803. // The prefix "llvm." indicates this is a temporary global, which should
  804. // not be emitted to ELF file.
  805. AccessKey = "llvm." + TypeName + ":" + std::to_string(InfoKind) + ":" +
  806. std::to_string(PatchImm) + "$" + AccessKey;
  807. return Base;
  808. }
  809. MDNode *BPFAbstractMemberAccess::computeAccessKey(CallInst *Call,
  810. CallInfo &CInfo,
  811. std::string &AccessKey,
  812. bool &IsInt32Ret) {
  813. DIType *Ty = stripQualifiers(cast<DIType>(CInfo.Metadata), false);
  814. assert(!Ty->getName().empty());
  815. int64_t PatchImm;
  816. std::string AccessStr("0");
  817. if (CInfo.AccessIndex == BPFCoreSharedInfo::TYPE_EXISTENCE) {
  818. PatchImm = 1;
  819. } else if (CInfo.AccessIndex == BPFCoreSharedInfo::TYPE_SIZE) {
  820. // typedef debuginfo type has size 0, get the eventual base type.
  821. DIType *BaseTy = stripQualifiers(Ty, true);
  822. PatchImm = BaseTy->getSizeInBits() / 8;
  823. } else {
  824. // ENUM_VALUE_EXISTENCE and ENUM_VALUE
  825. IsInt32Ret = false;
  826. const auto *CE = cast<ConstantExpr>(Call->getArgOperand(1));
  827. const GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0));
  828. assert(GV->hasInitializer());
  829. const ConstantDataArray *DA = cast<ConstantDataArray>(GV->getInitializer());
  830. assert(DA->isString());
  831. StringRef ValueStr = DA->getAsString();
  832. // ValueStr format: <EnumeratorStr>:<Value>
  833. size_t Separator = ValueStr.find_first_of(':');
  834. StringRef EnumeratorStr = ValueStr.substr(0, Separator);
  835. // Find enumerator index in the debuginfo
  836. DIType *BaseTy = stripQualifiers(Ty, true);
  837. const auto *CTy = cast<DICompositeType>(BaseTy);
  838. assert(CTy->getTag() == dwarf::DW_TAG_enumeration_type);
  839. int EnumIndex = 0;
  840. for (const auto Element : CTy->getElements()) {
  841. const auto *Enum = cast<DIEnumerator>(Element);
  842. if (Enum->getName() == EnumeratorStr) {
  843. AccessStr = std::to_string(EnumIndex);
  844. break;
  845. }
  846. EnumIndex++;
  847. }
  848. if (CInfo.AccessIndex == BPFCoreSharedInfo::ENUM_VALUE) {
  849. StringRef EValueStr = ValueStr.substr(Separator + 1);
  850. PatchImm = std::stoll(std::string(EValueStr));
  851. } else {
  852. PatchImm = 1;
  853. }
  854. }
  855. AccessKey = "llvm." + Ty->getName().str() + ":" +
  856. std::to_string(CInfo.AccessIndex) + std::string(":") +
  857. std::to_string(PatchImm) + std::string("$") + AccessStr;
  858. return Ty;
  859. }
  860. /// Call/Kind is the base preserve_*_access_index() call. Attempts to do
  861. /// transformation to a chain of relocable GEPs.
  862. bool BPFAbstractMemberAccess::transformGEPChain(CallInst *Call,
  863. CallInfo &CInfo) {
  864. std::string AccessKey;
  865. MDNode *TypeMeta;
  866. Value *Base = nullptr;
  867. bool IsInt32Ret;
  868. IsInt32Ret = CInfo.Kind == BPFPreserveFieldInfoAI;
  869. if (CInfo.Kind == BPFPreserveFieldInfoAI && CInfo.Metadata) {
  870. TypeMeta = computeAccessKey(Call, CInfo, AccessKey, IsInt32Ret);
  871. } else {
  872. Base = computeBaseAndAccessKey(Call, CInfo, AccessKey, TypeMeta);
  873. if (!Base)
  874. return false;
  875. }
  876. BasicBlock *BB = Call->getParent();
  877. GlobalVariable *GV;
  878. if (GEPGlobals.find(AccessKey) == GEPGlobals.end()) {
  879. IntegerType *VarType;
  880. if (IsInt32Ret)
  881. VarType = Type::getInt32Ty(BB->getContext()); // 32bit return value
  882. else
  883. VarType = Type::getInt64Ty(BB->getContext()); // 64bit ptr or enum value
  884. GV = new GlobalVariable(*M, VarType, false, GlobalVariable::ExternalLinkage,
  885. nullptr, AccessKey);
  886. GV->addAttribute(BPFCoreSharedInfo::AmaAttr);
  887. GV->setMetadata(LLVMContext::MD_preserve_access_index, TypeMeta);
  888. GEPGlobals[AccessKey] = GV;
  889. } else {
  890. GV = GEPGlobals[AccessKey];
  891. }
  892. if (CInfo.Kind == BPFPreserveFieldInfoAI) {
  893. // Load the global variable which represents the returned field info.
  894. LoadInst *LDInst;
  895. if (IsInt32Ret)
  896. LDInst = new LoadInst(Type::getInt32Ty(BB->getContext()), GV, "", Call);
  897. else
  898. LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", Call);
  899. Instruction *PassThroughInst =
  900. BPFCoreSharedInfo::insertPassThrough(M, BB, LDInst, Call);
  901. Call->replaceAllUsesWith(PassThroughInst);
  902. Call->eraseFromParent();
  903. return true;
  904. }
  905. // For any original GEP Call and Base %2 like
  906. // %4 = bitcast %struct.net_device** %dev1 to i64*
  907. // it is transformed to:
  908. // %6 = load llvm.sk_buff:0:50$0:0:0:2:0
  909. // %7 = bitcast %struct.sk_buff* %2 to i8*
  910. // %8 = getelementptr i8, i8* %7, %6
  911. // %9 = bitcast i8* %8 to i64*
  912. // using %9 instead of %4
  913. // The original Call inst is removed.
  914. // Load the global variable.
  915. auto *LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", Call);
  916. // Generate a BitCast
  917. auto *BCInst = new BitCastInst(Base, Type::getInt8PtrTy(BB->getContext()));
  918. BB->getInstList().insert(Call->getIterator(), BCInst);
  919. // Generate a GetElementPtr
  920. auto *GEP = GetElementPtrInst::Create(Type::getInt8Ty(BB->getContext()),
  921. BCInst, LDInst);
  922. BB->getInstList().insert(Call->getIterator(), GEP);
  923. // Generate a BitCast
  924. auto *BCInst2 = new BitCastInst(GEP, Call->getType());
  925. BB->getInstList().insert(Call->getIterator(), BCInst2);
  926. // For the following code,
  927. // Block0:
  928. // ...
  929. // if (...) goto Block1 else ...
  930. // Block1:
  931. // %6 = load llvm.sk_buff:0:50$0:0:0:2:0
  932. // %7 = bitcast %struct.sk_buff* %2 to i8*
  933. // %8 = getelementptr i8, i8* %7, %6
  934. // ...
  935. // goto CommonExit
  936. // Block2:
  937. // ...
  938. // if (...) goto Block3 else ...
  939. // Block3:
  940. // %6 = load llvm.bpf_map:0:40$0:0:0:2:0
  941. // %7 = bitcast %struct.sk_buff* %2 to i8*
  942. // %8 = getelementptr i8, i8* %7, %6
  943. // ...
  944. // goto CommonExit
  945. // CommonExit
  946. // SimplifyCFG may generate:
  947. // Block0:
  948. // ...
  949. // if (...) goto Block_Common else ...
  950. // Block2:
  951. // ...
  952. // if (...) goto Block_Common else ...
  953. // Block_Common:
  954. // PHI = [llvm.sk_buff:0:50$0:0:0:2:0, llvm.bpf_map:0:40$0:0:0:2:0]
  955. // %6 = load PHI
  956. // %7 = bitcast %struct.sk_buff* %2 to i8*
  957. // %8 = getelementptr i8, i8* %7, %6
  958. // ...
  959. // goto CommonExit
  960. // For the above code, we cannot perform proper relocation since
  961. // "load PHI" has two possible relocations.
  962. //
  963. // To prevent above tail merging, we use __builtin_bpf_passthrough()
  964. // where one of its parameters is a seq_num. Since two
  965. // __builtin_bpf_passthrough() funcs will always have different seq_num,
  966. // tail merging cannot happen. The __builtin_bpf_passthrough() will be
  967. // removed in the beginning of Target IR passes.
  968. //
  969. // This approach is also used in other places when global var
  970. // representing a relocation is used.
  971. Instruction *PassThroughInst =
  972. BPFCoreSharedInfo::insertPassThrough(M, BB, BCInst2, Call);
  973. Call->replaceAllUsesWith(PassThroughInst);
  974. Call->eraseFromParent();
  975. return true;
  976. }
  977. bool BPFAbstractMemberAccess::doTransformation(Function &F) {
  978. bool Transformed = false;
  979. // Collect PreserveDIAccessIndex Intrinsic call chains.
  980. // The call chains will be used to generate the access
  981. // patterns similar to GEP.
  982. collectAICallChains(F);
  983. for (auto &C : BaseAICalls)
  984. Transformed = transformGEPChain(C.first, C.second) || Transformed;
  985. return removePreserveAccessIndexIntrinsic(F) || Transformed;
  986. }
  987. PreservedAnalyses
  988. BPFAbstractMemberAccessPass::run(Function &F, FunctionAnalysisManager &AM) {
  989. return BPFAbstractMemberAccess(TM).run(F) ? PreservedAnalyses::none()
  990. : PreservedAnalyses::all();
  991. }