• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium 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 #include "mojo/public/c/system/thunks.h"
6 
7 #include <cstddef>
8 #include <cstdint>
9 #include <cstring>
10 
11 #include "base/logging.h"
12 #include "base/macros.h"
13 #include "base/memory/protected_memory.h"
14 #include "base/memory/protected_memory_cfi.h"
15 #include "base/no_destructor.h"
16 #include "build/build_config.h"
17 #include "mojo/public/c/system/core.h"
18 
19 #if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_WIN)
20 #include "base/environment.h"
21 #include "base/files/file_path.h"
22 #include "base/optional.h"
23 #include "base/scoped_native_library.h"
24 #include "base/threading/thread_restrictions.h"
25 #endif
26 
27 namespace {
28 
29 typedef void (*MojoGetSystemThunksFunction)(MojoSystemThunks* thunks);
30 
31 #if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_WIN)
32 PROTECTED_MEMORY_SECTION
33 base::ProtectedMemory<MojoGetSystemThunksFunction> g_get_thunks;
34 #endif
35 
36 PROTECTED_MEMORY_SECTION base::ProtectedMemory<MojoSystemThunks> g_thunks;
37 
NotImplemented(const char * name)38 MojoResult NotImplemented(const char* name) {
39   DLOG(ERROR) << "Function 'Mojo" << name
40               << "()' not supported in this version of Mojo Core.";
41   return MOJO_RESULT_UNIMPLEMENTED;
42 }
43 
44 }  // namespace
45 
46 // Macro to verify that the thunk symbol |name| is actually present in the
47 // runtime version of Mojo Core that is currently in use.
48 #define FUNCTION_IS_IMPLEMENTED(name)                                       \
49   (reinterpret_cast<uintptr_t>(static_cast<const void*>(&g_thunks->name)) - \
50        reinterpret_cast<uintptr_t>(static_cast<const void*>(&g_thunks)) <   \
51    g_thunks->size)
52 
53 #define INVOKE_THUNK(name, ...)                                              \
54   FUNCTION_IS_IMPLEMENTED(name)                                              \
55   ? base::UnsanitizedCfiCall(g_thunks, &MojoSystemThunks::name)(__VA_ARGS__) \
56   : NotImplemented(#name)
57 
58 namespace mojo {
59 
60 // NOTE: This is defined within the global mojo namespace so that it can be
61 // referenced as a friend to base::ScopedAllowBlocking when library support is
62 // enabled.
63 class CoreLibraryInitializer {
64  public:
CoreLibraryInitializer(const MojoInitializeOptions * options)65   CoreLibraryInitializer(const MojoInitializeOptions* options) {
66 #if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_WIN)
67     bool application_provided_path = false;
68     base::Optional<base::FilePath> library_path;
69     if (options && options->struct_size >= sizeof(*options) &&
70         options->mojo_core_path) {
71       base::StringPiece utf8_path(options->mojo_core_path,
72                                   options->mojo_core_path_length);
73       library_path.emplace(base::FilePath::FromUTF8Unsafe(utf8_path));
74       application_provided_path = true;
75     } else {
76       auto environment = base::Environment::Create();
77       std::string library_path_value;
78       const char kLibraryPathEnvironmentVar[] = "MOJO_CORE_LIBRARY_PATH";
79       if (environment->GetVar(kLibraryPathEnvironmentVar, &library_path_value))
80         library_path = base::FilePath::FromUTF8Unsafe(library_path_value);
81     }
82 
83     if (!library_path) {
84       // Default to looking for the library in the current working directory.
85 #if defined(OS_CHROMEOS) || defined(OS_LINUX)
86       const base::FilePath::CharType kDefaultLibraryPathValue[] =
87           FILE_PATH_LITERAL("./libmojo_core.so");
88 #elif defined(OS_WIN)
89       const base::FilePath::CharType kDefaultLibraryPathValue[] =
90           FILE_PATH_LITERAL("mojo_core.dll");
91 #endif
92       library_path.emplace(kDefaultLibraryPathValue);
93     }
94 
95     base::ScopedAllowBlocking allow_blocking;
96     library_.emplace(*library_path);
97     if (!application_provided_path) {
98       CHECK(library_->is_valid())
99           << "Unable to load the mojo_core library. Make sure the library is "
100           << "in the working directory or is correctly pointed to by the "
101           << "MOJO_CORE_LIBRARY_PATH environment variable.";
102     } else {
103       CHECK(library_->is_valid())
104           << "Unable to locate mojo_core library. This application expects to "
105           << "find it at " << library_path->value();
106     }
107 
108     const char kGetThunksFunctionName[] = "MojoGetSystemThunks";
109     {
110       auto writer = base::AutoWritableMemory::Create(g_get_thunks);
111       *g_get_thunks = reinterpret_cast<MojoGetSystemThunksFunction>(
112           library_->GetFunctionPointer(kGetThunksFunctionName));
113     }
114     CHECK(*g_get_thunks) << "Invalid mojo_core library: "
115                          << library_path->value();
116 
117     DCHECK_EQ(g_thunks->size, 0u);
118     {
119       auto writer = base::AutoWritableMemory::Create(g_thunks);
120       g_thunks->size = sizeof(*g_thunks);
121       base::UnsanitizedCfiCall(g_get_thunks)(&*g_thunks);
122     }
123 
124     CHECK_GT(g_thunks->size, 0u)
125         << "Invalid mojo_core library: " << library_path->value();
126 #else   // defined(OS_CHROMEOS) || defined(OS_LINUX)
127     NOTREACHED()
128         << "Dynamic mojo_core loading is not supported on this platform.";
129 #endif  // defined(OS_CHROMEOS) || defined(OS_LINUX)
130   }
131 
132   ~CoreLibraryInitializer() = default;
133 
134  private:
135 #if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_WIN)
136   base::Optional<base::ScopedNativeLibrary> library_;
137 #endif
138 
139   DISALLOW_COPY_AND_ASSIGN(CoreLibraryInitializer);
140 };
141 
142 }  // namespace mojo
143 
144 extern "C" {
145 
MojoInitialize(const struct MojoInitializeOptions * options)146 MojoResult MojoInitialize(const struct MojoInitializeOptions* options) {
147   static base::NoDestructor<mojo::CoreLibraryInitializer> initializer(options);
148   ALLOW_UNUSED_LOCAL(initializer);
149   DCHECK(g_thunks->Initialize);
150 
151   return INVOKE_THUNK(Initialize, options);
152 }
153 
MojoGetTimeTicksNow()154 MojoTimeTicks MojoGetTimeTicksNow() {
155   return INVOKE_THUNK(GetTimeTicksNow);
156 }
157 
MojoClose(MojoHandle handle)158 MojoResult MojoClose(MojoHandle handle) {
159   return INVOKE_THUNK(Close, handle);
160 }
161 
MojoQueryHandleSignalsState(MojoHandle handle,struct MojoHandleSignalsState * signals_state)162 MojoResult MojoQueryHandleSignalsState(
163     MojoHandle handle,
164     struct MojoHandleSignalsState* signals_state) {
165   return INVOKE_THUNK(QueryHandleSignalsState, handle, signals_state);
166 }
167 
MojoCreateMessagePipe(const MojoCreateMessagePipeOptions * options,MojoHandle * message_pipe_handle0,MojoHandle * message_pipe_handle1)168 MojoResult MojoCreateMessagePipe(const MojoCreateMessagePipeOptions* options,
169                                  MojoHandle* message_pipe_handle0,
170                                  MojoHandle* message_pipe_handle1) {
171   return INVOKE_THUNK(CreateMessagePipe, options, message_pipe_handle0,
172                       message_pipe_handle1);
173 }
174 
MojoWriteMessage(MojoHandle message_pipe_handle,MojoMessageHandle message_handle,const MojoWriteMessageOptions * options)175 MojoResult MojoWriteMessage(MojoHandle message_pipe_handle,
176                             MojoMessageHandle message_handle,
177                             const MojoWriteMessageOptions* options) {
178   return INVOKE_THUNK(WriteMessage, message_pipe_handle, message_handle,
179                       options);
180 }
181 
MojoReadMessage(MojoHandle message_pipe_handle,const MojoReadMessageOptions * options,MojoMessageHandle * message_handle)182 MojoResult MojoReadMessage(MojoHandle message_pipe_handle,
183                            const MojoReadMessageOptions* options,
184                            MojoMessageHandle* message_handle) {
185   return INVOKE_THUNK(ReadMessage, message_pipe_handle, options,
186                       message_handle);
187 }
188 
MojoFuseMessagePipes(MojoHandle handle0,MojoHandle handle1,const MojoFuseMessagePipesOptions * options)189 MojoResult MojoFuseMessagePipes(MojoHandle handle0,
190                                 MojoHandle handle1,
191                                 const MojoFuseMessagePipesOptions* options) {
192   return INVOKE_THUNK(FuseMessagePipes, handle0, handle1, options);
193 }
194 
MojoCreateDataPipe(const MojoCreateDataPipeOptions * options,MojoHandle * data_pipe_producer_handle,MojoHandle * data_pipe_consumer_handle)195 MojoResult MojoCreateDataPipe(const MojoCreateDataPipeOptions* options,
196                               MojoHandle* data_pipe_producer_handle,
197                               MojoHandle* data_pipe_consumer_handle) {
198   return INVOKE_THUNK(CreateDataPipe, options, data_pipe_producer_handle,
199                       data_pipe_consumer_handle);
200 }
201 
MojoWriteData(MojoHandle data_pipe_producer_handle,const void * elements,uint32_t * num_elements,const MojoWriteDataOptions * options)202 MojoResult MojoWriteData(MojoHandle data_pipe_producer_handle,
203                          const void* elements,
204                          uint32_t* num_elements,
205                          const MojoWriteDataOptions* options) {
206   return INVOKE_THUNK(WriteData, data_pipe_producer_handle, elements,
207                       num_elements, options);
208 }
209 
MojoBeginWriteData(MojoHandle data_pipe_producer_handle,const MojoBeginWriteDataOptions * options,void ** buffer,uint32_t * buffer_num_elements)210 MojoResult MojoBeginWriteData(MojoHandle data_pipe_producer_handle,
211                               const MojoBeginWriteDataOptions* options,
212                               void** buffer,
213                               uint32_t* buffer_num_elements) {
214   return INVOKE_THUNK(BeginWriteData, data_pipe_producer_handle, options,
215                       buffer, buffer_num_elements);
216 }
217 
MojoEndWriteData(MojoHandle data_pipe_producer_handle,uint32_t num_elements_written,const MojoEndWriteDataOptions * options)218 MojoResult MojoEndWriteData(MojoHandle data_pipe_producer_handle,
219                             uint32_t num_elements_written,
220                             const MojoEndWriteDataOptions* options) {
221   return INVOKE_THUNK(EndWriteData, data_pipe_producer_handle,
222                       num_elements_written, options);
223 }
224 
MojoReadData(MojoHandle data_pipe_consumer_handle,const MojoReadDataOptions * options,void * elements,uint32_t * num_elements)225 MojoResult MojoReadData(MojoHandle data_pipe_consumer_handle,
226                         const MojoReadDataOptions* options,
227                         void* elements,
228                         uint32_t* num_elements) {
229   return INVOKE_THUNK(ReadData, data_pipe_consumer_handle, options, elements,
230                       num_elements);
231 }
232 
MojoBeginReadData(MojoHandle data_pipe_consumer_handle,const MojoBeginReadDataOptions * options,const void ** buffer,uint32_t * buffer_num_elements)233 MojoResult MojoBeginReadData(MojoHandle data_pipe_consumer_handle,
234                              const MojoBeginReadDataOptions* options,
235                              const void** buffer,
236                              uint32_t* buffer_num_elements) {
237   return INVOKE_THUNK(BeginReadData, data_pipe_consumer_handle, options, buffer,
238                       buffer_num_elements);
239 }
240 
MojoEndReadData(MojoHandle data_pipe_consumer_handle,uint32_t num_elements_read,const MojoEndReadDataOptions * options)241 MojoResult MojoEndReadData(MojoHandle data_pipe_consumer_handle,
242                            uint32_t num_elements_read,
243                            const MojoEndReadDataOptions* options) {
244   return INVOKE_THUNK(EndReadData, data_pipe_consumer_handle, num_elements_read,
245                       options);
246 }
247 
MojoCreateSharedBuffer(uint64_t num_bytes,const MojoCreateSharedBufferOptions * options,MojoHandle * shared_buffer_handle)248 MojoResult MojoCreateSharedBuffer(uint64_t num_bytes,
249                                   const MojoCreateSharedBufferOptions* options,
250                                   MojoHandle* shared_buffer_handle) {
251   return INVOKE_THUNK(CreateSharedBuffer, num_bytes, options,
252                       shared_buffer_handle);
253 }
254 
MojoDuplicateBufferHandle(MojoHandle buffer_handle,const MojoDuplicateBufferHandleOptions * options,MojoHandle * new_buffer_handle)255 MojoResult MojoDuplicateBufferHandle(
256     MojoHandle buffer_handle,
257     const MojoDuplicateBufferHandleOptions* options,
258     MojoHandle* new_buffer_handle) {
259   return INVOKE_THUNK(DuplicateBufferHandle, buffer_handle, options,
260                       new_buffer_handle);
261 }
262 
MojoMapBuffer(MojoHandle buffer_handle,uint64_t offset,uint64_t num_bytes,const MojoMapBufferOptions * options,void ** buffer)263 MojoResult MojoMapBuffer(MojoHandle buffer_handle,
264                          uint64_t offset,
265                          uint64_t num_bytes,
266                          const MojoMapBufferOptions* options,
267                          void** buffer) {
268   return INVOKE_THUNK(MapBuffer, buffer_handle, offset, num_bytes, options,
269                       buffer);
270 }
271 
MojoUnmapBuffer(void * buffer)272 MojoResult MojoUnmapBuffer(void* buffer) {
273   return INVOKE_THUNK(UnmapBuffer, buffer);
274 }
275 
MojoGetBufferInfo(MojoHandle buffer_handle,const MojoGetBufferInfoOptions * options,MojoSharedBufferInfo * info)276 MojoResult MojoGetBufferInfo(MojoHandle buffer_handle,
277                              const MojoGetBufferInfoOptions* options,
278                              MojoSharedBufferInfo* info) {
279   return INVOKE_THUNK(GetBufferInfo, buffer_handle, options, info);
280 }
281 
MojoCreateTrap(MojoTrapEventHandler handler,const MojoCreateTrapOptions * options,MojoHandle * trap_handle)282 MojoResult MojoCreateTrap(MojoTrapEventHandler handler,
283                           const MojoCreateTrapOptions* options,
284                           MojoHandle* trap_handle) {
285   return INVOKE_THUNK(CreateTrap, handler, options, trap_handle);
286 }
287 
MojoAddTrigger(MojoHandle trap_handle,MojoHandle handle,MojoHandleSignals signals,MojoTriggerCondition condition,uintptr_t context,const MojoAddTriggerOptions * options)288 MojoResult MojoAddTrigger(MojoHandle trap_handle,
289                           MojoHandle handle,
290                           MojoHandleSignals signals,
291                           MojoTriggerCondition condition,
292                           uintptr_t context,
293                           const MojoAddTriggerOptions* options) {
294   return INVOKE_THUNK(AddTrigger, trap_handle, handle, signals, condition,
295                       context, options);
296 }
297 
MojoRemoveTrigger(MojoHandle trap_handle,uintptr_t context,const MojoRemoveTriggerOptions * options)298 MojoResult MojoRemoveTrigger(MojoHandle trap_handle,
299                              uintptr_t context,
300                              const MojoRemoveTriggerOptions* options) {
301   return INVOKE_THUNK(RemoveTrigger, trap_handle, context, options);
302 }
303 
MojoArmTrap(MojoHandle trap_handle,const MojoArmTrapOptions * options,uint32_t * num_blocking_events,MojoTrapEvent * blocking_events)304 MojoResult MojoArmTrap(MojoHandle trap_handle,
305                        const MojoArmTrapOptions* options,
306                        uint32_t* num_blocking_events,
307                        MojoTrapEvent* blocking_events) {
308   return INVOKE_THUNK(ArmTrap, trap_handle, options, num_blocking_events,
309                       blocking_events);
310 }
311 
MojoCreateMessage(const MojoCreateMessageOptions * options,MojoMessageHandle * message)312 MojoResult MojoCreateMessage(const MojoCreateMessageOptions* options,
313                              MojoMessageHandle* message) {
314   return INVOKE_THUNK(CreateMessage, options, message);
315 }
316 
MojoDestroyMessage(MojoMessageHandle message)317 MojoResult MojoDestroyMessage(MojoMessageHandle message) {
318   return INVOKE_THUNK(DestroyMessage, message);
319 }
320 
MojoSerializeMessage(MojoMessageHandle message,const MojoSerializeMessageOptions * options)321 MojoResult MojoSerializeMessage(MojoMessageHandle message,
322                                 const MojoSerializeMessageOptions* options) {
323   return INVOKE_THUNK(SerializeMessage, message, options);
324 }
325 
MojoAppendMessageData(MojoMessageHandle message,uint32_t payload_size,const MojoHandle * handles,uint32_t num_handles,const MojoAppendMessageDataOptions * options,void ** buffer,uint32_t * buffer_size)326 MojoResult MojoAppendMessageData(MojoMessageHandle message,
327                                  uint32_t payload_size,
328                                  const MojoHandle* handles,
329                                  uint32_t num_handles,
330                                  const MojoAppendMessageDataOptions* options,
331                                  void** buffer,
332                                  uint32_t* buffer_size) {
333   return INVOKE_THUNK(AppendMessageData, message, payload_size, handles,
334                       num_handles, options, buffer, buffer_size);
335 }
336 
MojoGetMessageData(MojoMessageHandle message,const MojoGetMessageDataOptions * options,void ** buffer,uint32_t * num_bytes,MojoHandle * handles,uint32_t * num_handles)337 MojoResult MojoGetMessageData(MojoMessageHandle message,
338                               const MojoGetMessageDataOptions* options,
339                               void** buffer,
340                               uint32_t* num_bytes,
341                               MojoHandle* handles,
342                               uint32_t* num_handles) {
343   return INVOKE_THUNK(GetMessageData, message, options, buffer, num_bytes,
344                       handles, num_handles);
345 }
346 
MojoSetMessageContext(MojoMessageHandle message,uintptr_t context,MojoMessageContextSerializer serializer,MojoMessageContextDestructor destructor,const MojoSetMessageContextOptions * options)347 MojoResult MojoSetMessageContext(MojoMessageHandle message,
348                                  uintptr_t context,
349                                  MojoMessageContextSerializer serializer,
350                                  MojoMessageContextDestructor destructor,
351                                  const MojoSetMessageContextOptions* options) {
352   return INVOKE_THUNK(SetMessageContext, message, context, serializer,
353                       destructor, options);
354 }
355 
MojoGetMessageContext(MojoMessageHandle message,const MojoGetMessageContextOptions * options,uintptr_t * context)356 MojoResult MojoGetMessageContext(MojoMessageHandle message,
357                                  const MojoGetMessageContextOptions* options,
358                                  uintptr_t* context) {
359   return INVOKE_THUNK(GetMessageContext, message, options, context);
360 }
361 
MojoNotifyBadMessage(MojoMessageHandle message,const char * error,uint32_t error_num_bytes,const MojoNotifyBadMessageOptions * options)362 MojoResult MojoNotifyBadMessage(MojoMessageHandle message,
363                                 const char* error,
364                                 uint32_t error_num_bytes,
365                                 const MojoNotifyBadMessageOptions* options) {
366   return INVOKE_THUNK(NotifyBadMessage, message, error, error_num_bytes,
367                       options);
368 }
369 
MojoWrapPlatformHandle(const MojoPlatformHandle * platform_handle,const MojoWrapPlatformHandleOptions * options,MojoHandle * mojo_handle)370 MojoResult MojoWrapPlatformHandle(const MojoPlatformHandle* platform_handle,
371                                   const MojoWrapPlatformHandleOptions* options,
372                                   MojoHandle* mojo_handle) {
373   return INVOKE_THUNK(WrapPlatformHandle, platform_handle, options,
374                       mojo_handle);
375 }
376 
MojoUnwrapPlatformHandle(MojoHandle mojo_handle,const MojoUnwrapPlatformHandleOptions * options,MojoPlatformHandle * platform_handle)377 MojoResult MojoUnwrapPlatformHandle(
378     MojoHandle mojo_handle,
379     const MojoUnwrapPlatformHandleOptions* options,
380     MojoPlatformHandle* platform_handle) {
381   return INVOKE_THUNK(UnwrapPlatformHandle, mojo_handle, options,
382                       platform_handle);
383 }
384 
MojoWrapPlatformSharedMemoryRegion(const struct MojoPlatformHandle * platform_handles,uint32_t num_platform_handles,uint64_t num_bytes,const MojoSharedBufferGuid * guid,MojoPlatformSharedMemoryRegionAccessMode access_mode,const MojoWrapPlatformSharedMemoryRegionOptions * options,MojoHandle * mojo_handle)385 MojoResult MojoWrapPlatformSharedMemoryRegion(
386     const struct MojoPlatformHandle* platform_handles,
387     uint32_t num_platform_handles,
388     uint64_t num_bytes,
389     const MojoSharedBufferGuid* guid,
390     MojoPlatformSharedMemoryRegionAccessMode access_mode,
391     const MojoWrapPlatformSharedMemoryRegionOptions* options,
392     MojoHandle* mojo_handle) {
393   return INVOKE_THUNK(WrapPlatformSharedMemoryRegion, platform_handles,
394                       num_platform_handles, num_bytes, guid, access_mode,
395                       options, mojo_handle);
396 }
397 
MojoUnwrapPlatformSharedMemoryRegion(MojoHandle mojo_handle,const MojoUnwrapPlatformSharedMemoryRegionOptions * options,struct MojoPlatformHandle * platform_handles,uint32_t * num_platform_handles,uint64_t * num_bytes,struct MojoSharedBufferGuid * guid,MojoPlatformSharedMemoryRegionAccessMode * access_mode)398 MojoResult MojoUnwrapPlatformSharedMemoryRegion(
399     MojoHandle mojo_handle,
400     const MojoUnwrapPlatformSharedMemoryRegionOptions* options,
401     struct MojoPlatformHandle* platform_handles,
402     uint32_t* num_platform_handles,
403     uint64_t* num_bytes,
404     struct MojoSharedBufferGuid* guid,
405     MojoPlatformSharedMemoryRegionAccessMode* access_mode) {
406   return INVOKE_THUNK(UnwrapPlatformSharedMemoryRegion, mojo_handle, options,
407                       platform_handles, num_platform_handles, num_bytes, guid,
408                       access_mode);
409 }
410 
MojoCreateInvitation(const MojoCreateInvitationOptions * options,MojoHandle * invitation_handle)411 MojoResult MojoCreateInvitation(const MojoCreateInvitationOptions* options,
412                                 MojoHandle* invitation_handle) {
413   return INVOKE_THUNK(CreateInvitation, options, invitation_handle);
414 }
415 
MojoAttachMessagePipeToInvitation(MojoHandle invitation_handle,const void * name,uint32_t name_num_bytes,const MojoAttachMessagePipeToInvitationOptions * options,MojoHandle * message_pipe_handle)416 MojoResult MojoAttachMessagePipeToInvitation(
417     MojoHandle invitation_handle,
418     const void* name,
419     uint32_t name_num_bytes,
420     const MojoAttachMessagePipeToInvitationOptions* options,
421     MojoHandle* message_pipe_handle) {
422   return INVOKE_THUNK(AttachMessagePipeToInvitation, invitation_handle, name,
423                       name_num_bytes, options, message_pipe_handle);
424 }
425 
MojoExtractMessagePipeFromInvitation(MojoHandle invitation_handle,const void * name,uint32_t name_num_bytes,const MojoExtractMessagePipeFromInvitationOptions * options,MojoHandle * message_pipe_handle)426 MojoResult MojoExtractMessagePipeFromInvitation(
427     MojoHandle invitation_handle,
428     const void* name,
429     uint32_t name_num_bytes,
430     const MojoExtractMessagePipeFromInvitationOptions* options,
431     MojoHandle* message_pipe_handle) {
432   return INVOKE_THUNK(ExtractMessagePipeFromInvitation, invitation_handle, name,
433                       name_num_bytes, options, message_pipe_handle);
434 }
435 
MojoSendInvitation(MojoHandle invitation_handle,const MojoPlatformProcessHandle * process_handle,const MojoInvitationTransportEndpoint * transport_endpoint,MojoProcessErrorHandler error_handler,uintptr_t error_handler_context,const MojoSendInvitationOptions * options)436 MojoResult MojoSendInvitation(
437     MojoHandle invitation_handle,
438     const MojoPlatformProcessHandle* process_handle,
439     const MojoInvitationTransportEndpoint* transport_endpoint,
440     MojoProcessErrorHandler error_handler,
441     uintptr_t error_handler_context,
442     const MojoSendInvitationOptions* options) {
443   return INVOKE_THUNK(SendInvitation, invitation_handle, process_handle,
444                       transport_endpoint, error_handler, error_handler_context,
445                       options);
446 }
447 
MojoAcceptInvitation(const MojoInvitationTransportEndpoint * transport_endpoint,const MojoAcceptInvitationOptions * options,MojoHandle * invitation_handle)448 MojoResult MojoAcceptInvitation(
449     const MojoInvitationTransportEndpoint* transport_endpoint,
450     const MojoAcceptInvitationOptions* options,
451     MojoHandle* invitation_handle) {
452   return INVOKE_THUNK(AcceptInvitation, transport_endpoint, options,
453                       invitation_handle);
454 }
455 
MojoSetQuota(MojoHandle handle,MojoQuotaType type,uint64_t limit,const MojoSetQuotaOptions * options)456 MojoResult MojoSetQuota(MojoHandle handle,
457                         MojoQuotaType type,
458                         uint64_t limit,
459                         const MojoSetQuotaOptions* options) {
460   return INVOKE_THUNK(SetQuota, handle, type, limit, options);
461 }
462 
MojoQueryQuota(MojoHandle handle,MojoQuotaType type,const MojoQueryQuotaOptions * options,uint64_t * limit,uint64_t * usage)463 MojoResult MojoQueryQuota(MojoHandle handle,
464                           MojoQuotaType type,
465                           const MojoQueryQuotaOptions* options,
466                           uint64_t* limit,
467                           uint64_t* usage) {
468   return INVOKE_THUNK(QueryQuota, handle, type, options, limit, usage);
469 }
470 
471 }  // extern "C"
472 
MojoEmbedderSetSystemThunks(const MojoSystemThunks * thunks)473 void MojoEmbedderSetSystemThunks(const MojoSystemThunks* thunks) {
474   // Assume embedders will always use matching versions of the Mojo Core and
475   // public APIs.
476   DCHECK_EQ(thunks->size, sizeof(*g_thunks));
477 
478   // This should only have to check that the |g_thunks->size| is zero, but we
479   // have multiple Mojo Core initializations in some test suites still. For now
480   // we allow double calls as long as they're the same thunks as before.
481   DCHECK(g_thunks->size == 0 || !memcmp(&*g_thunks, thunks, sizeof(*g_thunks)))
482       << "Cannot set embedder thunks after Mojo API calls have been made.";
483 
484   auto writer = base::AutoWritableMemory::Create(g_thunks);
485   *g_thunks = *thunks;
486 }
487