llvm.org GIT mirror llvm / 005e630
[LLVM-C] Add Bindings to GlobalIFunc Summary: Adds the standard gauntlet of accessors for global indirect functions and updates the echo test. Now it would be nice to have a target abstraction so one could know if they have access to a suitable ELF linker and runtime. Reviewers: whitequark, deadalnix Reviewed By: whitequark Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D56177 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353193 91177308-0d34-0410-b5e6-96231b3b80d8 Robert Widmann 7 months ago
4 changed file(s) with 245 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
26112611 */
26122612
26132613 /**
2614 * @defgroup LLVMCCoreValueGlobalIFunc IFuncs
2615 *
2616 * Functions in this group relate to indirect functions.
2617 *
2618 * Functions in this group expect LLVMValueRef instances that correspond
2619 * to llvm::GlobalIFunc instances.
2620 *
2621 * @{
2622 */
2623
2624 /**
2625 * Add a global indirect function to a module under a specified name.
2626 *
2627 * @see llvm::GlobalIFunc::create()
2628 */
2629 LLVMValueRef LLVMAddGlobalIFunc(LLVMModuleRef M,
2630 const char *Name, size_t NameLen,
2631 LLVMTypeRef Ty, unsigned AddrSpace,
2632 LLVMValueRef Resolver);
2633
2634 /**
2635 * Obtain a GlobalIFunc value from a Module by its name.
2636 *
2637 * The returned value corresponds to a llvm::GlobalIFunc value.
2638 *
2639 * @see llvm::Module::getNamedIFunc()
2640 */
2641 LLVMValueRef LLVMGetNamedGlobalIFunc(LLVMModuleRef M,
2642 const char *Name, size_t NameLen);
2643
2644 /**
2645 * Obtain an iterator to the first GlobalIFunc in a Module.
2646 *
2647 * @see llvm::Module::ifunc_begin()
2648 */
2649 LLVMValueRef LLVMGetFirstGlobalIFunc(LLVMModuleRef M);
2650
2651 /**
2652 * Obtain an iterator to the last GlobalIFunc in a Module.
2653 *
2654 * @see llvm::Module::ifunc_end()
2655 */
2656 LLVMValueRef LLVMGetLastGlobalIFunc(LLVMModuleRef M);
2657
2658 /**
2659 * Advance a GlobalIFunc iterator to the next GlobalIFunc.
2660 *
2661 * Returns NULL if the iterator was already at the end and there are no more
2662 * global aliases.
2663 */
2664 LLVMValueRef LLVMGetNextGlobalIFunc(LLVMValueRef IFunc);
2665
2666 /**
2667 * Decrement a GlobalIFunc iterator to the previous GlobalIFunc.
2668 *
2669 * Returns NULL if the iterator was already at the beginning and there are
2670 * no previous global aliases.
2671 */
2672 LLVMValueRef LLVMGetPreviousGlobalIFunc(LLVMValueRef IFunc);
2673
2674 /**
2675 * Retrieves the resolver function associated with this indirect function, or
2676 * NULL if it doesn't not exist.
2677 *
2678 * @see llvm::GlobalIFunc::getResolver()
2679 */
2680 LLVMValueRef LLVMGetGlobalIFuncResolver(LLVMValueRef IFunc);
2681
2682 /**
2683 * Sets the resolver function associated with this indirect function.
2684 *
2685 * @see llvm::GlobalIFunc::setResolver()
2686 */
2687 void LLVMSetGlobalIFuncResolver(LLVMValueRef IFunc, LLVMValueRef Resolver);
2688
2689 /**
2690 * Remove a global indirect function from its parent module and delete it.
2691 *
2692 * @see llvm::GlobalIFunc::eraseFromParent()
2693 */
2694 void LLVMEraseGlobalIFunc(LLVMValueRef IFunc);
2695
2696 /**
2697 * Remove a global indirect function from its parent module.
2698 *
2699 * This unlinks the global indirect function from its containing module but
2700 * keeps it alive.
2701 *
2702 * @see llvm::GlobalIFunc::removeFromParent()
2703 */
2704 void LLVMRemoveGlobalIFunc(LLVMValueRef IFunc);
2705
2706 /**
2707 * @}
2708 */
2709
2710 /**
26142711 * @}
26152712 */
26162713
24622462 A->addAttr(Attribute::getWithAlignment(A->getContext(), align));
24632463 }
24642464
2465 /*--.. Operations on ifuncs ................................................--*/
2466
2467 LLVMValueRef LLVMAddGlobalIFunc(LLVMModuleRef M,
2468 const char *Name, size_t NameLen,
2469 LLVMTypeRef Ty, unsigned AddrSpace,
2470 LLVMValueRef Resolver) {
2471 return wrap(GlobalIFunc::create(unwrap(Ty), AddrSpace,
2472 GlobalValue::ExternalLinkage,
2473 StringRef(Name, NameLen),
2474 unwrap(Resolver), unwrap(M)));
2475 }
2476
2477 LLVMValueRef LLVMGetNamedGlobalIFunc(LLVMModuleRef M,
2478 const char *Name, size_t NameLen) {
2479 return wrap(unwrap(M)->getNamedIFunc(StringRef(Name, NameLen)));
2480 }
2481
2482 LLVMValueRef LLVMGetFirstGlobalIFunc(LLVMModuleRef M) {
2483 Module *Mod = unwrap(M);
2484 Module::ifunc_iterator I = Mod->ifunc_begin();
2485 if (I == Mod->ifunc_end())
2486 return nullptr;
2487 return wrap(&*I);
2488 }
2489
2490 LLVMValueRef LLVMGetLastGlobalIFunc(LLVMModuleRef M) {
2491 Module *Mod = unwrap(M);
2492 Module::ifunc_iterator I = Mod->ifunc_end();
2493 if (I == Mod->ifunc_begin())
2494 return nullptr;
2495 return wrap(&*--I);
2496 }
2497
2498 LLVMValueRef LLVMGetNextGlobalIFunc(LLVMValueRef IFunc) {
2499 GlobalIFunc *GIF = unwrap(IFunc);
2500 Module::ifunc_iterator I(GIF);
2501 if (++I == GIF->getParent()->ifunc_end())
2502 return nullptr;
2503 return wrap(&*I);
2504 }
2505
2506 LLVMValueRef LLVMGetPreviousGlobalIFunc(LLVMValueRef IFunc) {
2507 GlobalIFunc *GIF = unwrap(IFunc);
2508 Module::ifunc_iterator I(GIF);
2509 if (I == GIF->getParent()->ifunc_begin())
2510 return nullptr;
2511 return wrap(&*--I);
2512 }
2513
2514 LLVMValueRef LLVMGetGlobalIFuncResolver(LLVMValueRef IFunc) {
2515 return wrap(unwrap(IFunc)->getResolver());
2516 }
2517
2518 void LLVMSetGlobalIFuncResolver(LLVMValueRef IFunc, LLVMValueRef Resolver) {
2519 unwrap(IFunc)->setResolver(unwrap(Resolver));
2520 }
2521
2522 void LLVMEraseGlobalIFunc(LLVMValueRef IFunc) {
2523 unwrap(IFunc)->eraseFromParent();
2524 }
2525
2526 void LLVMRemoveGlobalIFunc(LLVMValueRef IFunc) {
2527 unwrap(IFunc)->removeFromParent();
2528 }
2529
24652530 /*--.. Operations on basic blocks ..........................................--*/
24662531
24672532 LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef BB) {
2626 @aliased3 = external alias i32, i32* @var
2727 @aliased4 = weak alias i32, i32* @var
2828 @aliased5 = weak_odr alias i32, i32* @var
29
30 @ifunc = ifunc i32 (i32), i64 ()* @ifunc_resolver
31
32 define i64 @ifunc_resolver() {
33 entry:
34 ret i64 0
35 }
2936
3037 define { i64, %S* } @unpackrepack(%S %s) {
3138 %1 = extractvalue %S %s, 0
938938 if (!Begin) {
939939 if (End != nullptr)
940940 report_fatal_error("Range has an end but no beginning");
941 goto NamedMDDecl;
941 goto GlobalIFuncDecl;
942942 }
943943
944944 Cur = Begin;
966966 Cur = Next;
967967 }
968968
969 GlobalIFuncDecl:
970 Begin = LLVMGetFirstGlobalIFunc(Src);
971 End = LLVMGetLastGlobalIFunc(Src);
972 if (!Begin) {
973 if (End != nullptr)
974 report_fatal_error("Range has an end but no beginning");
975 goto NamedMDDecl;
976 }
977
978 Cur = Begin;
979 Next = nullptr;
980 while (true) {
981 size_t NameLen;
982 const char *Name = LLVMGetValueName2(Cur, &NameLen);
983 if (LLVMGetNamedGlobalIFunc(M, Name, NameLen))
984 report_fatal_error("Global ifunc already cloned");
985 LLVMTypeRef CurType = TypeCloner(M).Clone(LLVMGlobalGetValueType(Cur));
986 // FIXME: Allow NULL resolver.
987 LLVMAddGlobalIFunc(M, Name, NameLen,
988 CurType, /*addressSpace*/ 0, LLVMGetUndef(CurType));
989
990 Next = LLVMGetNextGlobalIFunc(Cur);
991 if (Next == nullptr) {
992 if (Cur != End)
993 report_fatal_error("");
994 break;
995 }
996
997 LLVMValueRef Prev = LLVMGetPreviousGlobalIFunc(Next);
998 if (Prev != Cur)
999 report_fatal_error("Next.Previous global is not Current");
1000
1001 Cur = Next;
1002 }
1003
9691004 NamedMDDecl:
9701005 LLVMNamedMDNodeRef BeginMD = LLVMGetFirstNamedMetadata(Src);
9711006 LLVMNamedMDNodeRef EndMD = LLVMGetLastNamedMetadata(Src);
11131148 if (!Begin) {
11141149 if (End != nullptr)
11151150 report_fatal_error("Range has an end but no beginning");
1116 goto NamedMDClone;
1151 goto GlobalIFuncClone;
11171152 }
11181153
11191154 Cur = Begin;
11461181 Cur = Next;
11471182 }
11481183
1184 GlobalIFuncClone:
1185 Begin = LLVMGetFirstGlobalIFunc(Src);
1186 End = LLVMGetLastGlobalIFunc(Src);
1187 if (!Begin) {
1188 if (End != nullptr)
1189 report_fatal_error("Range has an end but no beginning");
1190 goto NamedMDClone;
1191 }
1192
1193 Cur = Begin;
1194 Next = nullptr;
1195 while (true) {
1196 size_t NameLen;
1197 const char *Name = LLVMGetValueName2(Cur, &NameLen);
1198 LLVMValueRef IFunc = LLVMGetNamedGlobalIFunc(M, Name, NameLen);
1199 if (!IFunc)
1200 report_fatal_error("Global ifunc must have been declared already");
1201
1202 if (LLVMValueRef Resolver = LLVMGetGlobalIFuncResolver(Cur)) {
1203 LLVMSetGlobalIFuncResolver(IFunc, clone_constant(Resolver, M));
1204 }
1205
1206 LLVMSetLinkage(IFunc, LLVMGetLinkage(Cur));
1207 LLVMSetUnnamedAddress(IFunc, LLVMGetUnnamedAddress(Cur));
1208
1209 Next = LLVMGetNextGlobalIFunc(Cur);
1210 if (Next == nullptr) {
1211 if (Cur != End)
1212 report_fatal_error("Last global alias does not match End");
1213 break;
1214 }
1215
1216 LLVMValueRef Prev = LLVMGetPreviousGlobalIFunc(Next);
1217 if (Prev != Cur)
1218 report_fatal_error("Next.Previous global alias is not Current");
1219
1220 Cur = Next;
1221 }
1222
11491223 NamedMDClone:
11501224 LLVMNamedMDNodeRef BeginMD = LLVMGetFirstNamedMetadata(Src);
11511225 LLVMNamedMDNodeRef EndMD = LLVMGetLastNamedMetadata(Src);