diff options
author | Rich Felker <dalias@aerifal.cx> | 2012-12-07 23:04:49 -0500 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2012-12-07 23:04:49 -0500 |
commit | 34aa169dcfa0a2945504fb696dee29bdf989c125 (patch) | |
tree | 2e6bf0dcd539583cd361bdcdd74e6f2a7d098258 /crt/arm/crtn.s | |
parent | b8ccf8e46bab6ee9d63a6e392c3b33b9aa89255c (diff) | |
download | musl-34aa169dcfa0a2945504fb696dee29bdf989c125.tar.gz |
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.
Diffstat (limited to 'crt/arm/crtn.s')
-rw-r--r-- | crt/arm/crtn.s | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/crt/arm/crtn.s b/crt/arm/crtn.s index 5d5d6454..928e0686 100644 --- a/crt/arm/crtn.s +++ b/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 |