Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / chrome / test / data / nacl / nonsfi / libc_free.c
blobcc8eb839ab039e564b8046bf45244000743b782c
1 /*
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.
5 */
7 /*
8 * This is a minimal NaCl program without libc. It uses NaCl's stable IRT ABI.
9 */
11 #include <stdint.h>
13 #include "native_client/src/include/elf_auxv.h"
14 #include "native_client/src/untrusted/irt/irt.h"
15 #include "ppapi/c/pp_errors.h"
16 #include "ppapi/c/ppb_messaging.h"
17 #include "ppapi/c/ppb_var.h"
18 #include "ppapi/c/ppp_instance.h"
19 #include "ppapi/c/ppp_messaging.h"
20 #include "ppapi/nacl_irt/public/irt_ppapi.h"
22 static struct nacl_irt_basic __libnacl_irt_basic;
23 static struct nacl_irt_random __libnacl_irt_random;
24 static TYPE_nacl_irt_query __nacl_irt_query;
25 static struct PPP_Instance_1_0 ppp_instance;
26 static struct PPP_Messaging_1_0 ppp_messaging;
27 static const struct PPB_Messaging_1_0* ppb_messaging;
28 static const struct PPB_Var_1_2* ppb_var;
31 * To support 64bit binary, we declare Elf_auxv_t by using uintptr_t.
32 * See also native_client/src/include/elf32.h.
34 typedef struct {
35 uintptr_t a_type;
36 union {
37 uintptr_t a_val;
38 } a_un;
39 } Elf_auxv_t;
42 * This is simiplar to the one in
43 * native_client/src/untrusted/nacl/nacl_startup.h, but also supports 64 bit
44 * pointers.
46 static Elf_auxv_t* nacl_startup_auxv(const uintptr_t info[]) {
47 /* The layout of _start's argument is
48 * info[0]: fini.
49 * info[1]: envc
50 * info[2]: argc
51 * info[3]...[3+argc]: argv (NULL terminated)
52 * info[3+argc+1]...[3+argc+1+envc]: envv (NULL terminated)
53 * info[3+argc+1+envc+1]: auxv pairs.
55 int envc = info[1];
56 int argc = info[2];
57 return (Elf_auxv_t*) (info + 3 + envc + 1 + argc + 1);
60 static void grok_auxv(const Elf_auxv_t* auxv) {
61 const Elf_auxv_t* av;
62 for (av = auxv; av->a_type != AT_NULL; ++av) {
63 if (av->a_type == AT_SYSINFO) {
64 __nacl_irt_query = (TYPE_nacl_irt_query) av->a_un.a_val;
69 #define DO_QUERY(ident, name) __nacl_irt_query(ident, &name, sizeof(name))
71 static int my_strcmp(const char* a, const char* b) {
72 while (*a == *b) {
73 if (*a == '\0')
74 return 0;
75 ++a;
76 ++b;
78 return (int) (unsigned char) *a - (int) (unsigned char) *b;
81 static int my_strncmp(const char* a, const char* b, size_t n) {
82 while (n > 0 && *a == *b) {
83 if (*a == '\0')
84 return 0;
85 ++a;
86 ++b;
87 --n;
89 if (n == 0) {
90 return 0;
92 return (int) (unsigned char) *a - (int) (unsigned char) *b;
95 static size_t my_strlen(const char* a) {
96 size_t size = 0;
97 while (*a++)
98 size++;
99 return size;
102 static PP_Bool DidCreate(PP_Instance instance,
103 uint32_t argc,
104 const char* argn[],
105 const char* argv[]) {
106 return 1;
109 static void DidDestroy(PP_Instance instance) {
112 static void DidChangeView(PP_Instance instance,
113 const struct PP_Rect* position,
114 const struct PP_Rect* clip) {
117 static void DidChangeFocus(PP_Instance instance, PP_Bool has_focus) {
120 static PP_Bool HandleDocumentLoad(PP_Instance instance,
121 PP_Resource url_loader) {
122 return 0;
125 static int32_t MyPPP_InitializeModule(PP_Module module_id,
126 PPB_GetInterface get_browser_interface) {
127 ppb_messaging = get_browser_interface(PPB_MESSAGING_INTERFACE_1_0);
128 ppb_var = get_browser_interface(PPB_VAR_INTERFACE_1_2);
129 return PP_OK;
132 static void MyPPP_ShutdownModule(void) {
135 static const void* MyPPP_GetInterface(const char* interface_name) {
136 if (my_strcmp(interface_name, PPP_INSTANCE_INTERFACE_1_0) == 0)
137 return &ppp_instance;
138 if (my_strcmp(interface_name, PPP_MESSAGING_INTERFACE_1_0) == 0)
139 return &ppp_messaging;
140 return NULL;
143 static void PostStringMessage(PP_Instance instance,
144 const char* message_string) {
145 size_t message_length = my_strlen(message_string);
146 struct PP_Var message = ppb_var->VarFromUtf8(
147 message_string, message_length);
148 ppb_messaging->PostMessage(instance, message);
149 ppb_var->Release(message);
152 static void TestRandom(PP_Instance instance) {
153 // Javascript expects "randomsuccess", we will send back a different
154 // string via PostMessage to denote a failure, and that will be
155 // visible in the failure logs.
157 char random_buffer[512];
158 int i;
159 // zero-clear the buffer.
160 for (i = 0; i < sizeof random_buffer; ++i) {
161 random_buffer[i] = 0;
164 size_t read_len;
165 if (__libnacl_irt_random.get_random_bytes(random_buffer,
166 sizeof random_buffer,
167 &read_len) != 0) {
168 PostStringMessage(instance, "Get Random Bytes Failed.");
169 return;
172 // Try to see if the buffer looks different from bunch of zeros.
173 if (read_len != sizeof random_buffer) {
174 PostStringMessage(instance, "Give me moar random bytes");
175 return;
177 int num_zeroes = 0;
178 for (i = 0; i < sizeof random_buffer; ++i) {
179 if (random_buffer[i] == 0) {
180 num_zeroes++;
183 if (num_zeroes > 100) {
184 PostStringMessage(instance, "Too many zeros in this random stream.");
185 return;
188 PostStringMessage(instance, "randomsuccess");
191 // Handle message from javascript, javascript side will tell me what
192 // kind of test it wants, and I will respond accordingly.
193 static void HandleMessage(PP_Instance instance, struct PP_Var message) {
194 if (!ppb_messaging || !ppb_var || message.type != PP_VARTYPE_STRING) {
195 __libnacl_irt_basic.exit(1);
198 uint32_t message_len;
199 const char* message_string = ppb_var->VarToUtf8(message, &message_len);
201 if (!my_strncmp("Message from Javascript to NaCl",
202 message_string, message_len)) {
203 // Reply back with what we received.
204 ppb_messaging->PostMessage(instance, message);
205 } else if (!my_strncmp("random", message_string, message_len)) {
206 TestRandom(instance);
207 } else {
208 // Unknown message came.
209 PostStringMessage(instance, "Unknown message type");
213 void _start(uintptr_t info[]) {
214 Elf_auxv_t* auxv = nacl_startup_auxv(info);
215 grok_auxv(auxv);
216 DO_QUERY(NACL_IRT_BASIC_v0_1, __libnacl_irt_basic);
217 DO_QUERY(NACL_IRT_RANDOM_v0_1, __libnacl_irt_random);
219 struct nacl_irt_ppapihook ppapihook;
220 DO_QUERY(NACL_IRT_PPAPIHOOK_v0_1, ppapihook);
222 /* This is local as a workaround to avoid having to apply
223 * relocations to global variables. */
224 struct PP_StartFunctions start_funcs;
225 start_funcs.PPP_InitializeModule = MyPPP_InitializeModule;
226 start_funcs.PPP_ShutdownModule = MyPPP_ShutdownModule;
227 start_funcs.PPP_GetInterface = MyPPP_GetInterface;
228 /* Similarly, initialize some global variables, avoiding relocations. */
229 ppp_instance.DidCreate = DidCreate;
230 ppp_instance.DidDestroy = DidDestroy;
231 ppp_instance.DidChangeView = DidChangeView;
232 ppp_instance.DidChangeFocus = DidChangeFocus;
233 ppp_instance.HandleDocumentLoad = HandleDocumentLoad;
234 ppp_messaging.HandleMessage = HandleMessage;
236 ppapihook.ppapi_start(&start_funcs);
238 __libnacl_irt_basic.exit(0);