blob: c053586fe54fdc0a5e89faba37546fc8c5f603e9 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/nacl/loader/nonsfi/nonsfi_main.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_restrictions.h"
#include "components/nacl/loader/nonsfi/elf_loader.h"
#include "components/nacl/loader/nonsfi/irt_interfaces.h"
#include "native_client/src/include/elf_auxv.h"
#include "native_client/src/include/nacl_macros.h"
#include "native_client/src/trusted/desc/nacl_desc_base.h"
#include "native_client/src/trusted/desc/nacl_desc_io.h"
#include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
namespace nacl {
namespace nonsfi {
namespace {
typedef void (*EntryPointType)(uintptr_t*);
class PluginMainDelegate : public base::PlatformThread::Delegate {
public:
explicit PluginMainDelegate(EntryPointType entry_point)
: entry_point_(entry_point) {
}
virtual ~PluginMainDelegate() {
}
virtual void ThreadMain() override {
base::PlatformThread::SetName("NaClMainThread");
// This will only happen once per process, so we give the permission to
// create Singletons.
base::ThreadRestrictions::SetSingletonAllowed(true);
uintptr_t info[] = {
0, // Do not use fini.
0, // envc.
0, // argc.
0, // Null terminate for argv.
0, // Null terminate for envv.
AT_SYSINFO,
reinterpret_cast<uintptr_t>(&NaClIrtInterface),
AT_NULL,
0, // Null terminate for auxv.
};
entry_point_(info);
}
private:
EntryPointType entry_point_;
};
// Default stack size of the plugin main thread. We heuristically chose 16M.
const size_t kStackSize = (16 << 20);
struct NaClDescUnrefer {
void operator()(struct NaClDesc* desc) const {
NaClDescUnref(desc);
}
};
} // namespace
void MainStart(int nexe_file) {
::scoped_ptr<struct NaClDesc, NaClDescUnrefer> desc(
NaClDescIoDescFromDescAllocCtor(nexe_file, NACL_ABI_O_RDONLY));
ElfImage image;
if (image.Read(desc.get()) != LOAD_OK) {
LOG(ERROR) << "LoadModuleRpc: Failed to read binary.";
return;
}
if (image.Load(desc.get()) != LOAD_OK) {
LOG(ERROR) << "LoadModuleRpc: Failed to load the image";
return;
}
EntryPointType entry_point =
reinterpret_cast<EntryPointType>(image.entry_point());
if (!base::PlatformThread::CreateNonJoinable(
kStackSize, new PluginMainDelegate(entry_point))) {
LOG(ERROR) << "LoadModuleRpc: Failed to create plugin main thread.";
return;
}
}
} // namespace nonsfi
} // namespace nacl