diff options
| author | Peter Smith <peter.smith@linaro.org> | 2017-12-05 11:15:58 +0000 |
|---|---|---|
| committer | Peter Smith <peter.smith@linaro.org> | 2017-12-05 11:15:58 +0000 |
| commit | 7c40f93f387ac6b889c87683f63c82a9a5361fc1 (patch) | |
| tree | 8f86b4d5a3db5bb93dd6d663877e57e1821eeb54 | |
| parent | 86c40db49d89699d573347f093c3ea6a8a08eb61 (diff) | |
| download | bcm5719-llvm-7c40f93f387ac6b889c87683f63c82a9a5361fc1.tar.gz bcm5719-llvm-7c40f93f387ac6b889c87683f63c82a9a5361fc1.zip | |
[ELF] InX::BssRelRo should check section contents before marking relro
When a linker script is used with a pattern like { *(.bss .bss.*) } the
InX::BssRelRo section will match against .bss.*. By matching on the name
only, in the same way that .data.rel.ro works we prevent this
from happening, but permit scripts that want to explicitly provide
a .bss.rel.ro OutputSection.
Differential Revision: https://reviews.llvm.org/D40735
llvm-svn: 319755
| -rw-r--r-- | lld/ELF/Writer.cpp | 12 | ||||
| -rw-r--r-- | lld/test/ELF/relro-copyrel-bss-script.s | 40 |
2 files changed, 43 insertions, 9 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index f61be873d69..dfb5e08f335 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -576,20 +576,14 @@ static bool isRelroSection(const OutputSection *Sec) { if (Sec == InX::Dynamic->getParent()) return true; - // .bss.rel.ro is used for copy relocations for read-only symbols. - // Since the dynamic linker needs to process copy relocations, the - // section cannot be read-only, but once initialized, they shouldn't - // change. - if (Sec == InX::BssRelRo->getParent()) - return true; - // Sections with some special names are put into RELRO. This is a // bit unfortunate because section names shouldn't be significant in // ELF in spirit. But in reality many linker features depend on // magic section names. StringRef S = Sec->Name; - return S == ".data.rel.ro" || S == ".ctors" || S == ".dtors" || S == ".jcr" || - S == ".eh_frame" || S == ".openbsd.randomdata"; + return S == ".data.rel.ro" || S == ".bss.rel.ro" || S == ".ctors" || + S == ".dtors" || S == ".jcr" || S == ".eh_frame" || + S == ".openbsd.randomdata"; } // We compute a rank for each section. The rank indicates where the diff --git a/lld/test/ELF/relro-copyrel-bss-script.s b/lld/test/ELF/relro-copyrel-bss-script.s new file mode 100644 index 00000000000..5f3b981cae9 --- /dev/null +++ b/lld/test/ELF/relro-copyrel-bss-script.s @@ -0,0 +1,40 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/copy-in-shared.s -o %t2.o +// RUN: ld.lld -shared %t.o %t2.o -o %t.so + +// A linker script that will map .bss.rel.ro into .bss. +// RUN: echo "SECTIONS { \ +// RUN: .bss : { *(.bss) *(.bss.*) } \ +// RUN: } " > %t.script + +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t3.o +// RUN: ld.lld %t3.o %t.so -z relro -o %t --script=%t.script 2>&1 +// RUN: llvm-readobj --program-headers %t | FileCheck %s + .section .text, "ax", @progbits + .global bar + .global foo + .global _start +_start: + callq bar + // Will produce .bss.rel.ro that will match in .bss, this will lose + // the relro property of the copy relocation. + .quad foo + + // Non relro bss + .bss + // make large enough to affect PT_GNU_RELRO MemSize if this was marked + // as relro. + .space 0x2000 + +// CHECK: Type: PT_GNU_RELRO (0x6474E552) +// CHECK-NEXT: Offset: +// CHECK-NEXT: VirtualAddress: +// CHECK-NEXT: PhysicalAddress: +// CHECK-NEXT: FileSize: +// CHECK-NEXT: MemSize: 4096 +// CHECK-NEXT: Flags [ (0x4) +// CHECK-NEXT: PF_R (0x4) +// CHECK-NEXT: ] +// CHECK-NEXT: Alignment: 1 +// CHECK-NEXT: } |

