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 174 175 176 177 178 179 180
|
// REQUIRES: arm
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-exidx-cantunwind.s -o %tcantunwind
// RUN: ld.lld --no-merge-exidx-entries %t %tcantunwind -o %t2
// RUN: llvm-objdump -d --triple=armv7a-none-linux-gnueabi --no-show-raw-insn %t2 | FileCheck %s
// RUN: llvm-objdump -s --triple=armv7a-none-linux-gnueabi %t2 | FileCheck --check-prefix=CHECK-EXIDX %s
// RUN: llvm-readobj --program-headers --sections %t2 | FileCheck -check-prefix=CHECK-PT %s
// Use Linker script to place .ARM.exidx in between .text and orphan sections
// RUN: echo "SECTIONS { \
// RUN: .text 0x11000 : { *(.text*) } \
// RUN: .ARM.exidx : { *(.ARM.exidx) } } " > %t.script
// RUN: ld.lld --no-merge-exidx-entries --script %t.script %tcantunwind %t -o %t3
// RUN: llvm-objdump -d --triple=armv7a-none-linux-gnueabi %t3 | FileCheck --check-prefix=CHECK-SCRIPT %s
// RUN: llvm-objdump -s --triple=armv7a-none-linux-gnueabi %t3 | FileCheck --check-prefix=CHECK-SCRIPT-EXIDX %s
/// Each assembler created .ARM.exidx section has the SHF_LINK_ORDER flag set
/// with the sh_link containing the section index of the executable section
/// containing the function it describes. The linker must combine the .ARM.exidx
/// InputSections in the same order that it has combined the executable section,
/// such that the combined .ARM.exidx OutputSection can be used as a binary
/// search table.
.syntax unified
.section .text, "ax",%progbits
.globl _start
_start:
.fnstart
bx lr
.cantunwind
.fnend
.section .text.f1, "ax", %progbits
.globl f1
f1:
.fnstart
bx lr
.cantunwind
.fnend
.section .text.f2, "ax", %progbits
.globl f2
f2:
.fnstart
bx lr
.cantunwind
.fnend
.globl f3
f3:
.fnstart
bx lr
.cantunwind
.fnend
/// Check default no linker script order.
// CHECK: Disassembly of section .text:
// CHECK-EMPTY:
// CHECK: <_start>:
// CHECK-NEXT: 20124: bx lr
// CHECK: <f1>:
// CHECK-NEXT: 20128: bx lr
// CHECK: <f2>:
// CHECK-NEXT: 2012c: bx lr
// CHECK: <f3>:
// CHECK-NEXT: 20130: bx lr
// CHECK: <func4>:
// CHECK-NEXT: 20134: bx lr
// CHECK: <func5>:
// CHECK-NEXT: 20138: bx lr
// CHECK: Disassembly of section .func1:
// CHECK-EMPTY:
// CHECK-NEXT: <func1>:
// CHECK-NEXT: 2013c: bx lr
// CHECK: Disassembly of section .func2:
// CHECK-EMPTY:
// CHECK-NEXT: <func2>:
// CHECK-NEXT: 20140: bx lr
// CHECK: Disassembly of section .func3:
// CHECK-EMPTY:
// CHECK-NEXT: <func3>:
// CHECK-NEXT: 20144: bx lr
/// Each .ARM.exidx section has two 4 byte fields
/// Field 1 is the 31-bit offset to the function. The top bit is used to
/// indicate whether Field 2 is a pointer or an inline table entry.
/// Field 2 is either a pointer to a .ARM.extab section or an inline table
/// In this example all Field 2 entries are inline can't unwind (0x1)
/// We expect to see the entries in the same order as the functions
// CHECK-EXIDX: Contents of section .ARM.exidx:
/// 100d4 + 1050 = 11124 = _start
/// 100dc + 104c = 11128 = f1
// CHECK-EXIDX-NEXT: 100d4 50000100 01000000 4c000100 01000000
/// 100e4 + 1048 = 1112c = f2
/// 100ec + 1044 = 11130 = f3
// CHECK-EXIDX-NEXT: 100e4 48000100 01000000 44000100 01000000
/// 100f4 + 1040 = 11134 = func4
/// 100fc + 103c = 11138 = func5
// CHECK-EXIDX-NEXT: 100f4 40000100 01000000 3c000100 01000000
/// 10104 + 1038 = 1113c = func1
/// 1010c + 1034 = 11140 = func2
// CHECK-EXIDX-NEXT: 10104 38000100 01000000 34000100 01000000
/// 10114 + 1030 = 11144 = func3
// CHECK-EXIDX-NEXT: 10114 30000100 01000000
/// Check that PT_ARM_EXIDX program header has been generated that describes
/// the .ARM.exidx output section
// CHECK-PT: Name: .ARM.exidx
// CHECK-PT-NEXT: Type: SHT_ARM_EXIDX (0x70000001)
// CHECK-PT-NEXT: Flags [
// CHECK-PT-NEXT: SHF_ALLOC
// CHECK-PT-NEXT: SHF_LINK_ORDER
// CHECK-PT-NEXT: ]
// CHECK-PT-NEXT: Address: 0x100D4
// CHECK-PT-NEXT: Offset: 0xD4
// CHECK-PT-NEXT: Size: 80
// CHECK-PT: Type: PT_ARM_EXIDX (0x70000001)
// CHECK-PT-NEXT: Offset: 0xD4
// CHECK-PT-NEXT: VirtualAddress: 0x100D4
// CHECK-PT-NEXT: PhysicalAddress: 0x100D4
// CHECK-PT-NEXT: FileSize: 80
// CHECK-PT-NEXT: MemSize: 80
// CHECK-PT-NEXT: Flags [ (0x4)
// CHECK-PT-NEXT: PF_R (0x4)
// CHECK-PT-NEXT: ]
// CHECK-PT-NEXT: Alignment: 4
// CHECK-PT-NEXT: }
/// Check linker script order. The .ARM.exidx section will be inserted after
/// the .text section but before the orphan sections
// CHECK-SCRIPT: Disassembly of section .text:
// CHECK-SCRIPT-EMPTY:
// CHECK-SCRIPT-NEXT: <func4>:
// CHECK-SCRIPT-NEXT: 11000: e12fff1e bx lr
// CHECK-SCRIPT: <func5>:
// CHECK-SCRIPT-NEXT: 11004: e12fff1e bx lr
// CHECK-SCRIPT: <_start>:
// CHECK-SCRIPT-NEXT: 11008: e12fff1e bx lr
// CHECK-SCRIPT: <f1>:
// CHECK-SCRIPT-NEXT: 1100c: e12fff1e bx lr
// CHECK-SCRIPT: <f2>:
// CHECK-SCRIPT-NEXT: 11010: e12fff1e bx lr
// CHECK-SCRIPT: <f3>:
// CHECK-SCRIPT-NEXT: 11014: e12fff1e bx lr
// CHECK-SCRIPT-EMPTY:
// CHECK-SCRIPT-NEXT: Disassembly of section .func1:
// CHECK-SCRIPT-EMPTY:
// CHECK-SCRIPT-NEXT: <func1>:
// CHECK-SCRIPT-NEXT: 11018: e12fff1e bx lr
// CHECK-SCRIPT-EMPTY:
// CHECK-SCRIPT-NEXT: Disassembly of section .func2:
// CHECK-SCRIPT-EMPTY:
// CHECK-SCRIPT-NEXT: <func2>:
// CHECK-SCRIPT-NEXT: 1101c: e12fff1e bx lr
// CHECK-SCRIPT-EMPTY:
// CHECK-SCRIPT-NEXT: Disassembly of section .func3:
// CHECK-SCRIPT-EMPTY:
// CHECK-SCRIPT-NEXT: <func3>:
// CHECK-SCRIPT-NEXT: 11020: e12fff1e bx lr
/// Check that the .ARM.exidx section is sorted in order as the functions
/// The offset in field 1, is 32-bit so in the binary the most significant bit
/// 11024 - 24 = 11000 func4
/// 1102c - 28 = 11004 func5
// CHECK-SCRIPT-EXIDX: 11024 dcffff7f 01000000 d8ffff7f 01000000
/// 11034 - 2c = 11008 _start
/// 1103c - 30 = 1100c f1
// CHECK-SCRIPT-EXIDX-NEXT: 11034 d4ffff7f 01000000 d0ffff7f 01000000
/// 11044 - 34 = 11010 f2
/// 1104c - 38 = 11014 f3
// CHECK-SCRIPT-EXIDX-NEXT: 11044 ccffff7f 01000000 c8ffff7f 01000000
/// 11054 - 3c = 11018 func1
/// 1105c - 40 = 1101c func2
// CHECK-SCRIPT-EXIDX-NEXT: 11054 c4ffff7f 01000000 c0ffff7f 01000000
/// 11064 - 44 = 11020 func3
/// 11068 - 48 = 11024 func3 + sizeof(func3)
// CHECK-SCRIPT-EXIDX-NEXT: 11064 bcffff7f 01000000 b8ffff7f 01000000
|