================
@@ -0,0 +1,22 @@
+typedef void* Ptr;
+typedef struct { Ptr addr, toc, env; } Descr;
+typedef struct { Descr* desc; Ptr (*resolver)(); } IFUNC_PAIR;
+
+// A zero-length entry in section "ifunc_sec" to satisfy the __start_ifunc_sec
+// and __stop_ifunc_sec references in this file, when no user code has any.
+__attribute__((section("ifunc_sec"))) static int dummy_ifunc_sec[0];
+
+extern IFUNC_PAIR __start_ifunc_sec, __stop_ifunc_sec;
+
+__attribute__((constructor))
+void __init_ifuncs() {
+  void *volatile ref = &dummy_ifunc_sec; // hack to keep dummy_ifunc_sec alive
+
+  // hack to prevent compiler from assuming __start_ifunc_sec and
+  // __stop_ifunc_sec occupy different addresses.
+  IFUNC_PAIR *volatile volatile_end = &__stop_ifunc_sec;
----------------
w2yehia wrote:

I think the compiler assumes that two variable (non-alias) declarations cannot 
point to the same symbol, so the address of each variable is unique, so 
`&__start_ifunc_sec != &__stop_ifunc_sec` and so the for-loop can be 
transformed into a do-while loop (which executes at least once). So I used 
volatile to prevent the compiler making that assumption, and also this code 
forces a volatile load (of variable `volatile_end`) once rather than on every 
loop condition check.

https://github.com/llvm/llvm-project/pull/153049
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to