brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.5 KiB · b90f4e0 Raw
142 lines · cpp
1//===-- InitLLVM.cpp -----------------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/Support/InitLLVM.h"10#include "llvm/ADT/StringRef.h"11#include "llvm/Support/AutoConvert.h"12#include "llvm/Support/Error.h"13#include "llvm/Support/ErrorHandling.h"14#include "llvm/Support/ManagedStatic.h"15#include "llvm/Support/Signals.h"16 17#ifdef _WIN3218#include "llvm/Support/Windows/WindowsSupport.h"19#endif20 21#if defined(HAVE_UNISTD_H)22#include <unistd.h>23#else24#ifndef STDIN_FILENO25#define STDIN_FILENO 026#endif27#ifndef STDOUT_FILENO28#define STDOUT_FILENO 129#endif30#ifndef STDERR_FILENO31#define STDERR_FILENO 232#endif33#endif34 35static void RaiseLimits() {36#ifdef _AIX37  // AIX has restrictive memory soft-limits out-of-box, so raise them if needed.38  auto RaiseLimit = [](int resource) {39    struct rlimit r;40    getrlimit(resource, &r);41 42    // Increase the soft limit to the hard limit, if necessary and43    // possible.44    if (r.rlim_cur != RLIM_INFINITY && r.rlim_cur != r.rlim_max) {45      r.rlim_cur = r.rlim_max;46      setrlimit(resource, &r);47    }48  };49 50  // Address space size.51  RaiseLimit(RLIMIT_AS);52  // Heap size.53  RaiseLimit(RLIMIT_DATA);54  // Stack size.55  RaiseLimit(RLIMIT_STACK);56#ifdef RLIMIT_RSS57  // Resident set size.58  RaiseLimit(RLIMIT_RSS);59#endif60#endif61}62 63void CleanupStdHandles(void *Cookie) {64  llvm::raw_ostream *Outs = &llvm::outs(), *Errs = &llvm::errs();65  Outs->flush();66  Errs->flush();67  llvm::restoreStdHandleAutoConversion(STDIN_FILENO);68  llvm::restoreStdHandleAutoConversion(STDOUT_FILENO);69  llvm::restoreStdHandleAutoConversion(STDERR_FILENO);70}71 72using namespace llvm;73using namespace llvm::sys;74 75InitLLVM::InitLLVM(int &Argc, const char **&Argv,76                   bool InstallPipeSignalExitHandler) {77#ifndef NDEBUG78  static std::atomic<bool> Initialized{false};79  assert(!Initialized && "InitLLVM was already initialized!");80  Initialized = true;81#endif82 83  // Bring stdin/stdout/stderr into a known state.84  sys::AddSignalHandler(CleanupStdHandles, nullptr);85 86  if (InstallPipeSignalExitHandler)87    // The pipe signal handler must be installed before any other handlers are88    // registered. This is because the Unix \ref RegisterHandlers function does89    // not perform a sigaction() for SIGPIPE unless a one-shot handler is90    // present, to allow long-lived processes (like lldb) to fully opt-out of91    // llvm's SIGPIPE handling and ignore the signal safely.92    sys::SetOneShotPipeSignalFunction(sys::DefaultOneShotPipeSignalHandler);93  // Initialize the stack printer after installing the one-shot pipe signal94  // handler, so we can perform a sigaction() for SIGPIPE on Unix if requested.95  StackPrinter.emplace(Argc, Argv);96  sys::PrintStackTraceOnErrorSignal(Argv[0]);97  install_out_of_memory_new_handler();98  RaiseLimits();99 100#ifdef __MVS__101 102  // We use UTF-8 as the internal character encoding. On z/OS, all external103  // output is encoded in EBCDIC. In order to be able to read all104  // error messages, we turn conversion to EBCDIC on for stderr fd.105  std::string Banner = std::string(Argv[0]) + ": ";106  ExitOnError ExitOnErr(Banner);107 108  // If turning on conversion for stderr fails then the error message109  // may be garbled. There is no solution to this problem.110  ExitOnErr(errorCodeToError(llvm::enableAutoConversion(STDERR_FILENO)));111  ExitOnErr(errorCodeToError(llvm::enableAutoConversion(STDOUT_FILENO)));112#endif113 114#ifdef _WIN32115  // We use UTF-8 as the internal character encoding. On Windows,116  // arguments passed to main() may not be encoded in UTF-8. In order117  // to reliably detect encoding of command line arguments, we use an118  // Windows API to obtain arguments, convert them to UTF-8, and then119  // write them back to the Argv vector.120  //121  // There's probably other way to do the same thing (e.g. using122  // wmain() instead of main()), but this way seems less intrusive123  // than that.124  std::string Banner = std::string(Argv[0]) + ": ";125  ExitOnError ExitOnErr(Banner);126 127  ExitOnErr(errorCodeToError(windows::GetCommandLineArguments(Args, Alloc)));128 129  // GetCommandLineArguments doesn't terminate the vector with a130  // nullptr.  Do it to make it compatible with the real argv.131  Args.push_back(nullptr);132 133  Argc = Args.size() - 1;134  Argv = Args.data();135#endif136}137 138InitLLVM::~InitLLVM() {139  CleanupStdHandles(nullptr);140  llvm_shutdown();141}142