mirror of git://git.musl-libc.org/musl
in mips cancellable syscall asm, don't assume gp register is valid
the old __cp_cancel code path loaded the address of __cancel from the GOT using the $gp register, which happened to be set to point to the correct GOT by the calling C function, but there is no ABI requirement that this happen. instead, go the roundabout way and compute the address of __cancel via pc-relative and gp-relative addressing starting with a fake return address generated by a bal instruction, which is the same trick crt1 uses to bootstrap.
This commit is contained in:
parent
aecda35373
commit
756c8af858
|
@ -9,6 +9,9 @@
|
||||||
.global __cp_cancel
|
.global __cp_cancel
|
||||||
.hidden __cp_cancel
|
.hidden __cp_cancel
|
||||||
.type __cp_cancel,@function
|
.type __cp_cancel,@function
|
||||||
|
.global __cp_cancel_data
|
||||||
|
.hidden __cp_cancel_data
|
||||||
|
.type __cp_cancel_data,@function
|
||||||
.hidden __cancel
|
.hidden __cancel
|
||||||
.global __syscall_cp_asm
|
.global __syscall_cp_asm
|
||||||
.hidden __syscall_cp_asm
|
.hidden __syscall_cp_asm
|
||||||
|
@ -40,7 +43,15 @@ __cp_end:
|
||||||
nop
|
nop
|
||||||
|
|
||||||
__cp_cancel:
|
__cp_cancel:
|
||||||
|
move $2, $ra
|
||||||
|
bal 1f
|
||||||
addu $sp, $sp, 32
|
addu $sp, $sp, 32
|
||||||
lw $25, %call16(__cancel)($gp)
|
__cp_cancel_data:
|
||||||
|
.gpword __cp_cancel_data
|
||||||
|
.gpword __cancel
|
||||||
|
1: lw $3, ($ra)
|
||||||
|
subu $3, $ra, $3
|
||||||
|
lw $25, 4($ra)
|
||||||
|
addu $25, $25, $3
|
||||||
jr $25
|
jr $25
|
||||||
nop
|
move $ra, $2
|
||||||
|
|
Loading…
Reference in New Issue