diff options
| author | Rui Ueyama <ruiu@google.com> | 2017-02-27 20:44:59 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2017-02-27 20:44:59 +0000 |
| commit | 1720ef1343539e33b6d3a53de489d58deb07cb3e (patch) | |
| tree | cc5f61526df581cff727855dc25a9f4f1a91c834 | |
| parent | 3ead2e73ee4a0be4ae3b102c80331456f6c63020 (diff) | |
| download | bcm5719-llvm-1720ef1343539e33b6d3a53de489d58deb07cb3e.tar.gz bcm5719-llvm-1720ef1343539e33b6d3a53de489d58deb07cb3e.zip | |
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
| -rw-r--r-- | lld/ELF/SyntheticSections.cpp | 9 | ||||
| -rw-r--r-- | lld/test/ELF/eh-frame-hdr.s | 3 | ||||
| -rw-r--r-- | lld/test/ELF/eh-frame-merge.s | 3 | ||||
| -rw-r--r-- | lld/test/ELF/ehframe-relocation.s | 2 | ||||
| -rw-r--r-- | lld/test/ELF/invalid-fde-rel.s | 2 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/eh-frame-hdr.s | 2 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/symbols-synthetic.s | 2 | ||||
| -rw-r--r-- | lld/test/ELF/map-file.s | 4 | ||||
| -rw-r--r-- | lld/test/ELF/relocatable-eh-frame.s | 2 |
9 files changed, 19 insertions, 10 deletions
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 69a5d846cd0..f78b9da6a98 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -540,7 +540,14 @@ template <class ELFT> void EhFrameSection<ELFT>::finalizeContents() { Off += alignTo(Fde->size(), sizeof(uintX_t)); } } - this->Size = Off; + + // Add a CIE record of length 0 as a terminator. While the relevant + // standards don't explicitly require such a terminator, ld.bfd and + // ld.gold always seem to add one and some unwiders rely on its + // presence. It also prevents us from generating a .eh_frame section + // with zero Call Frame Information records, which isn't allowed by + // the LSB standard. + this->Size = Off + 4; } template <class ELFT> static uint64_t readFdeAddr(uint8_t *Buf, int Size) { diff --git a/lld/test/ELF/eh-frame-hdr.s b/lld/test/ELF/eh-frame-hdr.s index 35c14a4b65d..9d430d35e12 100644 --- a/lld/test/ELF/eh-frame-hdr.s +++ b/lld/test/ELF/eh-frame-hdr.s @@ -84,7 +84,7 @@ _start: // HDR-NEXT: ] // HDR-NEXT: Address: 0x200180 // HDR-NEXT: Offset: 0x180 -// HDR-NEXT: Size: 96 +// HDR-NEXT: Size: 100 // HDR-NEXT: Link: 0 // HDR-NEXT: Info: 0 // HDR-NEXT: AddressAlignment: 8 @@ -96,6 +96,7 @@ _start: // HDR-NEXT: 0030: 14000000 34000000 490E0000 01000000 // HDR-NEXT: 0040: 00000000 00000000 14000000 4C000000 // HDR-NEXT: 0050: 320E0000 01000000 00000000 00000000 +// HDR-NEXT: 0060: 00000000 // HDR-NEXT: ) // CIE: 14000000 00000000 017A5200 01781001 1B0C0708 90010000 // FDE(1): 14000000 1C000000 600E0000 01000000 00000000 00000000 diff --git a/lld/test/ELF/eh-frame-merge.s b/lld/test/ELF/eh-frame-merge.s index addbb3f857f..cfd731b813b 100644 --- a/lld/test/ELF/eh-frame-merge.s +++ b/lld/test/ELF/eh-frame-merge.s @@ -27,7 +27,7 @@ // CHECK-NEXT: ] // CHECK-NEXT: Address: // CHECK-NEXT: Offset: -// CHECK-NEXT: Size: 96 +// CHECK-NEXT: Size: 100 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 8 @@ -39,6 +39,7 @@ // CHECK-NEXT: 0030: 14000000 34000000 D20D0000 02000000 | // CHECK-NEXT: 0040: 00000000 00000000 14000000 4C000000 | // CHECK-NEXT: 0050: B90D0000 01000000 00000000 00000000 | +// CHECK-NEXT: 0060: 00000000 | // CHECK-NEXT: ) // CHECK: Name: foo diff --git a/lld/test/ELF/ehframe-relocation.s b/lld/test/ELF/ehframe-relocation.s index 0213b1bebf8..4ab44c20f8a 100644 --- a/lld/test/ELF/ehframe-relocation.s +++ b/lld/test/ELF/ehframe-relocation.s @@ -12,7 +12,7 @@ // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x200120 // CHECK-NEXT: Offset: -// CHECK-NEXT: Size: 48 +// CHECK-NEXT: Size: 52 // CHECK-NOT: .eh_frame // 0x200120 = 2097440 diff --git a/lld/test/ELF/invalid-fde-rel.s b/lld/test/ELF/invalid-fde-rel.s index f43b9da3003..f6513225b53 100644 --- a/lld/test/ELF/invalid-fde-rel.s +++ b/lld/test/ELF/invalid-fde-rel.s @@ -33,4 +33,4 @@ .long 0x0 .long 0x0 -// CHECK: 1 .eh_frame 00000018 +// CHECK: 1 .eh_frame 0000001c diff --git a/lld/test/ELF/linkerscript/eh-frame-hdr.s b/lld/test/ELF/linkerscript/eh-frame-hdr.s index d1545be632a..d3317e77f24 100644 --- a/lld/test/ELF/linkerscript/eh-frame-hdr.s +++ b/lld/test/ELF/linkerscript/eh-frame-hdr.s @@ -7,7 +7,7 @@ # RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t # RUN: llvm-objdump -s -section=".eh_frame_hdr" %t1 | FileCheck %s -# CHECK: 011b033b 14000000 01000000 49000000 +# CHECK: 011b033b 14000000 01000000 4d000000 # CHECK-NEXT: 30000000 .global _start diff --git a/lld/test/ELF/linkerscript/symbols-synthetic.s b/lld/test/ELF/linkerscript/symbols-synthetic.s index 95cdae9a929..df62a314b28 100644 --- a/lld/test/ELF/linkerscript/symbols-synthetic.s +++ b/lld/test/ELF/linkerscript/symbols-synthetic.s @@ -60,7 +60,7 @@ # SIMPLE: 0000000000000128 .foo 00000000 .hidden _end_sec # SIMPLE-NEXT: 0000000000000120 .foo 00000000 _begin_sec # SIMPLE-NEXT: 0000000000000128 *ABS* 00000000 _end_sec_abs -# SIMPLE-NEXT: 0000000000001048 .text 00000000 _start +# SIMPLE-NEXT: 000000000000104c .text 00000000 _start # SIMPLE-NEXT: 0000000000000120 .foo 00000000 begin_foo # SIMPLE-NEXT: 0000000000000128 .foo 00000000 end_foo # SIMPLE-NEXT: 0000000000000008 *ABS* 00000000 size_foo_1 diff --git a/lld/test/ELF/map-file.s b/lld/test/ELF/map-file.s index 4b02aecd8de..da22bbe4e2b 100644 --- a/lld/test/ELF/map-file.s +++ b/lld/test/ELF/map-file.s @@ -27,8 +27,8 @@ local: .comm common,4,16 // CHECK: Address Size Align Out In File Symbol -// CHECK-NEXT: 0000000000200158 0000000000000030 8 .eh_frame -// CHECK-NEXT: 0000000000200158 0000000000000030 8 .eh_frame +// CHECK-NEXT: 0000000000200158 0000000000000034 8 .eh_frame +// CHECK-NEXT: 0000000000200158 0000000000000034 8 .eh_frame // CHECK-NEXT: 0000000000201000 0000000000000015 4 .text // CHECK-NEXT: 0000000000201000 000000000000000e 4 .text // CHECK-NEXT: 0000000000201000 000000000000000e 4 {{.*}}{{/|\\}}map-file.s.tmp1.o diff --git a/lld/test/ELF/relocatable-eh-frame.s b/lld/test/ELF/relocatable-eh-frame.s index c2e5ec63f86..dee906acb87 100644 --- a/lld/test/ELF/relocatable-eh-frame.s +++ b/lld/test/ELF/relocatable-eh-frame.s @@ -5,7 +5,7 @@ # RUN: ld.lld %t -o %t.so -shared # RUN: llvm-objdump -h %t.so | FileCheck --check-prefix=DSO %s -# DSO: .eh_frame 00000030 +# DSO: .eh_frame 00000034 # CHECK: Relocations [ # CHECK-NEXT: Section ({{.*}}) .rela.eh_frame { |

