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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
# File to either setup register 2 to point to the GOT, or to adjust the
# pointers in the .got2 section to point to their new addresses.
.file "eabi.asm"
.section ".text"
.globl __eabi
.section ".got2","aw"
.LCTOC1 = . # +32768
# Table of addresses
.Ltable = .-.LCTOC1
.long .LCTOC1 # address we are really at
.Lgot = .-.LCTOC1
.long _GLOBAL_OFFSET_TABLE_ # normal GOT address
.Lgots = .-.LCTOC1
.long _GOT_START_ # start of .got section
.Lgote = .-.LCTOC1
.long _GOT_END_ # end of .got section
.Lgot2s = .-.LCTOC1
.long _GOT2_START_ # -mrelocatable GOT pointers start
.Lgot2e = .-.LCTOC1
.long _GOT2_END_ # -mrelocatable GOT pointers end
.text
.Lptr:
.long .LCTOC1-.Laddr # PC relative pointer to .got2
.long 0x4000 # traceback table
__eabi: mflr 0
bl .Laddr # get current address
.Laddr:
mflr 12 # real address of .Laddr
lwz 11,(.Lptr-.Laddr)(12) # linker generated address of .LCTOC1
add 11,11,12 # correct to real pointer
lwz 12,.Ltable(11) # get linker's idea of where .Laddr is
subf. 12,12,11 # calculate difference
mtlr 0 # restore link register
bc 4,2,.Lreloc # skip if we need to relocate
# Only load up register 2 if there is a .got section
lwz 3,.Lgots(11) # start of .got section
lwz 4,.Lgote(11) # end of .got section
cmpw 1,3,4 # .got section non-empty?
bc 12,6,.Ldone
# Normal program, load up register 2
lwz 2,.Lgot(11) # normal GOT address
b __do_global_ctors # do any C++ global contstructors (which returns to caller)
# We need to relocate the .got2 pointers. Don't load register 2
.Lreloc:
lwz 3,.Lgot2s(11) # GOT pointers start
lwz 4,.Lgot2e(11) # GOT pointers end
add 3,12,3 # adjust pointers
add 4,12,4
cmpw 1,3,4 # any pointers to adjust
bc 12,6,.Ldone
.Lloop:
lwz 11,0(3) # next pointer
add 11,11,12 # adjust
stw 11,0(3)
addi 3,3,4 # bump to next word
cmpw 1,3,4 # more pointers to adjust?
bc 4,6,.Lloop
# Done adjusting pointers, return
.Ldone:
b __do_global_ctors # do any C++ global contstructors (which returns to caller)
# Routines for saving floating point registers, called by the compiler.
# Called with r11 pointing to the stack header word of the caller of the
# function, just beyond the end of the floating point save area.
.globl _savefpr_14_l
.globl _savefpr_15_l
.globl _savefpr_16_l
.globl _savefpr_17_l
.globl _savefpr_18_l
.globl _savefpr_19_l
.globl _savefpr_20_l
.globl _savefpr_21_l
.globl _savefpr_22_l
.globl _savefpr_23_l
.globl _savefpr_24_l
.globl _savefpr_25_l
.globl _savefpr_26_l
.globl _savefpr_27_l
.globl _savefpr_28_l
.globl _savefpr_29_l
.globl _savefpr_30_l
.globl _savefpr_31_l
.long 0x00400000 # traceback tag
_savefpr_14_l: stfd 14,-144(11) # save fp registers
_savefpr_15_l: stfd 15,-136(11)
_savefpr_16_l: stfd 16,-128(11)
_savefpr_17_l: stfd 17,-120(11)
_savefpr_18_l: stfd 18,-112(11)
_savefpr_19_l: stfd 19,-104(11)
_savefpr_20_l: stfd 20,-96(11)
_savefpr_21_l: stfd 21,-88(11)
_savefpr_22_l: stfd 22,-80(11)
_savefpr_23_l: stfd 23,-72(11)
_savefpr_24_l: stfd 24,-64(11)
_savefpr_25_l: stfd 25,-56(11)
_savefpr_26_l: stfd 26,-48(11)
_savefpr_27_l: stfd 27,-40(11)
_savefpr_28_l: stfd 28,-32(11)
_savefpr_29_l: stfd 29,-24(11)
_savefpr_30_l: stfd 30,-16(11)
_savefpr_31_l: stfd 31,-8(11)
stw 0,4(11) # save return address also
blr
# Routines for restoring floating point registers, called by the compiler.
# Called with r11 pointing to the stack header word of the caller of the
# function, just beyond the end of the floating point save area.
.globl _restfpr_14_l
.globl _restfpr_15_l
.globl _restfpr_16_l
.globl _restfpr_17_l
.globl _restfpr_18_l
.globl _restfpr_19_l
.globl _restfpr_20_l
.globl _restfpr_21_l
.globl _restfpr_22_l
.globl _restfpr_23_l
.globl _restfpr_24_l
.globl _restfpr_25_l
.globl _restfpr_26_l
.globl _restfpr_27_l
.globl _restfpr_28_l
.globl _restfpr_29_l
.globl _restfpr_30_l
.globl _restfpr_31_l
.long 0x00600000 # traceback tag
_restfpr_14_l: lfd 14,-144(11) # restore fp registers
_restfpr_15_l: lfd 15,-136(11)
_restfpr_16_l: lfd 16,-128(11)
_restfpr_17_l: lfd 17,-120(11)
_restfpr_18_l: lfd 18,-112(11)
_restfpr_19_l: lfd 19,-104(11)
_restfpr_20_l: lfd 20,-96(11)
_restfpr_21_l: lfd 21,-88(11)
_restfpr_22_l: lfd 22,-80(11)
_restfpr_23_l: lfd 23,-72(11)
_restfpr_24_l: lfd 24,-64(11)
_restfpr_25_l: lfd 25,-56(11)
_restfpr_26_l: lfd 26,-48(11)
_restfpr_27_l: lfd 27,-40(11)
_restfpr_28_l: lfd 28,-32(11)
_restfpr_29_l: lfd 29,-24(11)
_restfpr_30_l: lfd 30,-16(11)
_restfpr_31_l: lwz 0,4(11) # caller's caller address
lfd 31,-8(11)
mtlr 0
mr 1,11
blr
|