2 * Copyright 2014 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
8 * This is a minimal NaCl program without libc. It uses NaCl's stable IRT ABI.
13 #include "native_client/src/include/elf_auxv.h"
14 #include "native_client/src/untrusted/irt/irt.h"
15 #include "ppapi/nacl_irt/irt_ppapi.h"
16 #include "ppapi/c/pp_errors.h"
17 #include "ppapi/c/ppp_instance.h"
19 static struct nacl_irt_basic __libnacl_irt_basic
;
20 static struct nacl_irt_fdio __libnacl_irt_fdio
;
21 static TYPE_nacl_irt_query __nacl_irt_query
;
22 static struct PPP_Instance_1_0 ppp_instance
;
25 * To support 64bit binary, we declare Elf_auxv_t by using uintptr_t.
26 * See also native_client/src/include/elf32.h.
36 * This is simiplar to the one in
37 * native_client/src/untrusted/nacl/nacl_startup.h, but also supports 64 bit
40 static Elf_auxv_t
*nacl_startup_auxv(const uintptr_t info
[]) {
41 /* The layout of _start's argument is
45 * info[3]...[3+argc]: argv (NULL terminated)
46 * info[3+argc+1]...[3+argc+1+envc]: envv (NULL terminated)
47 * info[3+argc+1+envc+1]: auxv pairs.
51 return (Elf_auxv_t
*) (info
+ 3 + envc
+ 1 + argc
+ 1);
54 static void grok_auxv(const Elf_auxv_t
*auxv
) {
56 for (av
= auxv
; av
->a_type
!= AT_NULL
; ++av
) {
57 if (av
->a_type
== AT_SYSINFO
) {
58 __nacl_irt_query
= (TYPE_nacl_irt_query
) av
->a_un
.a_val
;
63 #define DO_QUERY(ident, name) __nacl_irt_query(ident, &name, sizeof(name))
65 static int my_strcmp(const char *a
, const char *b
) {
72 return (int) (unsigned char) *a
- (int) (unsigned char) *b
;
75 static PP_Bool
DidCreate(PP_Instance instance
,
82 static void DidDestroy(PP_Instance instance
) {
85 static void DidChangeView(PP_Instance instance
,
86 const struct PP_Rect
* position
,
87 const struct PP_Rect
* clip
) {
90 static void DidChangeFocus(PP_Instance instance
, PP_Bool has_focus
) {
93 static PP_Bool
HandleDocumentLoad(PP_Instance instance
,
94 PP_Resource url_loader
) {
98 static int32_t MyPPP_InitializeModule(PP_Module module_id
,
99 PPB_GetInterface get_browser_interface
) {
103 static void MyPPP_ShutdownModule(void) {
106 static const void *MyPPP_GetInterface(const char *interface_name
) {
107 if (my_strcmp(interface_name
, PPP_INSTANCE_INTERFACE_1_0
) == 0)
108 return &ppp_instance
;
112 void _start(uintptr_t info
[]) {
113 Elf_auxv_t
*auxv
= nacl_startup_auxv(info
);
115 DO_QUERY(NACL_IRT_BASIC_v0_1
, __libnacl_irt_basic
);
116 DO_QUERY(NACL_IRT_DEV_FDIO_v0_1
, __libnacl_irt_fdio
);
118 struct nacl_irt_ppapihook ppapihook
;
119 DO_QUERY(NACL_IRT_PPAPIHOOK_v0_1
, ppapihook
);
121 /* This is local as a workaround to avoid having to apply
122 * relocations to global variables. */
123 struct PP_StartFunctions start_funcs
= {
124 MyPPP_InitializeModule
,
125 MyPPP_ShutdownModule
,
128 /* Similarly, initialise some global variables, avoiding relocations. */
129 struct PPP_Instance_1_0 local_ppp_instance
= {
136 ppp_instance
= local_ppp_instance
;
138 ppapihook
.ppapi_start(&start_funcs
);
140 __libnacl_irt_basic
.exit(0);