summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/OutputSections.cpp18
-rw-r--r--lld/test/ELF/eh-frame-hdr-icf.s27
2 files changed, 37 insertions, 8 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 753960447fa..89a9df0c44b 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -727,23 +727,25 @@ EhFrameHeader<ELFT>::getFdePc(uintX_t EhVA, const FdeData &F) {
template <class ELFT> void EhFrameHeader<ELFT>::writeTo(uint8_t *Buf) {
const endianness E = ELFT::TargetEndianness;
+ uintX_t EhVA = Sec->getVA();
+ uintX_t VA = this->getVA();
+
+ // InitialPC -> Offset in .eh_frame, sorted by InitialPC, and deduplicate PCs.
+ // FIXME: Deduplication leaves unneeded null bytes at the end of the section.
+ std::map<uintX_t, size_t> PcToOffset;
+ for (const FdeData &F : FdeList)
+ PcToOffset[getFdePc(EhVA, F)] = F.Off;
+
const uint8_t Header[] = {1, DW_EH_PE_pcrel | DW_EH_PE_sdata4,
DW_EH_PE_udata4,
DW_EH_PE_datarel | DW_EH_PE_sdata4};
memcpy(Buf, Header, sizeof(Header));
- uintX_t EhVA = Sec->getVA();
- uintX_t VA = this->getVA();
uintX_t EhOff = EhVA - VA - 4;
write32<E>(Buf + 4, EhOff);
- write32<E>(Buf + 8, this->FdeList.size());
+ write32<E>(Buf + 8, PcToOffset.size());
Buf += 12;
- // InitialPC -> Offset in .eh_frame, sorted by InitialPC.
- std::map<uintX_t, size_t> PcToOffset;
- for (const FdeData &F : FdeList)
- PcToOffset[getFdePc(EhVA, F)] = F.Off;
-
for (auto &I : PcToOffset) {
// The first four bytes are an offset to the initial PC value for the FDE.
write32<E>(Buf, I.first - VA);
diff --git a/lld/test/ELF/eh-frame-hdr-icf.s b/lld/test/ELF/eh-frame-hdr-icf.s
new file mode 100644
index 00000000000..09b76458e53
--- /dev/null
+++ b/lld/test/ELF/eh-frame-hdr-icf.s
@@ -0,0 +1,27 @@
+# REQUIRES: x86
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t2 --icf=all --eh-frame-hdr
+# RUN: llvm-objdump -s %t2 | FileCheck %s
+
+# CHECK: Contents of section .eh_frame_hdr:
+# CHECK-NEXT: 101a0 011b033b b4ffffff 01000000 600e0000
+# ^ FDE count
+# CHECK-NEXT: 101b0 e8ffffff 00000000 00000000
+# ^ FDE for f2
+
+.globl _start, f1, f2
+_start:
+ ret
+
+.section .text.f1, "ax"
+f1:
+ .cfi_startproc
+ ret
+ .cfi_endproc
+
+.section .text.f2, "ax"
+f2:
+ .cfi_startproc
+ ret
+ .cfi_endproc
OpenPOWER on IntegriCloud