]> git.saurik.com Git - apple/ld64.git/blob - unit-tests/test-cases/relocs-asm/relocs-asm.s
4d38f2de3b9efaa2c93ef41302ccdc89bab09b89
[apple/ld64.git] / unit-tests / test-cases / relocs-asm / relocs-asm.s
1 /*
2 * Copyright (c) 2005-2007 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25
26 #if __arm__
27 .text
28 .align 2
29
30 .globl _test_loads
31 _test_loads:
32 @ PIC load of a
33 ldr r0, L100
34 L0:
35 ldr r0, [pc, r0]
36
37 @ PIC load of c
38 ldr r0, L100+4
39 L1:
40 ldr r0, [pc, r0]
41
42 @ sorta-absolute load of a
43 ldr r0, L100+8
44 ldr r0, [r0, #0]
45
46 @ sorta-absolute load of c
47 ldr r0, L100+12
48 ldr r0, [r0, #0]
49
50 @ sorta-absolute load of external
51 ldr r0, L100+16
52 ldr r0, [r0, #0]
53
54 @ PIC load of a + addend ??
55 bx lr
56
57 L100:
58 .long _a-(L0+8)
59 .long _c-(L1+8)
60 .long _a
61 .long _c
62 .long _ax
63
64 _test_calls:
65 @ call internal
66 bl _test_branches
67
68 @ call internal + addend
69 bl _test_branches+0x19000
70
71 @ call external
72 bl _external
73
74 @ call external + addend
75 bl _external+0x19000
76
77
78 _test_branches:
79 @ call internal
80 bne _test_calls
81
82 @ call internal + addend
83 bne _test_calls+16
84
85 @ call external
86 bne _external
87
88 @ call external + addend
89 bne _external+16
90
91 nop
92 bl 1f
93 1: nop
94
95 .text
96 _pointer_diffs:
97 .long _foo-1b
98 .long _foo+10-1b
99 .long _test_branches-1b
100 .long _test_branches+3-1b
101 .long (_test_branches - _test_loads) + -2097152
102 .long (_test_calls - _test_loads) + -2097152
103
104 .text
105 .code 32
106 _arm1:
107 bx lr
108 _arm2:
109 bx lr
110 .weak_definition _arm3
111 .globl _arm3
112 .private_extern _arm3
113 _arm3:
114 bx lr
115 .weak_definition _arm4
116 .globl _arm4
117 .private_extern _arm4
118 _arm4:
119 bx lr
120
121 .code 16
122 .thumb_func _thumb1
123 _thumb1:
124 bx lr
125 .thumb_func _thumb2
126 _thumb2:
127 bx lr
128 .weak_definition _thumb3
129 .globl _thumb3
130 .private_extern _thumb3
131 .thumb_func _thumb3
132 _thumb3:
133 bx lr
134 .weak_definition _thumb4
135 .globl _thumb4
136 .private_extern _thumb4
137 .thumb_func _thumb4
138 _thumb4:
139 bx lr
140
141 .thumb_func _thumb_func_ref_test
142 _thumb_func_ref_test:
143 push {r7, lr}
144 add r7, sp, #0
145 ldr r3, L6
146 L2: add r3, pc
147 ldr r3, L7
148 L3: add r3, pc
149 ldr r3, L8
150 L4: add r3, pc
151 ldr r3, L9
152 L5: add r3, pc
153 pop {r7, pc}
154 .align 2
155 L6: .long _thumb1-(L2+4)
156 L7: .long _thumb2-(L3+4)
157 L7a:.long _thumb3-(L3+4)
158 L7b:.long _thumb4-(L3+4)
159 L8: .long _arm1-(L4+4)
160 L9: .long _arm2-(L5+4)
161 L9a:.long _arm3-(L5+4)
162 L9b:.long _arm4-(L5+4)
163
164 .code 32
165 .align 2
166 _arm_func_ref_test:
167 push {r7, lr}
168 add r7, sp, #0
169 ldr r3, L16
170 L12:add r3, pc
171 ldr r3, L17
172 L13:add r3, pc
173 ldr r3, L18
174 L14:add r3, pc
175 ldr r3, L19
176 L15:add r3, pc
177 pop {r7, pc}
178 .align 2
179 L16: .long _thumb1-(L12+8)
180 L17: .long _thumb2-(L13+8)
181 L17a: .long _thumb3-(L3+8)
182 L17b: .long _thumb4-(L3+8)
183 L18: .long _arm1-(L14+8)
184 L19: .long _arm2-(L15+8)
185 L19a: .long _arm3-(L15+8)
186 L19b: .long _arm4-(L15+8)
187
188 .section __DATA,__const
189 _myVTable:
190 .long _thumb1
191 .long _thumb2
192 .long _thumb3
193 .long _arm1
194 .long _arm2
195
196 #endif
197
198 #if __ppc__ || __ppc64__
199
200 .text
201 .align 2
202
203 .globl _test_loads
204 _test_loads:
205 stmw r30,-8(r1)
206 stwu r1,-48(r1)
207 Lpicbase:
208
209 ; PIC load of a
210 addis r2,r10,ha16(_a-Lpicbase)
211 lwz r2,lo16(_a-Lpicbase)(r2)
212
213 ; PIC load of c
214 addis r2,r10,ha16(_c-Lpicbase)
215 lwz r2,lo16(_c-Lpicbase)(r2)
216
217 ; absolute load of a
218 lis r2,ha16(_a)
219 lwz r2,lo16(_a)(r2)
220
221 ; absolute load of c
222 lis r2,ha16(_c)
223 lwz r2,lo16(_c)(r2)
224
225 ; absolute load of external
226 lis r2,ha16(_ax)
227 lwz r2,lo16(_ax)(r2)
228
229 ; absolute lea of external
230 lis r2,hi16(_ax)
231 ori r2,r2,lo16(_ax)
232
233
234 ; PIC load of a + addend
235 addis r2,r10,ha16(_a+0x19000-Lpicbase)
236 lwz r2,lo16(_a+0x19000-Lpicbase)(r2)
237
238 ; absolute load of a + addend
239 lis r2,ha16(_a+0x19000)
240 lwz r2,lo16(_a+0x19000)(r2)
241
242 ; lea of a + addend
243 lis r2,ha16(_a+0x19000)
244 addi r2,r2,lo16(_a+0x19000)
245
246 ; alt lea of a + addend
247 lis r2,hi16(_a+0x19000)
248 ori r2,r2,lo16(_a+0x19000)
249
250 ; absolute load of external + addend
251 lis r2,ha16(_ax+0x19000)
252 lwz r2,lo16(_ax+0x19000)(r2)
253
254 ; absolute lea of external + addend
255 lis r2,hi16(_ax+0x19000)
256 ori r2,r2,lo16(_ax+0x19000)
257
258
259 ; PIC load of a + addend
260 addis r2,r10,ha16(_a+0x09000-Lpicbase)
261 lwz r2,lo16(_a+0x09000-Lpicbase)(r2)
262
263 ; absolute load of a + addend
264 lis r2,ha16(_a+0x09000)
265 lwz r2,lo16(_a+0x09000)(r2)
266
267 ; lea of a + addend
268 lis r2,ha16(_a+0x09000)
269 addi r2,r2,lo16(_a+0x09000)
270
271 ; alt lea of a + addend
272 lis r2,hi16(_a+0x09000)
273 ori r2,r2,lo16(_a+0x09000)
274
275 ; absolute load of external + addend
276 lis r2,ha16(_ax+0x09000)
277 lwz r2,lo16(_ax+0x09000)(r2)
278
279 ; absolute lea of external + addend
280 lis r2,hi16(_ax+0x09000)
281 ori r2,r2,lo16(_ax+0x09000)
282
283 blr
284
285
286 _test_calls:
287 ; call internal
288 bl _test_branches
289
290 ; call internal + addend
291 bl _test_branches+0x19000
292
293 ; call external
294 bl _external
295
296 ; call external + addend
297 bl _external+0x19000
298
299
300 _test_branches:
301 ; call internal
302 bne _test_calls
303
304 ; call internal + addend
305 bne _test_calls+16
306
307 ; call external
308 bne _external
309
310 ; call external + addend
311 bne _external+16
312 #endif
313
314
315
316 #if __i386__
317 .text
318 .align 2
319
320 .globl _test_loads
321 _test_loads:
322 pushl %ebp
323 Lpicbase:
324
325 # PIC load of a
326 movl _a-Lpicbase(%ebx), %eax
327
328 # absolute load of a
329 movl _a, %eax
330
331 # absolute load of external
332 movl _ax, %eax
333
334 # absolute lea of external
335 leal _ax, %eax
336
337
338 # PIC load of a + addend
339 movl _a-Lpicbase+0x19000(%ebx), %eax
340
341 # absolute load of a + addend
342 movl _a+0x19000(%ebx), %eax
343
344 # absolute load of external + addend
345 movl _ax+0x19000(%ebx), %eax
346
347 # absolute lea of external + addend
348 leal _ax+0x1900, %eax
349
350 ret
351
352
353 _test_calls:
354 # call internal
355 call _test_branches
356
357 # call internal + addend
358 call _test_branches+0x19000
359
360 # 16-bit call internal
361 callw _test_branches
362
363 # 16-bit call internal + addend
364 callw _test_branches+13
365
366 # call external
367 call _external
368
369 # call external + addend
370 call _external+0x19000
371
372
373 _test_branches:
374 # call internal
375 jne _test_calls
376
377 # call internal + addend
378 jne _test_calls+16
379
380 # call external
381 jne _external
382
383 # call external + addend
384 jne _external+16
385
386 _pointer_diffs:
387 nop
388 call _get_ret_eax
389 1: movl _foo-1b(%eax),%esi
390 movl _foo+10-1b(%eax),%esi
391 movl _test_branches-1b(%eax),%esi
392 movl _test_branches+3-1b(%eax),%esi
393 cmpl $(( (_test_branches - _test_loads) + -2097152 )),(%esp)
394 cmpl $(( (_test_calls - _test_loads) + -2097152 )),(%esp)
395
396
397 _word_relocs:
398 callw _pointer_diffs
399
400 _byte_relocs:
401 mov $100, %ecx
402 c_1:
403 loop c_1
404 mov $100, %ecx
405 c_2:
406 sub $(1), %ecx
407 jcxz c_2
408
409 #endif
410
411
412
413 #if __x86_64__
414 .text
415 .align 2
416
417 .globl _test_loads
418 _test_loads:
419
420 # PIC load of a
421 movl _a(%rip), %eax
422
423 # PIC load of a + addend
424 movl _a+0x1234(%rip), %eax
425
426 # PIC lea
427 leaq _a(%rip), %rax
428
429 # PIC lea through GOT
430 movq _a@GOTPCREL(%rip), %rax
431
432 # PIC access of GOT
433 pushq _a@GOTPCREL(%rip)
434
435 # PIC lea external through GOT
436 movq _ax@GOTPCREL(%rip), %rax
437
438 # PIC external access of GOT
439 pushq _ax@GOTPCREL(%rip)
440
441 # 1-byte store
442 movb $0x12, _a(%rip)
443 movb $0x12, _a+2(%rip)
444 movb $0x12, L0(%rip)
445
446 # 4-byte store
447 movl $0x12345678, _a(%rip)
448 movl $0x12345678, _a+4(%rip)
449 movl $0x12345678, L0(%rip)
450
451 # test local labels
452 lea L1(%rip), %rax
453 movl L0(%rip), %eax
454
455 ret
456
457
458 _test_calls:
459 # call internal
460 call _test_branches
461
462 # call internal + addend
463 call _test_branches+0x19000
464
465 # call external
466 call _external
467
468 # call external + addend
469 call _external+0x19000
470
471
472 _test_branches:
473 # call internal
474 jne _test_calls
475
476 # call internal + addend
477 jne _test_calls+16
478
479 # call external
480 jne _external
481
482 # call external + addend
483 jne _external+16
484
485 _byte_relocs:
486 mov $100, %ecx
487 c_1:
488 loop _byte_relocs
489 nop
490
491 #endif
492
493
494
495 # test that pointer-diff relocs are preserved
496 .text
497 _test_diffs:
498 .align 2
499 Llocal2:
500 .long 0
501 .long Llocal2-_test_branches
502 .long . - _test_branches
503 .long . - _test_branches + 8
504 .long _test_branches - .
505 .long _test_branches - . + 8
506 .long _test_branches - . - 8
507 .long 0
508 .long 0
509 #if __ppc64__
510 .quad Llocal2-_test_branches
511 #endif
512
513 _foo: nop
514
515 .align 2
516 _distance_from_foo:
517 .long 0
518 .long . - _foo
519 .long . - 8 - _foo
520
521
522 _distance_to_foo:
523 .long _foo - .
524 .long _foo - . + 4
525
526
527 _distance_to_here:
528 .long _foo - _distance_to_here
529 .long _foo - _distance_to_here - 4
530 .long _foo - _distance_to_here - 12
531 .long 0
532
533
534 #if __x86_64__
535 .data
536 L0: .quad _test_branches
537 _prev:
538 .quad _test_branches+4
539 L1: .quad _test_branches - _test_diffs
540 .quad _test_branches - _test_diffs + 4
541 .long _test_branches - _test_diffs
542 # .long LCL0-. ### assembler bug: should SUB/UNSIGNED with content= LCL0-24, or single pc-rel SIGNED reloc with content = LCL0-.+4
543 .quad L1
544 .quad L0
545 .quad _test_branches - .
546 .quad _test_branches - L1
547 .quad L1 - _prev
548 #tests support for 32-bit absolute pointers
549 .long _prev
550 .long L1
551
552 # the following generates: _foo cannot be undefined in a subtraction expression
553 # but it should be ok (it will be a linker error if _foo and _bar are not in same linkage unit)
554 # .quad _foo - _bar ### assembler bug
555
556 .section __DATA,__data2
557 LCL0: .long 2
558
559
560 #endif
561
562
563 .data
564 _a:
565 .long 0
566
567 _b:
568 #if __ppc__ || __i386__ || __arm__
569 .long _test_calls
570 .long _test_calls+16
571 .long _external
572 .long _external+16
573 #elif __ppc64__ || __x86_64__
574 .quad _test_calls
575 .quad _test_calls+16
576 .quad _external
577 .quad _external+16
578 #endif
579
580 # test that reloc sizes are the same
581 Llocal3:
582 .long 0
583
584 Llocal4:
585 .long 0
586
587 .long Llocal4-Llocal3
588
589 Lfiller:
590 .space 0x9000
591 _c:
592 .long 0
593