Skip to content

Commit 5908559

Browse files
authored
[X86] Don't set SHF_X86_64_LARGE for variables with explicit section name of a well-known small data section prefix (#70748)
Commit f3ea731 allows SHF_X86_64_LARGE for all global variables with an explicit section. For the following variables, their data sections will be annotated as SHF_X86_64_LARGE. ``` const char relro[512] __attribute__((section(".rodata"))) = "a"; const char *const relro __attribute__((section(".data.rel.ro"))) = "a"; char data[512] __attribute__((section(".data"))) = "a"; ``` The typical linker requirement is that we do not create more than one output section with the same name, and the only output section should have the bitwise OR value of all input section flags. Therefore, the output .data section will have the SHF_X86_64_LARGE flag and be moved away from the regular sections. This is undesired but benign. However, .data.rel.ro having the SHF_X86_64_LARGE flag is problematic because dynamic loaders do not support more than one PT_GNU_RELRO program header, and LLD produces the error `error: section: .jcr is not contiguous with other relro sections`. I believe the most appropriate solution is to disallow SHF_X86_64_LARGE on variables with an explicit section of certain prefixes ( .bss/.data/.bss) and allow others (e.g. metadata sections for various instrumentation). Fortunately, global variables with an explicit .bss/.data/.bss section are rare, so they should not cause excessive relocation overflow pressure.
1 parent 4b3cd37 commit 5908559

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

llvm/lib/Target/TargetMachine.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,20 @@ bool TargetMachine::isLargeData(const GlobalVariable *GV) const {
4646
// restrict this to medium.
4747
if (getCodeModel() != CodeModel::Medium)
4848
return false;
49+
50+
// Allowing large metadata sections in the presence of an explicit section is
51+
// useful, even if GCC does not allow them. However, we should not mark
52+
// certain well-known prefixes as large, because it would make the whole
53+
// output section large and cause the linker to move it, which is almost
54+
// always undesired.
55+
StringRef Name = GV->getSection();
56+
auto IsPrefix = [&](StringRef Prefix) {
57+
StringRef S = Name;
58+
return S.consume_front(Prefix) && (S.empty() || S[0] == '.');
59+
};
60+
if (IsPrefix(".bss") || IsPrefix(".data") || IsPrefix(".rodata"))
61+
return false;
62+
4963
const DataLayout &DL = GV->getParent()->getDataLayout();
5064
uint64_t Size = DL.getTypeSizeInBits(GV->getValueType()) / 8;
5165
return Size == 0 || Size > LargeDataThreshold;

llvm/test/CodeGen/X86/code-model-elf-sections.ll

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,18 @@
1717
; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SMALL-DS
1818

1919
; SMALL: .data {{.*}} WA {{.*}}
20+
; SMALL: .data.x {{.*}} WA {{.*}}
21+
; SMALL: .data0 {{.*}} WA {{.*}}
2022
; SMALL: foo {{.*}} WA {{.*}}
2123
; SMALL: .bss {{.*}} WA {{.*}}
2224
; SMALL: .rodata {{.*}} A {{.*}}
2325
; SMALL: .data.rel.ro {{.*}} WA {{.*}}
2426
; SMALL: .tbss {{.*}} WAT {{.*}}
2527
; SMALL: .tdata {{.*}} WAT {{.*}}
2628

29+
; SMALL-DS: .data {{.*}} WA {{.*}}
30+
; SMALL-DS: .data.x {{.*}} WA {{.*}}
31+
; SMALL-DS: .data0 {{.*}} WA {{.*}}
2732
; SMALL-DS: .data.data {{.*}} WA {{.*}}
2833
; SMALL-DS: foo {{.*}} WA {{.*}}
2934
; SMALL-DS: .bss.bss {{.*}} WA {{.*}}
@@ -32,17 +37,27 @@
3237
; SMALL-DS: .tbss.tbss {{.*}} WAT {{.*}}
3338
; SMALL-DS: .tdata.tdata {{.*}} WAT {{.*}}
3439

40+
; LARGE: .data {{.*}} WA {{.*}}
41+
; LARGE: .data.x {{.*}} WA {{.*}}
42+
; LARGE: .data0 {{.*}} WAl {{.*}}
3543
; LARGE: .ldata {{.*}} WAl {{.*}}
3644
; LARGE: foo {{.*}} WAl {{.*}}
45+
; LARGE: .bss {{.*}} WA {{.*}}
3746
; LARGE: .lbss {{.*}} WAl {{.*}}
47+
; LARGE: .rodata {{.*}} A {{.*}}
3848
; LARGE: .lrodata {{.*}} Al {{.*}}
3949
; LARGE: .ldata.rel.ro {{.*}} WAl {{.*}}
4050
; LARGE: .tbss {{.*}} WAT {{.*}}
4151
; LARGE: .tdata {{.*}} WAT {{.*}}
4252

53+
; LARGE-DS: .data {{.*}} WA {{.*}}
54+
; LARGE-DS: .data.x {{.*}} WA {{.*}}
55+
; LARGE-DS: .data0 {{.*}} WAl {{.*}}
4356
; LARGE-DS: .ldata.data {{.*}} WAl {{.*}}
4457
; LARGE-DS: foo {{.*}} WAl {{.*}}
58+
; LARGE-DS: .bss {{.*}} WA {{.*}}
4559
; LARGE-DS: .lbss.bss {{.*}} WAl {{.*}}
60+
; LARGE-DS: .rodata {{.*}} A {{.*}}
4661
; LARGE-DS: .lrodata.rodata {{.*}} Al {{.*}}
4762
; LARGE-DS: .ldata.rel.ro.relro {{.*}} WAl {{.*}}
4863
; LARGE-DS: .tbss.tbss {{.*}} WAT {{.*}}
@@ -51,9 +66,14 @@
5166
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5267
target triple = "x86_64--linux"
5368

69+
@data_with_explicit_section = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], section ".data"
70+
@data_with_explicit_section2 = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], section ".data.x"
71+
@data_with_explicit_section0 = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], section ".data0"
5472
@data = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0]
55-
@data_with_explicit_section = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], section "foo"
73+
@foo_with_explicit_section = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0], section "foo"
74+
@bss_with_explicit_section = internal global [10 x i64] zeroinitializer, section ".bss"
5675
@bss = internal global [10 x i64] zeroinitializer
76+
@rodata_with_explicit_section = internal constant [10 x i64] zeroinitializer, section ".rodata"
5777
@rodata = internal constant [10 x i64] zeroinitializer
5878
@relro = internal constant [10 x ptr] [ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func]
5979
@tbss = internal thread_local global [10 x i64] zeroinitializer

0 commit comments

Comments
 (0)