diff options
-rw-r--r-- | include/clang/Basic/LangOptions.def | 3 | ||||
-rw-r--r-- | include/clang/Driver/CC1Options.td | 2 | ||||
-rw-r--r-- | include/clang/Driver/Options.td | 10 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCGNU.cpp | 2 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 66 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 3 | ||||
-rw-r--r-- | lib/Frontend/InitPreprocessor.cpp | 4 | ||||
-rw-r--r-- | test/Driver/fno-pic.c | 5 | ||||
-rw-r--r-- | test/Driver/pic.c | 81 | ||||
-rw-r--r-- | test/Preprocessor/pic.c | 22 |
10 files changed, 168 insertions, 30 deletions
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def index a1ba2daf08..d2ce7c0df6 100644 --- a/include/clang/Basic/LangOptions.def +++ b/include/clang/Basic/LangOptions.def @@ -96,7 +96,8 @@ LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro") LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)") VALUE_LANGOPT(PackStruct , 32, 0, "default struct packing maximum alignment") -VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level") +VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level") +VALUE_LANGOPT(PIELevel , 2, 0, "__PIE__ level") LANGOPT(GNUInline , 1, 0, "GNU inline semantics") LANGOPT(NoInlineDefine , 1, 0, "__NO_INLINE__ predefined macro") LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro") diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 18caca6df1..3ab8f83481 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -632,6 +632,8 @@ def fwrapv : Flag<"-fwrapv">, HelpText<"Treat signed integer overflow as two's complement">; def pic_level : Separate<"-pic-level">, HelpText<"Value for __PIC__">; +def pie_level : Separate<"-pie-level">, + HelpText<"Value for __PIE__">; def pthread : Flag<"-pthread">, HelpText<"Support POSIX threads in generated code">; def fpack_struct : Separate<"-fpack-struct">, diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 7875eae4b7..1b6b20c6b3 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -265,8 +265,8 @@ def exported__symbols__list : Separate<"-exported_symbols_list">; def e : JoinedOrSeparate<"-e">; def fPIC : Flag<"-fPIC">, Group<f_Group>; def fno_PIC : Flag<"-fno-PIC">, Group<f_Group>; -def fPIE : Flag<"-fPIE">, Group<f_Group>, Flags<[NoArgumentUnused]>; -def fno_PIE : Flag<"-fno-PIE">, Group<f_Group>, Flags<[NoArgumentUnused]>; +def fPIE : Flag<"-fPIE">, Group<f_Group>; +def fno_PIE : Flag<"-fno-PIE">, Group<f_Group>; def faccess_control : Flag<"-faccess-control">, Group<f_Group>; def fallow_unsupported : Flag<"-fallow-unsupported">, Group<f_Group>; def faltivec : Flag<"-faltivec">, Group<f_Group>; @@ -499,8 +499,8 @@ def fpascal_strings : Flag<"-fpascal-strings">, Group<f_Group>; def fpch_preprocess : Flag<"-fpch-preprocess">, Group<f_Group>; def fpic : Flag<"-fpic">, Group<f_Group>; def fno_pic : Flag<"-fno-pic">, Group<f_Group>; -def fpie : Flag<"-fpie">, Group<f_Group>, Flags<[NoArgumentUnused]>; -def fno_pie : Flag<"-fno-pie">, Group<f_Group>, Flags<[NoArgumentUnused]>; +def fpie : Flag<"-fpie">, Group<f_Group>; +def fno_pie : Flag<"-fno-pie">, Group<f_Group>; def fprofile_arcs : Flag<"-fprofile-arcs">, Group<f_Group>; def fprofile_generate : Flag<"-fprofile-generate">, Group<f_Group>; def framework : Separate<"-framework">, Flags<[LinkerInput]>; @@ -605,7 +605,7 @@ def march_EQ : Joined<"-march=">, Group<m_Group>; def mcmodel_EQ : Joined<"-mcmodel=">, Group<m_Group>; def mconstant_cfstrings : Flag<"-mconstant-cfstrings">, Group<clang_ignored_m_Group>; def mcpu_EQ : Joined<"-mcpu=">, Group<m_Group>; -def mdynamic_no_pic : Joined<"-mdynamic-no-pic">, Group<m_Group>, Flags<[NoArgumentUnused]>; +def mdynamic_no_pic : Joined<"-mdynamic-no-pic">, Group<m_Group>; def mfix_and_continue : Flag<"-mfix-and-continue">, Group<clang_ignored_m_Group>; def mfloat_abi_EQ : Joined<"-mfloat-abi=">, Group<m_Group>; def mfpmath_EQ : Joined<"-mfpmath=">, Group<m_Group>; diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 68895dd93e..db0bd951c1 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -2594,7 +2594,7 @@ llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable( // to replace it with the real version for a library. In non-PIC code you // must compile with the fragile ABI if you want to use ivars from a // GCC-compiled class. - if (CGM.getLangOpts().PICLevel) { + if (CGM.getLangOpts().PICLevel || CGM.getLangOpts().PIELevel) { llvm::GlobalVariable *IvarOffsetGV = new llvm::GlobalVariable(TheModule, Int32Ty, false, llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+".guess"); diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index fd064d5bb5..14842f36e7 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1480,19 +1480,43 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // would do to enable flag_pic. // // FIXME: Centralize this code. - bool PICEnabled = (Args.hasArg(options::OPT_fPIC) || - Args.hasArg(options::OPT_fpic) || - Args.hasArg(options::OPT_fPIE) || - Args.hasArg(options::OPT_fpie)); - bool PICDisabled = (Args.hasArg(options::OPT_mkernel) || - Args.hasArg(options::OPT_static) || - Args.hasArg(options::OPT_fno_PIC) || - Args.hasArg(options::OPT_fno_pic) || - Args.hasArg(options::OPT_fno_PIE) || - Args.hasArg(options::OPT_fno_pie)); + Arg *LastPICArg = 0; + for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) { + if ((*I)->getOption().matches(options::OPT_fPIC) || + (*I)->getOption().matches(options::OPT_fno_PIC) || + (*I)->getOption().matches(options::OPT_fpic) || + (*I)->getOption().matches(options::OPT_fno_pic) || + (*I)->getOption().matches(options::OPT_fPIE) || + (*I)->getOption().matches(options::OPT_fno_PIE) || + (*I)->getOption().matches(options::OPT_fpie) || + (*I)->getOption().matches(options::OPT_fno_pie)) { + LastPICArg = *I; + (*I)->claim(); + } + } + bool PICDisabled = false; + bool PICEnabled = false; + bool PICForPIE = false; + if (LastPICArg) { + PICForPIE = (LastPICArg->getOption().matches(options::OPT_fPIE) || + LastPICArg->getOption().matches(options::OPT_fpie)); + PICEnabled = (PICForPIE || + LastPICArg->getOption().matches(options::OPT_fPIC) || + LastPICArg->getOption().matches(options::OPT_fpic)); + PICDisabled = !PICEnabled; + } + // Note that these flags are trump-cards. Regardless of the order w.r.t. the + // PIC or PIE options above, if these show up, PIC is disabled. + if (Args.hasArg(options::OPT_mkernel)) + PICDisabled = true; + if (Args.hasArg(options::OPT_static)) + PICDisabled = true; + bool DynamicNoPIC = Args.hasArg(options::OPT_mdynamic_no_pic); + + // Select the relocation model. const char *Model = getToolChain().GetForcedPicModel(); if (!Model) { - if (Args.hasArg(options::OPT_mdynamic_no_pic)) + if (DynamicNoPIC) Model = "dynamic-no-pic"; else if (PICDisabled) Model = "static"; @@ -1501,19 +1525,25 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, else Model = getToolChain().GetDefaultRelocationModel(); } - if (StringRef(Model) != "pic") { + StringRef ModelStr = Model ? Model : ""; + if (Model && ModelStr != "pic") { CmdArgs.push_back("-mrelocation-model"); CmdArgs.push_back(Model); } - // Infer the __PIC__ value. - // - // FIXME: This isn't quite right on Darwin, which always sets - // __PIC__=2. - if (strcmp(Model, "pic") == 0 || strcmp(Model, "dynamic-no-pic") == 0) { + // Infer the __PIC__ and __PIE__ values. + if (ModelStr == "pic" && PICForPIE) { + CmdArgs.push_back("-pie-level"); + CmdArgs.push_back((LastPICArg && + LastPICArg->getOption().matches(options::OPT_fPIE)) ? + "2" : "1"); + } else if (ModelStr == "pic" || ModelStr == "dynamic-no-pic") { CmdArgs.push_back("-pic-level"); - CmdArgs.push_back(Args.hasArg(options::OPT_fPIC) ? "2" : "1"); + CmdArgs.push_back(((ModelStr != "dynamic-no-pic" && LastPICArg && + LastPICArg->getOption().matches(options::OPT_fPIC)) || + getToolChain().getTriple().isOSDarwin()) ? "2" : "1"); } + if (!Args.hasFlag(options::OPT_fmerge_all_constants, options::OPT_fno_merge_all_constants)) CmdArgs.push_back("-fno-merge-all-constants"); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 6e36242be2..02947c778c 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -740,6 +740,8 @@ static void LangOptsToArgs(const LangOptions &Opts, ToArgsList &Res) { Res.push_back("-fno-bitfield-type-alignment"); if (Opts.PICLevel) Res.push_back("-pic-level", llvm::utostr(Opts.PICLevel)); + if (Opts.PIELevel) + Res.push_back("-pie-level", llvm::utostr(Opts.PIELevel)); if (Opts.ObjCGCBitmapPrint) Res.push_back("-print-ivar-layout"); if (Opts.NoConstantCFStrings) @@ -1897,6 +1899,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls); Opts.PackStruct = Args.getLastArgIntValue(OPT_fpack_struct, 0, Diags); Opts.PICLevel = Args.getLastArgIntValue(OPT_pic_level, 0, Diags); + Opts.PIELevel = Args.getLastArgIntValue(OPT_pie_level, 0, Diags); Opts.Static = Args.hasArg(OPT_static_define); Opts.DumpRecordLayoutsSimple = Args.hasArg(OPT_fdump_record_layouts_simple); Opts.DumpRecordLayouts = Opts.DumpRecordLayoutsSimple diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp index 37e89173ab..c1b9d57f09 100644 --- a/lib/Frontend/InitPreprocessor.cpp +++ b/lib/Frontend/InitPreprocessor.cpp @@ -528,6 +528,10 @@ static void InitializePredefinedMacros(const TargetInfo &TI, Builder.defineMacro("__PIC__", Twine(PICLevel)); Builder.defineMacro("__pic__", Twine(PICLevel)); } + if (unsigned PIELevel = LangOpts.PIELevel) { + Builder.defineMacro("__PIE__", Twine(PIELevel)); + Builder.defineMacro("__pie__", Twine(PIELevel)); + } // Macros to control C99 numerics and <float.h> Builder.defineMacro("__FLT_EVAL_METHOD__", Twine(TI.getFloatEvalMethod())); diff --git a/test/Driver/fno-pic.c b/test/Driver/fno-pic.c deleted file mode 100644 index 5ec122850d..0000000000 --- a/test/Driver/fno-pic.c +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %clang -c %s -target i386-apple-darwin -### 2>&1 | FileCheck %s --check-prefix=PIC_ON_BY_DEFAULT -// PIC_ON_BY_DEFAULT: "-pic-level" "1" - -// RUN: %clang -c %s -target i386-apple-darwin -### -fno-pic 2>&1 | FileCheck %s --check-prefix=FNO_PIC -// FNO_PIC: "-mrelocation-model" "static" diff --git a/test/Driver/pic.c b/test/Driver/pic.c new file mode 100644 index 0000000000..3952f85ceb --- /dev/null +++ b/test/Driver/pic.c @@ -0,0 +1,81 @@ +// Test the driver's control over the PIC behavior. These consist of tests of +// the relocation model flags and the pic level flags passed to CC1. +// +// CHECK-NO-PIC: "-mrelocation-model" "static" +// CHECK-NO-PIC-NOT: "-pic-level" +// CHECK-NO-PIC-NOT: "-pie-level" +// +// CHECK-DYNAMIC-NO-PIC1: "-mrelocation-model" "dynamic-no-pic" +// CHECK-DYNAMIC-NO-PIC1: "-pic-level" "1" +// +// CHECK-DYNAMIC-NO-PIC2: "-mrelocation-model" "dynamic-no-pic" +// CHECK-DYNAMIC-NO-PIC2: "-pic-level" "2" +// +// CHECK-PIC1-NOT: "-mrelocation-model" +// CHECK-PIC1: "-pic-level" "1" +// +// CHECK-PIC2-NOT: "-mrelocation-model" +// CHECK-PIC2: "-pic-level" "2" +// +// CHECK-PIE1-NOT: "-mrelocation-model" +// CHECK-PIE1: "-pie-level" "1" +// +// CHECK-PIE2-NOT: "-mrelocation-model" +// CHECK-PIE2: "-pie-level" "2" +// +// RUN: %clang -c %s -target i386-unknown-unknown -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// RUN: %clang -c %s -target i386-unknown-unknown -fpic -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIC1 +// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIC2 +// RUN: %clang -c %s -target i386-unknown-unknown -fpie -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE1 +// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE2 +// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fno-pic -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fno-PIC -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fno-PIC -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fno-pic -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fno-pie -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fno-PIE -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fno-PIE -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fno-pie -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fno-pic -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fno-pie -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fPIC -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIC2 +// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fpic -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIC1 +// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fPIE -fpie -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE1 +// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fPIC -fPIE -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIE2 +// +// Defaults change for Darwin. +// RUN: %clang -c %s -target i386-apple-darwin -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIC2 +// RUN: %clang -c %s -target i386-apple-darwin -fno-pic -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// RUN: %clang -c %s -target i386-apple-darwin -fno-PIC -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// +// Disregard any of the PIC-specific flags if we have a trump-card flag. +// RUN: %clang -c %s -target i386-unknown-unknown -mkernel -fPIC -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// RUN: %clang -c %s -target i386-unknown-unknown -static -fPIC -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC +// RUN: %clang -c %s -target i386-unknown-unknown -mdynamic-no-pic -fPIC -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-DYNAMIC-NO-PIC1 +// RUN: %clang -c %s -target i386-apple-darwin -mdynamic-no-pic -fPIC -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-DYNAMIC-NO-PIC2 diff --git a/test/Preprocessor/pic.c b/test/Preprocessor/pic.c index 4597f4301f..3e649ee5ea 100644 --- a/test/Preprocessor/pic.c +++ b/test/Preprocessor/pic.c @@ -1,12 +1,34 @@ // RUN: %clang_cc1 -dM -E -o - %s \ // RUN: | FileCheck %s // CHECK-NOT: #define __PIC__ +// CHECK-NOT: #define __PIE__ // CHECK-NOT: #define __pic__ +// CHECK-NOT: #define __pie__ +// // RUN: %clang_cc1 -pic-level 1 -dM -E -o - %s \ // RUN: | FileCheck --check-prefix=CHECK-PIC1 %s // CHECK-PIC1: #define __PIC__ 1 +// CHECK-PIC1-NOT: #define __PIE__ // CHECK-PIC1: #define __pic__ 1 +// CHECK-PIC1-NOT: #define __pie__ +// // RUN: %clang_cc1 -pic-level 2 -dM -E -o - %s \ // RUN: | FileCheck --check-prefix=CHECK-PIC2 %s // CHECK-PIC2: #define __PIC__ 2 +// CHECK-PIC2-NOT: #define __PIE__ // CHECK-PIC2: #define __pic__ 2 +// CHECK-PIC2-NOT: #define __pie__ +// +// RUN: %clang_cc1 -pie-level 1 -dM -E -o - %s \ +// RUN: | FileCheck --check-prefix=CHECK-PIE1 %s +// CHECK-PIE1-NOT: #define __PIC__ +// CHECK-PIE1: #define __PIE__ 1 +// CHECK-PIE1-NOT: #define __pic__ +// CHECK-PIE1: #define __pie__ 1 +// +// RUN: %clang_cc1 -pie-level 2 -dM -E -o - %s \ +// RUN: | FileCheck --check-prefix=CHECK-PIE2 %s +// CHECK-PIE2-NOT: #define __PIC__ +// CHECK-PIE2: #define __PIE__ 2 +// CHECK-PIE2-NOT: #define __pic__ +// CHECK-PIE2: #define __pie__ 2 |