diff options
author | Robert Widmann <devteam.codafi@gmail.com> | 2019-02-05 18:05:44 +0000 |
---|---|---|
committer | Robert Widmann <devteam.codafi@gmail.com> | 2019-02-05 18:05:44 +0000 |
commit | d5444ccf17cb016779c6ace75e41826173497361 (patch) | |
tree | a0db02f9c042adf60bb9baf0cf9a738610d5575f /llvm/tools/llvm-c-test/echo.cpp | |
parent | b26134bf9213d50a506b33803a3410b812f9470a (diff) | |
download | bcm5719-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.cpp | 78 |
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); |