gollvm: support -fPIE/-fno-PIE/-fpie/-fno-pie
Make sure that all of the various PIE compiler options are supported
properly. Prior to this point the driver accepted -fpic/-fPIC and
-pie/-no-pie but not -fPIE/-fno-PIE/-fpie/-fno-pie. As with clang,
rightmost pic/pie flag wins, e.g. -fpic -fno-PIE turns off -fpic.
Change-Id: I81b2503b28951d20a6fa3b548cb1331afa792457
Reviewed-on: https://go-review.googlesource.com/115055
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/driver/CompileGo.cpp b/driver/CompileGo.cpp
index 4100966..9f25875 100644
--- a/driver/CompileGo.cpp
+++ b/driver/CompileGo.cpp
@@ -415,6 +415,8 @@
module_->setTargetTriple(triple_.getTriple());
module_->setDataLayout(target_->createDataLayout());
module_->setPICLevel(driver_.getPicLevel());
+ if (driver_.picIsPIE())
+ module_->setPIELevel(driver_.getPieLevel());
// Now construct Llvm_backend helper.
bridge_.reset(new Llvm_backend(context_, module_.get(), linemap_.get()));
diff --git a/driver/Driver.cpp b/driver/Driver.cpp
index 63d2e43..6916894 100644
--- a/driver/Driver.cpp
+++ b/driver/Driver.cpp
@@ -127,26 +127,72 @@
return (arg ? arg->getOption().matches(options::OPT_pie) : false);
}
-// Return any settings from the -fPIC/-fpic options, if present. The
-// intent of the code below is to support "rightmost on the command
-// line wins" (compatible with clang and other compilers), so if you
-// specify "-fPIC -fpic" you get small PIC, whereas "-fPIC -fpic
-// -fPIC" this will give you large PIC.
+// Return any settings from the -fPIC/-fpic/-fPIE/-fpie options, if
+// present. The intent of the code below is to support "rightmost
+// on the command line wins" (compatible with clang and other
+// compilers), so if you specify "-fPIC -fpic" you get small PIC,
+// whereas "-fPIC -fpic -fPIC" will give you large PIC.
+// Similarly the presence of a "-fno-pic" to the right of "-fPIE"
+// will disable use of the PIE code model.
+
PICLevel::Level Driver::getPicLevel()
{
opt::Arg *arg = args_.getLastArg(gollvm::options::OPT_fpic,
gollvm::options::OPT_fno_pic,
gollvm::options::OPT_fPIC,
- gollvm::options::OPT_fno_PIC);
+ gollvm::options::OPT_fno_PIC,
+ gollvm::options::OPT_fpie,
+ gollvm::options::OPT_fno_pie,
+ gollvm::options::OPT_fPIE,
+ gollvm::options::OPT_fno_PIE);
if (arg == nullptr)
return PICLevel::NotPIC;
- if (arg->getOption().matches(gollvm::options::OPT_fpic))
+ if (arg->getOption().matches(gollvm::options::OPT_fpic) ||
+ arg->getOption().matches(gollvm::options::OPT_fpie))
return PICLevel::SmallPIC;
- else if (arg->getOption().matches(gollvm::options::OPT_fPIC))
+ else if (arg->getOption().matches(gollvm::options::OPT_fPIC) ||
+ arg->getOption().matches(gollvm::options::OPT_fPIE))
return PICLevel::BigPIC;
return PICLevel::NotPIC;
}
+// Similar to the routine above, but for -fPIE/-fpie etc.
+
+PIELevel::Level Driver::getPieLevel()
+{
+ opt::Arg *arg = args_.getLastArg(gollvm::options::OPT_fpie,
+ gollvm::options::OPT_fno_pie,
+ gollvm::options::OPT_fPIE,
+ gollvm::options::OPT_fno_PIE);
+ if (arg == nullptr)
+ return PIELevel::Default;
+ if (arg->getOption().matches(gollvm::options::OPT_fpie))
+ return PIELevel::Small;
+ else if (arg->getOption().matches(gollvm::options::OPT_fPIE))
+ return PIELevel::Large;
+ return PIELevel::Default;
+}
+
+// Returns TRUE if the rightmost enable -fpic/-fpie command line option is
+// PIE as opposed to PIC.
+
+bool Driver::picIsPIE()
+{
+ opt::Arg *lpa = args_.getLastArg(gollvm::options::OPT_fPIC,
+ gollvm::options::OPT_fno_PIC,
+ gollvm::options::OPT_fpic,
+ gollvm::options::OPT_fno_pic,
+ gollvm::options::OPT_fPIE,
+ gollvm::options::OPT_fno_PIE,
+ gollvm::options::OPT_fpie,
+ gollvm::options::OPT_fno_pie);
+ if (!lpa)
+ return false;
+ opt::Option opt = lpa->getOption();
+ return (opt.matches(gollvm::options::OPT_fPIE) ||
+ opt.matches(gollvm::options::OPT_fpie));
+}
+
// Given a pair of llvm::opt options (presumably corresponding to
// -fXXX and -fno-XXX boolean flags), select the correct value for the
// option depending on the relative position of the options on the
diff --git a/driver/Driver.h b/driver/Driver.h
index a69d888..24b35c9 100644
--- a/driver/Driver.h
+++ b/driver/Driver.h
@@ -93,6 +93,8 @@
// Helpers related to command line options.
llvm::PICLevel::Level getPicLevel();
+ llvm::PIELevel::Level getPieLevel();
+ bool picIsPIE();
bool isPIE();
template<typename IT>
llvm::Optional<IT> getLastArgAsInteger(gollvm::options::ID id,
diff --git a/driver/GollvmOptions.td b/driver/GollvmOptions.td
index bb947d0..9686261 100644
--- a/driver/GollvmOptions.td
+++ b/driver/GollvmOptions.td
@@ -223,6 +223,11 @@
def fno_PIC : Flag<["-"], "fno-PIC">, 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>;
+def fno_PIE : Flag<["-"], "fno-PIE">, Group<f_Group>;
+def fpie : Flag<["-"], "fpie">, Group<f_Group>;
+def fno_pie : Flag<["-"], "fno-pie">, Group<f_Group>;
+
def fno_inline : Flag<["-"], "fno-inline">, Group<f_Group>,
HelpText<"Disable inlining">;