summaryrefslogtreecommitdiffstats
path: root/libc/arch-x86/bionic/crtend_so.S
diff options
context:
space:
mode:
Diffstat (limited to 'libc/arch-x86/bionic/crtend_so.S')
-rw-r--r--libc/arch-x86/bionic/crtend_so.S47
1 files changed, 47 insertions, 0 deletions
diff --git a/libc/arch-x86/bionic/crtend_so.S b/libc/arch-x86/bionic/crtend_so.S
new file mode 100644
index 0000000..7fb2280
--- /dev/null
+++ b/libc/arch-x86/bionic/crtend_so.S
@@ -0,0 +1,47 @@
+.text
+.align 4
+.type __bionic_call_ctors, @function
+
+/*
+ * The CTORS_LIST is marked by -1 (start) and 0 (end).
+ * We mark the end of the .ctors section with the __CTOR_END__ section so
+ * that we can just iterate backwards from it until we hit -1 and execute
+ * all the function pointers. This seems to be the way to do it for SVR4
+ * derived systems.
+ */
+__bionic_call_ctors:
+ pushl %esi
+ mov $__CTOR_END__, %esi
+
+0:
+ /* now grab the next function pointer and check if its -1. If not,
+ * call it, otherwise we're done. We use %esi since it's callee saved.
+ */
+ subl $4, %esi
+ mov (%esi), %eax
+ cmp $0xffffffff, %eax
+ je 1f
+ call *%eax
+ jmp 0b
+
+1:
+ /* we're done */
+ popl %esi
+ ret
+
+.section .init
+.align 4
+ call __bionic_call_ctors
+ ret
+
+.section .ctors, "aw", @progbits
+.align 4
+.type __CTOR_END__, @object
+__CTOR_END__:
+ .long 0
+
+.section .init_array, "aw"
+ .long 0
+
+.section .fini_array, "aw"
+ .long 0