aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp2
-rw-r--r--lib/Driver/Tools.cpp66
-rw-r--r--lib/Frontend/CompilerInvocation.cpp3
-rw-r--r--lib/Frontend/InitPreprocessor.cpp4
4 files changed, 56 insertions, 19 deletions
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()));