blob: f075d93a3054a3f1d9de8167b93b95425ef8babc [file] [log] [blame]
commit d30d46193876102a6bc99b527dfaf79be4b09515
Author: Fangrui Song <maskray@google.com>
Date: Fri Aug 7 22:08:00 2020 -0700
[ELF] Support .cfi_signal_frame
glibc/sysdeps/unix/sysv/linux/x86_64/sigaction.c libc.a(sigaction.o) has a CIE
with the augmentation string "zRS". Support 'S' to allow --icf={safe,all}.
diff --git a/lld/ELF/EhFrame.cpp b/lld/ELF/EhFrame.cpp
index 4596a014838..13f0484ff9e 100644
--- a/lld/ELF/EhFrame.cpp
+++ b/lld/ELF/EhFrame.cpp
@@ -188,19 +188,14 @@ uint8_t EhReader::getFdeEncoding() {
for (char c : aug) {
if (c == 'R')
return readByte();
- if (c == 'z') {
+ if (c == 'z')
skipLeb128();
- continue;
- }
- if (c == 'P') {
- skipAugP();
- continue;
- }
- if (c == 'L') {
+ else if (c == 'L')
readByte();
- continue;
- }
- failOn(aug.data(), "unknown .eh_frame augmentation string: " + aug);
+ else if (c == 'P')
+ skipAugP();
+ else if (c != 'S')
+ failOn(aug.data(), "unknown .eh_frame augmentation string: " + aug);
}
return DW_EH_PE_absptr;
}
@@ -216,7 +211,7 @@ bool EhReader::hasLSDA() {
skipAugP();
else if (c == 'R')
readByte();
- else
+ else if (c != 'S')
failOn(aug.data(), "unknown .eh_frame augmentation string: " + aug);
}
return false;
diff --git a/lld/test/ELF/eh-frame-value-format7.s b/lld/test/ELF/eh-frame-value-format7.s
index 5ebd5af44be..3f87b2915a7 100644
--- a/lld/test/ELF/eh-frame-value-format7.s
+++ b/lld/test/ELF/eh-frame-value-format7.s
@@ -22,7 +22,7 @@
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: SectionData (
# CHECK-NEXT: 0000: 011B033B 10000000 01000000 30F2FFFF
-# CHECK-NEXT: 0010: 24000000
+# CHECK-NEXT: 0010: 2C000000
# Header (always 4 bytes): 011B033B
# 10000000 = .eh_frame(0x2018) - .eh_frame_hdr(0x2004) - 4
# 01000000 = 1 = the number of FDE pointers in the table.
@@ -43,10 +43,11 @@
# CHECK-NEXT: AddressAlignment:
# CHECK-NEXT: EntrySize:
# CHECK-NEXT: SectionData (
-# CHECK-NEXT: 0000: 0C000000 00000000 01520001 010102FF
-# CHECK-NEXT: 0010: 0C000000 14000000 34120000 00000000
-# ^
-# ---> ADDR(foo) + 0x234 = 0x1234
+# CHECK-NEXT: 0000: 14000000 00000000 01525300 01010102
+# CHECK-NEXT: 0010: FF000000 00000000 0C000000 1C000000
+# CHECK-NEXT: 0020: 34120000 00000000 00000000
+# ^
+# ---> ADDR(foo) + 0x234 = 0x1234
.text
.global foo
@@ -54,11 +55,12 @@ foo:
nop
.section .eh_frame,"a",@unwind
- .long 12 # Size
+ .long 13 # Size
.long 0x00 # ID
.byte 0x01 # Version.
- .byte 0x52 # Augmentation string: 'R','\0'
+ .byte 0x52 # Augmentation string: 'R','S','\0'
+ .byte 0x53
.byte 0x00
.byte 0x01
@@ -71,5 +73,5 @@ foo:
.byte 0xFF
.long 0x6 # Size
- .long 0x14 # ID
+ .long 0x15 # ID
.short foo + 0x234
diff --git a/lld/test/ELF/icf-eh-frame.s b/lld/test/ELF/icf-eh-frame.s
index 0b895ec8cc2..a09db020819 100644
--- a/lld/test/ELF/icf-eh-frame.s
+++ b/lld/test/ELF/icf-eh-frame.s
@@ -29,6 +29,7 @@ _Z1bv:
.section .text.Z1cv,"ax",@progbits
_Z1cv:
.cfi_startproc
+ .cfi_signal_frame
ret
.cfi_endproc