summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-c-test/echo.cpp
diff options
context:
space:
mode:
authorRobert Widmann <devteam.codafi@gmail.com>2019-02-05 18:05:44 +0000
committerRobert Widmann <devteam.codafi@gmail.com>2019-02-05 18:05:44 +0000
commitd5444ccf17cb016779c6ace75e41826173497361 (patch)
treea0db02f9c042adf60bb9baf0cf9a738610d5575f /llvm/tools/llvm-c-test/echo.cpp
parentb26134bf9213d50a506b33803a3410b812f9470a (diff)
downloadbcm5719-llvm-d5444ccf17cb016779c6ace75e41826173497361.tar.gz
bcm5719-llvm-d5444ccf17cb016779c6ace75e41826173497361.zip
[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 llvm-svn: 353193
Diffstat (limited to 'llvm/tools/llvm-c-test/echo.cpp')
-rw-r--r--llvm/tools/llvm-c-test/echo.cpp78
1 files changed, 76 insertions, 2 deletions
diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp
index 73da1ee8b21..8341b11aa45 100644
--- a/llvm/tools/llvm-c-test/echo.cpp
+++ b/llvm/tools/llvm-c-test/echo.cpp
@@ -939,7 +939,7 @@ AliasDecl:
if (!Begin) {
if (End != nullptr)
report_fatal_error("Range has an end but no beginning");
- goto NamedMDDecl;
+ goto GlobalIFuncDecl;
}
Cur = Begin;
@@ -967,6 +967,41 @@ AliasDecl:
Cur = Next;
}
+GlobalIFuncDecl:
+ Begin = LLVMGetFirstGlobalIFunc(Src);
+ End = LLVMGetLastGlobalIFunc(Src);
+ if (!Begin) {
+ if (End != nullptr)
+ report_fatal_error("Range has an end but no beginning");
+ goto NamedMDDecl;
+ }
+
+ Cur = Begin;
+ Next = nullptr;
+ while (true) {
+ size_t NameLen;
+ const char *Name = LLVMGetValueName2(Cur, &NameLen);
+ if (LLVMGetNamedGlobalIFunc(M, Name, NameLen))
+ report_fatal_error("Global ifunc already cloned");
+ LLVMTypeRef CurType = TypeCloner(M).Clone(LLVMGlobalGetValueType(Cur));
+ // FIXME: Allow NULL resolver.
+ LLVMAddGlobalIFunc(M, Name, NameLen,
+ CurType, /*addressSpace*/ 0, LLVMGetUndef(CurType));
+
+ Next = LLVMGetNextGlobalIFunc(Cur);
+ if (Next == nullptr) {
+ if (Cur != End)
+ report_fatal_error("");
+ break;
+ }
+
+ LLVMValueRef Prev = LLVMGetPreviousGlobalIFunc(Next);
+ if (Prev != Cur)
+ report_fatal_error("Next.Previous global is not Current");
+
+ Cur = Next;
+ }
+
NamedMDDecl:
LLVMNamedMDNodeRef BeginMD = LLVMGetFirstNamedMetadata(Src);
LLVMNamedMDNodeRef EndMD = LLVMGetLastNamedMetadata(Src);
@@ -1114,7 +1149,7 @@ AliasClone:
if (!Begin) {
if (End != nullptr)
report_fatal_error("Range has an end but no beginning");
- goto NamedMDClone;
+ goto GlobalIFuncClone;
}
Cur = Begin;
@@ -1147,6 +1182,45 @@ AliasClone:
Cur = Next;
}
+GlobalIFuncClone:
+ Begin = LLVMGetFirstGlobalIFunc(Src);
+ End = LLVMGetLastGlobalIFunc(Src);
+ if (!Begin) {
+ if (End != nullptr)
+ report_fatal_error("Range has an end but no beginning");
+ goto NamedMDClone;
+ }
+
+ Cur = Begin;
+ Next = nullptr;
+ while (true) {
+ size_t NameLen;
+ const char *Name = LLVMGetValueName2(Cur, &NameLen);
+ LLVMValueRef IFunc = LLVMGetNamedGlobalIFunc(M, Name, NameLen);
+ if (!IFunc)
+ report_fatal_error("Global ifunc must have been declared already");
+
+ if (LLVMValueRef Resolver = LLVMGetGlobalIFuncResolver(Cur)) {
+ LLVMSetGlobalIFuncResolver(IFunc, clone_constant(Resolver, M));
+ }
+
+ LLVMSetLinkage(IFunc, LLVMGetLinkage(Cur));
+ LLVMSetUnnamedAddress(IFunc, LLVMGetUnnamedAddress(Cur));
+
+ Next = LLVMGetNextGlobalIFunc(Cur);
+ if (Next == nullptr) {
+ if (Cur != End)
+ report_fatal_error("Last global alias does not match End");
+ break;
+ }
+
+ LLVMValueRef Prev = LLVMGetPreviousGlobalIFunc(Next);
+ if (Prev != Cur)
+ report_fatal_error("Next.Previous global alias is not Current");
+
+ Cur = Next;
+ }
+
NamedMDClone:
LLVMNamedMDNodeRef BeginMD = LLVMGetFirstNamedMetadata(Src);
LLVMNamedMDNodeRef EndMD = LLVMGetLastNamedMetadata(Src);
OpenPOWER on IntegriCloud