BPFAbstractMemberAccess.cpp 44 KB

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