xref: /llvm-project/lld/test/ELF/arm-exidx-nonzero-offset.s (revision 7a2000ac5301dbdef8c3495fbeb49cab4ac439cb)
1// REQUIRES: arm
2// RUN: rm -rf %t && split-file %s %t
3
4// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi --arm-add-build-attributes %t/a.s -o %t/a.o
5// RUN: ld.lld %t/a.o -T %t/exidx-non-zero-offset.t -o %t/non-zero
6// RUN: llvm-readelf --program-headers --unwind --symbols -x .exceptions %t/non-zero | FileCheck %s
7// RUN: ld.lld %t/a.o -T %t/exidx-zero-offset.t -o %t/zero
8// RUN: llvm-readelf --program-headers --unwind --symbols -x .exceptions %t/zero | FileCheck %s
9
10/// On platforms that load ELF files directly the ARM.exidx sections
11/// are located with the PT_ARM_EXIDX program header. This requires
12/// all .ARM.exidx input sections to be placed in a single
13/// .ARM.exidx output section. Embedded systems that do not load
14/// from an ELF file use the linker defined symbols __exidx_start and
15/// __exidx_stop. There is no requirement to place the .ARM.exidx
16/// input sections in their own output section. This test case checks
17/// that a .ARM.exidx synthetic section that isn't at a zero offset
18/// within the output section gets the correct offsets. We check
19/// this by checking that equal amounts of alignment padding
20/// inserted before and after the section start produce the same
21/// results.
22
23/// For the two linker scripts, one with the .ARM.exidx table
24/// at a zero offset within its output section and one with a
25/// non-zero offset, but both at the same file and address;
26/// the PT_ARM_EXIDX, symbols and table contents should be the
27/// same.
28// CHECK:      EXIDX 0x010080 0x00000080 0x00000080 0x00028 0x00028 R   0x4
29
30/// unwind entries starting from the right address are identical.
31/// llvm-readelf does not seem to be able to detect Thumb functionNames
32/// whereas arm-none-eabi-readelf can. Used CHECK rather than CHECK-NEXT
33/// to cope with possible improvements llvm-readelf.
34// CHECK:        FunctionAddress: 0x0
35// CHECK-NEXT:   FunctionName: f1
36// CHECK-NEXT:   Model: Compact (Inline)
37// CHECK-NEXT:   PersonalityIndex: 0
38// CHECK-NEXT:   Opcodes [
39// CHECK-NEXT:     0x97      ; vsp = r7
40// CHECK-NEXT:     0x84 0x08 ; pop {r7, lr}
41// CHECK-NEXT:   ]
42// CHECK-NEXT: }
43// CHECK-NEXT: Entry {
44// CHECK-NEXT:   FunctionAddress: 0x8
45// CHECK-NEXT:   FunctionName: f2
46// CHECK-NEXT:   Model: CantUnwind
47// CHECK-NEXT: }
48// CHECK-NEXT: Entry {
49// CHECK-NEXT:   FunctionAddress: 0xE
50// CHECK:        ExceptionHandlingTable: .ARM.extab
51// CHECK-NEXT:   TableEntryAddress: 0xA8
52// CHECK-NEXT:   Model: Generic
53// CHECK-NEXT:   PersonalityRoutineAddress: 0x12
54// CHECK-NEXT: }
55// CHECK-NEXT: Entry {
56// CHECK-NEXT:   FunctionAddress: 0x10
57// CHECK:        Model: CantUnwind
58// CHECK-NEXT: }
59// CHECK-NEXT: Entry {
60// CHECK-NEXT:   FunctionAddress: 0x14
61// CHECK-NEXT:   FunctionName: __ARMv7ABSLongThunk_f3
62// CHECK-NEXT:   Model: CantUnwind
63// CHECK-NEXT: }
64
65// CHECK:      {{[0-9]+}}: 00000080 {{.*}} __exidx_start
66// CHECK-NEXT: {{[0-9]+}}: 000000a8 {{.*}} __exidx_end
67
68// CHECK:      0x00000080 80ffff7f 08849780 80ffff7f 01000000
69// CHECK-NEXT: 0x00000090 7effff7f 14000000 78ffff7f 01000000
70// CHECK-NEXT: 0x000000a0 74ffff7f 01000000
71
72//--- exidx-non-zero-offset.t
73SECTIONS {
74  .text : { *(.text .text.*) }
75  /* Addition of thunk in .text changes alignment padding */
76  .exceptions : {
77  /* Alignment padding within .exceptions */
78  . = ALIGN(128);
79  /* Embedded C libraries find exceptions via linker defined
80     symbols */
81  __exidx_start = .;
82  *(.ARM.exidx) ;
83  __exidx_end = .;
84  }
85  .ARM.extab : { *(.ARM.extab .ARM.extab.*) }
86}
87
88//--- exidx-zero-offset.t
89SECTIONS {
90  .text : { *(.text .text.*) }
91  /* Addition of thunk in .text changes alignment padding */
92  /* alignment padding before .exceptions starts */
93  .exceptions : ALIGN(128) {
94  /* Embedded C libraries find exceptions via linker defined
95     symbols */
96  __exidx_start = .;
97  *(.ARM.exidx) ;
98  __exidx_end = .;
99  }
100  .ARM.extab : { *(.ARM.extab .ARM.extab.*) }
101}
102
103//--- a.s
104.syntax unified
105
106/// Expect inline unwind instructions.
107.section .text.01, "ax", %progbits
108.arm
109.balign 4
110.global f1
111.type f1, %function
112f1:
113.fnstart
114/// provoke an interworking thunk.
115b f3
116bx lr
117.save {r7, lr}
118.setfp r7, sp, #0
119.fnend
120
121/// Expect no unwind information from assembler. The linker must
122/// synthesise an EXIDX_CANTUNWIND entry to prevent an exception
123/// thrown through f2 from matching against the unwind instructions
124/// for f1.
125.section .text.02, "ax", %progbits
126.global f2
127.type f2, %function
128.balign 4
129f2:
130bx lr
131
132/// Expect 1 EXIDX_CANTUNWIND entry that can be merged into the linker
133/// generated EXIDX_CANTUNWIND as if the assembler had generated it.
134.section .text.03, "ax",%progbits
135.global f3
136.type f3, %function
137.thumb
138.balign 2
139f3:
140.fnstart
141bx lr
142.cantunwind
143.fnend
144
145/// Expect a section with a reference to an .ARM.extab.
146.section .text.04, "ax",%progbits
147.global f4
148.balign 2
149.type f4, %function
150f4:
151.fnstart
152bx lr
153.personality __gxx_personality_v0
154.handlerdata
155.long 0
156.fnend
157
158
159/// Dummy implementation of personality routines to satisfy reference
160/// from exception tables, linker will generate EXIDX_CANTUNWIND.
161.section .text.__aeabi_unwind_cpp_pr0, "ax", %progbits
162.global __aeabi_unwind_cpp_pr0
163.type __aeabi_unwind_cpp_pr0, %function
164.balign 2
165__aeabi_unwind_cpp_pr0:
166bx lr
167
168.section .text.__gcc_personality_v0, "ax", %progbits
169.global __gxx_personality_v0
170.type __gcc_personality_v0, %function
171.balign 2
172__gxx_personality_v0:
173bx lr
174