gollvm: support debug compression options for integ assembler
Add support for accepting the -Wa,--compress-debug-sections option
in combination with the integrated assembler.
Change-Id: Ib0b1bab8297626f10b416a1024fb44056a7135bf
Reviewed-on: https://go-review.googlesource.com/c/gollvm/+/260736
Trust: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
diff --git a/driver/CompileGo.cpp b/driver/CompileGo.cpp
index a270d83..6510b72 100644
--- a/driver/CompileGo.cpp
+++ b/driver/CompileGo.cpp
@@ -414,6 +414,10 @@
assert(jat == Action::A_CompileAndAssemble ||
jat == Action::A_Compile);
Options.DisableIntegratedAS = !(jat == Action::A_CompileAndAssemble);
+ llvm::DebugCompressionType dct = llvm::DebugCompressionType::None;
+ if (!driver_.determineDebugCompressionType(&dct))
+ return false;
+ Options.CompressDebugSections = dct;
// FIXME: this hard-wires on the equivalent of -ffunction-sections
// and -fdata-sections, since there doesn't seem to be a high-level
diff --git a/driver/Driver.cpp b/driver/Driver.cpp
index 13e7cf7..e8aa35a 100644
--- a/driver/Driver.cpp
+++ b/driver/Driver.cpp
@@ -163,17 +163,104 @@
if (arg != nullptr)
return arg->getOption().matches(options::OPT_fintegrated_as);
- // If -Xassembler or -Wa,... used, then don't use the integrated
- // assembler, since the driver doesn't support the full complement
- // of assembler options (this can be removed if/when we do).
- auto waComArg = args_.getLastArg(gollvm::options::OPT_Wa_COMMA);
- auto xAsmArg = args_.getLastArg(gollvm::options::OPT_Xassembler);
- if (waComArg != nullptr || xAsmArg != nullptr)
+ // If -Xassembler or -Wa,... is used with an unsupported asm option then don't
+ // use the integrated assembler, since the driver doesn't support the full
+ // complement of assembler options (this can be removed if/when a more
+ // complete set is implemented).
+ if (!supportedAsmOptions())
return false;
return true;
}
+// Returns TRUE if the assembler options given on the command line fall into the
+// subset that we support, FALSE otherwise. At the moment the driver handles a
+// very limited set of -Wa,... options, mainly --compress-debug-sections.
+bool Driver::supportedAsmOptions()
+{
+ for (const opt::Arg *arg : args_.filtered(gollvm::options::OPT_Wa_COMMA,
+ gollvm::options::OPT_Xassembler)) {
+ auto value = llvm::StringRef(arg->getValue());
+ if (value == "-nocompress-debug-sections" ||
+ value == "--nocompress-debug-sections") {
+ continue;
+ }
+ if (value.startswith("-compress-debug-sections") ||
+ value.startswith("--compress-debug-sections")) {
+ continue;
+ }
+ // Unrecognized -Wa,... option
+ return false;
+ }
+ return true;
+}
+
+// Convert a "-gz=" argument to llvm::DebugCompressionType. Returns
+// its second argument if ok, nullptr if a bad argument is given (and
+// issues an error in this case).
+llvm::DebugCompressionType *Driver::gzArgToDCT(llvm::StringRef ga,
+ llvm::DebugCompressionType *dct,
+ const char *which)
+{
+ if (ga == "zlib") {
+ *dct = llvm::DebugCompressionType::Z;
+ return dct;
+ } else if (ga == "zlib-gnu") {
+ *dct = llvm::DebugCompressionType::GNU;
+ return dct;
+ } else if (ga == "none") {
+ *dct = llvm::DebugCompressionType::None;
+ return dct;
+ } else {
+ errs() << progname_ << ": error: Invalid " << which
+ << " argument '" << ga << "'\n";
+ return nullptr;
+ }
+}
+
+// This method sifts through the command line from left to right and picks out
+// arguments related to debug info compression (-gz,
+// -Wa,--compress-debug-sections, etc), with the rightmost setting taking
+// precedence. If an invalid argument is suplied to '-gz=' or related, we return
+// FALSE; otherwise return TRUE with a possibly updated value stored to "*dct".
+bool Driver::determineDebugCompressionType(llvm::DebugCompressionType *dct)
+{
+ for (const opt::Arg *arg : args_.filtered(gollvm::options::OPT_gz,
+ gollvm::options::OPT_gz_EQ,
+ gollvm::options::OPT_Wa_COMMA,
+ gollvm::options::OPT_Xassembler)) {
+ if (arg->getOption().matches(gollvm::options::OPT_gz)) {
+ *dct = llvm::DebugCompressionType::GNU;
+ } else if (arg->getOption().matches(gollvm::options::OPT_gz_EQ)) {
+ auto value = llvm::StringRef(arg->getValue());
+ if (gzArgToDCT(value, dct, "-gz=") == nullptr)
+ return false;
+ } else if (arg->getOption().matches(gollvm::options::OPT_Wa_COMMA) ||
+ arg->getOption().matches(gollvm::options::OPT_Xassembler)) {
+ auto value = llvm::StringRef(arg->getValue());
+ if (value == "-nocompress-debug-sections" ||
+ value == "--nocompress-debug-sections") {
+ *dct = llvm::DebugCompressionType::None;
+ } else if (value.startswith("-compress-debug-sections") ||
+ value.startswith("--compress-debug-sections")) {
+ const char *wh =
+ (arg->getOption().matches(gollvm::options::OPT_Xassembler) ?
+ "-Xassembler" : "-Wa,");
+ value.consume_front("--compress-debug-sections");
+ value.consume_front("-compress-debug-sections");
+ auto arg = value;
+ if (value.startswith("="))
+ arg.consume_front("=");
+ else
+ arg = "zlib";
+ if (gzArgToDCT(arg, dct, wh) == nullptr)
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
// FIXME: some platforms have PIE enabled by default; we don't
// yet support auto-detection of such platforms.
diff --git a/driver/Driver.h b/driver/Driver.h
index 34ce9d4..3b2813d 100644
--- a/driver/Driver.h
+++ b/driver/Driver.h
@@ -109,6 +109,8 @@
bool picIsPIE();
bool isPIE();
bool useIntegratedAssembler();
+ bool supportedAsmOptions();
+ bool determineDebugCompressionType(llvm::DebugCompressionType *dct);
bool usingSplitStack() const { return usingSplitStack_; }
template<typename IT>
llvm::Optional<IT> getLastArgAsInteger(gollvm::options::ID id,
@@ -148,6 +150,9 @@
bool processAction(Action *act, Compilation &compilation, bool lastAct);
ArtifactList collectInputArtifacts(Action *act, InternalTool *it);
+ llvm::DebugCompressionType *gzArgToDCT(llvm::StringRef ga,
+ llvm::DebugCompressionType *dct,
+ const char *which);
};
template<typename IT>
diff --git a/driver/IntegAssembler.cpp b/driver/IntegAssembler.cpp
index 5ba554b..f6262c8 100644
--- a/driver/IntegAssembler.cpp
+++ b/driver/IntegAssembler.cpp
@@ -181,19 +181,8 @@
TheTarget->createMCAsmInfo(*MRI, Trip, MCOptions));
assert(MAI && "Unable to create target asm info!");
- // FIXME: at this point what we need to do is collect up any assembler
- // arguments specified with -Wa,XXX and turn them into the correct
- // back end setup options. For now, just assert if we see -Wa.
- auto waComArg = args_.getLastArg(gollvm::options::OPT_Wa_COMMA);
- auto xAsmArg = args_.getLastArg(gollvm::options::OPT_Xassembler);
- if (waComArg != nullptr || xAsmArg != nullptr) {
- errs() << progname_ << ": internal error: option '"
- << (waComArg != nullptr ? waComArg->getAsString(args_) :
- xAsmArg->getAsString(args_))
- << "' not yet implemented in integrated assembler\n";
- assert(false);
- return false;
- }
+ // Note: -Xassembler and -Wa, options should already have been
+ // examined at this point.
// FIXME: no support yet for -march (bring over from CompileGo.cpp)
opt::Arg *cpuarg = args_.getLastArg(gollvm::options::OPT_march_EQ);
@@ -208,23 +197,8 @@
// Support for compressed debug.
llvm::DebugCompressionType CompressDebugSections =
llvm::DebugCompressionType::None;
- llvm::opt::Arg *gzarg = args_.getLastArg(gollvm::options::OPT_gz,
- gollvm::options::OPT_gz_EQ);
- if (gzarg != nullptr) {
- if (gzarg->getOption().matches(gollvm::options::OPT_gz)) {
- CompressDebugSections = llvm::DebugCompressionType::GNU;
- } else {
- std::string ga(gzarg->getValue());
- if (ga == "zlib") {
- CompressDebugSections = llvm::DebugCompressionType::Z;
- } else if (ga == "zlib-gnu") {
- CompressDebugSections = llvm::DebugCompressionType::GNU;
- } else if (ga != "none") {
- errs() << progname_ << ": error: Invalid -Wa,--compress-debug-sections"
- << " argument '" << ga << "'\n";
- }
- }
- }
+ if (!driver_.determineDebugCompressionType(&CompressDebugSections))
+ return false;
// Ensure MCAsmInfo initialization occurs before any use, otherwise sections
// may be created with a combination of default and explicit settings.