Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -463,6 +463,10 @@ Sec->Parent = this; Alignment = std::max(Alignment, Sec->Alignment); + // TODO: ideally we should only make .eh_frame writable if we have any dynamic + // relocations against it. + if (Sec->Flags & SHF_WRITE) + Flags |= SHF_WRITE; // TODO: Or should we just do Flags |= Sec->Flags? Sections.push_back(Sec); for (auto *DS : Sec->DependentSections) Index: test/ELF/eh-frame-writable.test =================================================================== --- /dev/null +++ test/ELF/eh-frame-writable.test @@ -0,0 +1,98 @@ +# RUN: yaml2obj %s -o %t.o +# RUN: llvm-readobj -r -s %t.o | FileCheck %s -check-prefix OBJECT +# RUN: ld.lld --eh-frame-hdr --shared --fatal-warnings -o %t.so %t.o +# RUN: llvm-readobj -elf-output-style=GNU -program-headers -relocations -sections %t.so | FileCheck %s + +# OBJECT-LABEL: Section { +# OBJECT: Name: .eh_frame +# OBJECT-NEXT: Type: SHT_PROGBITS (0x1) +# OBJECT-NEXT: Flags [ (0x3) +# OBJECT-NEXT: SHF_ALLOC (0x2) +# OBJECT-NEXT: SHF_WRITE (0x1) +# OBJECT-NEXT: ] + +# OBJECT-LABEL: Relocations [ +# OBJECT-NEXT: Section ({{.+}}) .rela.eh_frame { +# OBJECT-NEXT: 0x1C R_MIPS_64/R_MIPS_NONE/R_MIPS_NONE .text 0x0 +# OBJECT-NEXT: } +# OBJECT-NEXT: ] + +# CHECK-LABEL: Section Headers: +# CHECK-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al +# CHECK: [{{.+}}] .eh_frame PROGBITS 0000000000030000 030000 000038 00 WA 0 0 8 + + +# CHECK-LABEL: Relocation section '.rel.dyn' +# CHECK-SAME: at offset 0x{{.+}} contains 1 entries: +# CHECK-NEXT: Offset Info Type Symbol's Value Symbol's Name +# CHECK-NEXT: 0000000000030020 0000000000001203 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE + +# CHECK-LABEL: There are 8 program headers, starting at offset 64 +# CHECK: Program Headers: +# CHECK-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align +# CHECK-NEXT: PHDR 0x000040 0x{{.+}} 0x{{.+}} 0x{{.+}} 0x{{.+}} R 0x8 +# CHECK-NEXT: LOAD 0x000000 0x{{.+}} 0x{{.+}} 0x{{.+}} 0x{{.+}} R 0x10000 +# CHECK-NEXT: LOAD 0x010000 0x{{.+}} 0x{{.+}} 0x{{.+}} 0x{{.+}} R E 0x10000 +# CHECK-NEXT: LOAD 0x020000 0x{{.+}} 0x{{.+}} 0x{{.+}} 0x{{.+}} RW 0x10000 +# CHECK-NEXT: DYNAMIC 0x000248 0x{{.+}} 0x{{.+}} 0x{{.+}} 0x{{.+}} R 0x8 +# CHECK-NEXT: GNU_RELRO 0x030000 0x{{.+}} 0x{{.+}} 0x{{.+}} 0x{{.+}} R 0x1 +# CHECK-NEXT: GNU_EH_FRAME 0x000360 0x{{.+}} 0x{{.+}} 0x{{.+}} 0x{{.+}} R 0x4 +# CHECK-NEXT: GNU_STACK 0x000000 0x{{.+}} 0x{{.+}} 0x{{.+}} 0x{{.+}} RW 0x0 + +# CHECK-LABEL: Section to Segment mapping: +# CHECK-NEXT: Segment Sections... +# CHECK-NEXT: 00 +# CHECK-NEXT: 01 .dynsym .hash .dynamic .dynstr .rel.dyn .eh_frame_hdr +# CHECK-NEXT: 02 .text +# CHECK-NEXT: 03 .data .got .eh_frame +# CHECK-NEXT: 04 .dynamic +# CHECK-NEXT: 05 .eh_frame +# CHECK-NEXT: 06 .eh_frame_hdr +# CHECK-NEXT: 07 + + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2MSB + OSABI: ELFOSABI_FREEBSD + Type: ET_REL + Machine: EM_MIPS + Flags: [ EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64 ] +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000010 + Content: 3C0B0001 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000010 + Content: '' + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000010 + - Name: .eh_frame + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000008 + Content: 0000001000000000017A520001781F010C0C1D0000000018000000180000000000000000000000000000000400000000 + - Name: .rela.eh_frame + Type: SHT_RELA + Link: .symtab + AddressAlign: 0x0000000000000008 + Info: .eh_frame + Relocations: + - Offset: 0x000000000000001C + Symbol: .text + Type: R_MIPS_64 +Symbols: + Local: + - Name: .text + Type: STT_SECTION + Section: .text + Global: + - Name: foo + Section: .text