11cb0ef41Sopenharmony_ci// Copyright 2021 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef INCLUDE_V8_INITIALIZATION_H_ 61cb0ef41Sopenharmony_ci#define INCLUDE_V8_INITIALIZATION_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <stddef.h> 91cb0ef41Sopenharmony_ci#include <stdint.h> 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci#include "v8-callbacks.h" // NOLINT(build/include_directory) 121cb0ef41Sopenharmony_ci#include "v8-internal.h" // NOLINT(build/include_directory) 131cb0ef41Sopenharmony_ci#include "v8-isolate.h" // NOLINT(build/include_directory) 141cb0ef41Sopenharmony_ci#include "v8-platform.h" // NOLINT(build/include_directory) 151cb0ef41Sopenharmony_ci#include "v8config.h" // NOLINT(build/include_directory) 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ci// We reserve the V8_* prefix for macros defined in V8 public API and 181cb0ef41Sopenharmony_ci// assume there are no name conflicts with the embedder's code. 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ci/** 211cb0ef41Sopenharmony_ci * The v8 JavaScript engine. 221cb0ef41Sopenharmony_ci */ 231cb0ef41Sopenharmony_cinamespace v8 { 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ciclass PageAllocator; 261cb0ef41Sopenharmony_ciclass Platform; 271cb0ef41Sopenharmony_citemplate <class K, class V, class T> 281cb0ef41Sopenharmony_ciclass PersistentValueMapBase; 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ci/** 311cb0ef41Sopenharmony_ci * EntropySource is used as a callback function when v8 needs a source 321cb0ef41Sopenharmony_ci * of entropy. 331cb0ef41Sopenharmony_ci */ 341cb0ef41Sopenharmony_ciusing EntropySource = bool (*)(unsigned char* buffer, size_t length); 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci/** 371cb0ef41Sopenharmony_ci * ReturnAddressLocationResolver is used as a callback function when v8 is 381cb0ef41Sopenharmony_ci * resolving the location of a return address on the stack. Profilers that 391cb0ef41Sopenharmony_ci * change the return address on the stack can use this to resolve the stack 401cb0ef41Sopenharmony_ci * location to wherever the profiler stashed the original return address. 411cb0ef41Sopenharmony_ci * 421cb0ef41Sopenharmony_ci * \param return_addr_location A location on stack where a machine 431cb0ef41Sopenharmony_ci * return address resides. 441cb0ef41Sopenharmony_ci * \returns Either return_addr_location, or else a pointer to the profiler's 451cb0ef41Sopenharmony_ci * copy of the original return address. 461cb0ef41Sopenharmony_ci * 471cb0ef41Sopenharmony_ci * \note The resolver function must not cause garbage collection. 481cb0ef41Sopenharmony_ci */ 491cb0ef41Sopenharmony_ciusing ReturnAddressLocationResolver = 501cb0ef41Sopenharmony_ci uintptr_t (*)(uintptr_t return_addr_location); 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ciusing DcheckErrorCallback = void (*)(const char* file, int line, 531cb0ef41Sopenharmony_ci const char* message); 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci/** 561cb0ef41Sopenharmony_ci * Container class for static utility functions. 571cb0ef41Sopenharmony_ci */ 581cb0ef41Sopenharmony_ciclass V8_EXPORT V8 { 591cb0ef41Sopenharmony_ci public: 601cb0ef41Sopenharmony_ci /** 611cb0ef41Sopenharmony_ci * Hand startup data to V8, in case the embedder has chosen to build 621cb0ef41Sopenharmony_ci * V8 with external startup data. 631cb0ef41Sopenharmony_ci * 641cb0ef41Sopenharmony_ci * Note: 651cb0ef41Sopenharmony_ci * - By default the startup data is linked into the V8 library, in which 661cb0ef41Sopenharmony_ci * case this function is not meaningful. 671cb0ef41Sopenharmony_ci * - If this needs to be called, it needs to be called before V8 681cb0ef41Sopenharmony_ci * tries to make use of its built-ins. 691cb0ef41Sopenharmony_ci * - To avoid unnecessary copies of data, V8 will point directly into the 701cb0ef41Sopenharmony_ci * given data blob, so pretty please keep it around until V8 exit. 711cb0ef41Sopenharmony_ci * - Compression of the startup blob might be useful, but needs to 721cb0ef41Sopenharmony_ci * handled entirely on the embedders' side. 731cb0ef41Sopenharmony_ci * - The call will abort if the data is invalid. 741cb0ef41Sopenharmony_ci */ 751cb0ef41Sopenharmony_ci static void SetSnapshotDataBlob(StartupData* startup_blob); 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci /** Set the callback to invoke in case of Dcheck failures. */ 781cb0ef41Sopenharmony_ci static void SetDcheckErrorHandler(DcheckErrorCallback that); 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci /** 811cb0ef41Sopenharmony_ci * Sets V8 flags from a string. 821cb0ef41Sopenharmony_ci */ 831cb0ef41Sopenharmony_ci static void SetFlagsFromString(const char* str); 841cb0ef41Sopenharmony_ci static void SetFlagsFromString(const char* str, size_t length); 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci /** 871cb0ef41Sopenharmony_ci * Sets V8 flags from the command line. 881cb0ef41Sopenharmony_ci */ 891cb0ef41Sopenharmony_ci static void SetFlagsFromCommandLine(int* argc, char** argv, 901cb0ef41Sopenharmony_ci bool remove_flags); 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci /** Get the version string. */ 931cb0ef41Sopenharmony_ci static const char* GetVersion(); 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci /** 961cb0ef41Sopenharmony_ci * Initializes V8. This function needs to be called before the first Isolate 971cb0ef41Sopenharmony_ci * is created. It always returns true. 981cb0ef41Sopenharmony_ci */ 991cb0ef41Sopenharmony_ci V8_INLINE static bool Initialize() { 1001cb0ef41Sopenharmony_ci const int kBuildConfiguration = 1011cb0ef41Sopenharmony_ci (internal::PointerCompressionIsEnabled() ? kPointerCompression : 0) | 1021cb0ef41Sopenharmony_ci (internal::SmiValuesAre31Bits() ? k31BitSmis : 0) | 1031cb0ef41Sopenharmony_ci (internal::SandboxIsEnabled() ? kSandbox : 0); 1041cb0ef41Sopenharmony_ci return Initialize(kBuildConfiguration); 1051cb0ef41Sopenharmony_ci } 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci /** 1081cb0ef41Sopenharmony_ci * Allows the host application to provide a callback which can be used 1091cb0ef41Sopenharmony_ci * as a source of entropy for random number generators. 1101cb0ef41Sopenharmony_ci */ 1111cb0ef41Sopenharmony_ci static void SetEntropySource(EntropySource source); 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci /** 1141cb0ef41Sopenharmony_ci * Allows the host application to provide a callback that allows v8 to 1151cb0ef41Sopenharmony_ci * cooperate with a profiler that rewrites return addresses on stack. 1161cb0ef41Sopenharmony_ci */ 1171cb0ef41Sopenharmony_ci static void SetReturnAddressLocationResolver( 1181cb0ef41Sopenharmony_ci ReturnAddressLocationResolver return_address_resolver); 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci /** 1211cb0ef41Sopenharmony_ci * Releases any resources used by v8 and stops any utility threads 1221cb0ef41Sopenharmony_ci * that may be running. Note that disposing v8 is permanent, it 1231cb0ef41Sopenharmony_ci * cannot be reinitialized. 1241cb0ef41Sopenharmony_ci * 1251cb0ef41Sopenharmony_ci * It should generally not be necessary to dispose v8 before exiting 1261cb0ef41Sopenharmony_ci * a process, this should happen automatically. It is only necessary 1271cb0ef41Sopenharmony_ci * to use if the process needs the resources taken up by v8. 1281cb0ef41Sopenharmony_ci */ 1291cb0ef41Sopenharmony_ci static bool Dispose(); 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci /** 1321cb0ef41Sopenharmony_ci * Initialize the ICU library bundled with V8. The embedder should only 1331cb0ef41Sopenharmony_ci * invoke this method when using the bundled ICU. Returns true on success. 1341cb0ef41Sopenharmony_ci * 1351cb0ef41Sopenharmony_ci * If V8 was compiled with the ICU data in an external file, the location 1361cb0ef41Sopenharmony_ci * of the data file has to be provided. 1371cb0ef41Sopenharmony_ci */ 1381cb0ef41Sopenharmony_ci static bool InitializeICU(const char* icu_data_file = nullptr); 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci /** 1411cb0ef41Sopenharmony_ci * Initialize the ICU library bundled with V8. The embedder should only 1421cb0ef41Sopenharmony_ci * invoke this method when using the bundled ICU. If V8 was compiled with 1431cb0ef41Sopenharmony_ci * the ICU data in an external file and when the default location of that 1441cb0ef41Sopenharmony_ci * file should be used, a path to the executable must be provided. 1451cb0ef41Sopenharmony_ci * Returns true on success. 1461cb0ef41Sopenharmony_ci * 1471cb0ef41Sopenharmony_ci * The default is a file called icudtl.dat side-by-side with the executable. 1481cb0ef41Sopenharmony_ci * 1491cb0ef41Sopenharmony_ci * Optionally, the location of the data file can be provided to override the 1501cb0ef41Sopenharmony_ci * default. 1511cb0ef41Sopenharmony_ci */ 1521cb0ef41Sopenharmony_ci static bool InitializeICUDefaultLocation(const char* exec_path, 1531cb0ef41Sopenharmony_ci const char* icu_data_file = nullptr); 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci /** 1561cb0ef41Sopenharmony_ci * Initialize the external startup data. The embedder only needs to 1571cb0ef41Sopenharmony_ci * invoke this method when external startup data was enabled in a build. 1581cb0ef41Sopenharmony_ci * 1591cb0ef41Sopenharmony_ci * If V8 was compiled with the startup data in an external file, then 1601cb0ef41Sopenharmony_ci * V8 needs to be given those external files during startup. There are 1611cb0ef41Sopenharmony_ci * three ways to do this: 1621cb0ef41Sopenharmony_ci * - InitializeExternalStartupData(const char*) 1631cb0ef41Sopenharmony_ci * This will look in the given directory for the file "snapshot_blob.bin". 1641cb0ef41Sopenharmony_ci * - InitializeExternalStartupDataFromFile(const char*) 1651cb0ef41Sopenharmony_ci * As above, but will directly use the given file name. 1661cb0ef41Sopenharmony_ci * - Call SetSnapshotDataBlob. 1671cb0ef41Sopenharmony_ci * This will read the blobs from the given data structure and will 1681cb0ef41Sopenharmony_ci * not perform any file IO. 1691cb0ef41Sopenharmony_ci */ 1701cb0ef41Sopenharmony_ci static void InitializeExternalStartupData(const char* directory_path); 1711cb0ef41Sopenharmony_ci static void InitializeExternalStartupDataFromFile(const char* snapshot_blob); 1721cb0ef41Sopenharmony_ci 1731cb0ef41Sopenharmony_ci /** 1741cb0ef41Sopenharmony_ci * Sets the v8::Platform to use. This should be invoked before V8 is 1751cb0ef41Sopenharmony_ci * initialized. 1761cb0ef41Sopenharmony_ci */ 1771cb0ef41Sopenharmony_ci static void InitializePlatform(Platform* platform); 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_ci /** 1801cb0ef41Sopenharmony_ci * Clears all references to the v8::Platform. This should be invoked after 1811cb0ef41Sopenharmony_ci * V8 was disposed. 1821cb0ef41Sopenharmony_ci */ 1831cb0ef41Sopenharmony_ci static void DisposePlatform(); 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ci#if defined(V8_ENABLE_SANDBOX) 1861cb0ef41Sopenharmony_ci /** 1871cb0ef41Sopenharmony_ci * Returns true if the sandbox is configured securely. 1881cb0ef41Sopenharmony_ci * 1891cb0ef41Sopenharmony_ci * If V8 cannot create a regular sandbox during initialization, for example 1901cb0ef41Sopenharmony_ci * because not enough virtual address space can be reserved, it will instead 1911cb0ef41Sopenharmony_ci * create a fallback sandbox that still allows it to function normally but 1921cb0ef41Sopenharmony_ci * does not have the same security properties as a regular sandbox. This API 1931cb0ef41Sopenharmony_ci * can be used to determine if such a fallback sandbox is being used, in 1941cb0ef41Sopenharmony_ci * which case it will return false. 1951cb0ef41Sopenharmony_ci */ 1961cb0ef41Sopenharmony_ci static bool IsSandboxConfiguredSecurely(); 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ci /** 1991cb0ef41Sopenharmony_ci * Provides access to the virtual address subspace backing the sandbox. 2001cb0ef41Sopenharmony_ci * 2011cb0ef41Sopenharmony_ci * This can be used to allocate pages inside the sandbox, for example to 2021cb0ef41Sopenharmony_ci * obtain virtual memory for ArrayBuffer backing stores, which must be 2031cb0ef41Sopenharmony_ci * located inside the sandbox. 2041cb0ef41Sopenharmony_ci * 2051cb0ef41Sopenharmony_ci * It should be assumed that an attacker can corrupt data inside the sandbox, 2061cb0ef41Sopenharmony_ci * and so in particular the contents of pages allocagted in this virtual 2071cb0ef41Sopenharmony_ci * address space, arbitrarily and concurrently. Due to this, it is 2081cb0ef41Sopenharmony_ci * recommended to to only place pure data buffers in them. 2091cb0ef41Sopenharmony_ci */ 2101cb0ef41Sopenharmony_ci static VirtualAddressSpace* GetSandboxAddressSpace(); 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_ci /** 2131cb0ef41Sopenharmony_ci * Returns the size of the sandbox in bytes. 2141cb0ef41Sopenharmony_ci * 2151cb0ef41Sopenharmony_ci * This represents the size of the address space that V8 can directly address 2161cb0ef41Sopenharmony_ci * and in which it allocates its objects. 2171cb0ef41Sopenharmony_ci */ 2181cb0ef41Sopenharmony_ci static size_t GetSandboxSizeInBytes(); 2191cb0ef41Sopenharmony_ci 2201cb0ef41Sopenharmony_ci /** 2211cb0ef41Sopenharmony_ci * Returns the size of the address space reservation backing the sandbox. 2221cb0ef41Sopenharmony_ci * 2231cb0ef41Sopenharmony_ci * This may be larger than the sandbox (i.e. |GetSandboxSizeInBytes()|) due 2241cb0ef41Sopenharmony_ci * to surrounding guard regions, or may be smaller than the sandbox in case a 2251cb0ef41Sopenharmony_ci * fallback sandbox is being used, which will use a smaller virtual address 2261cb0ef41Sopenharmony_ci * space reservation. In the latter case this will also be different from 2271cb0ef41Sopenharmony_ci * |GetSandboxAddressSpace()->size()| as that will cover a larger part of the 2281cb0ef41Sopenharmony_ci * address space than what has actually been reserved. 2291cb0ef41Sopenharmony_ci */ 2301cb0ef41Sopenharmony_ci static size_t GetSandboxReservationSizeInBytes(); 2311cb0ef41Sopenharmony_ci#endif // V8_ENABLE_SANDBOX 2321cb0ef41Sopenharmony_ci 2331cb0ef41Sopenharmony_ci /** 2341cb0ef41Sopenharmony_ci * Activate trap-based bounds checking for WebAssembly. 2351cb0ef41Sopenharmony_ci * 2361cb0ef41Sopenharmony_ci * \param use_v8_signal_handler Whether V8 should install its own signal 2371cb0ef41Sopenharmony_ci * handler or rely on the embedder's. 2381cb0ef41Sopenharmony_ci */ 2391cb0ef41Sopenharmony_ci static bool EnableWebAssemblyTrapHandler(bool use_v8_signal_handler); 2401cb0ef41Sopenharmony_ci 2411cb0ef41Sopenharmony_ci#if defined(V8_OS_WIN) 2421cb0ef41Sopenharmony_ci /** 2431cb0ef41Sopenharmony_ci * On Win64, by default V8 does not emit unwinding data for jitted code, 2441cb0ef41Sopenharmony_ci * which means the OS cannot walk the stack frames and the system Structured 2451cb0ef41Sopenharmony_ci * Exception Handling (SEH) cannot unwind through V8-generated code: 2461cb0ef41Sopenharmony_ci * https://code.google.com/p/v8/issues/detail?id=3598. 2471cb0ef41Sopenharmony_ci * 2481cb0ef41Sopenharmony_ci * This function allows embedders to register a custom exception handler for 2491cb0ef41Sopenharmony_ci * exceptions in V8-generated code. 2501cb0ef41Sopenharmony_ci */ 2511cb0ef41Sopenharmony_ci static void SetUnhandledExceptionCallback( 2521cb0ef41Sopenharmony_ci UnhandledExceptionCallback callback); 2531cb0ef41Sopenharmony_ci#endif 2541cb0ef41Sopenharmony_ci 2551cb0ef41Sopenharmony_ci /** 2561cb0ef41Sopenharmony_ci * Allows the host application to provide a callback that will be called when 2571cb0ef41Sopenharmony_ci * v8 has encountered a fatal failure to allocate memory and is about to 2581cb0ef41Sopenharmony_ci * terminate. 2591cb0ef41Sopenharmony_ci */ 2601cb0ef41Sopenharmony_ci static void SetFatalMemoryErrorCallback(OOMErrorCallback callback); 2611cb0ef41Sopenharmony_ci 2621cb0ef41Sopenharmony_ci /** 2631cb0ef41Sopenharmony_ci * Get statistics about the shared memory usage. 2641cb0ef41Sopenharmony_ci */ 2651cb0ef41Sopenharmony_ci static void GetSharedMemoryStatistics(SharedMemoryStatistics* statistics); 2661cb0ef41Sopenharmony_ci 2671cb0ef41Sopenharmony_ci private: 2681cb0ef41Sopenharmony_ci V8(); 2691cb0ef41Sopenharmony_ci 2701cb0ef41Sopenharmony_ci enum BuildConfigurationFeatures { 2711cb0ef41Sopenharmony_ci kPointerCompression = 1 << 0, 2721cb0ef41Sopenharmony_ci k31BitSmis = 1 << 1, 2731cb0ef41Sopenharmony_ci kSandbox = 1 << 2, 2741cb0ef41Sopenharmony_ci }; 2751cb0ef41Sopenharmony_ci 2761cb0ef41Sopenharmony_ci /** 2771cb0ef41Sopenharmony_ci * Checks that the embedder build configuration is compatible with 2781cb0ef41Sopenharmony_ci * the V8 binary and if so initializes V8. 2791cb0ef41Sopenharmony_ci */ 2801cb0ef41Sopenharmony_ci static bool Initialize(int build_config); 2811cb0ef41Sopenharmony_ci 2821cb0ef41Sopenharmony_ci friend class Context; 2831cb0ef41Sopenharmony_ci template <class K, class V, class T> 2841cb0ef41Sopenharmony_ci friend class PersistentValueMapBase; 2851cb0ef41Sopenharmony_ci}; 2861cb0ef41Sopenharmony_ci 2871cb0ef41Sopenharmony_ci} // namespace v8 2881cb0ef41Sopenharmony_ci 2891cb0ef41Sopenharmony_ci#endif // INCLUDE_V8_INITIALIZATION_H_ 290