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
19namespace nacl {
20namespace nonsfi {
21namespace {
22
23typedef void (*EntryPointType)(uintptr_t*);
24
25class 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.
59const size_t kStackSize = (16 << 20);
60
61struct NaClDescUnrefer {
62  void operator()(struct NaClDesc* desc) const {
63    NaClDescUnref(desc);
64  }
65};
66
67}  // namespace
68
69void 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