summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/tools/clang
diff options
context:
space:
mode:
authordlg <dlg@openbsd.org>2019-01-30 03:08:12 +0000
committerdlg <dlg@openbsd.org>2019-01-30 03:08:12 +0000
commit728e23dfc36a7a5f9a19f349b6c8d489de3d3859 (patch)
treecd910b6c2a97a90f6de6b76e84d2d74246997cc1 /gnu/llvm/tools/clang
parentuse MPLS_SHIM2LABEL and MPLS_LABEL2SHIM (diff)
downloadwireguard-openbsd-728e23dfc36a7a5f9a19f349b6c8d489de3d3859.tar.xz
wireguard-openbsd-728e23dfc36a7a5f9a19f349b6c8d489de3d3859.zip
implement -msave-args in clang/llvm, like the sun did for gcc
this is a bit different to gcc as gcc likes to use movs to move stuff on and off the stack, and directly updates the stack pointers with add and sub instructions. llvm prefers to use push and pop instructions, is a lot more careful about keeping track of how much stuff is currently on the stack, and generally pops the frame pointer rather than do maths on it. -msave-args adds a bunch of pushes as the first thing a function prologue does. to keep the stack aligned, if there's an odd number of arguments to the function it pushes the first one again to put the frame back on a 16 byte boundary. to undo the pushes the frame pointer needs to be updated in function epilogues. clang emits a series of pops to fix up the registers on the way out, but popping saved arguments is a waste of time and harmful to actual data in the function. rather than add an offset to the stack pointer, -msave-args emits a leaveq operation to fix up the frame again. leaveq is effectively mov rbp,rsp; pop rbp, and is a single byte, meaning there's less potential for gadgets compared to a direct add to rsp, or an explicit mov rbp,rsp. the only thing missing compared to the gcc implementation is adding the SUN_amd64_parmdump dwarf flag to affected functions. if someone can tell me how to add that from the frame lowering code, let me know. when enabled in kernel builds again, this will provide useful arguments in ddb stack traces again.
Diffstat (limited to 'gnu/llvm/tools/clang')
-rw-r--r--gnu/llvm/tools/clang/include/clang/Driver/Options.td2
-rw-r--r--gnu/llvm/tools/clang/lib/Basic/Targets/X86.cpp3
-rw-r--r--gnu/llvm/tools/clang/lib/Basic/Targets/X86.h1
3 files changed, 6 insertions, 0 deletions
diff --git a/gnu/llvm/tools/clang/include/clang/Driver/Options.td b/gnu/llvm/tools/clang/include/clang/Driver/Options.td
index e8afeb469c5..b9b054606fb 100644
--- a/gnu/llvm/tools/clang/include/clang/Driver/Options.td
+++ b/gnu/llvm/tools/clang/include/clang/Driver/Options.td
@@ -2814,6 +2814,8 @@ def mretpoline : Flag<["-"], "mretpoline">, Group<m_x86_Features_Group>;
def mno_retpoline : Flag<["-"], "mno-retpoline">, Group<m_x86_Features_Group>;
def mretpoline_external_thunk : Flag<["-"], "mretpoline-external-thunk">, Group<m_x86_Features_Group>;
def mno_retpoline_external_thunk : Flag<["-"], "mno-retpoline-external-thunk">, Group<m_x86_Features_Group>;
+def msave_args : Flag<["-"], "msave-args">, Group<m_x86_Features_Group>;
+def mno_save_args : Flag<["-"], "mno-save-args">, Group<m_x86_Features_Group>;
// These are legacy user-facing driver-level option spellings. They are always
// aliases for options that are spelled using the more common Unix / GNU flag
diff --git a/gnu/llvm/tools/clang/lib/Basic/Targets/X86.cpp b/gnu/llvm/tools/clang/lib/Basic/Targets/X86.cpp
index e295cff9d5d..ffa9e0d2a87 100644
--- a/gnu/llvm/tools/clang/lib/Basic/Targets/X86.cpp
+++ b/gnu/llvm/tools/clang/lib/Basic/Targets/X86.cpp
@@ -814,6 +814,8 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasPTWRITE = true;
} else if (Feature == "+invpcid") {
HasINVPCID = true;
+ } else if (Feature == "+save-args") {
+ HasSaveArgs = true;
}
X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
@@ -1386,6 +1388,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("movdiri", HasMOVDIRI)
.Case("movdir64b", HasMOVDIR64B)
.Case("mpx", HasMPX)
+ .Case("save-args", HasSaveArgs)
.Case("mwaitx", HasMWAITX)
.Case("pclmul", HasPCLMUL)
.Case("pconfig", HasPCONFIG)
diff --git a/gnu/llvm/tools/clang/lib/Basic/Targets/X86.h b/gnu/llvm/tools/clang/lib/Basic/Targets/X86.h
index 1d23b0ef693..c476326102d 100644
--- a/gnu/llvm/tools/clang/lib/Basic/Targets/X86.h
+++ b/gnu/llvm/tools/clang/lib/Basic/Targets/X86.h
@@ -107,6 +107,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasMOVDIR64B = false;
bool HasPTWRITE = false;
bool HasINVPCID = false;
+ bool HasSaveArgs = false;
protected:
/// Enumeration of all of the X86 CPUs supported by Clang.