• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef INCLUDE_V8_INITIALIZATION_H_
6 #define INCLUDE_V8_INITIALIZATION_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include "v8-callbacks.h"  // NOLINT(build/include_directory)
12 #include "v8-internal.h"   // NOLINT(build/include_directory)
13 #include "v8-isolate.h"    // NOLINT(build/include_directory)
14 #include "v8-platform.h"   // NOLINT(build/include_directory)
15 #include "v8config.h"      // NOLINT(build/include_directory)
16 
17 // We reserve the V8_* prefix for macros defined in V8 public API and
18 // assume there are no name conflicts with the embedder's code.
19 
20 /**
21  * The v8 JavaScript engine.
22  */
23 namespace v8 {
24 
25 class PageAllocator;
26 class Platform;
27 template <class K, class V, class T>
28 class PersistentValueMapBase;
29 
30 /**
31  * EntropySource is used as a callback function when v8 needs a source
32  * of entropy.
33  */
34 using EntropySource = bool (*)(unsigned char* buffer, size_t length);
35 
36 /**
37  * ReturnAddressLocationResolver is used as a callback function when v8 is
38  * resolving the location of a return address on the stack. Profilers that
39  * change the return address on the stack can use this to resolve the stack
40  * location to wherever the profiler stashed the original return address.
41  *
42  * \param return_addr_location A location on stack where a machine
43  *    return address resides.
44  * \returns Either return_addr_location, or else a pointer to the profiler's
45  *    copy of the original return address.
46  *
47  * \note The resolver function must not cause garbage collection.
48  */
49 using ReturnAddressLocationResolver =
50     uintptr_t (*)(uintptr_t return_addr_location);
51 
52 using DcheckErrorCallback = void (*)(const char* file, int line,
53                                      const char* message);
54 
55 /**
56  * Container class for static utility functions.
57  */
58 class V8_EXPORT V8 {
59  public:
60   /**
61    * Hand startup data to V8, in case the embedder has chosen to build
62    * V8 with external startup data.
63    *
64    * Note:
65    * - By default the startup data is linked into the V8 library, in which
66    *   case this function is not meaningful.
67    * - If this needs to be called, it needs to be called before V8
68    *   tries to make use of its built-ins.
69    * - To avoid unnecessary copies of data, V8 will point directly into the
70    *   given data blob, so pretty please keep it around until V8 exit.
71    * - Compression of the startup blob might be useful, but needs to
72    *   handled entirely on the embedders' side.
73    * - The call will abort if the data is invalid.
74    */
75   static void SetSnapshotDataBlob(StartupData* startup_blob);
76 
77   /** Set the callback to invoke in case of Dcheck failures. */
78   static void SetDcheckErrorHandler(DcheckErrorCallback that);
79 
80   /**
81    * Sets V8 flags from a string.
82    */
83   static void SetFlagsFromString(const char* str);
84   static void SetFlagsFromString(const char* str, size_t length);
85 
86   /**
87    * Sets V8 flags from the command line.
88    */
89   static void SetFlagsFromCommandLine(int* argc, char** argv,
90                                       bool remove_flags);
91 
92   /** Get the version string. */
93   static const char* GetVersion();
94 
95   /**
96    * Initializes V8. This function needs to be called before the first Isolate
97    * is created. It always returns true.
98    */
Initialize()99   V8_INLINE static bool Initialize() {
100     const int kBuildConfiguration =
101         (internal::PointerCompressionIsEnabled() ? kPointerCompression : 0) |
102         (internal::SmiValuesAre31Bits() ? k31BitSmis : 0) |
103         (internal::SandboxedExternalPointersAreEnabled()
104              ? kSandboxedExternalPointers
105              : 0) |
106         (internal::SandboxIsEnabled() ? kSandbox : 0);
107     return Initialize(kBuildConfiguration);
108   }
109 
110   /**
111    * Allows the host application to provide a callback which can be used
112    * as a source of entropy for random number generators.
113    */
114   static void SetEntropySource(EntropySource source);
115 
116   /**
117    * Allows the host application to provide a callback that allows v8 to
118    * cooperate with a profiler that rewrites return addresses on stack.
119    */
120   static void SetReturnAddressLocationResolver(
121       ReturnAddressLocationResolver return_address_resolver);
122 
123   /**
124    * Releases any resources used by v8 and stops any utility threads
125    * that may be running.  Note that disposing v8 is permanent, it
126    * cannot be reinitialized.
127    *
128    * It should generally not be necessary to dispose v8 before exiting
129    * a process, this should happen automatically.  It is only necessary
130    * to use if the process needs the resources taken up by v8.
131    */
132   static bool Dispose();
133 
134   /**
135    * Initialize the ICU library bundled with V8. The embedder should only
136    * invoke this method when using the bundled ICU. Returns true on success.
137    *
138    * If V8 was compiled with the ICU data in an external file, the location
139    * of the data file has to be provided.
140    */
141   static bool InitializeICU(const char* icu_data_file = nullptr);
142 
143   /**
144    * Initialize the ICU library bundled with V8. The embedder should only
145    * invoke this method when using the bundled ICU. If V8 was compiled with
146    * the ICU data in an external file and when the default location of that
147    * file should be used, a path to the executable must be provided.
148    * Returns true on success.
149    *
150    * The default is a file called icudtl.dat side-by-side with the executable.
151    *
152    * Optionally, the location of the data file can be provided to override the
153    * default.
154    */
155   static bool InitializeICUDefaultLocation(const char* exec_path,
156                                            const char* icu_data_file = nullptr);
157 
158   /**
159    * Initialize the external startup data. The embedder only needs to
160    * invoke this method when external startup data was enabled in a build.
161    *
162    * If V8 was compiled with the startup data in an external file, then
163    * V8 needs to be given those external files during startup. There are
164    * three ways to do this:
165    * - InitializeExternalStartupData(const char*)
166    *   This will look in the given directory for the file "snapshot_blob.bin".
167    * - InitializeExternalStartupDataFromFile(const char*)
168    *   As above, but will directly use the given file name.
169    * - Call SetSnapshotDataBlob.
170    *   This will read the blobs from the given data structure and will
171    *   not perform any file IO.
172    */
173   static void InitializeExternalStartupData(const char* directory_path);
174   static void InitializeExternalStartupDataFromFile(const char* snapshot_blob);
175 
176   /**
177    * Sets the v8::Platform to use. This should be invoked before V8 is
178    * initialized.
179    */
180   static void InitializePlatform(Platform* platform);
181 
182   /**
183    * Clears all references to the v8::Platform. This should be invoked after
184    * V8 was disposed.
185    */
186   static void DisposePlatform();
187   V8_DEPRECATED("Use DisposePlatform()")
ShutdownPlatform()188   static void ShutdownPlatform() { DisposePlatform(); }
189 
190 #ifdef V8_SANDBOX
191   //
192   // Sandbox related API.
193   //
194   // This API is not yet stable and subject to changes in the future.
195   //
196 
197   /**
198    * Initializes the V8 sandbox.
199    *
200    * This must be invoked after the platform was initialized but before V8 is
201    * initialized. The sandbox is torn down during platform shutdown.
202    * Returns true on success, false otherwise.
203    *
204    * TODO(saelo) Once it is no longer optional to initialize the sandbox when
205    * compiling with V8_SANDBOX, the sandbox initialization will likely happen
206    * as part of V8::Initialize, at which point this function should be removed.
207    */
208   static bool InitializeSandbox();
209   V8_DEPRECATE_SOON("Use InitializeSandbox()")
InitializeVirtualMemoryCage()210   static bool InitializeVirtualMemoryCage() { return InitializeSandbox(); }
211 
212   /**
213    * Provides access to the virtual address subspace backing the sandbox.
214    *
215    * This can be used to allocate pages inside the sandbox, for example to
216    * obtain virtual memory for ArrayBuffer backing stores, which must be
217    * located inside the sandbox.
218    *
219    * It should be assumed that an attacker can corrupt data inside the sandbox,
220    * and so in particular the contents of pages allocagted in this virtual
221    * address space, arbitrarily and concurrently. Due to this, it is
222    * recommended to to only place pure data buffers in them.
223    *
224    * This function must only be called after initializing the sandbox.
225    */
226   static VirtualAddressSpace* GetSandboxAddressSpace();
227   V8_DEPRECATE_SOON("Use GetSandboxAddressSpace()")
228   static PageAllocator* GetVirtualMemoryCagePageAllocator();
229 
230   /**
231    * Returns the size of the sandbox in bytes.
232    *
233    * If the sandbox has not been initialized, or if the initialization failed,
234    * this returns zero.
235    */
236   static size_t GetSandboxSizeInBytes();
237   V8_DEPRECATE_SOON("Use GetSandboxSizeInBytes()")
GetVirtualMemoryCageSizeInBytes()238   static size_t GetVirtualMemoryCageSizeInBytes() {
239     return GetSandboxSizeInBytes();
240   }
241 
242   /**
243    * Returns whether the sandbox is configured securely.
244    *
245    * If V8 cannot create a proper sandbox, it will fall back to creating a
246    * sandbox that doesn't have the desired security properties but at least
247    * still allows V8 to function. This API can be used to determine if such an
248    * insecure sandbox is being used, in which case it will return false.
249    */
250   static bool IsSandboxConfiguredSecurely();
251   V8_DEPRECATE_SOON("Use IsSandboxConfiguredSecurely()")
IsUsingSecureVirtualMemoryCage()252   static bool IsUsingSecureVirtualMemoryCage() {
253     return IsSandboxConfiguredSecurely();
254   }
255 #endif
256 
257   /**
258    * Activate trap-based bounds checking for WebAssembly.
259    *
260    * \param use_v8_signal_handler Whether V8 should install its own signal
261    * handler or rely on the embedder's.
262    */
263   static bool EnableWebAssemblyTrapHandler(bool use_v8_signal_handler);
264 
265 #if defined(V8_OS_WIN)
266   /**
267    * On Win64, by default V8 does not emit unwinding data for jitted code,
268    * which means the OS cannot walk the stack frames and the system Structured
269    * Exception Handling (SEH) cannot unwind through V8-generated code:
270    * https://code.google.com/p/v8/issues/detail?id=3598.
271    *
272    * This function allows embedders to register a custom exception handler for
273    * exceptions in V8-generated code.
274    */
275   static void SetUnhandledExceptionCallback(
276       UnhandledExceptionCallback unhandled_exception_callback);
277 #endif
278 
279   /**
280    * Allows the host application to provide a callback that will be called when
281    * v8 has encountered a fatal failure to allocate memory and is about to
282    * terminate.
283    */
284 
285   static void SetFatalMemoryErrorCallback(OOMErrorCallback oom_error_callback);
286 
287   /**
288    * Get statistics about the shared memory usage.
289    */
290   static void GetSharedMemoryStatistics(SharedMemoryStatistics* statistics);
291 
292  private:
293   V8();
294 
295   enum BuildConfigurationFeatures {
296     kPointerCompression = 1 << 0,
297     k31BitSmis = 1 << 1,
298     kSandboxedExternalPointers = 1 << 2,
299     kSandbox = 1 << 3,
300   };
301 
302   /**
303    * Checks that the embedder build configuration is compatible with
304    * the V8 binary and if so initializes V8.
305    */
306   static bool Initialize(int build_config);
307 
308   friend class Context;
309   template <class K, class V, class T>
310   friend class PersistentValueMapBase;
311 };
312 
313 }  // namespace v8
314 
315 #endif  // INCLUDE_V8_INITIALIZATION_H_
316