-/* r0 = virtual target address */
-/* r1 = instruction to patch */
-.macro dyna_linker_main
-#ifndef NO_WRITE_EXEC
- load_varadr_ext r3, jump_in
- /* get_page */
- lsr r2, r0, #12
- mov r6, #4096
- bic r2, r2, #0xe0000
- sub r6, r6, #1
- cmp r2, #0x1000
- ldr r7, [r1]
- biclt r2, #0x0e00
- and r6, r6, r2
- cmp r2, #2048
- add r12, r7, #2
- orrcs r2, r6, #2048
- ldr r5, [r3, r2, lsl #2]
- lsl r12, r12, #8
- add r6, r1, r12, asr #6
- mov r8, #0
- /* jump_in lookup */
-1:
- movs r4, r5
- beq 2f
- ldr r3, [r5] /* ll_entry .vaddr */
- ldrd r4, r5, [r4, #8] /* ll_entry .next, .addr */
- teq r3, r0
- bne 1b
- teq r4, r6
- moveq pc, r4 /* Stale i-cache */
- mov r8, r4
- b 1b /* jump_in may have dupes, continue search */
-2:
- tst r8, r8
- beq 3f /* r0 not in jump_in */
-
- mov r5, r1
- mov r1, r6
- bl add_link
- sub r2, r8, r5
- and r1, r7, #0xff000000
- lsl r2, r2, #6
- sub r1, r1, #2
- add r1, r1, r2, lsr #8
- str r1, [r5]
- mov pc, r8
-3:
- /* hash_table lookup */
- cmp r2, #2048
- load_varadr_ext r3, jump_dirty
- eor r4, r0, r0, lsl #16
- lslcc r2, r0, #9
- load_varadr_ext r6, hash_table
- lsr r4, r4, #12
- lsrcc r2, r2, #21
- bic r4, r4, #15
- ldr r5, [r3, r2, lsl #2]
- ldr r7, [r6, r4]!
- teq r7, r0
- ldreq pc, [r6, #4]
- ldr r7, [r6, #8]
- teq r7, r0
- ldreq pc, [r6, #12]
- /* jump_dirty lookup */
-6:
- movs r4, r5
- beq 8f
- ldr r3, [r5]
- ldr r5, [r4, #12]
- teq r3, r0
- bne 6b
-7:
- ldr r1, [r4, #8]
- /* hash_table insert */
- ldr r2, [r6]
- ldr r3, [r6, #4]
- str r0, [r6]
- str r1, [r6, #4]
- str r2, [r6, #8]
- str r3, [r6, #12]
- mov pc, r1
-8:
-#else
- /* XXX: should be able to do better than this... */
- bl get_addr_ht
- mov pc, r0
-#endif
-.endm
-
-