1 //===-- cc1_main.cpp - Clang CC1 Compiler Frontend ------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This is the entry point to the clang -cc1 functionality, which implements the 10 // core compiler functionality along with a number of additional tools for 11 // demonstration and testing purposes. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "clang/Basic/Stack.h" 16 #include "clang/Basic/TargetOptions.h" 17 #include "clang/CodeGen/ObjectFilePCHContainerOperations.h" 18 #include "clang/Config/config.h" 19 #include "clang/Driver/DriverDiagnostic.h" 20 #include "clang/Driver/Options.h" 21 #include "clang/Frontend/CompilerInstance.h" 22 #include "clang/Frontend/CompilerInvocation.h" 23 #include "clang/Frontend/FrontendDiagnostic.h" 24 #include "clang/Frontend/TextDiagnosticBuffer.h" 25 #include "clang/Frontend/TextDiagnosticPrinter.h" 26 #include "clang/Frontend/Utils.h" 27 #include "clang/FrontendTool/Utils.h" 28 #include "llvm/ADT/Statistic.h" 29 #include "llvm/Config/llvm-config.h" 30 #include "llvm/LinkAllPasses.h" 31 #include "llvm/MC/MCSubtargetInfo.h" 32 #include "llvm/MC/TargetRegistry.h" 33 #include "llvm/Option/Arg.h" 34 #include "llvm/Option/ArgList.h" 35 #include "llvm/Option/OptTable.h" 36 #include "llvm/Support/BuryPointer.h" 37 #include "llvm/Support/Compiler.h" 38 #include "llvm/Support/ErrorHandling.h" 39 #include "llvm/Support/ManagedStatic.h" 40 #include "llvm/Support/Path.h" 41 #include "llvm/Support/Process.h" 42 #include "llvm/Support/RISCVISAInfo.h" 43 #include "llvm/Support/Signals.h" 44 #include "llvm/Support/TargetSelect.h" 45 #include "llvm/Support/TimeProfiler.h" 46 #include "llvm/Support/Timer.h" 47 #include "llvm/Support/raw_ostream.h" 48 #include "llvm/Target/TargetMachine.h" 49 #include "llvm/TargetParser/AArch64TargetParser.h" 50 #include "llvm/TargetParser/ARMTargetParser.h" 51 #include <cstdio> 52 53 #ifdef CLANG_HAVE_RLIMITS 54 #include <sys/resource.h> 55 #endif 56 57 using namespace clang; 58 using namespace llvm::opt; 59 60 //===----------------------------------------------------------------------===// 61 // Main driver 62 //===----------------------------------------------------------------------===// 63 64 static void LLVMErrorHandler(void *UserData, const char *Message, 65 bool GenCrashDiag) { 66 DiagnosticsEngine &Diags = *static_cast<DiagnosticsEngine*>(UserData); 67 68 Diags.Report(diag::err_fe_error_backend) << Message; 69 70 // Run the interrupt handlers to make sure any special cleanups get done, in 71 // particular that we remove files registered with RemoveFileOnSignal. 72 llvm::sys::RunInterruptHandlers(); 73 74 // We cannot recover from llvm errors. When reporting a fatal error, exit 75 // with status 70 to generate crash diagnostics. For BSD systems this is 76 // defined as an internal software error. Otherwise, exit with status 1. 77 llvm::sys::Process::Exit(GenCrashDiag ? 70 : 1); 78 } 79 80 #ifdef CLANG_HAVE_RLIMITS 81 #if defined(__linux__) && defined(__PIE__) 82 static size_t getCurrentStackAllocation() { 83 // If we can't compute the current stack usage, allow for 512K of command 84 // line arguments and environment. 85 size_t Usage = 512 * 1024; 86 if (FILE *StatFile = fopen("/proc/self/stat", "r")) { 87 // We assume that the stack extends from its current address to the end of 88 // the environment space. In reality, there is another string literal (the 89 // program name) after the environment, but this is close enough (we only 90 // need to be within 100K or so). 91 unsigned long StackPtr, EnvEnd; 92 // Disable silly GCC -Wformat warning that complains about length 93 // modifiers on ignored format specifiers. We want to retain these 94 // for documentation purposes even though they have no effect. 95 #if defined(__GNUC__) && !defined(__clang__) 96 #pragma GCC diagnostic push 97 #pragma GCC diagnostic ignored "-Wformat" 98 #endif 99 if (fscanf(StatFile, 100 "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu %*lu " 101 "%*lu %*ld %*ld %*ld %*ld %*ld %*ld %*llu %*lu %*ld %*lu %*lu " 102 "%*lu %*lu %lu %*lu %*lu %*lu %*lu %*lu %*llu %*lu %*lu %*d %*d " 103 "%*u %*u %*llu %*lu %*ld %*lu %*lu %*lu %*lu %*lu %*lu %lu %*d", 104 &StackPtr, &EnvEnd) == 2) { 105 #if defined(__GNUC__) && !defined(__clang__) 106 #pragma GCC diagnostic pop 107 #endif 108 Usage = StackPtr < EnvEnd ? EnvEnd - StackPtr : StackPtr - EnvEnd; 109 } 110 fclose(StatFile); 111 } 112 return Usage; 113 } 114 115 #include <alloca.h> 116 117 LLVM_ATTRIBUTE_NOINLINE 118 static void ensureStackAddressSpace() { 119 // Linux kernels prior to 4.1 will sometimes locate the heap of a PIE binary 120 // relatively close to the stack (they are only guaranteed to be 128MiB 121 // apart). This results in crashes if we happen to heap-allocate more than 122 // 128MiB before we reach our stack high-water mark. 123 // 124 // To avoid these crashes, ensure that we have sufficient virtual memory 125 // pages allocated before we start running. 126 size_t Curr = getCurrentStackAllocation(); 127 const int kTargetStack = DesiredStackSize - 256 * 1024; 128 if (Curr < kTargetStack) { 129 volatile char *volatile Alloc = 130 static_cast<volatile char *>(alloca(kTargetStack - Curr)); 131 Alloc[0] = 0; 132 Alloc[kTargetStack - Curr - 1] = 0; 133 } 134 } 135 #else 136 static void ensureStackAddressSpace() {} 137 #endif 138 139 /// Attempt to ensure that we have at least 8MiB of usable stack space. 140 static void ensureSufficientStack() { 141 struct rlimit rlim; 142 if (getrlimit(RLIMIT_STACK, &rlim) != 0) 143 return; 144 145 // Increase the soft stack limit to our desired level, if necessary and 146 // possible. 147 if (rlim.rlim_cur != RLIM_INFINITY && 148 rlim.rlim_cur < rlim_t(DesiredStackSize)) { 149 // Try to allocate sufficient stack. 150 if (rlim.rlim_max == RLIM_INFINITY || 151 rlim.rlim_max >= rlim_t(DesiredStackSize)) 152 rlim.rlim_cur = DesiredStackSize; 153 else if (rlim.rlim_cur == rlim.rlim_max) 154 return; 155 else 156 rlim.rlim_cur = rlim.rlim_max; 157 158 if (setrlimit(RLIMIT_STACK, &rlim) != 0 || 159 rlim.rlim_cur != DesiredStackSize) 160 return; 161 } 162 163 // We should now have a stack of size at least DesiredStackSize. Ensure 164 // that we can actually use that much, if necessary. 165 ensureStackAddressSpace(); 166 } 167 #else 168 static void ensureSufficientStack() {} 169 #endif 170 171 /// Print supported cpus of the given target. 172 static int PrintSupportedCPUs(std::string TargetStr) { 173 std::string Error; 174 const llvm::Target *TheTarget = 175 llvm::TargetRegistry::lookupTarget(TargetStr, Error); 176 if (!TheTarget) { 177 llvm::errs() << Error; 178 return 1; 179 } 180 181 // the target machine will handle the mcpu printing 182 llvm::TargetOptions Options; 183 std::unique_ptr<llvm::TargetMachine> TheTargetMachine( 184 TheTarget->createTargetMachine(TargetStr, "", "+cpuhelp", Options, 185 std::nullopt)); 186 return 0; 187 } 188 189 static int PrintSupportedExtensions(std::string TargetStr) { 190 std::string Error; 191 const llvm::Target *TheTarget = 192 llvm::TargetRegistry::lookupTarget(TargetStr, Error); 193 if (!TheTarget) { 194 llvm::errs() << Error; 195 return 1; 196 } 197 198 llvm::TargetOptions Options; 199 std::unique_ptr<llvm::TargetMachine> TheTargetMachine( 200 TheTarget->createTargetMachine(TargetStr, "", "", Options, std::nullopt)); 201 const llvm::Triple &MachineTriple = TheTargetMachine->getTargetTriple(); 202 const llvm::MCSubtargetInfo *MCInfo = TheTargetMachine->getMCSubtargetInfo(); 203 const llvm::ArrayRef<llvm::SubtargetFeatureKV> Features = 204 MCInfo->getAllProcessorFeatures(); 205 206 llvm::StringMap<llvm::StringRef> DescMap; 207 for (const llvm::SubtargetFeatureKV &feature : Features) 208 DescMap.insert({feature.Key, feature.Desc}); 209 210 if (MachineTriple.isRISCV()) 211 llvm::riscvExtensionsHelp(DescMap); 212 else if (MachineTriple.isAArch64()) 213 llvm::AArch64::PrintSupportedExtensions(DescMap); 214 else if (MachineTriple.isARM()) 215 llvm::ARM::PrintSupportedExtensions(DescMap); 216 else { 217 // The option was already checked in Driver::HandleImmediateArgs, 218 // so we do not expect to get here if we are not a supported architecture. 219 assert(0 && "Unhandled triple for --print-supported-extensions option."); 220 return 1; 221 } 222 223 return 0; 224 } 225 226 int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) { 227 ensureSufficientStack(); 228 229 std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); 230 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 231 232 // Register the support for object-file-wrapped Clang modules. 233 auto PCHOps = Clang->getPCHContainerOperations(); 234 PCHOps->registerWriter(std::make_unique<ObjectFilePCHContainerWriter>()); 235 PCHOps->registerReader(std::make_unique<ObjectFilePCHContainerReader>()); 236 237 // Initialize targets first, so that --version shows registered targets. 238 llvm::InitializeAllTargets(); 239 llvm::InitializeAllTargetMCs(); 240 llvm::InitializeAllAsmPrinters(); 241 llvm::InitializeAllAsmParsers(); 242 243 // Buffer diagnostics from argument parsing so that we can output them using a 244 // well formed diagnostic object. 245 IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); 246 TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer; 247 DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer); 248 249 // Setup round-trip remarks for the DiagnosticsEngine used in CreateFromArgs. 250 if (find(Argv, StringRef("-Rround-trip-cc1-args")) != Argv.end()) 251 Diags.setSeverity(diag::remark_cc1_round_trip_generated, 252 diag::Severity::Remark, {}); 253 254 bool Success = CompilerInvocation::CreateFromArgs(Clang->getInvocation(), 255 Argv, Diags, Argv0); 256 257 if (!Clang->getFrontendOpts().TimeTracePath.empty()) { 258 llvm::timeTraceProfilerInitialize( 259 Clang->getFrontendOpts().TimeTraceGranularity, Argv0); 260 } 261 // --print-supported-cpus takes priority over the actual compilation. 262 if (Clang->getFrontendOpts().PrintSupportedCPUs) 263 return PrintSupportedCPUs(Clang->getTargetOpts().Triple); 264 265 // --print-supported-extensions takes priority over the actual compilation. 266 if (Clang->getFrontendOpts().PrintSupportedExtensions) 267 return PrintSupportedExtensions(Clang->getTargetOpts().Triple); 268 269 // Infer the builtin include path if unspecified. 270 if (Clang->getHeaderSearchOpts().UseBuiltinIncludes && 271 Clang->getHeaderSearchOpts().ResourceDir.empty()) 272 Clang->getHeaderSearchOpts().ResourceDir = 273 CompilerInvocation::GetResourcesPath(Argv0, MainAddr); 274 275 // Create the actual diagnostics engine. 276 Clang->createDiagnostics(); 277 if (!Clang->hasDiagnostics()) 278 return 1; 279 280 // Set an error handler, so that any LLVM backend diagnostics go through our 281 // error handler. 282 llvm::install_fatal_error_handler(LLVMErrorHandler, 283 static_cast<void*>(&Clang->getDiagnostics())); 284 285 DiagsBuffer->FlushDiagnostics(Clang->getDiagnostics()); 286 if (!Success) { 287 Clang->getDiagnosticClient().finish(); 288 return 1; 289 } 290 291 // Execute the frontend actions. 292 { 293 llvm::TimeTraceScope TimeScope("ExecuteCompiler"); 294 Success = ExecuteCompilerInvocation(Clang.get()); 295 } 296 297 // If any timers were active but haven't been destroyed yet, print their 298 // results now. This happens in -disable-free mode. 299 llvm::TimerGroup::printAll(llvm::errs()); 300 llvm::TimerGroup::clearAll(); 301 302 if (llvm::timeTraceProfilerEnabled()) { 303 // It is possible that the compiler instance doesn't own a file manager here 304 // if we're compiling a module unit. Since the file manager are owned by AST 305 // when we're compiling a module unit. So the file manager may be invalid 306 // here. 307 // 308 // It should be fine to create file manager here since the file system 309 // options are stored in the compiler invocation and we can recreate the VFS 310 // from the compiler invocation. 311 if (!Clang->hasFileManager()) 312 Clang->createFileManager(createVFSFromCompilerInvocation( 313 Clang->getInvocation(), Clang->getDiagnostics())); 314 315 if (auto profilerOutput = Clang->createOutputFile( 316 Clang->getFrontendOpts().TimeTracePath, /*Binary=*/false, 317 /*RemoveFileOnSignal=*/false, 318 /*useTemporary=*/false)) { 319 llvm::timeTraceProfilerWrite(*profilerOutput); 320 profilerOutput.reset(); 321 llvm::timeTraceProfilerCleanup(); 322 Clang->clearOutputFiles(false); 323 } 324 } 325 326 // Our error handler depends on the Diagnostics object, which we're 327 // potentially about to delete. Uninstall the handler now so that any 328 // later errors use the default handling behavior instead. 329 llvm::remove_fatal_error_handler(); 330 331 // When running with -disable-free, don't do any destruction or shutdown. 332 if (Clang->getFrontendOpts().DisableFree) { 333 llvm::BuryPointer(std::move(Clang)); 334 return !Success; 335 } 336 337 return !Success; 338 } 339