Home | History | Annotate | Download | only in nonsfi
      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