diff options
Diffstat (limited to 'tools/driver')
-rw-r--r-- | tools/driver/CMakeLists.txt | 27 | ||||
-rw-r--r-- | tools/driver/Info.plist.in | 2 | ||||
-rw-r--r-- | tools/driver/cc1_main.cpp | 105 | ||||
-rw-r--r-- | tools/driver/cc1as_main.cpp | 21 | ||||
-rw-r--r-- | tools/driver/driver.cpp | 6 |
5 files changed, 145 insertions, 16 deletions
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt index e03b3fa3951ef..49bde947f4c64 100644 --- a/tools/driver/CMakeLists.txt +++ b/tools/driver/CMakeLists.txt @@ -24,10 +24,17 @@ if(CLANG_PLUGIN_SUPPORT) set(LLVM_NO_DEAD_STRIP 1) endif() +if(NOT CLANG_BUILT_STANDALONE) + set(tablegen_deps intrinsics_gen) +endif() + add_clang_tool(clang driver.cpp cc1_main.cpp cc1as_main.cpp + + DEPENDS + ${tablegen_deps} ) target_link_libraries(clang @@ -52,7 +59,7 @@ endif() add_dependencies(clang clang-headers) if(NOT CLANG_LINKS_TO_CREATE) - set(CLANG_LINKS_TO_CREATE clang++ clang-cl) + set(CLANG_LINKS_TO_CREATE clang++ clang-cl clang-cpp) if (WIN32) list(APPEND CLANG_LINKS_TO_CREATE ../msbuild-bin/cl) @@ -74,7 +81,7 @@ if (APPLE) set(TOOL_INFO_UTI "${CLANG_VENDOR_UTI}") set(TOOL_INFO_VERSION "${CLANG_VERSION}") - set(TOOL_INFO_BUILD_VERSION "${LLVM_MAJOR_VERSION}.${LLVM_MINOR_VERSION}") + set(TOOL_INFO_BUILD_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}") set(TOOL_INFO_PLIST_OUT "${CMAKE_CURRENT_BINARY_DIR}/${TOOL_INFO_PLIST}") target_link_libraries(clang @@ -101,8 +108,15 @@ if(LD64_EXECUTABLE AND CLANG_ORDER_FILE) # This is a test to ensure the actual order file works with the linker. check_linker_flag("-Wl,-order_file,${CLANG_ORDER_FILE}" LINKER_ORDER_FILE_WORKS) - - if(LINKER_ORDER_FILE_WORKS) + + # Passing an empty order file disables some linker layout optimizations. + # To work around this and enable workflows for re-linking when the order file + # changes we check during configuration if the file is empty, and make it a + # configuration dependency. + file(READ ${CLANG_ORDER_FILE} ORDER_FILE LIMIT 20) + if("${ORDER_FILE}" STREQUAL "\n") + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CLANG_ORDER_FILE}) + elseif(LINKER_ORDER_FILE_WORKS) target_link_libraries(clang "-Wl,-order_file,${CLANG_ORDER_FILE}") set_target_properties(clang PROPERTIES LINK_DEPENDS ${CLANG_ORDER_FILE}) endif() @@ -110,9 +124,4 @@ endif() if(WITH_POLLY AND LINK_POLLY_INTO_TOOLS) target_link_libraries(clang Polly) - if(POLLY_LINK_LIBS) - foreach(lib ${POLLY_LINK_LIBS}) - target_link_libraries(clang ${lib}) - endforeach(lib) - endif(POLLY_LINK_LIBS) endif(WITH_POLLY AND LINK_POLLY_INTO_TOOLS) diff --git a/tools/driver/Info.plist.in b/tools/driver/Info.plist.in index c938fb053d927..c2b157021df4d 100644 --- a/tools/driver/Info.plist.in +++ b/tools/driver/Info.plist.in @@ -7,7 +7,7 @@ <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> - <string>@TOOL_INFO_NAME</string> + <string>@TOOL_INFO_NAME@</string> <key>CFBundleShortVersionString</key> <string>@TOOL_INFO_VERSION@</string> <key>CFBundleVersion</key> diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp index d78a31e67a2f9..1a16746d589d3 100644 --- a/tools/driver/cc1_main.cpp +++ b/tools/driver/cc1_main.cpp @@ -15,6 +15,7 @@ #include "llvm/Option/Arg.h" #include "clang/CodeGen/ObjectFilePCHContainerOperations.h" +#include "clang/Config/config.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "clang/Frontend/CompilerInstance.h" @@ -28,6 +29,7 @@ #include "llvm/LinkAllPasses.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/OptTable.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Signals.h" @@ -35,6 +37,11 @@ #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" #include <cstdio> + +#ifdef CLANG_HAVE_RLIMITS +#include <sys/resource.h> +#endif + using namespace clang; using namespace llvm::opt; @@ -64,7 +71,105 @@ void initializePollyPasses(llvm::PassRegistry &Registry); } #endif +#ifdef CLANG_HAVE_RLIMITS +// The amount of stack we think is "sufficient". If less than this much is +// available, we may be unable to reach our template instantiation depth +// limit and other similar limits. +// FIXME: Unify this with the stack we request when spawning a thread to build +// a module. +static const int kSufficientStack = 8 << 20; + +#if defined(__linux__) && defined(__PIE__) +static size_t getCurrentStackAllocation() { + // If we can't compute the current stack usage, allow for 512K of command + // line arguments and environment. + size_t Usage = 512 * 1024; + if (FILE *StatFile = fopen("/proc/self/stat", "r")) { + // We assume that the stack extends from its current address to the end of + // the environment space. In reality, there is another string literal (the + // program name) after the environment, but this is close enough (we only + // need to be within 100K or so). + unsigned long StackPtr, EnvEnd; + // Disable silly GCC -Wformat warning that complains about length + // modifiers on ignored format specifiers. We want to retain these + // for documentation purposes even though they have no effect. +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat" +#endif + if (fscanf(StatFile, + "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu %*lu " + "%*lu %*ld %*ld %*ld %*ld %*ld %*ld %*llu %*lu %*ld %*lu %*lu " + "%*lu %*lu %lu %*lu %*lu %*lu %*lu %*lu %*llu %*lu %*lu %*d %*d " + "%*u %*u %*llu %*lu %*ld %*lu %*lu %*lu %*lu %*lu %*lu %lu %*d", + &StackPtr, &EnvEnd) == 2) { +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + Usage = StackPtr < EnvEnd ? EnvEnd - StackPtr : StackPtr - EnvEnd; + } + fclose(StatFile); + } + return Usage; +} + +#include <alloca.h> + +LLVM_ATTRIBUTE_NOINLINE +static void ensureStackAddressSpace(int ExtraChunks = 0) { + // Linux kernels prior to 4.1 will sometimes locate the heap of a PIE binary + // relatively close to the stack (they are only guaranteed to be 128MiB + // apart). This results in crashes if we happen to heap-allocate more than + // 128MiB before we reach our stack high-water mark. + // + // To avoid these crashes, ensure that we have sufficient virtual memory + // pages allocated before we start running. + size_t Curr = getCurrentStackAllocation(); + const int kTargetStack = kSufficientStack - 256 * 1024; + if (Curr < kTargetStack) { + volatile char *volatile Alloc = + static_cast<volatile char *>(alloca(kTargetStack - Curr)); + Alloc[0] = 0; + Alloc[kTargetStack - Curr - 1] = 0; + } +} +#else +static void ensureStackAddressSpace() {} +#endif + +/// Attempt to ensure that we have at least 8MiB of usable stack space. +static void ensureSufficientStack() { + struct rlimit rlim; + if (getrlimit(RLIMIT_STACK, &rlim) != 0) + return; + + // Increase the soft stack limit to our desired level, if necessary and + // possible. + if (rlim.rlim_cur != RLIM_INFINITY && rlim.rlim_cur < kSufficientStack) { + // Try to allocate sufficient stack. + if (rlim.rlim_max == RLIM_INFINITY || rlim.rlim_max >= kSufficientStack) + rlim.rlim_cur = kSufficientStack; + else if (rlim.rlim_cur == rlim.rlim_max) + return; + else + rlim.rlim_cur = rlim.rlim_max; + + if (setrlimit(RLIMIT_STACK, &rlim) != 0 || + rlim.rlim_cur != kSufficientStack) + return; + } + + // We should now have a stack of size at least kSufficientStack. Ensure + // that we can actually use that much, if necessary. + ensureStackAddressSpace(); +} +#else +static void ensureSufficientStack() {} +#endif + int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) { + ensureSufficientStack(); + std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp index 2d17be99e2d57..263751346b803 100644 --- a/tools/driver/cc1as_main.cpp +++ b/tools/driver/cc1as_main.cpp @@ -77,6 +77,9 @@ struct AssemblerInvocation { /// be a list of strings starting with '+' or '-'. std::vector<std::string> Features; + /// The list of symbol definitions. + std::vector<std::string> SymbolDefs; + /// @} /// @name Language Options /// @{ @@ -252,6 +255,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, Opts.RelocationModel = Args.getLastArgValue(OPT_mrelocation_model, "pic"); Opts.IncrementalLinkerCompatible = Args.hasArg(OPT_mincremental_linker_compatible); + Opts.SymbolDefs = Args.getAllArgValues(OPT_defsym); return Success; } @@ -379,7 +383,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, MCAsmBackend *MAB = nullptr; if (Opts.ShowEncoding) { CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx); - MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, Opts.CPU); + MCTargetOptions Options; + MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, Opts.CPU, Options); } auto FOut = llvm::make_unique<formatted_raw_ostream>(*Out); Str.reset(TheTarget->createAsmStreamer( @@ -396,8 +401,9 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, } MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx); + MCTargetOptions Options; MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, - Opts.CPU); + Opts.CPU, Options); Triple T(Opts.Triple); Str.reset(TheTarget->createMCObjectStreamer( T, Ctx, *MAB, *Out, CE, *STI, Opts.RelaxAll, @@ -418,6 +424,17 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts, if (!TAP) Failed = Diags.Report(diag::err_target_unknown_triple) << Opts.Triple; + // Set values for symbols, if any. + for (auto &S : Opts.SymbolDefs) { + auto Pair = StringRef(S).split('='); + auto Sym = Pair.first; + auto Val = Pair.second; + int64_t Value; + // We have already error checked this in the driver. + Val.getAsInteger(0, Value); + Ctx.setSymbolValue(Parser->getStreamer(), Sym, Value); + } + if (!Failed) { Parser->setTargetParser(*TAP.get()); Failed = Parser->Run(Opts.NoInitialTextSection); diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp index 4d69aaffba23e..61613028625b3 100644 --- a/tools/driver/driver.cpp +++ b/tools/driver/driver.cpp @@ -12,7 +12,6 @@ // //===----------------------------------------------------------------------===// -#include "clang/Basic/CharInfo.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" @@ -25,7 +24,6 @@ #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Frontend/Utils.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Config/llvm-config.h" @@ -37,7 +35,6 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/Host.h" #include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Process.h" @@ -49,6 +46,7 @@ #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" #include <memory> +#include <set> #include <system_error> using namespace clang; using namespace clang::driver; @@ -395,7 +393,7 @@ int main(int argc_, const char **argv_) { // Handle CL and _CL_ which permits additional command line options to be // prepended or appended. - if (Tokenizer == &llvm::cl::TokenizeWindowsCommandLine) { + if (ClangCLMode) { // Arguments in "CL" are prepended. llvm::Optional<std::string> OptCL = llvm::sys::Process::GetEnv("CL"); if (OptCL.hasValue()) { |