/js/src/sharkctl.cpp

http://github.com/zpao/v8monkey · C++ · 238 lines · 173 code · 30 blank · 35 comment · 15 complexity · 9a57f7a0a3d4d1d4391e10f2d4af5c50 MD5 · raw file

  1. /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2. * vim: set ts=8 sw=4 et tw=80:
  3. *
  4. * ***** BEGIN LICENSE BLOCK *****
  5. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  6. *
  7. * The contents of this file are subject to the Mozilla Public License Version
  8. * 1.1 (the "License"); you may not use this file except in compliance with
  9. * the License. You may obtain a copy of the License at
  10. * http://www.mozilla.org/MPL/
  11. *
  12. * Software distributed under the License is distributed on an "AS IS" basis,
  13. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  14. * for the specific language governing rights and limitations under the
  15. * License.
  16. *
  17. * Copyright (C) 2010 Patrick Walton <pcwalton@mimiga.net>
  18. *
  19. * Contributor(s):
  20. * Andreas Gal <gal@mozilla.com>
  21. *
  22. * Alternatively, the contents of this file may be used under the terms of
  23. * either of the GNU General Public License Version 2 or later (the "GPL"),
  24. * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  25. * in which case the provisions of the GPL or the LGPL are applicable instead
  26. * of those above. If you wish to allow use of your version of this file only
  27. * under the terms of either the GPL or the LGPL, and not to allow others to
  28. * use your version of this file under the terms of the MPL, indicate your
  29. * decision by deleting the provisions above and replace them with the notice
  30. * and other provisions required by the GPL or the LGPL. If you do not delete
  31. * the provisions above, a recipient may use your version of this file under
  32. * the terms of any one of the MPL, the GPL or the LGPL.
  33. *
  34. * ***** END LICENSE BLOCK ***** */
  35. #ifdef __APPLE__
  36. #include "sharkctl.h"
  37. #include "sharkctl.h"
  38. #include <stddef.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <unistd.h>
  42. #include "jsutil.h"
  43. #define SHARK_MSG_ACQUIRE 0x29a
  44. #define SHARK_MSG_RELEASE 0x29b
  45. #define SHARK_MSG_STOP 0x29c
  46. #define SHARK_MSG_START 0x29d
  47. #define RECV_SIZEOF(ty) offsetof(ty, out)
  48. // Private API in libSystem.dylib
  49. extern "C" void bootstrap_look_up(mach_port_t special_port, const char *name,
  50. mach_port_t *dest_port);
  51. struct chud_client_acquire_msg {
  52. mach_msg_header_t hdr;
  53. uint32_t unk0; // always 0
  54. uint32_t unk1; // always 1
  55. uint32_t pid;
  56. uint32_t out[2];
  57. };
  58. struct chud_client_start_msg {
  59. mach_msg_header_t hdr;
  60. uint32_t unk0; // always 1
  61. uint32_t name0;
  62. uint32_t arg2; // always 6
  63. uint8_t unk1; // always 0
  64. uint8_t unk2; // always 1
  65. uint8_t unk3; // uninitialized
  66. uint8_t unk4; // always 1
  67. uint32_t unk5; // always 0
  68. uint32_t unk6; // always 1
  69. uint32_t name1; // same as name0
  70. };
  71. struct chud_client_stop_msg {
  72. mach_msg_header_t hdr;
  73. uint32_t out[5];
  74. };
  75. struct chud_client_release_msg {
  76. mach_msg_header_t hdr;
  77. uint32_t unk0; // always 0
  78. uint32_t unk1; // always 1
  79. uint32_t pid;
  80. uint32_t out[2];
  81. };
  82. static mach_port_t
  83. CreatePort(void)
  84. {
  85. mach_port_t bootstrap_port, shark_port = 0;
  86. task_get_special_port(mach_task_self(), TASK_BOOTSTRAP_PORT,
  87. &bootstrap_port);
  88. bootstrap_look_up(bootstrap_port, "CHUD_IPC", &shark_port);
  89. return shark_port;
  90. }
  91. static mach_msg_return_t
  92. Connect(mach_port_t shark_port)
  93. {
  94. mach_port_t reply_port = mig_get_reply_port();
  95. struct chud_client_acquire_msg msg;
  96. msg.hdr.msgh_bits = 0x1513;
  97. msg.hdr.msgh_size = sizeof(mach_msg_header_t);
  98. msg.hdr.msgh_remote_port = shark_port;
  99. msg.hdr.msgh_local_port = reply_port;
  100. msg.hdr.msgh_reserved = 0;
  101. msg.hdr.msgh_id = SHARK_MSG_ACQUIRE;
  102. msg.unk0 = 0;
  103. msg.unk1 = 1;
  104. msg.pid = getpid();
  105. JS_ASSERT(RECV_SIZEOF(struct chud_client_acquire_msg) == 0x24);
  106. JS_ASSERT(sizeof(msg) == 0x2c);
  107. mach_msg_return_t result = mach_msg(&msg.hdr, MACH_SEND_MSG | MACH_RCV_MSG,
  108. RECV_SIZEOF(struct chud_client_acquire_msg),
  109. sizeof(msg), reply_port, 0, 0);
  110. mig_dealloc_reply_port(reply_port);
  111. return result;
  112. }
  113. static mach_msg_return_t
  114. Start(mach_port_t shark_port, uint32_t name)
  115. {
  116. mach_port_t reply_port = mig_get_reply_port();
  117. struct chud_client_start_msg msg;
  118. msg.hdr.msgh_bits = 0x80001513;
  119. msg.hdr.msgh_size = sizeof(mach_msg_header_t);
  120. msg.hdr.msgh_remote_port = shark_port;
  121. msg.hdr.msgh_local_port = reply_port;
  122. msg.hdr.msgh_reserved = 0;
  123. msg.hdr.msgh_id = SHARK_MSG_START;
  124. msg.unk0 = 1;
  125. msg.name0 = name;
  126. msg.arg2 = 6;
  127. msg.unk1 = 0;
  128. msg.unk2 = 1;
  129. msg.unk3 = 0;
  130. msg.unk4 = 1;
  131. msg.unk5 = 0;
  132. msg.unk6 = 1;
  133. msg.name1 = name;
  134. JS_ASSERT(sizeof(msg) == 0x34);
  135. mach_msg_return_t result = mach_msg(&msg.hdr, MACH_SEND_MSG | MACH_RCV_MSG,
  136. sizeof(msg), 0x30, reply_port, 0, 0);
  137. mig_dealloc_reply_port(reply_port);
  138. return result;
  139. }
  140. mach_msg_return_t
  141. Stop(mach_port_t shark_port)
  142. {
  143. mach_port_t reply_port = mig_get_reply_port();
  144. struct chud_client_stop_msg msg;
  145. msg.hdr.msgh_bits = 0x1513;
  146. msg.hdr.msgh_size = sizeof(mach_msg_header_t);
  147. msg.hdr.msgh_remote_port = shark_port;
  148. msg.hdr.msgh_local_port = reply_port;
  149. msg.hdr.msgh_reserved = 0;
  150. msg.hdr.msgh_id = SHARK_MSG_STOP;
  151. JS_ASSERT(RECV_SIZEOF(struct chud_client_stop_msg) == 0x18);
  152. JS_ASSERT(sizeof(msg) == 0x2c);
  153. mach_msg_return_t result = mach_msg(&msg.hdr, MACH_SEND_MSG | MACH_RCV_MSG,
  154. RECV_SIZEOF(struct chud_client_stop_msg),
  155. sizeof(msg), reply_port, 0, 0);
  156. mig_dealloc_reply_port(reply_port);
  157. return result;
  158. }
  159. static mach_msg_return_t
  160. Disconnect(mach_port_t shark_port)
  161. {
  162. mach_port_t reply_port = mig_get_reply_port();
  163. struct chud_client_release_msg msg;
  164. msg.hdr.msgh_bits = 0x1513;
  165. msg.hdr.msgh_size = sizeof(mach_msg_header_t);
  166. msg.hdr.msgh_remote_port = shark_port;
  167. msg.hdr.msgh_local_port = reply_port;
  168. msg.hdr.msgh_reserved = 0;
  169. msg.hdr.msgh_id = SHARK_MSG_RELEASE;
  170. msg.unk0 = 0;
  171. msg.unk1 = 1;
  172. msg.pid = getpid();
  173. JS_ASSERT(RECV_SIZEOF(struct chud_client_release_msg) == 0x24);
  174. JS_ASSERT(sizeof(msg) == 0x2c);
  175. mach_msg_return_t result = mach_msg(&msg.hdr, MACH_SEND_MSG | MACH_RCV_MSG,
  176. RECV_SIZEOF(struct chud_client_release_msg),
  177. sizeof(msg), reply_port, 0, 0);
  178. mig_dealloc_reply_port(reply_port);
  179. return result;
  180. }
  181. static mach_port_t shark_port = 0;
  182. static bool connected = false;
  183. static bool running = false;
  184. namespace Shark {
  185. bool
  186. Start()
  187. {
  188. if (!shark_port && !(shark_port = CreatePort()))
  189. return false;
  190. if (!connected && Connect(shark_port))
  191. return false;
  192. connected = true;
  193. if (!running && ::Start(shark_port, 0xdeadbeef))
  194. return false;
  195. return running = true;
  196. };
  197. void
  198. Stop()
  199. {
  200. if (!shark_port || !connected)
  201. return;
  202. ::Stop(shark_port);
  203. running = false;
  204. Disconnect(shark_port);
  205. connected = false;
  206. }
  207. }
  208. #endif