1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
AREA |DynamicLinker|, CODE, READONLY, REENTRANT
EXPORT |__rt_dynlink|
|__rt_dynlink|
; Enter from a call through the stub vector with r0-r6, lr saved on sp...
; ip (the 'new sb' value) is the index of the proxy function in the stub
; vector which caused this entry to the dynamic linker and identifies
; which call to resume after linking.
; On entry r0 points to the 4-word dynamic linker entry veneer at the
; end of the stub vector.
MOV r6, r0
LDR r5, [r6, #-8] ; # entries - 1
ADD r5, r5, #1 ; # entries
MOV r4, ip ; resume index
; r6+24 points to the EFT parameter block; call the library location function
; to return a pointer to the matching library... Here we assume it's loaded
; at 0x40000...
; In the following line, the Makefile relies on a space after '#' and on the
; contents of the comment. DO NOT CHANGE THESE OR Makefile WILL FAIL.
MOV r0, # 0x40000 ; EFT Address (DO NOT ALTER THIS COMMENT)
; r0 now points to the EFT
LDR ip, [r0] ; #entries
CMPS ip, r5
BLT Botched ; not enough entries to init the stub
LDR ip, [r6, #16] ; stub data len
BIC ip, ip, #3 ; word aligned, I insist...
ADD r3, r0, #4
LDR r3, [r3, r5, LSL #2] ; library data len...
CMPS r3, ip
BNE Botched
LDR r3, [r6, #20] ; stub data dest
SUB r2, r0, ip ; library data src - precedes EFT
01 SUBS ip, ip, #4 ; word by word copy loop
LDRGE r1, [r2], #4
STRGE r1, [r3], #4
BGE %B01
LDR ip, [r6, #12] ; length of the inter-LU data area
ADD r3, r6, #24 ; end of the inter-LU data area...
SUB r3, r3, ip ; sb = start of inter-LU data area
LDR r2, [r6, #-8]! ; index of stub entry
00 SUB ip, r5, #1 ; index of the lib entry
CMPS ip, r2 ; is this lib entry in the stub?
SUBGT r5, r5, #1 ; no, skip it
BGT %B00
CMPS r2, r4 ; found the retry index?
MOVEQ lr, r6 ; yes: remember it
LDR ip, [r0, r5, lsl #2] ; entry point offset
ADD ip, ip, r0 ; entry point address
STMIA r6, {r3, ip} ; save {sb, pc}
LDR r2, [r6, #-8]! ; load index and decrement r6...
TST r2, #&ff000000 ; ... or if loaded instruction?
LDRNE r2, [r6, #-8]! ; load index and decrement r6 if instr
SUBS r5, r5, #1
BGT %B00
MOV ip, lr ; retry address
LDMFD sp!, {r0-r6, lr} ; restore saved regs
LDMIA ip, {ip, pc} ; and retry the call
Botched B Botched
END
|