1 // Copyright 2014 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 "components/nacl/loader/nonsfi/nonsfi_main.h" 6 7 #include "base/logging.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/threading/platform_thread.h" 10 #include "base/threading/thread_restrictions.h" 11 #include "components/nacl/loader/nonsfi/elf_loader.h" 12 #include "components/nacl/loader/nonsfi/irt_interfaces.h" 13 #include "native_client/src/include/elf_auxv.h" 14 #include "native_client/src/include/nacl_macros.h" 15 #include "native_client/src/trusted/desc/nacl_desc_base.h" 16 #include "native_client/src/trusted/desc/nacl_desc_io.h" 17 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h" 18 19 namespace nacl { 20 namespace nonsfi { 21 namespace { 22 23 typedef void (*EntryPointType)(uintptr_t*); 24 25 class PluginMainDelegate : public base::PlatformThread::Delegate { 26 public: 27 explicit PluginMainDelegate(EntryPointType entry_point) 28 : entry_point_(entry_point) { 29 } 30 31 virtual ~PluginMainDelegate() { 32 } 33 34 virtual void ThreadMain() OVERRIDE { 35 base::PlatformThread::SetName("NaClMainThread"); 36 37 // This will only happen once per process, so we give the permission to 38 // create Singletons. 39 base::ThreadRestrictions::SetSingletonAllowed(true); 40 uintptr_t info[] = { 41 0, // Do not use fini. 42 0, // envc. 43 0, // argc. 44 0, // Null terminate for argv. 45 0, // Null terminate for envv. 46 AT_SYSINFO, 47 reinterpret_cast<uintptr_t>(&NaClIrtInterface), 48 AT_NULL, 49 0, // Null terminate for auxv. 50 }; 51 entry_point_(info); 52 } 53 54 private: 55 EntryPointType entry_point_; 56 }; 57 58 // Default stack size of the plugin main thread. We heuristically chose 16M. 59 const size_t kStackSize = (16 << 20); 60 61 struct NaClDescUnrefer { 62 void operator()(struct NaClDesc* desc) const { 63 NaClDescUnref(desc); 64 } 65 }; 66 67 } // namespace 68 69 void MainStart(int nexe_file) { 70 ::scoped_ptr<struct NaClDesc, NaClDescUnrefer> desc( 71 NaClDescIoDescFromDescAllocCtor(nexe_file, NACL_ABI_O_RDONLY)); 72 ElfImage image; 73 if (image.Read(desc.get()) != LOAD_OK) { 74 LOG(ERROR) << "LoadModuleRpc: Failed to read binary."; 75 return; 76 } 77 78 if (image.Load(desc.get()) != LOAD_OK) { 79 LOG(ERROR) << "LoadModuleRpc: Failed to load the image"; 80 return; 81 } 82 83 EntryPointType entry_point = 84 reinterpret_cast<EntryPointType>(image.entry_point()); 85 if (!base::PlatformThread::CreateNonJoinable( 86 kStackSize, new PluginMainDelegate(entry_point))) { 87 LOG(ERROR) << "LoadModuleRpc: Failed to create plugin main thread."; 88 return; 89 } 90 } 91 92 } // namespace nonsfi 93 } // namespace nacl 94