Browse Source

add support for ctors/dtors on arm with modern gcc

a while back, gcc switched from using the old _init/_fini fragments
method for calling ctors and dtors on arm to the __init_array and
__fini_array method. unfortunately, on glibc this depends on ugly
hacks involving making libc.so a linker script and pulling parts of
libc into the main program binary. so I cheat a little bit, and just
write asm to iterate over the init/fini arrays from the _init/_fini
asm. the same approach could be used on any arch it's needed on, but
for now arm is the only one.
Rich Felker 12 năm trước cách đây
mục cha
commit
34aa169dcf
2 tập tin đã thay đổi với 40 bổ sung4 xóa
  1. 20 2
      crt/arm/crti.s
  2. 20 2
      crt/arm/crtn.s

+ 20 - 2
crt/arm/crti.s

@@ -1,9 +1,27 @@
 .section .init
 .global _init
 _init:
-	push {lr}
+	push {r0,r1,r2,r4,r5,lr}
+
+.weak __fini_array_start
+.weak __fini_array_end
 
 .section .fini
 .global _fini
 _fini:
-	push {lr}
+	push {r4,r5,r6,lr}
+	adr lr, 1f
+	ldr r4, 2f
+	ldr r5, 2f+4
+	add r4, r4, lr
+	add r5, r5, lr
+1:	adr lr, 1b
+	cmp r4, r5
+	beq 3f
+	ldmia r4!, {r3}
+	tst r3,#1
+	moveq pc,r3
+	bx r3
+2:	.word __fini_array_start-1b
+	.word __fini_array_end-1b
+3:	

+ 20 - 2
crt/arm/crtn.s

@@ -1,11 +1,29 @@
+.weak __init_array_start
+.weak __init_array_end
+
 .section .init
-	pop {lr}
+	adr lr, 1f
+	ldr r4, 2f
+	ldr r5, 2f+4
+	add r4, r4, lr
+	add r5, r5, lr
+1:	adr lr, 1b
+	cmp r4, r5
+	beq 3f
+	ldmia r4!, {r3}
+	ldm sp, {r0,r1,r2}
+	tst r3,#1
+	moveq pc,r3
+	bx r3
+3:	pop {r0,r1,r2,r4,r5,lr}
 	tst lr,#1
 	moveq pc,lr
 	bx lr
+2:	.word __init_array_start-1b
+	.word __init_array_end-1b
 
 .section .fini
-	pop {lr}
+	pop {r4,r5,r6,lr}
 	tst lr,#1
 	moveq pc,lr
 	bx lr