From d30d46193876102a6bc99b527dfaf79be4b09515 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 7 Aug 2020 22:08:00 -0700 Subject: [PATCH] [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}. --- lld/ELF/EhFrame.cpp | 19 +++++++------------ lld/test/ELF/eh-frame-value-format7.s | 18 ++++++++++-------- lld/test/ELF/icf-eh-frame.s | 1 + 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/lld/ELF/EhFrame.cpp b/lld/ELF/EhFrame.cpp index 4596a014838e..13f0484ff9e4 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 5ebd5af44bed..3f87b2915a72 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 0b895ec8cc2c..a09db0208194 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