| 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 |
| |