[llvm-branch-commits] [clang] 1d3ebbf - Add -f[no-]direct-access-external-data to supersede -mpie-copy-relocations
Fangrui Song via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Jan 9 00:36:39 PST 2021
Author: Fangrui Song
Date: 2021-01-09T00:32:01-08:00
New Revision: 1d3ebbf537832f80be97739abc4f6962caad1dab
URL: https://github.com/llvm/llvm-project/commit/1d3ebbf537832f80be97739abc4f6962caad1dab
DIFF: https://github.com/llvm/llvm-project/commit/1d3ebbf537832f80be97739abc4f6962caad1dab.diff
LOG: Add -f[no-]direct-access-external-data to supersede -mpie-copy-relocations
GCC r218397 "x86-64: Optimize access to globals in PIE with copy reloc" made
-fpie code emit R_X86_64_PC32 to reference external data symbols by default.
Clang adopted -mpie-copy-relocations D19996 as a flexible alternative.
The name -mpie-copy-relocations can be improved [1] and does not capture the
idea that this option can apply to -fno-pic and -fpic [2], so this patch
introduces -f[no-]direct-access-external-data and makes -mpie-copy-relocations
their aliases for compatibility.
[1]
For
```
extern int var;
int get() { return var; }
```
if var is defined in another translation unit in the link unit, there is no copy
relocation.
[2]
-fno-pic -fno-direct-access-external-data is useful to avoid copy relocations.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65888
If a shared object is linked with -Bsymbolic or --dynamic-list and exports a
data symbol, normally the data symbol cannot be accessed by -fno-pic code
(because by default an absolute relocation is produced which will lead to a copy
relocation). -fno-direct-access-external-data can prevent copy relocations.
-fpic -fdirect-access-external-data can avoid GOT indirection. This is like the
undefined counterpart of -fno-semantic-interposition. However, the user should
define var in another translation unit and link with -Bsymbolic or
--dynamic-list, otherwise the linker will error in a -shared link. Generally
the user has better tools for their goal but I want to mention that this
combination is valid.
On COFF, the behavior is like always -fdirect-access-external-data.
`__declspec(dllimport)` is needed to enable indirect access.
There is currently no plan to affect non-ELF behaviors or -fpic behaviors.
-fno-pic -fno-direct-access-external-data will be implemented in the subsequent patch.
GCC feature request https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98112
Reviewed By: tmsriram
Differential Revision: https://reviews.llvm.org/D92633
Added:
clang/test/Driver/fdirect-access-external-data.c
Modified:
clang/include/clang/Basic/CodeGenOptions.def
clang/include/clang/Driver/Options.td
clang/lib/CodeGen/CodeGenModule.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Frontend/CompilerInvocation.cpp
clang/test/CodeGen/dso-local-executable.c
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index d3851df23122..5c8af65326ed 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -368,8 +368,8 @@ VALUE_CODEGENOPT(EmitCheckPathComponentsToStrip, 32, 0)
/// Whether to report the hotness of the code region for optimization remarks.
CODEGENOPT(DiagnosticsWithHotness, 1, 0)
-/// Whether copy relocations support is available when building as PIE.
-CODEGENOPT(PIECopyRelocations, 1, 0)
+/// Whether to use direct access relocations (instead of GOT) to reference external data symbols.
+CODEGENOPT(DirectAccessExternalData, 1, 0)
/// Whether we should use the undefined behaviour optimization for control flow
/// paths that reach the end of a function without executing a required return.
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 9e1059cd14f0..741c28aa1f01 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2184,6 +2184,10 @@ def fpic : Flag<["-"], "fpic">, Group<f_Group>;
def fno_pic : Flag<["-"], "fno-pic">, Group<f_Group>;
def fpie : Flag<["-"], "fpie">, Group<f_Group>;
def fno_pie : Flag<["-"], "fno-pie">, Group<f_Group>;
+def fdirect_access_external_data : Flag<["-"], "fdirect-access-external-data">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Don't use GOT indirection to reference external data symbols">;
+def fno_direct_access_external_data : Flag<["-"], "fno-direct-access-external-data">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Use GOT indirection to reference external data symbols">;
defm plt : BoolFOption<"plt",
"CodeGenOpts.NoPLT", DefaultsToFalse,
ChangedBy<NegFlag, [], "Use GOT indirection instead of PLT to make external function calls (x86 only)">,
@@ -3151,10 +3155,10 @@ def mstack_protector_guard_offset_EQ : Joined<["-"], "mstack-protector-guard-off
HelpText<"Use the given offset for addressing the stack-protector guard">;
def mstack_protector_guard_reg_EQ : Joined<["-"], "mstack-protector-guard-reg=">, Group<m_Group>, Flags<[CC1Option]>,
HelpText<"Use the given reg for addressing the stack-protector guard">;
-defm pie_copy_relocations : BoolOption<"pie-copy-relocations",
- "CodeGenOpts.PIECopyRelocations", DefaultsToFalse,
- ChangedBy<PosFlag, [CC1Option], "Use copy relocations support for PIE builds">,
- ResetBy<NegFlag>, BothFlags<[]>, "m">, Group<m_Group>;
+def mpie_copy_relocations : Flag<["-"], "mpie-copy-relocations">,
+ Alias<fdirect_access_external_data>, Group<m_Group>;
+def mno_pie_copy_relocations : Flag<["-"], "mno-pie-copy-relocations">,
+ Alias<fno_direct_access_external_data>, Group<m_Group>;
def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at function entry (x86/SystemZ only)">,
Flags<[CC1Option]>, Group<m_Group>,
MarshallingInfoFlag<"CodeGenOpts.CallFEntry">;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index cfc0f732748c..959f149667d9 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -986,7 +986,7 @@ static bool shouldAssumeDSOLocal(const CodeGenModule &CGM,
// If we can use copy relocations we can assume it is local.
if (auto *Var = dyn_cast<llvm::GlobalVariable>(GV))
if (!Var->isThreadLocal() &&
- (RM == llvm::Reloc::Static || CGOpts.PIECopyRelocations))
+ (RM == llvm::Reloc::Static || CGOpts.DirectAccessExternalData))
return true;
// If we can use a plt entry as the symbol address we can assume it
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index d6453777200f..be4fe7f8eddd 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4851,11 +4851,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-mms-bitfields");
}
- if (Args.hasFlag(options::OPT_mpie_copy_relocations,
- options::OPT_mno_pie_copy_relocations,
- false)) {
- CmdArgs.push_back("-mpie-copy-relocations");
- }
+ // Non-PIC code defaults to -fdirect-access-external-data while PIC code
+ // defaults to -fno-direct-access-external-data. Pass the option if
diff erent
+ // from the default.
+ if (Arg *A = Args.getLastArg(options::OPT_fdirect_access_external_data,
+ options::OPT_fno_direct_access_external_data))
+ if (A->getOption().matches(options::OPT_fdirect_access_external_data) !=
+ (PICLevel == 0))
+ A->render(Args, CmdArgs);
if (Args.hasFlag(options::OPT_fno_plt, options::OPT_fplt, false)) {
CmdArgs.push_back("-fno-plt");
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index dd66bf5b4efc..90203637ccbc 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -942,6 +942,13 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
}
}
+ // PIC defaults to -fno-direct-access-external-data while non-PIC defaults to
+ // -fdirect-access-external-data.
+ Opts.DirectAccessExternalData =
+ Args.hasArg(OPT_fdirect_access_external_data) ||
+ (!Args.hasArg(OPT_fno_direct_access_external_data) &&
+ getLastArgIntValue(Args, OPT_pic_level, 0, Diags) == 0);
+
// If -fuse-ctor-homing is set and limited debug info is already on, then use
// constructor homing.
if (Args.getLastArg(OPT_fuse_ctor_homing))
diff --git a/clang/test/CodeGen/dso-local-executable.c b/clang/test/CodeGen/dso-local-executable.c
index f4a886d4639b..5c5c6f59c09c 100644
--- a/clang/test/CodeGen/dso-local-executable.c
+++ b/clang/test/CodeGen/dso-local-executable.c
@@ -42,7 +42,7 @@
// PIE-DAG: define dso_local i32* @zed()
// PIE-DAG: declare void @import_func()
-// RUN: %clang_cc1 -triple x86_64 -emit-llvm -pic-level 1 -pic-is-pie -mpie-copy-relocations %s -o - | FileCheck --check-prefix=PIE-DIRECT %s
+// RUN: %clang_cc1 -triple x86_64 -emit-llvm -pic-level 1 -pic-is-pie -fdirect-access-external-data %s -o - | FileCheck --check-prefix=PIE-DIRECT %s
// PIE-DIRECT: @baz = dso_local global i32 42
// PIE-DIRECT-NEXT: @import_var = external dso_local global i32
// PIE-DIRECT-NEXT: @weak_bar = extern_weak global i32
@@ -64,7 +64,7 @@
// NOPLT-DAG: define dso_local i32* @zed()
// NOPLT-DAG: declare void @import_func()
-// RUN: %clang_cc1 -triple x86_64 -emit-llvm -fno-plt -pic-level 1 -pic-is-pie -mpie-copy-relocations %s -o - | FileCheck --check-prefix=PIE-DIRECT-NOPLT %s
+// RUN: %clang_cc1 -triple x86_64 -emit-llvm -fno-plt -pic-level 1 -pic-is-pie -fdirect-access-external-data %s -o - | FileCheck --check-prefix=PIE-DIRECT-NOPLT %s
// PIE-DIRECT-NOPLT: @baz = dso_local global i32 42
// PIE-DIRECT-NOPLT-NEXT: @import_var = external dso_local global i32
// PIE-DIRECT-NOPLT-NEXT: @weak_bar = extern_weak global i32
@@ -75,7 +75,7 @@
// PIE-DIRECT-NOPLT-DAG: define dso_local i32* @zed()
// PIE-DIRECT-NOPLT-DAG: declare void @import_func()
-// RUN: %clang_cc1 -triple x86_64 -emit-llvm -pic-is-pie -fno-plt %s -o - | FileCheck --check-prefix=PIE-NO-PLT %s
+// RUN: %clang_cc1 -triple x86_64 -emit-llvm -pic-level 1 -pic-is-pie -fno-plt %s -o - | FileCheck --check-prefix=PIE-NO-PLT %s
// RUN: %clang_cc1 -triple powerpc64le -emit-llvm -mrelocation-model static %s -o - | FileCheck --check-prefix=PIE-NO-PLT %s
// PIE-NO-PLT: @baz = dso_local global i32 42
// PIE-NO-PLT-NEXT: @import_var = external global i32
diff --git a/clang/test/Driver/fdirect-access-external-data.c b/clang/test/Driver/fdirect-access-external-data.c
new file mode 100644
index 000000000000..c3fc93064179
--- /dev/null
+++ b/clang/test/Driver/fdirect-access-external-data.c
@@ -0,0 +1,18 @@
+/// -fno-pic code defaults to -fdirect-access-external-data.
+// RUN: %clang -### -c -target x86_64 %s 2>&1 | FileCheck %s --check-prefix=DEFAULT
+// RUN: %clang -### -c -target x86_64 %s -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DEFAULT
+// RUN: %clang -### -c -target x86_64 %s -fdirect-access-external-data -fno-direct-access-external-data 2>&1 | FileCheck %s --check-prefix=INDIRECT
+
+/// -fpie/-fpic code defaults to -fdirect-access-external-data.
+// RUN: %clang -### -c -target x86_64 %s -fpie 2>&1 | FileCheck %s --check-prefix=DEFAULT
+// RUN: %clang -### -c -target x86_64 %s -fpie -fno-direct-access-external-data -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DIRECT
+// RUN: %clang -### -c -target aarch64 %s -fpic 2>&1 | FileCheck %s --check-prefix=DEFAULT
+// RUN: %clang -### -c -target aarch64 %s -fpic -fdirect-access-external-data 2>&1 | FileCheck %s --check-prefix=DIRECT
+
+/// -m[no-]pie-copy-relocations are aliases for compatibility.
+// RUN: %clang -### -c -target riscv64 %s -mno-pie-copy-relocations 2>&1 | FileCheck %s --check-prefix=INDIRECT
+// RUN: %clang -### -c -target riscv64 %s -fpic -mpie-copy-relocations 2>&1 | FileCheck %s --check-prefix=DIRECT
+
+// DEFAULT-NOT: direct-access-external-data"
+// DIRECT: "-fdirect-access-external-data"
+// INDIRECT: "-fno-direct-access-external-data"
More information about the llvm-branch-commits
mailing list