diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2025-04-29 12:40:43 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-29 12:40:43 -0700 |
commit | c88b53777130a80ac08f39166c487ea7bb721441 (patch) | |
tree | 6b616c0bc48f13ecdf7ce2df14770f878b80b4ec | |
parent | f784fa727543463b86511f7e5797174422cbeeaf (diff) | |
download | llvm-c88b53777130a80ac08f39166c487ea7bb721441.zip llvm-c88b53777130a80ac08f39166c487ea7bb721441.tar.gz llvm-c88b53777130a80ac08f39166c487ea7bb721441.tar.bz2 |
Target: Stop assigning RELRO sections to .ldata.rel.ro.
Linkers do not currently support PT_GNU_RELRO for SHF_X86_64_LARGE
sections; that would require the linker to emit more than one
PT_GNU_RELRO because large sections are discontiguous by design,
and most ELF dynamic loaders do not support that (bionic appears to
support it but glibc/musl/FreeBSD/NetBSD/OpenBSD appear not to). With
current linkers these sections will end up in .ldata which results
in silently disabling RELRO. Therefore, disable SHF_X86_64_LARGE for
RELRO sections. If this ever gets supported by downstream components
in the future we could add an opt-in flag for moving these sections
to .ldata.rel.ro which would trigger the creation of a second
PT_GNU_RELRO.
Reviewers: MaskRay, aeubanks
Reviewed By: aeubanks
Pull Request: https://github.com/llvm/llvm-project/pull/137742
-rw-r--r-- | llvm/lib/Target/TargetMachine.cpp | 13 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/code-model-elf-sections.ll | 4 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/code-model-elf.ll | 40 |
3 files changed, 34 insertions, 23 deletions
diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp index 439e735..69b6e26 100644 --- a/llvm/lib/Target/TargetMachine.cpp +++ b/llvm/lib/Target/TargetMachine.cpp @@ -119,6 +119,19 @@ bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const { GV->getName().starts_with("__start_") || GV->getName().starts_with("__stop_"))) return true; + // Linkers do not currently support PT_GNU_RELRO for SHF_X86_64_LARGE + // sections; that would require the linker to emit more than one + // PT_GNU_RELRO because large sections are discontiguous by design, and most + // ELF dynamic loaders do not support that (bionic appears to support it but + // glibc/musl/FreeBSD/NetBSD/OpenBSD appear not to). With current linkers + // these sections will end up in .ldata which results in silently disabling + // RELRO. If this ever gets supported by downstream components in the future + // we could add an opt-in flag for moving these sections to .ldata.rel.ro + // which would trigger the creation of a second PT_GNU_RELRO. + if (!GV->isDeclarationForLinker() && + TargetLoweringObjectFile::getKindForGlobal(GV, *this) + .isReadOnlyWithRel()) + return false; const DataLayout &DL = GV->getDataLayout(); uint64_t Size = DL.getTypeAllocSize(GV->getValueType()); return Size == 0 || Size > LargeDataThreshold; diff --git a/llvm/test/CodeGen/X86/code-model-elf-sections.ll b/llvm/test/CodeGen/X86/code-model-elf-sections.ll index fc5dac8..f7a7ebb 100644 --- a/llvm/test/CodeGen/X86/code-model-elf-sections.ll +++ b/llvm/test/CodeGen/X86/code-model-elf-sections.ll @@ -66,7 +66,7 @@ ; LARGE: .lbss {{.*}} WAl {{.*}} ; LARGE: .rodata {{.*}} A {{.*}} ; LARGE: .lrodata {{.*}} Al {{.*}} -; LARGE: .ldata.rel.ro {{.*}} WAl {{.*}} +; LARGE: .data.rel.ro {{.*}} WA {{.*}} ; LARGE: .tbss {{.*}} WAT {{.*}} ; LARGE: .tdata {{.*}} WAT {{.*}} @@ -84,7 +84,7 @@ ; LARGE-DS: .lbss.bss {{.*}} WAl {{.*}} ; LARGE-DS: .rodata {{.*}} A {{.*}} ; LARGE-DS: .lrodata.rodata {{.*}} Al {{.*}} -; LARGE-DS: .ldata.rel.ro.relro {{.*}} WAl {{.*}} +; LARGE-DS: .data.rel.ro.relro {{.*}} WA {{.*}} ; LARGE-DS: .tbss.tbss {{.*}} WAT {{.*}} ; LARGE-DS: .tdata.tdata {{.*}} WAT {{.*}} diff --git a/llvm/test/CodeGen/X86/code-model-elf.ll b/llvm/test/CodeGen/X86/code-model-elf.ll index f60f75b..aa2cc3a 100644 --- a/llvm/test/CodeGen/X86/code-model-elf.ll +++ b/llvm/test/CodeGen/X86/code-model-elf.ll @@ -50,7 +50,7 @@ target triple = "x86_64--linux" @global_data = dso_local global [10 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0], align 16 @static_data = internal global [10 x i32] zeroinitializer, align 16 -@static_data_alias = internal constant ptr getelementptr inbounds ([10 x i32], ptr @static_data, i64 0, i64 2), align 8 +@static_data_relro = internal constant ptr getelementptr inbounds ([10 x i32], ptr @static_data, i64 0, i64 2), align 8 @extern_data = external global [10 x i32], align 16 @thread_data = external thread_local global i32, align 4 @unknown_size_data = dso_local global [0 x i32] zeroinitializer, align 16 @@ -117,59 +117,57 @@ define dso_local ptr @lea_static_data() #0 { ret ptr @static_data } -define dso_local ptr @lea_static_data_alias() #0 { -; SMALL-STATIC-LABEL: lea_static_data_alias: +define dso_local ptr @lea_static_data_relro() #0 { +; SMALL-STATIC-LABEL: lea_static_data_relro: ; SMALL-STATIC: # %bb.0: -; SMALL-STATIC-NEXT: movl $static_data_alias, %eax +; SMALL-STATIC-NEXT: movl $static_data_relro, %eax ; SMALL-STATIC-NEXT: retq ; -; MEDIUM-STATIC-LABEL: lea_static_data_alias: +; MEDIUM-STATIC-LABEL: lea_static_data_relro: ; MEDIUM-STATIC: # %bb.0: -; MEDIUM-STATIC-NEXT: movabsq $static_data_alias, %rax +; MEDIUM-STATIC-NEXT: movabsq $static_data_relro, %rax ; MEDIUM-STATIC-NEXT: retq ; -; LARGE-STATIC-LABEL: lea_static_data_alias: +; LARGE-STATIC-LABEL: lea_static_data_relro: ; LARGE-STATIC: # %bb.0: -; LARGE-STATIC-NEXT: movabsq $static_data_alias, %rax +; LARGE-STATIC-NEXT: movabsq $static_data_relro, %rax ; LARGE-STATIC-NEXT: retq ; -; SMALL-PIC-LABEL: lea_static_data_alias: +; SMALL-PIC-LABEL: lea_static_data_relro: ; SMALL-PIC: # %bb.0: -; SMALL-PIC-NEXT: leaq static_data_alias(%rip), %rax +; SMALL-PIC-NEXT: leaq static_data_relro(%rip), %rax ; SMALL-PIC-NEXT: retq ; -; MEDIUM-SMALL-DATA-PIC-LABEL: lea_static_data_alias: +; MEDIUM-SMALL-DATA-PIC-LABEL: lea_static_data_relro: ; MEDIUM-SMALL-DATA-PIC: # %bb.0: -; MEDIUM-SMALL-DATA-PIC-NEXT: leaq static_data_alias(%rip), %rax +; MEDIUM-SMALL-DATA-PIC-NEXT: leaq static_data_relro(%rip), %rax ; MEDIUM-SMALL-DATA-PIC-NEXT: retq ; -; MEDIUM-PIC-LABEL: lea_static_data_alias: +; MEDIUM-PIC-LABEL: lea_static_data_relro: ; MEDIUM-PIC: # %bb.0: -; MEDIUM-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx -; MEDIUM-PIC-NEXT: movabsq $static_data_alias@GOTOFF, %rax -; MEDIUM-PIC-NEXT: addq %rcx, %rax +; MEDIUM-PIC-NEXT: leaq static_data_relro(%rip), %rax ; MEDIUM-PIC-NEXT: retq ; -; LARGE-PIC-LABEL: lea_static_data_alias: +; LARGE-PIC-LABEL: lea_static_data_relro: ; LARGE-PIC: # %bb.0: ; LARGE-PIC-NEXT: .L1$pb: ; LARGE-PIC-NEXT: leaq .L1$pb(%rip), %rax ; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L1$pb, %rcx ; LARGE-PIC-NEXT: addq %rax, %rcx -; LARGE-PIC-NEXT: movabsq $static_data_alias@GOTOFF, %rax +; LARGE-PIC-NEXT: movabsq $static_data_relro@GOTOFF, %rax ; LARGE-PIC-NEXT: addq %rcx, %rax ; LARGE-PIC-NEXT: retq ; -; LARGE-SMALL-DATA-PIC-LABEL: lea_static_data_alias: +; LARGE-SMALL-DATA-PIC-LABEL: lea_static_data_relro: ; LARGE-SMALL-DATA-PIC: # %bb.0: ; LARGE-SMALL-DATA-PIC-NEXT: .L1$pb: ; LARGE-SMALL-DATA-PIC-NEXT: leaq .L1$pb(%rip), %rax ; LARGE-SMALL-DATA-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L1$pb, %rcx ; LARGE-SMALL-DATA-PIC-NEXT: addq %rax, %rcx -; LARGE-SMALL-DATA-PIC-NEXT: movabsq $static_data_alias@GOTOFF, %rax +; LARGE-SMALL-DATA-PIC-NEXT: movabsq $static_data_relro@GOTOFF, %rax ; LARGE-SMALL-DATA-PIC-NEXT: addq %rcx, %rax ; LARGE-SMALL-DATA-PIC-NEXT: retq - ret ptr @static_data_alias + ret ptr @static_data_relro } define dso_local ptr @lea_global_data() #0 { |