Skip to content

Commit 1720ef1

Browse files
committedFeb 27, 2017
Add terminator to .eh_frame sections
Patch by Mark Kettenis. Currenlty ld.lld does not add a terminator (a CIE with its length field set to zero) to the .eh_frame sections it generates. While the relevant standards (the AMD64 SysV ABI and the Linux LSB) are not explicit about this, such a terminator is expected by some unwinder implementations and seems to be always emitted by ld.bfd. In addition to that, the Linux LSB https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html#EHFRAME explicitly says that The .eh_frame section shall contain 1 or more Call Frame Information (CFI) records. Currently, if the .eh_frame sections of the input files only contain terminators, ld.lld emits a zero=sized .eh_frame section which clearly doesn't meet that requirement. The diff makes sure a terminator gets added to each .eh_frame section and adjusts all the relevant tests to account for that. An additional test isn't needed as these adjustments mean that the existence of the terminator is tested for by several tests already. Differential Revision: https://reviews.llvm.org/D30335 llvm-svn: 296378
1 parent 3ead2e7 commit 1720ef1

9 files changed

+19
-10
lines changed
 

‎lld/ELF/SyntheticSections.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,14 @@ template <class ELFT> void EhFrameSection<ELFT>::finalizeContents() {
540540
Off += alignTo(Fde->size(), sizeof(uintX_t));
541541
}
542542
}
543-
this->Size = Off;
543+
544+
// Add a CIE record of length 0 as a terminator. While the relevant
545+
// standards don't explicitly require such a terminator, ld.bfd and
546+
// ld.gold always seem to add one and some unwiders rely on its
547+
// presence. It also prevents us from generating a .eh_frame section
548+
// with zero Call Frame Information records, which isn't allowed by
549+
// the LSB standard.
550+
this->Size = Off + 4;
544551
}
545552

546553
template <class ELFT> static uint64_t readFdeAddr(uint8_t *Buf, int Size) {

‎lld/test/ELF/eh-frame-hdr.s

+2-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ _start:
8484
// HDR-NEXT: ]
8585
// HDR-NEXT: Address: 0x200180
8686
// HDR-NEXT: Offset: 0x180
87-
// HDR-NEXT: Size: 96
87+
// HDR-NEXT: Size: 100
8888
// HDR-NEXT: Link: 0
8989
// HDR-NEXT: Info: 0
9090
// HDR-NEXT: AddressAlignment: 8
@@ -96,6 +96,7 @@ _start:
9696
// HDR-NEXT: 0030: 14000000 34000000 490E0000 01000000
9797
// HDR-NEXT: 0040: 00000000 00000000 14000000 4C000000
9898
// HDR-NEXT: 0050: 320E0000 01000000 00000000 00000000
99+
// HDR-NEXT: 0060: 00000000
99100
// HDR-NEXT: )
100101
// CIE: 14000000 00000000 017A5200 01781001 1B0C0708 90010000
101102
// FDE(1): 14000000 1C000000 600E0000 01000000 00000000 00000000

‎lld/test/ELF/eh-frame-merge.s

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
// CHECK-NEXT: ]
2828
// CHECK-NEXT: Address:
2929
// CHECK-NEXT: Offset:
30-
// CHECK-NEXT: Size: 96
30+
// CHECK-NEXT: Size: 100
3131
// CHECK-NEXT: Link: 0
3232
// CHECK-NEXT: Info: 0
3333
// CHECK-NEXT: AddressAlignment: 8
@@ -39,6 +39,7 @@
3939
// CHECK-NEXT: 0030: 14000000 34000000 D20D0000 02000000 |
4040
// CHECK-NEXT: 0040: 00000000 00000000 14000000 4C000000 |
4141
// CHECK-NEXT: 0050: B90D0000 01000000 00000000 00000000 |
42+
// CHECK-NEXT: 0060: 00000000 |
4243
// CHECK-NEXT: )
4344

4445
// CHECK: Name: foo

‎lld/test/ELF/ehframe-relocation.s

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// CHECK-NEXT: ]
1313
// CHECK-NEXT: Address: 0x200120
1414
// CHECK-NEXT: Offset:
15-
// CHECK-NEXT: Size: 48
15+
// CHECK-NEXT: Size: 52
1616
// CHECK-NOT: .eh_frame
1717

1818
// 0x200120 = 2097440

‎lld/test/ELF/invalid-fde-rel.s

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@
3333
.long 0x0
3434
.long 0x0
3535

36-
// CHECK: 1 .eh_frame 00000018
36+
// CHECK: 1 .eh_frame 0000001c

‎lld/test/ELF/linkerscript/eh-frame-hdr.s

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t
88
# RUN: llvm-objdump -s -section=".eh_frame_hdr" %t1 | FileCheck %s
99

10-
# CHECK: 011b033b 14000000 01000000 49000000
10+
# CHECK: 011b033b 14000000 01000000 4d000000
1111
# CHECK-NEXT: 30000000
1212

1313
.global _start

‎lld/test/ELF/linkerscript/symbols-synthetic.s

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
# SIMPLE: 0000000000000128 .foo 00000000 .hidden _end_sec
6161
# SIMPLE-NEXT: 0000000000000120 .foo 00000000 _begin_sec
6262
# SIMPLE-NEXT: 0000000000000128 *ABS* 00000000 _end_sec_abs
63-
# SIMPLE-NEXT: 0000000000001048 .text 00000000 _start
63+
# SIMPLE-NEXT: 000000000000104c .text 00000000 _start
6464
# SIMPLE-NEXT: 0000000000000120 .foo 00000000 begin_foo
6565
# SIMPLE-NEXT: 0000000000000128 .foo 00000000 end_foo
6666
# SIMPLE-NEXT: 0000000000000008 *ABS* 00000000 size_foo_1

‎lld/test/ELF/map-file.s

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ local:
2727
.comm common,4,16
2828

2929
// CHECK: Address Size Align Out In File Symbol
30-
// CHECK-NEXT: 0000000000200158 0000000000000030 8 .eh_frame
31-
// CHECK-NEXT: 0000000000200158 0000000000000030 8 .eh_frame
30+
// CHECK-NEXT: 0000000000200158 0000000000000034 8 .eh_frame
31+
// CHECK-NEXT: 0000000000200158 0000000000000034 8 .eh_frame
3232
// CHECK-NEXT: 0000000000201000 0000000000000015 4 .text
3333
// CHECK-NEXT: 0000000000201000 000000000000000e 4 .text
3434
// CHECK-NEXT: 0000000000201000 000000000000000e 4 {{.*}}{{/|\\}}map-file.s.tmp1.o

‎lld/test/ELF/relocatable-eh-frame.s

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# RUN: ld.lld %t -o %t.so -shared
66
# RUN: llvm-objdump -h %t.so | FileCheck --check-prefix=DSO %s
77

8-
# DSO: .eh_frame 00000030
8+
# DSO: .eh_frame 00000034
99

1010
# CHECK: Relocations [
1111
# CHECK-NEXT: Section ({{.*}}) .rela.eh_frame {

0 commit comments

Comments
 (0)
Please sign in to comment.