aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2025-04-29 12:40:43 -0700
committerGitHub <noreply@github.com>2025-04-29 12:40:43 -0700
commitc88b53777130a80ac08f39166c487ea7bb721441 (patch)
tree6b616c0bc48f13ecdf7ce2df14770f878b80b4ec
parentf784fa727543463b86511f7e5797174422cbeeaf (diff)
downloadllvm-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.cpp13
-rw-r--r--llvm/test/CodeGen/X86/code-model-elf-sections.ll4
-rw-r--r--llvm/test/CodeGen/X86/code-model-elf.ll40
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 {