Advertisement
Guest User

hooks.c

a guest
Aug 15th, 2017
36
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 94.97 KB | None | 0 0
  1. /*
  2. * Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
  3. * Copyright (c) 2012 Canonical Ltd
  4. * Copyright (c) 2013 Christophe Chapuis <chris.chapuis@gmail.com>
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. */
  19.  
  20. #include "config.h"
  21.  
  22. #include <hybris/common/binding.h>
  23.  
  24. #include "hooks_shm.h"
  25.  
  26. #include <stdio.h>
  27. #include <stdarg.h>
  28. #include <stdio_ext.h>
  29. #include <stddef.h>
  30. #include <stdlib.h>
  31. #include <limits.h>
  32. #include <malloc.h>
  33. #include <string.h>
  34. #include <inttypes.h>
  35. #include <strings.h>
  36. #include <dlfcn.h>
  37. #include <pthread.h>
  38. #include <sys/xattr.h>
  39. #include <grp.h>
  40. #include <signal.h>
  41. #include <errno.h>
  42. #include <dirent.h>
  43. #include <sys/types.h>
  44. #include <stdarg.h>
  45. #include <wchar.h>
  46. #include <sched.h>
  47. #include <pwd.h>
  48. #include <signal.h>
  49. #include <setjmp.h>
  50. #include <sys/signalfd.h>
  51.  
  52. #include <sys/ipc.h>
  53. #include <sys/shm.h>
  54. #include <fcntl.h>
  55.  
  56. #include <linux/futex.h>
  57. #include <sys/syscall.h>
  58. #include <sys/time.h>
  59.  
  60. #include <netdb.h>
  61. #include <unistd.h>
  62. #include <syslog.h>
  63. #include <locale.h>
  64. #include <sys/syscall.h>
  65. #include <sys/auxv.h>
  66. #include <sys/prctl.h>
  67.  
  68. #include <sys/mman.h>
  69. #include <libgen.h>
  70. #include <mntent.h>
  71.  
  72. #include <hybris/properties/properties.h>
  73. #include <hybris/common/hooks.h>
  74.  
  75. #include "pthread_helpers.h"
  76.  
  77. #ifndef WANT_INITIALIZE_BIONIC
  78. static locale_t hybris_locale;
  79. static int locale_inited = 0;
  80. #endif
  81. static hybris_hook_cb hook_callback = NULL;
  82.  
  83. static void (*_android_linker_init)(int sdk_version, void* (*get_hooked_symbol)(const char*, const char*)) = NULL;
  84. static void* (*_android_dlopen)(const char *filename, int flags) = NULL;
  85. static void* (*_android_dlsym)(void *handle, const char *symbol) = NULL;
  86. static void* (*_android_dladdr)(void *addr, Dl_info *info) = NULL;
  87. static int (*_android_dlclose)(void *handle) = NULL;
  88. static const char* (*_android_dlerror)(void) = NULL;
  89.  
  90. /* TODO:
  91. * - Check if the int arguments at attr_set/get match the ones at Android
  92. * - Check how to deal with memory leaks (specially with static initializers)
  93. * - Check for shared rwlock
  94. */
  95.  
  96. /* Base address to check for Android specifics */
  97. #define ANDROID_TOP_ADDR_VALUE_MUTEX 0xFFFF
  98. #define ANDROID_TOP_ADDR_VALUE_COND 0xFFFF
  99. #define ANDROID_TOP_ADDR_VALUE_RWLOCK 0xFFFF
  100.  
  101. #define ANDROID_MUTEX_SHARED_MASK 0x2000
  102. #define ANDROID_COND_SHARED_MASK 0x0001
  103. #define ANDROID_COND_COUNTER_INCREMENT 0x0002
  104. #define ANDROID_COND_COUNTER_MASK (~ANDROID_COND_SHARED_MASK)
  105. #define ANDROID_RWLOCKATTR_SHARED_MASK 0x0010
  106.  
  107. #define ANDROID_COND_IS_SHARED(c) (((c)->value & ANDROID_COND_SHARED_MASK) != 0)
  108.  
  109. /* For the static initializer types */
  110. #define ANDROID_PTHREAD_MUTEX_INITIALIZER 0
  111. #define ANDROID_PTHREAD_RECURSIVE_MUTEX_INITIALIZER 0x4000
  112. #define ANDROID_PTHREAD_ERRORCHECK_MUTEX_INITIALIZER 0x8000
  113. #define ANDROID_PTHREAD_COND_INITIALIZER 0
  114. #define ANDROID_PTHREAD_RWLOCK_INITIALIZER 0
  115.  
  116. #define MALI_HIST_DUMP_THREAD_NAME "mali-hist-dump"
  117.  
  118. /* Debug */
  119. #include "logging.h"
  120. #define LOGD(message, ...) HYBRIS_DEBUG_LOG(HOOKS, message, ##__VA_ARGS__)
  121.  
  122. #define TRACE_HOOK(message, ...) \
  123. HYBRIS_DEBUG_LOG(HOOKS, message, ##__VA_ARGS__);
  124.  
  125. /*
  126. * symbols that can be hooked directly shall use HOOK_DIRECT
  127. * - during debug they will be redirected to a function that traces the calls
  128. * - during normal execution they will be redirected to the glibc equivalent
  129. */
  130. #define HOOK_DIRECT(symbol) {#symbol, symbol, _hybris_hook_##symbol}
  131.  
  132. /*
  133. * same as above but for symbols who have no dedicated debug wrapper
  134. */
  135. #define HOOK_DIRECT_NO_DEBUG(symbol) {#symbol, symbol, symbol}
  136.  
  137. /*
  138. * symbols that can only be hooked directly to a (symbol with a different name)
  139. * shall use HOOK_TO
  140. */
  141. #define HOOK_TO(symbol, hook) {#symbol, hook, hook}
  142.  
  143. /*
  144. * symbols that can only be hooked indirectly shall use HOOK
  145. */
  146. #define HOOK_INDIRECT(symbol) {#symbol, _hybris_hook_##symbol, _hybris_hook_##symbol}
  147.  
  148. /* we have a value p:
  149. * - if p <= ANDROID_TOP_ADDR_VALUE_MUTEX then it is an android mutex, not one we processed
  150. * - if p > VMALLOC_END, then the pointer is not a result of malloc ==> it is an shm offset
  151. */
  152.  
  153. struct _hook {
  154. const char *name;
  155. void *func;
  156. void *debug_func;
  157. };
  158.  
  159. /* pthread cond struct as done in Android */
  160. typedef struct {
  161. int volatile value;
  162. } android_cond_t;
  163.  
  164. /* Helpers */
  165. static int hybris_check_android_shared_mutex(uintptr_t mutex_addr)
  166. {
  167. /* If not initialized or initialized by Android, it should contain a low
  168. * address, which is basically just the int values for Android's own
  169. * pthread_mutex_t */
  170. if ((mutex_addr <= ANDROID_TOP_ADDR_VALUE_MUTEX) &&
  171. (mutex_addr & ANDROID_MUTEX_SHARED_MASK))
  172. return 1;
  173.  
  174. return 0;
  175. }
  176.  
  177. static int hybris_check_android_shared_cond(uintptr_t cond_addr)
  178. {
  179. /* If not initialized or initialized by Android, it should contain a low
  180. * address, which is basically just the int values for Android's own
  181. * pthread_cond_t */
  182. if ((cond_addr <= ANDROID_TOP_ADDR_VALUE_COND) &&
  183. (cond_addr & ANDROID_COND_SHARED_MASK))
  184. return 1;
  185.  
  186. /* In case android is setting up cond_addr with a negative value,
  187. * used for error control */
  188. if (cond_addr > HYBRIS_SHM_MASK_TOP)
  189. return 1;
  190.  
  191. return 0;
  192. }
  193.  
  194. /* Based on Android's Bionic pthread implementation.
  195. * This is just needed when we have a shared cond with Android */
  196. static int __android_pthread_cond_pulse(android_cond_t *cond, int counter)
  197. {
  198. long flags;
  199. int fret;
  200.  
  201. if (cond == NULL)
  202. return EINVAL;
  203.  
  204. flags = (cond->value & ~ANDROID_COND_COUNTER_MASK);
  205. for (;;) {
  206. long oldval = cond->value;
  207. long newval = 0;
  208. /* In our case all we need to do is make sure the negative value
  209. * is under our range, which is the last 0xF from SHM_MASK */
  210. if (oldval < -12)
  211. newval = ((oldval + ANDROID_COND_COUNTER_INCREMENT) &
  212. ANDROID_COND_COUNTER_MASK) | flags;
  213. else
  214. newval = ((oldval - ANDROID_COND_COUNTER_INCREMENT) &
  215. ANDROID_COND_COUNTER_MASK) | flags;
  216. if (__sync_bool_compare_and_swap(&cond->value, oldval, newval))
  217. break;
  218. }
  219.  
  220. int pshared = cond->value & ANDROID_COND_SHARED_MASK;
  221. fret = syscall(SYS_futex , &cond->value,
  222. pshared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, counter,
  223. NULL, NULL, NULL);
  224. LOGD("futex based pthread_cond_*, value %d, counter %d, ret %d",
  225. cond->value, counter, fret);
  226. return 0;
  227. }
  228.  
  229. int android_pthread_cond_broadcast(android_cond_t *cond)
  230. {
  231. return __android_pthread_cond_pulse(cond, INT_MAX);
  232. }
  233.  
  234. int android_pthread_cond_signal(android_cond_t *cond)
  235. {
  236. return __android_pthread_cond_pulse(cond, 1);
  237. }
  238.  
  239. static void hybris_set_mutex_attr(unsigned int android_value, pthread_mutexattr_t *attr)
  240. {
  241. /* Init already sets as PTHREAD_MUTEX_NORMAL */
  242. pthread_mutexattr_init(attr);
  243.  
  244. if (android_value & ANDROID_PTHREAD_RECURSIVE_MUTEX_INITIALIZER) {
  245. pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE);
  246. } else if (android_value & ANDROID_PTHREAD_ERRORCHECK_MUTEX_INITIALIZER) {
  247. pthread_mutexattr_settype(attr, PTHREAD_MUTEX_ERRORCHECK);
  248. }
  249. }
  250.  
  251. static pthread_mutex_t* hybris_alloc_init_mutex(unsigned int android_mutex)
  252. {
  253. pthread_mutex_t *realmutex = malloc(sizeof(pthread_mutex_t));
  254. pthread_mutexattr_t attr;
  255. hybris_set_mutex_attr(android_mutex, &attr);
  256. pthread_mutex_init(realmutex, &attr);
  257. return realmutex;
  258. }
  259.  
  260. static pthread_cond_t* hybris_alloc_init_cond(void)
  261. {
  262. pthread_cond_t *realcond = malloc(sizeof(pthread_cond_t));
  263. pthread_condattr_t attr;
  264. pthread_condattr_init(&attr);
  265. pthread_cond_init(realcond, &attr);
  266. return realcond;
  267. }
  268.  
  269. static pthread_rwlock_t* hybris_alloc_init_rwlock(void)
  270. {
  271. pthread_rwlock_t *realrwlock = malloc(sizeof(pthread_rwlock_t));
  272. pthread_rwlockattr_t attr;
  273. pthread_rwlockattr_init(&attr);
  274. pthread_rwlock_init(realrwlock, &attr);
  275. return realrwlock;
  276. }
  277.  
  278. /*
  279. * Main pthread functions
  280. *
  281. * Custom implementations to workaround difference between Bionic and Glibc.
  282. * Our own pthread_create helps avoiding direct handling of TLS.
  283. *
  284. * */
  285.  
  286. struct hybris_start_routine_t {
  287. void *(*start_routine)(void*);
  288. void *arg;
  289. volatile pid_t pid;
  290. };
  291.  
  292. void hybris_pthread_start_routine(void *a)
  293. {
  294. struct hybris_start_routine_t *sr = (struct hybris_start_routine*)a;
  295. pid_t pid;
  296.  
  297. void *(*start_routine)(void*) = sr->start_routine;
  298. void *arg = sr->arg;
  299.  
  300. pid = sr->pid = syscall(__NR_gettid);
  301.  
  302. start_routine(arg);
  303.  
  304. // sr is free'd by the thread which created this so use pid here
  305. remove_pthread_pid_mapping(pid);
  306. }
  307.  
  308. static int _hybris_hook_pthread_create(pthread_t *thread, const pthread_attr_t *__attr,
  309. void *(*start_routine)(void*), void *arg)
  310. {
  311. pthread_attr_t *realattr = NULL;
  312. int ret = 0;
  313.  
  314. TRACE_HOOK("thread %p attr %p", thread, __attr);
  315.  
  316. if (__attr != NULL)
  317. realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  318.  
  319. struct hybris_start_routine_t *sr = (struct hybris_start_routine_t*)malloc(sizeof(struct hybris_start_routine_t));
  320.  
  321. sr->start_routine = start_routine;
  322. sr->arg = arg;
  323. sr->pid = -1;
  324.  
  325. ret = pthread_create(thread, realattr, hybris_pthread_start_routine, sr);
  326.  
  327. while(sr->pid == -1)
  328. {
  329. pthread_yield();
  330. }
  331.  
  332. add_pthread_pid_mapping(*thread, sr->pid);
  333.  
  334. free(sr);
  335.  
  336. return ret;
  337. }
  338.  
  339. static int _hybris_hook_pthread_kill(pthread_t thread, int sig)
  340. {
  341. TRACE_HOOK("thread %llu sig %d", (unsigned long long) thread, sig);
  342.  
  343. if (thread == 0)
  344. return ESRCH;
  345.  
  346. return pthread_kill(thread, sig);
  347. }
  348.  
  349. static int _hybris_hook_pthread_setspecific(pthread_key_t key, const void *ptr)
  350. {
  351. TRACE_HOOK("key %d ptr %" PRIdPTR, key, (intptr_t) ptr);
  352.  
  353. // see android_bionic/tests/pthread_test.cpp, test static_pthread_key_used_before_creation
  354. if(!key) return EINVAL;
  355.  
  356. return pthread_setspecific(key, ptr);
  357. }
  358.  
  359. static void* _hybris_hook_pthread_getspecific(pthread_key_t key)
  360. {
  361. TRACE_HOOK("key %d", key);
  362.  
  363. // see android_bionic/tests/pthread_test.cpp, test static_pthread_key_used_before_creation
  364. if(!key) return NULL;
  365.  
  366. return pthread_getspecific(key);
  367. }
  368.  
  369. static int _hybris_hook_pthread_key_delete(pthread_key_t key)
  370. {
  371. TRACE_HOOK("key %d", key);
  372.  
  373. // see android_bionic/tests/pthread_test.cpp, test static_pthread_key_used_before_creation
  374. if(!key) return EINVAL;
  375.  
  376. return pthread_key_delete(key);
  377. }
  378.  
  379. /*
  380. * pthread_attr_* functions
  381. *
  382. * Specific implementations to workaround the differences between at the
  383. * pthread_attr_t struct differences between Bionic and Glibc.
  384. *
  385. * */
  386.  
  387. static int _hybris_hook_pthread_attr_init(pthread_attr_t *__attr)
  388. {
  389. pthread_attr_t *realattr;
  390.  
  391. TRACE_HOOK("attr %p", __attr);
  392.  
  393. realattr = malloc(sizeof(pthread_attr_t));
  394. *((uintptr_t *)__attr) = (uintptr_t) realattr;
  395.  
  396. return pthread_attr_init(realattr);
  397. }
  398.  
  399. static int _hybris_hook_pthread_attr_destroy(pthread_attr_t *__attr)
  400. {
  401. int ret;
  402. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  403.  
  404. TRACE_HOOK("attr %p", __attr);
  405.  
  406. ret = pthread_attr_destroy(realattr);
  407. /* We need to release the memory allocated at _hybris_hook_pthread_attr_init
  408. * Possible side effects if destroy is called without our init */
  409. free(realattr);
  410.  
  411. return ret;
  412. }
  413.  
  414. static int _hybris_hook_pthread_attr_setdetachstate(pthread_attr_t *__attr, int state)
  415. {
  416. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  417.  
  418. TRACE_HOOK("attr %p state %d", __attr, state);
  419.  
  420. return pthread_attr_setdetachstate(realattr, state);
  421. }
  422.  
  423. static int _hybris_hook_pthread_attr_getdetachstate(pthread_attr_t const *__attr, int *state)
  424. {
  425. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  426.  
  427. TRACE_HOOK("attr %p state %p", __attr, state);
  428.  
  429. return pthread_attr_getdetachstate(realattr, state);
  430. }
  431.  
  432. static int _hybris_hook_pthread_attr_setschedpolicy(pthread_attr_t *__attr, int policy)
  433. {
  434. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  435.  
  436. TRACE_HOOK("attr %p policy %d", __attr, policy);
  437.  
  438. return pthread_attr_setschedpolicy(realattr, policy);
  439. }
  440.  
  441. static int _hybris_hook_pthread_attr_getschedpolicy(pthread_attr_t const *__attr, int *policy)
  442. {
  443. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  444.  
  445. TRACE_HOOK("attr %p policy %p", __attr, policy);
  446.  
  447. return pthread_attr_getschedpolicy(realattr, policy);
  448. }
  449.  
  450. static int _hybris_hook_pthread_attr_setschedparam(pthread_attr_t *__attr, struct sched_param const *param)
  451. {
  452. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  453.  
  454. TRACE_HOOK("attr %p param %p", __attr, param);
  455.  
  456. return pthread_attr_setschedparam(realattr, param);
  457. }
  458.  
  459. static int _hybris_hook_pthread_attr_getschedparam(pthread_attr_t const *__attr, struct sched_param *param)
  460. {
  461. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  462.  
  463. TRACE_HOOK("attr %p param %p", __attr, param);
  464.  
  465. return pthread_attr_getschedparam(realattr, param);
  466. }
  467.  
  468. static int _hybris_hook_pthread_attr_setstacksize(pthread_attr_t *__attr, size_t stack_size)
  469. {
  470. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  471.  
  472. TRACE_HOOK("attr %p stack size %zu", __attr, stack_size);
  473.  
  474. return pthread_attr_setstacksize(realattr, stack_size);
  475. }
  476.  
  477. static int _hybris_hook_pthread_attr_getstacksize(pthread_attr_t const *__attr, size_t *stack_size)
  478. {
  479. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  480.  
  481. TRACE_HOOK("attr %p stack size %p", __attr, stack_size);
  482.  
  483. return pthread_attr_getstacksize(realattr, stack_size);
  484. }
  485.  
  486. static int _hybris_hook_pthread_attr_setstackaddr(pthread_attr_t *__attr, void *stack_addr)
  487. {
  488. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  489.  
  490. TRACE_HOOK("attr %p stack addr %p", __attr, stack_addr);
  491.  
  492. return pthread_attr_setstackaddr(realattr, stack_addr);
  493. }
  494.  
  495. static int _hybris_hook_pthread_attr_getstackaddr(pthread_attr_t const *__attr, void **stack_addr)
  496. {
  497. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  498.  
  499. TRACE_HOOK("attr %p stack addr %p", __attr, stack_addr);
  500.  
  501. return pthread_attr_getstackaddr(realattr, stack_addr);
  502. }
  503.  
  504. static int _hybris_hook_pthread_attr_setstack(pthread_attr_t *__attr, void *stack_base, size_t stack_size)
  505. {
  506. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  507.  
  508. TRACE_HOOK("attr %p stack base %p stack size %zu", __attr,
  509. stack_base, stack_size);
  510.  
  511. return pthread_attr_setstack(realattr, stack_base, stack_size);
  512. }
  513.  
  514. static int _hybris_hook_pthread_attr_getstack(pthread_attr_t const *__attr, void **stack_base, size_t *stack_size)
  515. {
  516. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  517.  
  518. TRACE_HOOK("attr %p stack base %p stack size %p", __attr,
  519. stack_base, stack_size);
  520.  
  521. return pthread_attr_getstack(realattr, stack_base, stack_size);
  522. }
  523.  
  524. static int _hybris_hook_pthread_attr_setguardsize(pthread_attr_t *__attr, size_t guard_size)
  525. {
  526. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  527.  
  528. TRACE_HOOK("attr %p guard size %zu", __attr, guard_size);
  529.  
  530. return pthread_attr_setguardsize(realattr, guard_size);
  531. }
  532.  
  533. static int _hybris_hook_pthread_attr_getguardsize(pthread_attr_t const *__attr, size_t *guard_size)
  534. {
  535. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  536.  
  537. TRACE_HOOK("attr %p guard size %p", __attr, guard_size);
  538.  
  539. return pthread_attr_getguardsize(realattr, guard_size);
  540. }
  541.  
  542. static int _hybris_hook_pthread_attr_setscope(pthread_attr_t *__attr, int scope)
  543. {
  544. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  545.  
  546. TRACE_HOOK("attr %p scope %d", __attr, scope);
  547.  
  548. return pthread_attr_setscope(realattr, scope);
  549. }
  550.  
  551. static int _hybris_hook_pthread_attr_getscope(pthread_attr_t const *__attr)
  552. {
  553. int scope;
  554. pthread_attr_t *realattr = (pthread_attr_t *) *(uintptr_t *) __attr;
  555.  
  556. TRACE_HOOK("attr %p", __attr);
  557.  
  558. /* Android doesn't have the scope attribute because it always
  559. * returns PTHREAD_SCOPE_SYSTEM */
  560. pthread_attr_getscope(realattr, &scope);
  561.  
  562. return scope;
  563. }
  564.  
  565. static int _hybris_hook_pthread_getattr_np(pthread_t thid, pthread_attr_t *__attr)
  566. {
  567. pthread_attr_t *realattr;
  568.  
  569. TRACE_HOOK("attr %p", __attr);
  570.  
  571. realattr = malloc(sizeof(pthread_attr_t));
  572. *((uintptr_t *)__attr) = (uintptr_t) realattr;
  573.  
  574. return pthread_getattr_np(thid, realattr);
  575. }
  576.  
  577. /*
  578. * pthread_mutex* functions
  579. *
  580. * Specific implementations to workaround the differences between at the
  581. * pthread_mutex_t struct differences between Bionic and Glibc.
  582. *
  583. * */
  584.  
  585. static int _hybris_hook_pthread_mutex_init(pthread_mutex_t *__mutex,
  586. __const pthread_mutexattr_t *__mutexattr)
  587. {
  588. pthread_mutex_t *realmutex = NULL;
  589.  
  590. TRACE_HOOK("mutex %p attr %p", __mutex, __mutexattr);
  591.  
  592. int pshared = 0;
  593. if (__mutexattr)
  594. pthread_mutexattr_getpshared(__mutexattr, &pshared);
  595.  
  596. if (!pshared) {
  597. /* non shared, standard mutex: use malloc */
  598. realmutex = malloc(sizeof(pthread_mutex_t));
  599.  
  600. *((uintptr_t *)__mutex) = (uintptr_t) realmutex;
  601. }
  602. else {
  603. /* process-shared mutex: use the shared memory segment */
  604. hybris_shm_pointer_t handle = hybris_shm_alloc(sizeof(pthread_mutex_t));
  605.  
  606. *((hybris_shm_pointer_t *)__mutex) = handle;
  607.  
  608. if (handle)
  609. realmutex = (pthread_mutex_t *)hybris_get_shmpointer(handle);
  610. }
  611.  
  612. return pthread_mutex_init(realmutex, __mutexattr);
  613. }
  614.  
  615. static int _hybris_hook_pthread_mutex_destroy(pthread_mutex_t *__mutex)
  616. {
  617. int ret;
  618.  
  619. TRACE_HOOK("mutex %p", __mutex);
  620.  
  621. if (!__mutex)
  622. return EINVAL;
  623.  
  624. pthread_mutex_t *realmutex = (pthread_mutex_t *) *(uintptr_t *) __mutex;
  625.  
  626. if (!realmutex)
  627. return EINVAL;
  628.  
  629. if (!hybris_is_pointer_in_shm((void*)realmutex)) {
  630. ret = pthread_mutex_destroy(realmutex);
  631. free(realmutex);
  632. }
  633. else {
  634. realmutex = (pthread_mutex_t *)hybris_get_shmpointer((hybris_shm_pointer_t)realmutex);
  635. ret = pthread_mutex_destroy(realmutex);
  636. }
  637.  
  638. *((uintptr_t *)__mutex) = 0;
  639.  
  640. return ret;
  641. }
  642.  
  643. static int _hybris_hook_pthread_mutex_lock(pthread_mutex_t *__mutex)
  644. {
  645. TRACE_HOOK("mutex %p", __mutex);
  646.  
  647. if (!__mutex) {
  648. LOGD("Null mutex lock, not locking.");
  649. return 0;
  650. }
  651.  
  652. uintptr_t value = (*(uintptr_t *) __mutex);
  653. if (hybris_check_android_shared_mutex(value)) {
  654. LOGD("Shared mutex with Android, not locking.");
  655. return 0;
  656. }
  657.  
  658. pthread_mutex_t *realmutex = (pthread_mutex_t *) value;
  659. if (hybris_is_pointer_in_shm((void*)value))
  660. realmutex = (pthread_mutex_t *)hybris_get_shmpointer((hybris_shm_pointer_t)value);
  661.  
  662. if (value <= ANDROID_TOP_ADDR_VALUE_MUTEX) {
  663. TRACE("value %p <= ANDROID_TOP_ADDR_VALUE_MUTEX 0x%x",
  664. (void*) value, ANDROID_TOP_ADDR_VALUE_MUTEX);
  665. realmutex = hybris_alloc_init_mutex(value);
  666. *((uintptr_t *)__mutex) = (uintptr_t) realmutex;
  667. }
  668.  
  669. return pthread_mutex_lock(realmutex);
  670. }
  671.  
  672. static int _hybris_hook_pthread_mutex_trylock(pthread_mutex_t *__mutex)
  673. {
  674. uintptr_t value = (*(uintptr_t *) __mutex);
  675.  
  676. TRACE_HOOK("mutex %p", __mutex);
  677.  
  678. if (hybris_check_android_shared_mutex(value)) {
  679. LOGD("Shared mutex with Android, not try locking.");
  680. return 0;
  681. }
  682.  
  683. pthread_mutex_t *realmutex = (pthread_mutex_t *) value;
  684. if (hybris_is_pointer_in_shm((void*)value))
  685. realmutex = (pthread_mutex_t *)hybris_get_shmpointer((hybris_shm_pointer_t)value);
  686.  
  687. if (value <= ANDROID_TOP_ADDR_VALUE_MUTEX) {
  688. realmutex = hybris_alloc_init_mutex(value);
  689. *((uintptr_t *)__mutex) = (uintptr_t) realmutex;
  690. }
  691.  
  692. return pthread_mutex_trylock(realmutex);
  693. }
  694.  
  695. static int _hybris_hook_pthread_mutex_unlock(pthread_mutex_t *__mutex)
  696. {
  697. TRACE_HOOK("mutex %p", __mutex);
  698.  
  699. if (!__mutex) {
  700. LOGD("Null mutex lock, not unlocking.");
  701. return 0;
  702. }
  703.  
  704. uintptr_t value = (*(uintptr_t *) __mutex);
  705. if (hybris_check_android_shared_mutex(value)) {
  706. LOGD("Shared mutex with Android, not unlocking.");
  707. return 0;
  708. }
  709.  
  710. if (value <= ANDROID_TOP_ADDR_VALUE_MUTEX) {
  711. LOGD("Trying to unlock a lock that's not locked/initialized"
  712. " by Hybris, not unlocking.");
  713. return 0;
  714. }
  715.  
  716. pthread_mutex_t *realmutex = (pthread_mutex_t *) value;
  717. if (hybris_is_pointer_in_shm((void*)value))
  718. realmutex = (pthread_mutex_t *)hybris_get_shmpointer((hybris_shm_pointer_t)value);
  719.  
  720. return pthread_mutex_unlock(realmutex);
  721. }
  722.  
  723. static int _hybris_hook_pthread_mutex_lock_timeout_np(pthread_mutex_t *__mutex, unsigned __msecs)
  724. {
  725. struct timespec tv;
  726. pthread_mutex_t *realmutex;
  727. uintptr_t value = (*(uintptr_t *) __mutex);
  728.  
  729. TRACE_HOOK("mutex %p msecs %u", __mutex, __msecs);
  730.  
  731. if (hybris_check_android_shared_mutex(value)) {
  732. LOGD("Shared mutex with Android, not lock timeout np.");
  733. return 0;
  734. }
  735.  
  736. realmutex = (pthread_mutex_t *) value;
  737.  
  738. if (value <= ANDROID_TOP_ADDR_VALUE_MUTEX) {
  739. realmutex = hybris_alloc_init_mutex(value);
  740. *((uintptr_t *)__mutex) = (uintptr_t) realmutex;
  741. }
  742.  
  743. clock_gettime(CLOCK_REALTIME, &tv);
  744. tv.tv_sec += __msecs/1000;
  745. tv.tv_nsec += (__msecs % 1000) * 1000000;
  746. if (tv.tv_nsec >= 1000000000) {
  747. tv.tv_sec++;
  748. tv.tv_nsec -= 1000000000;
  749. }
  750.  
  751. return pthread_mutex_timedlock(realmutex, &tv);
  752. }
  753.  
  754. static int _hybris_hook_pthread_mutex_timedlock(pthread_mutex_t *__mutex,
  755. const struct timespec *__abs_timeout)
  756. {
  757. TRACE_HOOK("mutex %p abs timeout %p", __mutex, __abs_timeout);
  758.  
  759. if (!__mutex) {
  760. LOGD("Null mutex lock, not unlocking.");
  761. return 0;
  762. }
  763.  
  764. uintptr_t value = (*(uintptr_t *) __mutex);
  765. if (hybris_check_android_shared_mutex(value)) {
  766. LOGD("Shared mutex with Android, not lock timeout np.");
  767. return 0;
  768. }
  769.  
  770. pthread_mutex_t *realmutex = (pthread_mutex_t *) value;
  771. if (value <= ANDROID_TOP_ADDR_VALUE_MUTEX) {
  772. realmutex = hybris_alloc_init_mutex(value);
  773. *((uintptr_t *)__mutex) = (uintptr_t) realmutex;
  774. }
  775.  
  776. return pthread_mutex_timedlock(realmutex, __abs_timeout);
  777. }
  778.  
  779. static int _hybris_hook_pthread_mutexattr_setpshared(pthread_mutexattr_t *__attr,
  780. int pshared)
  781. {
  782. TRACE_HOOK("attr %p pshared %d", __attr, pshared);
  783.  
  784. return pthread_mutexattr_setpshared(__attr, pshared);
  785. }
  786.  
  787. /*
  788. * pthread_cond* functions
  789. *
  790. * Specific implementations to workaround the differences between at the
  791. * pthread_cond_t struct differences between Bionic and Glibc.
  792. *
  793. * */
  794.  
  795. static int _hybris_hook_pthread_cond_init(pthread_cond_t *cond,
  796. const pthread_condattr_t *attr)
  797. {
  798. pthread_cond_t *realcond = NULL;
  799.  
  800. TRACE_HOOK("cond %p attr %p", cond, attr);
  801.  
  802. int pshared = 0;
  803.  
  804. if (attr)
  805. pthread_condattr_getpshared(attr, &pshared);
  806.  
  807. if (!pshared) {
  808. /* non shared, standard cond: use malloc */
  809. realcond = malloc(sizeof(pthread_cond_t));
  810.  
  811. *((uintptr_t *) cond) = (uintptr_t) realcond;
  812. }
  813. else {
  814. /* process-shared condition: use the shared memory segment */
  815. hybris_shm_pointer_t handle = hybris_shm_alloc(sizeof(pthread_cond_t));
  816.  
  817. *((uintptr_t *)cond) = (uintptr_t) handle;
  818.  
  819. if (handle)
  820. realcond = (pthread_cond_t *)hybris_get_shmpointer(handle);
  821. }
  822.  
  823. return pthread_cond_init(realcond, attr);
  824. }
  825.  
  826. static int _hybris_hook_pthread_cond_destroy(pthread_cond_t *cond)
  827. {
  828. int ret;
  829. pthread_cond_t *realcond = (pthread_cond_t *) *(uintptr_t *) cond;
  830.  
  831. TRACE_HOOK("cond %p", cond);
  832.  
  833. if (!realcond) {
  834. return EINVAL;
  835. }
  836.  
  837. if (!hybris_is_pointer_in_shm((void*)realcond)) {
  838. ret = pthread_cond_destroy(realcond);
  839. free(realcond);
  840. }
  841. else {
  842. realcond = (pthread_cond_t *)hybris_get_shmpointer((hybris_shm_pointer_t)realcond);
  843. ret = pthread_cond_destroy(realcond);
  844. }
  845.  
  846. *((uintptr_t *)cond) = 0;
  847.  
  848. return ret;
  849. }
  850.  
  851. static int _hybris_hook_pthread_cond_broadcast(pthread_cond_t *cond)
  852. {
  853. uintptr_t value = (*(uintptr_t *) cond);
  854.  
  855. TRACE_HOOK("cond %p", cond);
  856.  
  857. if (hybris_check_android_shared_cond(value)) {
  858. LOGD("Shared condition with Android, broadcasting with futex.");
  859. return android_pthread_cond_broadcast((android_cond_t *) cond);
  860. }
  861.  
  862. pthread_cond_t *realcond = (pthread_cond_t *) value;
  863. if (hybris_is_pointer_in_shm((void*)value))
  864. realcond = (pthread_cond_t *)hybris_get_shmpointer((hybris_shm_pointer_t)value);
  865.  
  866. if (value <= ANDROID_TOP_ADDR_VALUE_COND) {
  867. realcond = hybris_alloc_init_cond();
  868. *((uintptr_t *) cond) = (uintptr_t) realcond;
  869. }
  870.  
  871. return pthread_cond_broadcast(realcond);
  872. }
  873.  
  874. static int _hybris_hook_pthread_cond_signal(pthread_cond_t *cond)
  875. {
  876. uintptr_t value = (*(uintptr_t *) cond);
  877.  
  878. TRACE_HOOK("cond %p", cond);
  879.  
  880. if (hybris_check_android_shared_cond(value)) {
  881. LOGD("Shared condition with Android, broadcasting with futex.");
  882. return android_pthread_cond_signal((android_cond_t *) cond);
  883. }
  884.  
  885. pthread_cond_t *realcond = (pthread_cond_t *) value;
  886. if (hybris_is_pointer_in_shm((void*)value))
  887. realcond = (pthread_cond_t *)hybris_get_shmpointer((hybris_shm_pointer_t)value);
  888.  
  889. if (value <= ANDROID_TOP_ADDR_VALUE_COND) {
  890. realcond = hybris_alloc_init_cond();
  891. *((uintptr_t *) cond) = (uintptr_t) realcond;
  892. }
  893.  
  894. return pthread_cond_signal(realcond);
  895. }
  896.  
  897. static int _hybris_hook_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
  898. {
  899. /* Both cond and mutex can be statically initialized, check for both */
  900. uintptr_t cvalue = (*(uintptr_t *) cond);
  901. uintptr_t mvalue = (*(uintptr_t *) mutex);
  902.  
  903. TRACE_HOOK("cond %p mutex %p", cond, mutex);
  904.  
  905. if (hybris_check_android_shared_cond(cvalue) ||
  906. hybris_check_android_shared_mutex(mvalue)) {
  907. LOGD("Shared condition/mutex with Android, not waiting.");
  908. return 0;
  909. }
  910.  
  911. pthread_cond_t *realcond = (pthread_cond_t *) cvalue;
  912. if (hybris_is_pointer_in_shm((void*)cvalue))
  913. realcond = (pthread_cond_t *)hybris_get_shmpointer((hybris_shm_pointer_t)cvalue);
  914.  
  915. if (cvalue <= ANDROID_TOP_ADDR_VALUE_COND) {
  916. realcond = hybris_alloc_init_cond();
  917. *((uintptr_t *) cond) = (uintptr_t) realcond;
  918. }
  919.  
  920. pthread_mutex_t *realmutex = (pthread_mutex_t *) mvalue;
  921. if (hybris_is_pointer_in_shm((void*)mvalue))
  922. realmutex = (pthread_mutex_t *)hybris_get_shmpointer((hybris_shm_pointer_t)mvalue);
  923.  
  924. if (mvalue <= ANDROID_TOP_ADDR_VALUE_MUTEX) {
  925. realmutex = hybris_alloc_init_mutex(mvalue);
  926. *((uintptr_t *) mutex) = (uintptr_t) realmutex;
  927. }
  928.  
  929. return pthread_cond_wait(realcond, realmutex);
  930. }
  931.  
  932. static int _hybris_hook_pthread_cond_timedwait(pthread_cond_t *cond,
  933. pthread_mutex_t *mutex, const struct timespec *abstime)
  934. {
  935. /* Both cond and mutex can be statically initialized, check for both */
  936. uintptr_t cvalue = (*(uintptr_t *) cond);
  937. uintptr_t mvalue = (*(uintptr_t *) mutex);
  938.  
  939. TRACE_HOOK("cond %p mutex %p abstime %p", cond, mutex, abstime);
  940.  
  941. if (hybris_check_android_shared_cond(cvalue) ||
  942. hybris_check_android_shared_mutex(mvalue)) {
  943. LOGD("Shared condition/mutex with Android, not waiting.");
  944. return 0;
  945. }
  946.  
  947. pthread_cond_t *realcond = (pthread_cond_t *) cvalue;
  948. if (hybris_is_pointer_in_shm((void*)cvalue))
  949. realcond = (pthread_cond_t *)hybris_get_shmpointer((hybris_shm_pointer_t)cvalue);
  950.  
  951. if (cvalue <= ANDROID_TOP_ADDR_VALUE_COND) {
  952. realcond = hybris_alloc_init_cond();
  953. *((uintptr_t *) cond) = (uintptr_t) realcond;
  954. }
  955.  
  956. pthread_mutex_t *realmutex = (pthread_mutex_t *) mvalue;
  957. if (hybris_is_pointer_in_shm((void*)mvalue))
  958. realmutex = (pthread_mutex_t *)hybris_get_shmpointer((hybris_shm_pointer_t)mvalue);
  959.  
  960. if (mvalue <= ANDROID_TOP_ADDR_VALUE_MUTEX) {
  961. realmutex = hybris_alloc_init_mutex(mvalue);
  962. *((uintptr_t *) mutex) = (uintptr_t) realmutex;
  963. }
  964.  
  965. return pthread_cond_timedwait(realcond, realmutex, abstime);
  966. }
  967.  
  968. static int _hybris_hook_pthread_cond_timedwait_relative_np(pthread_cond_t *cond,
  969. pthread_mutex_t *mutex, const struct timespec *reltime)
  970. {
  971. /* Both cond and mutex can be statically initialized, check for both */
  972. uintptr_t cvalue = (*(uintptr_t *) cond);
  973. uintptr_t mvalue = (*(uintptr_t *) mutex);
  974.  
  975. TRACE_HOOK("cond %p mutex %p reltime %p", cond, mutex, reltime);
  976.  
  977. if (hybris_check_android_shared_cond(cvalue) ||
  978. hybris_check_android_shared_mutex(mvalue)) {
  979. LOGD("Shared condition/mutex with Android, not waiting.");
  980. return 0;
  981. }
  982.  
  983. pthread_cond_t *realcond = (pthread_cond_t *) cvalue;
  984. if( hybris_is_pointer_in_shm((void*)cvalue) )
  985. realcond = (pthread_cond_t *)hybris_get_shmpointer((hybris_shm_pointer_t)cvalue);
  986.  
  987. if (cvalue <= ANDROID_TOP_ADDR_VALUE_COND) {
  988. realcond = hybris_alloc_init_cond();
  989. *((uintptr_t *) cond) = (uintptr_t) realcond;
  990. }
  991.  
  992. pthread_mutex_t *realmutex = (pthread_mutex_t *) mvalue;
  993. if (hybris_is_pointer_in_shm((void*)mvalue))
  994. realmutex = (pthread_mutex_t *)hybris_get_shmpointer((hybris_shm_pointer_t)mvalue);
  995.  
  996. if (mvalue <= ANDROID_TOP_ADDR_VALUE_MUTEX) {
  997. realmutex = hybris_alloc_init_mutex(mvalue);
  998. *((uintptr_t *) mutex) = (uintptr_t) realmutex;
  999. }
  1000.  
  1001. struct timespec tv;
  1002. clock_gettime(CLOCK_REALTIME, &tv);
  1003. tv.tv_sec += reltime->tv_sec;
  1004. tv.tv_nsec += reltime->tv_nsec;
  1005. if (tv.tv_nsec >= 1000000000) {
  1006. tv.tv_sec++;
  1007. tv.tv_nsec -= 1000000000;
  1008. }
  1009. return pthread_cond_timedwait(realcond, realmutex, &tv);
  1010. }
  1011.  
  1012. int _hybris_hook_pthread_setname_np(pthread_t thread, const char *name)
  1013. {
  1014. TRACE_HOOK("thread %llu name %s", (unsigned long long) thread, name);
  1015.  
  1016. #ifdef MALI_QUIRKS
  1017. if (strcmp(name, MALI_HIST_DUMP_THREAD_NAME) == 0) {
  1018. HYBRIS_DEBUG_LOG(HOOKS, "%s: Found mali-hist-dump thread, killing it ...",
  1019. __FUNCTION__);
  1020.  
  1021. if (thread != pthread_self()) {
  1022. HYBRIS_DEBUG_LOG(HOOKS, "%s: -> Failed, as calling thread is not mali-hist-dump itself",
  1023. __FUNCTION__);
  1024. return 0;
  1025. }
  1026.  
  1027. pthread_exit((void*) thread);
  1028.  
  1029. return 0;
  1030. }
  1031. #endif
  1032.  
  1033. return pthread_setname_np(thread, name);
  1034. }
  1035.  
  1036. /*
  1037. * pthread_rwlockattr_* functions
  1038. *
  1039. * Specific implementations to workaround the differences between at the
  1040. * pthread_rwlockattr_t struct differences between Bionic and Glibc.
  1041. *
  1042. * */
  1043.  
  1044. static int _hybris_hook_pthread_rwlockattr_init(pthread_rwlockattr_t *__attr)
  1045. {
  1046. pthread_rwlockattr_t *realattr;
  1047.  
  1048. TRACE_HOOK("attr %p", __attr);
  1049.  
  1050. realattr = malloc(sizeof(pthread_rwlockattr_t));
  1051. *((uintptr_t *)__attr) = (uintptr_t) realattr;
  1052.  
  1053. return pthread_rwlockattr_init(realattr);
  1054. }
  1055.  
  1056. static int _hybris_hook_pthread_rwlockattr_destroy(pthread_rwlockattr_t *__attr)
  1057. {
  1058. int ret;
  1059. pthread_rwlockattr_t *realattr = (pthread_rwlockattr_t *) *(uintptr_t *) __attr;
  1060.  
  1061. TRACE_HOOK("attr %p", __attr);
  1062.  
  1063. ret = pthread_rwlockattr_destroy(realattr);
  1064. free(realattr);
  1065.  
  1066. return ret;
  1067. }
  1068.  
  1069. static int _hybris_hook_pthread_rwlockattr_setpshared(pthread_rwlockattr_t *__attr,
  1070. int pshared)
  1071. {
  1072. pthread_rwlockattr_t *realattr = (pthread_rwlockattr_t *) *(uintptr_t *) __attr;
  1073.  
  1074. TRACE_HOOK("attr %p pshared %d", __attr, pshared);
  1075.  
  1076. return pthread_rwlockattr_setpshared(realattr, pshared);
  1077. }
  1078.  
  1079. static int _hybris_hook_pthread_rwlockattr_getpshared(pthread_rwlockattr_t *__attr,
  1080. int *pshared)
  1081. {
  1082. pthread_rwlockattr_t *realattr = (pthread_rwlockattr_t *) *(uintptr_t *) __attr;
  1083.  
  1084. TRACE_HOOK("attr %p pshared %p", __attr, pshared);
  1085.  
  1086. return pthread_rwlockattr_getpshared(realattr, pshared);
  1087. }
  1088.  
  1089. int _hybris_hook_pthread_rwlockattr_setkind_np(pthread_rwlockattr_t *attr, int pref)
  1090. {
  1091. pthread_rwlockattr_t *realattr = (pthread_rwlockattr_t *) *(uintptr_t *) attr;
  1092.  
  1093. TRACE_HOOK("attr %p pref %i", attr, pref);
  1094.  
  1095. return pthread_rwlockattr_setkind_np(realattr, pref);
  1096. }
  1097.  
  1098. int _hybris_hook_pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t *attr, int *pref)
  1099. {
  1100. pthread_rwlockattr_t *realattr = (pthread_rwlockattr_t *) *(uintptr_t *) attr;
  1101.  
  1102. TRACE_HOOK("attr %p pref %p", attr, pref);
  1103.  
  1104. return pthread_rwlockattr_getkind_np(realattr, pref);
  1105. }
  1106.  
  1107. /*
  1108. * pthread_rwlock_* functions
  1109. *
  1110. * Specific implementations to workaround the differences between at the
  1111. * pthread_rwlock_t struct differences between Bionic and Glibc.
  1112. *
  1113. * */
  1114.  
  1115. static int _hybris_hook_pthread_rwlock_init(pthread_rwlock_t *__rwlock,
  1116. __const pthread_rwlockattr_t *__attr)
  1117. {
  1118. pthread_rwlock_t *realrwlock = NULL;
  1119. pthread_rwlockattr_t *realattr = NULL;
  1120. int pshared = 0;
  1121.  
  1122. TRACE_HOOK("rwlock %p attr %p", __rwlock, __attr);
  1123.  
  1124. if (__attr != NULL)
  1125. realattr = (pthread_rwlockattr_t *) *(uintptr_t *) __attr;
  1126.  
  1127. if (realattr)
  1128. pthread_rwlockattr_getpshared(realattr, &pshared);
  1129.  
  1130. if (!pshared) {
  1131. /* non shared, standard rwlock: use malloc */
  1132. realrwlock = malloc(sizeof(pthread_rwlock_t));
  1133.  
  1134. *((uintptr_t *) __rwlock) = (uintptr_t) realrwlock;
  1135. }
  1136. else {
  1137. /* process-shared condition: use the shared memory segment */
  1138. hybris_shm_pointer_t handle = hybris_shm_alloc(sizeof(pthread_rwlock_t));
  1139.  
  1140. *((uintptr_t *)__rwlock) = (uintptr_t) handle;
  1141.  
  1142. if (handle)
  1143. realrwlock = (pthread_rwlock_t *)hybris_get_shmpointer(handle);
  1144. }
  1145.  
  1146. return pthread_rwlock_init(realrwlock, realattr);
  1147. }
  1148.  
  1149. static int _hybris_hook_pthread_rwlock_destroy(pthread_rwlock_t *__rwlock)
  1150. {
  1151. int ret;
  1152. pthread_rwlock_t *realrwlock = (pthread_rwlock_t *) *(uintptr_t *) __rwlock;
  1153.  
  1154. TRACE_HOOK("rwlock %p", __rwlock);
  1155.  
  1156. if (!hybris_is_pointer_in_shm((void*)realrwlock)) {
  1157. ret = pthread_rwlock_destroy(realrwlock);
  1158. free(realrwlock);
  1159. }
  1160. else {
  1161. ret = pthread_rwlock_destroy(realrwlock);
  1162. realrwlock = (pthread_rwlock_t *)hybris_get_shmpointer((hybris_shm_pointer_t)realrwlock);
  1163. }
  1164.  
  1165. return ret;
  1166. }
  1167.  
  1168. static pthread_rwlock_t* hybris_set_realrwlock(pthread_rwlock_t *rwlock)
  1169. {
  1170. uintptr_t value = (*(uintptr_t *) rwlock);
  1171. pthread_rwlock_t *realrwlock = (pthread_rwlock_t *) value;
  1172.  
  1173. if (hybris_is_pointer_in_shm((void*)value))
  1174. realrwlock = (pthread_rwlock_t *)hybris_get_shmpointer((hybris_shm_pointer_t)value);
  1175.  
  1176. if ((uintptr_t)realrwlock <= ANDROID_TOP_ADDR_VALUE_RWLOCK) {
  1177. realrwlock = hybris_alloc_init_rwlock();
  1178. *((uintptr_t *)rwlock) = (uintptr_t) realrwlock;
  1179. }
  1180. return realrwlock;
  1181. }
  1182.  
  1183. static int _hybris_hook_pthread_rwlock_rdlock(pthread_rwlock_t *__rwlock)
  1184. {
  1185. TRACE_HOOK("rwlock %p", __rwlock);
  1186.  
  1187. pthread_rwlock_t *realrwlock = hybris_set_realrwlock(__rwlock);
  1188.  
  1189. return pthread_rwlock_rdlock(realrwlock);
  1190. }
  1191.  
  1192. static int _hybris_hook_pthread_rwlock_tryrdlock(pthread_rwlock_t *__rwlock)
  1193. {
  1194. TRACE_HOOK("rwlock %p", __rwlock);
  1195.  
  1196. pthread_rwlock_t *realrwlock = hybris_set_realrwlock(__rwlock);
  1197.  
  1198. return pthread_rwlock_tryrdlock(realrwlock);
  1199. }
  1200.  
  1201. static int _hybris_hook_pthread_rwlock_timedrdlock(pthread_rwlock_t *__rwlock,
  1202. __const struct timespec *abs_timeout)
  1203. {
  1204. TRACE_HOOK("rwlock %p abs timeout %p", __rwlock, abs_timeout);
  1205.  
  1206. pthread_rwlock_t *realrwlock = hybris_set_realrwlock(__rwlock);
  1207.  
  1208. return pthread_rwlock_timedrdlock(realrwlock, abs_timeout);
  1209. }
  1210.  
  1211. static int _hybris_hook_pthread_rwlock_wrlock(pthread_rwlock_t *__rwlock)
  1212. {
  1213. TRACE_HOOK("rwlock %p", __rwlock);
  1214.  
  1215. pthread_rwlock_t *realrwlock = hybris_set_realrwlock(__rwlock);
  1216.  
  1217. return pthread_rwlock_wrlock(realrwlock);
  1218. }
  1219.  
  1220. static int _hybris_hook_pthread_rwlock_trywrlock(pthread_rwlock_t *__rwlock)
  1221. {
  1222. TRACE_HOOK("rwlock %p", __rwlock);
  1223.  
  1224. pthread_rwlock_t *realrwlock = hybris_set_realrwlock(__rwlock);
  1225.  
  1226. return pthread_rwlock_trywrlock(realrwlock);
  1227. }
  1228.  
  1229. static int _hybris_hook_pthread_rwlock_timedwrlock(pthread_rwlock_t *__rwlock,
  1230. __const struct timespec *abs_timeout)
  1231. {
  1232. TRACE_HOOK("rwlock %p abs timeout %p", __rwlock, abs_timeout);
  1233.  
  1234. pthread_rwlock_t *realrwlock = hybris_set_realrwlock(__rwlock);
  1235.  
  1236. return pthread_rwlock_timedwrlock(realrwlock, abs_timeout);
  1237. }
  1238.  
  1239. static int _hybris_hook_pthread_rwlock_unlock(pthread_rwlock_t *__rwlock)
  1240. {
  1241. uintptr_t value = (*(uintptr_t *) __rwlock);
  1242.  
  1243. TRACE_HOOK("rwlock %p", __rwlock);
  1244.  
  1245. if (value <= ANDROID_TOP_ADDR_VALUE_RWLOCK) {
  1246. LOGD("Trying to unlock a rwlock that's not locked/initialized"
  1247. " by Hybris, not unlocking.");
  1248. return 0;
  1249. }
  1250.  
  1251. pthread_rwlock_t *realrwlock = (pthread_rwlock_t *) value;
  1252. if (hybris_is_pointer_in_shm((void*)value))
  1253. realrwlock = (pthread_rwlock_t *)hybris_get_shmpointer((hybris_shm_pointer_t)value);
  1254.  
  1255. return pthread_rwlock_unlock(realrwlock);
  1256. }
  1257.  
  1258. #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
  1259.  
  1260. static pid_t _hybris_hook_pthread_gettid_np(pthread_t t)
  1261. {
  1262. TRACE_HOOK("thread %lu", (unsigned long) t);
  1263.  
  1264. return get_pid_for_pthread(t);
  1265. }
  1266.  
  1267. static int _hybris_hook___set_errno(int oi_errno)
  1268. {
  1269. TRACE_HOOK("errno %d", oi_errno);
  1270.  
  1271. errno = oi_errno;
  1272.  
  1273. return -1;
  1274. }
  1275.  
  1276. /*
  1277. * __isthreaded is used in bionic's stdio.h to choose between a fast internal implementation
  1278. * and a more classic stdio function call.
  1279. * For example:
  1280. * #define __sfeof(p) (((p)->_flags & __SEOF) != 0)
  1281. * #define feof(p) (!__isthreaded ? __sfeof(p) : (feof)(p))
  1282. *
  1283. * We see here that if __isthreaded is false, then it will use directly the bionic's FILE structure
  1284. * instead of calling one of the hooked methods.
  1285. * Therefore we need to set __isthreaded to true, even if we are not in a multi-threaded context.
  1286. */
  1287. static int _hybris_hook___isthreaded = 1;
  1288.  
  1289. #ifndef WANT_INITIALIZE_BIONIC
  1290.  
  1291. /* "struct __sbuf" from bionic/libc/include/stdio.h */
  1292. #if defined(__LP64__)
  1293. struct bionic_sbuf {
  1294. unsigned char* _base;
  1295. size_t _size;
  1296. };
  1297. #else
  1298. struct bionic_sbuf {
  1299. unsigned char *_base;
  1300. int _size;
  1301. };
  1302. #endif
  1303.  
  1304. typedef off_t bionic_fpos_t;
  1305.  
  1306. /* "struct __sFILE" from bionic/libc/include/stdio.h */
  1307. struct __attribute__((packed)) bionic_file {
  1308. unsigned char *_p; /* current position in (some) buffer */
  1309. int _r; /* read space left for getc() */
  1310. int _w; /* write space left for putc() */
  1311. #if defined(__LP64__)
  1312. int _flags; /* flags, below; this FILE is free if 0 */
  1313. int _file; /* fileno, if Unix descriptor, else -1 */
  1314. #else
  1315. short _flags; /* flags, below; this FILE is free if 0 */
  1316. short _file; /* fileno, if Unix descriptor, else -1 */
  1317. #endif
  1318. struct bionic_sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
  1319. int _lbfsize; /* 0 or -_bf._size, for inline putc */
  1320.  
  1321. /* operations */
  1322. void *_cookie; /* cookie passed to io functions */
  1323. int (*_close)(void *);
  1324. int (*_read)(void *, char *, int);
  1325. bionic_fpos_t (*_seek)(void *, bionic_fpos_t, int);
  1326. int (*_write)(void *, const char *, int);
  1327.  
  1328. /* extension data, to avoid further ABI breakage */
  1329. struct bionic_sbuf _ext;
  1330. /* data for long sequences of ungetc() */
  1331. unsigned char *_up; /* saved _p when _p is doing ungetc data */
  1332. int _ur; /* saved _r when _r is counting ungetc data */
  1333.  
  1334. /* tricks to meet minimum requirements even when malloc() fails */
  1335. unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */
  1336. unsigned char _nbuf[1]; /* guarantee a getc() buffer */
  1337.  
  1338. /* separate buffer for fgetln() when line crosses buffer boundary */
  1339. struct bionic_sbuf _lb; /* buffer for fgetln() */
  1340.  
  1341. /* Unix stdio files get aligned to block boundaries on fseek() */
  1342. int _blksize; /* stat.st_blksize (may be != _bf._size) */
  1343. bionic_fpos_t _offset; /* current lseek offset */
  1344. };
  1345.  
  1346. /*
  1347. * redirection for bionic's __sF, which is defined as:
  1348. * FILE __sF[3];
  1349. * #define stdin &__sF[0];
  1350. * #define stdout &__sF[1];
  1351. * #define stderr &__sF[2];
  1352. * So the goal here is to catch the call to file methods where the FILE* pointer
  1353. * is either stdin, stdout or stderr, and translate that pointer to a valid glibc
  1354. * pointer.
  1355. * Currently, only fputs is managed.
  1356. */
  1357. static char _hybris_hook_sF[3 * sizeof(struct bionic_file)] = {0};
  1358. static FILE *_get_actual_fp(FILE *fp)
  1359. {
  1360. char *c_fp = (char*)fp;
  1361. if (c_fp == &_hybris_hook_sF[0])
  1362. return stdin;
  1363. else if (c_fp == &_hybris_hook_sF[sizeof(struct bionic_file)])
  1364. return stdout;
  1365. else if (c_fp == &_hybris_hook_sF[sizeof(struct bionic_file) * 2])
  1366. return stderr;
  1367.  
  1368. return fp;
  1369. }
  1370.  
  1371. static void _hybris_hook_clearerr(FILE *fp)
  1372. {
  1373. TRACE_HOOK("fp %p", fp);
  1374.  
  1375. clearerr(_get_actual_fp(fp));
  1376. }
  1377.  
  1378. static int _hybris_hook_fclose(FILE *fp)
  1379. {
  1380. TRACE_HOOK("fp %p", fp);
  1381.  
  1382. return fclose(_get_actual_fp(fp));
  1383. }
  1384.  
  1385. static int _hybris_hook_feof(FILE *fp)
  1386. {
  1387. TRACE_HOOK("fp %p", fp);
  1388.  
  1389. return feof(_get_actual_fp(fp));
  1390. }
  1391.  
  1392. static int _hybris_hook_ferror(FILE *fp)
  1393. {
  1394. TRACE_HOOK("fp %p", fp);
  1395.  
  1396. return ferror(_get_actual_fp(fp));
  1397. }
  1398.  
  1399. static int _hybris_hook_fflush(FILE *fp)
  1400. {
  1401. TRACE_HOOK("fp %p", fp);
  1402.  
  1403. return fflush(_get_actual_fp(fp));
  1404. }
  1405.  
  1406. static int _hybris_hook_fgetc(FILE *fp)
  1407. {
  1408. TRACE_HOOK("fp %p", fp);
  1409.  
  1410. return fgetc(_get_actual_fp(fp));
  1411. }
  1412.  
  1413. static int _hybris_hook_fgetpos(FILE *fp, bionic_fpos_t *pos)
  1414. {
  1415. TRACE_HOOK("fp %p pos %p", fp, pos);
  1416.  
  1417. fpos_t my_fpos;
  1418. int ret = fgetpos(_get_actual_fp(fp), &my_fpos);
  1419.  
  1420. *pos = my_fpos.__pos;
  1421.  
  1422. return ret;
  1423. }
  1424.  
  1425. static char* _hybris_hook_fgets(char *s, int n, FILE *fp)
  1426. {
  1427. TRACE_HOOK("s %s n %d fp %p", s, n, fp);
  1428.  
  1429. return fgets(s, n, _get_actual_fp(fp));
  1430. }
  1431.  
  1432. FP_ATTRIB static int _hybris_hook_fprintf(FILE *fp, const char *fmt, ...)
  1433. {
  1434. int ret = 0;
  1435.  
  1436. TRACE_HOOK("fp %p fmt '%s'", fp, fmt);
  1437.  
  1438. va_list args;
  1439. va_start(args,fmt);
  1440. ret = vfprintf(_get_actual_fp(fp), fmt, args);
  1441. va_end(args);
  1442.  
  1443. return ret;
  1444. }
  1445.  
  1446. static int _hybris_hook_fputc(int c, FILE *fp)
  1447. {
  1448. TRACE_HOOK("c %d fp %p", c, fp);
  1449.  
  1450. return fputc(c, _get_actual_fp(fp));
  1451. }
  1452.  
  1453. static int _hybris_hook_fputs(const char *s, FILE *fp)
  1454. {
  1455. TRACE_HOOK("s '%s' fp %p", s, fp);
  1456.  
  1457. return fputs(s, _get_actual_fp(fp));
  1458. }
  1459.  
  1460. static size_t _hybris_hook_fread(void *ptr, size_t size, size_t nmemb, FILE *fp)
  1461. {
  1462. TRACE_HOOK("ptr %p size %zu nmemb %zu fp %p", ptr, size, nmemb, fp);
  1463.  
  1464. return fread(ptr, size, nmemb, _get_actual_fp(fp));
  1465. }
  1466.  
  1467. static FILE* _hybris_hook_freopen(const char *filename, const char *mode, FILE *fp)
  1468. {
  1469. TRACE_HOOK("filename '%s' mode '%s' fp %p", filename, mode, fp);
  1470.  
  1471. return freopen(filename, mode, _get_actual_fp(fp));
  1472. }
  1473.  
  1474. FP_ATTRIB static int _hybris_hook_fscanf(FILE *fp, const char *fmt, ...)
  1475. {
  1476. int ret = 0;
  1477.  
  1478. TRACE_HOOK("fp %p fmt '%s'", fp, fmt);
  1479.  
  1480. va_list args;
  1481. va_start(args,fmt);
  1482. ret = vfscanf(_get_actual_fp(fp), fmt, args);
  1483. va_end(args);
  1484.  
  1485. return ret;
  1486. }
  1487.  
  1488. static int _hybris_hook_fseek(FILE *fp, long offset, int whence)
  1489. {
  1490. TRACE_HOOK("fp %p offset %jd whence %d", fp, offset, whence);
  1491.  
  1492. return fseek(_get_actual_fp(fp), offset, whence);
  1493. }
  1494.  
  1495. static int _hybris_hook_fseeko(FILE *fp, off_t offset, int whence)
  1496. {
  1497. TRACE_HOOK("fp %p offset %jd whence %d", fp, offset, whence);
  1498.  
  1499. return fseeko(_get_actual_fp(fp), offset, whence);
  1500. }
  1501.  
  1502. static int _hybris_hook_fsetpos(FILE *fp, const bionic_fpos_t *pos)
  1503. {
  1504. TRACE_HOOK("fp %p pos %p", fp, pos);
  1505.  
  1506. fpos_t my_fpos;
  1507. my_fpos.__pos = *pos;
  1508. memset(&my_fpos.__state, 0, sizeof(mbstate_t));
  1509. mbsinit(&my_fpos.__state);
  1510.  
  1511. return fsetpos(_get_actual_fp(fp), &my_fpos);
  1512. }
  1513.  
  1514. static long _hybris_hook_ftell(FILE *fp)
  1515. {
  1516. TRACE_HOOK("fp %p", fp);
  1517.  
  1518. return ftell(_get_actual_fp(fp));
  1519. }
  1520.  
  1521. static off_t _hybris_hook_ftello(FILE *fp)
  1522. {
  1523. TRACE_HOOK("fp %p", fp);
  1524.  
  1525. return ftello(_get_actual_fp(fp));
  1526. }
  1527.  
  1528. static size_t _hybris_hook_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *fp)
  1529. {
  1530. TRACE_HOOK("ptr %p size %zu nmemb %zu fp %p", ptr, size, nmemb, fp);
  1531.  
  1532. return fwrite(ptr, size, nmemb, _get_actual_fp(fp));
  1533. }
  1534.  
  1535. static int _hybris_hook_getc(FILE *fp)
  1536. {
  1537. TRACE_HOOK("fp %p", fp);
  1538.  
  1539. return getc(_get_actual_fp(fp));
  1540. }
  1541.  
  1542. static ssize_t _hybris_hook_getdelim(char ** lineptr, size_t *n, int delimiter, FILE * fp)
  1543. {
  1544. TRACE_HOOK("lineptr %p n %p delimiter %d fp %p", lineptr, n, delimiter, fp);
  1545.  
  1546. return getdelim(lineptr, n, delimiter, _get_actual_fp(fp));
  1547. }
  1548.  
  1549. static ssize_t _hybris_hook_getline(char **lineptr, size_t *n, FILE *fp)
  1550. {
  1551. TRACE_HOOK("lineptr %p n %p fp %p", lineptr, n, fp);
  1552.  
  1553. return getline(lineptr, n, _get_actual_fp(fp));
  1554. }
  1555.  
  1556. static int _hybris_hook_putc(int c, FILE *fp)
  1557. {
  1558. TRACE_HOOK("c %d fp %p", c, fp);
  1559.  
  1560. return putc(c, _get_actual_fp(fp));
  1561. }
  1562.  
  1563. static void _hybris_hook_rewind(FILE *fp)
  1564. {
  1565. TRACE_HOOK("fp %p", fp);
  1566.  
  1567. rewind(_get_actual_fp(fp));
  1568. }
  1569.  
  1570. static void _hybris_hook_setbuf(FILE *fp, char *buf)
  1571. {
  1572. TRACE_HOOK("fp %p buf '%s'", fp, buf);
  1573.  
  1574. setbuf(_get_actual_fp(fp), buf);
  1575. }
  1576.  
  1577. static int _hybris_hook_setvbuf(FILE *fp, char *buf, int mode, size_t size)
  1578. {
  1579. TRACE_HOOK("fp %p buf '%s' mode %d size %zu", fp, buf, mode, size);
  1580.  
  1581. return setvbuf(_get_actual_fp(fp), buf, mode, size);
  1582. }
  1583.  
  1584. static int _hybris_hook_ungetc(int c, FILE *fp)
  1585. {
  1586. TRACE_HOOK("c %d fp %p", c, fp);
  1587.  
  1588. return ungetc(c, _get_actual_fp(fp));
  1589. }
  1590.  
  1591. static int _hybris_hook_vfprintf(FILE *fp, const char *fmt, va_list arg)
  1592. {
  1593. TRACE_HOOK("fp %p fmt '%s'", fp, fmt);
  1594.  
  1595. return vfprintf(_get_actual_fp(fp), fmt, arg);
  1596. }
  1597.  
  1598. static int _hybris_hook_vfscanf(FILE *fp, const char *fmt, va_list arg)
  1599. {
  1600. TRACE_HOOK("fp %p fmt '%s'", fp, fmt);
  1601.  
  1602. return vfscanf(_get_actual_fp(fp), fmt, arg);
  1603. }
  1604.  
  1605. static int _hybris_hook_fileno(FILE *fp)
  1606. {
  1607. TRACE_HOOK("fp %p", fp);
  1608.  
  1609. return fileno(_get_actual_fp(fp));
  1610. }
  1611.  
  1612. static int _hybris_hook_pclose(FILE *fp)
  1613. {
  1614. TRACE_HOOK("fp %p", fp);
  1615.  
  1616. return pclose(_get_actual_fp(fp));
  1617. }
  1618.  
  1619. static void _hybris_hook_flockfile(FILE *fp)
  1620. {
  1621. TRACE_HOOK("fp %p", fp);
  1622.  
  1623. return flockfile(_get_actual_fp(fp));
  1624. }
  1625.  
  1626. static int _hybris_hook_ftrylockfile(FILE *fp)
  1627. {
  1628. TRACE_HOOK("fp %p", fp);
  1629.  
  1630. return ftrylockfile(_get_actual_fp(fp));
  1631. }
  1632.  
  1633. static void _hybris_hook_funlockfile(FILE *fp)
  1634. {
  1635. TRACE_HOOK("fp %p", fp);
  1636.  
  1637. return funlockfile(_get_actual_fp(fp));
  1638. }
  1639.  
  1640. static int _hybris_hook_getc_unlocked(FILE *fp)
  1641. {
  1642. TRACE_HOOK("fp %p", fp);
  1643.  
  1644. return getc_unlocked(_get_actual_fp(fp));
  1645. }
  1646.  
  1647. static int _hybris_hook_putc_unlocked(int c, FILE *fp)
  1648. {
  1649. TRACE_HOOK("fp %p", fp);
  1650.  
  1651. return putc_unlocked(c, _get_actual_fp(fp));
  1652. }
  1653.  
  1654. /* exists only on the BSD platform
  1655. static char* _hybris_hook_fgetln(FILE *fp, size_t *len)
  1656. {
  1657. return fgetln(_get_actual_fp(fp), len);
  1658. }
  1659. */
  1660.  
  1661. static int _hybris_hook_fpurge(FILE *fp)
  1662. {
  1663. TRACE_HOOK("fp %p", fp);
  1664.  
  1665. __fpurge(_get_actual_fp(fp));
  1666.  
  1667. return 0;
  1668. }
  1669.  
  1670. static int _hybris_hook_getw(FILE *fp)
  1671. {
  1672. TRACE_HOOK("fp %p", fp);
  1673.  
  1674. return getw(_get_actual_fp(fp));
  1675. }
  1676.  
  1677. static int _hybris_hook_putw(int w, FILE *fp)
  1678. {
  1679. TRACE_HOOK("w %d fp %p", w, fp);
  1680.  
  1681. return putw(w, _get_actual_fp(fp));
  1682. }
  1683.  
  1684. static void _hybris_hook_setbuffer(FILE *fp, char *buf, int size)
  1685. {
  1686. TRACE_HOOK("fp %p buf '%s' size %d", fp, buf, size);
  1687.  
  1688. setbuffer(_get_actual_fp(fp), buf, size);
  1689. }
  1690.  
  1691. static int _hybris_hook_setlinebuf(FILE *fp)
  1692. {
  1693. TRACE_HOOK("fp %p", fp);
  1694.  
  1695. setlinebuf(_get_actual_fp(fp));
  1696.  
  1697. return 0;
  1698. }
  1699.  
  1700. /* "struct dirent" from bionic/libc/include/dirent.h */
  1701. struct bionic_dirent {
  1702. uint64_t d_ino;
  1703. int64_t d_off;
  1704. unsigned short d_reclen;
  1705. unsigned char d_type;
  1706. char d_name[256];
  1707. };
  1708.  
  1709. static struct bionic_dirent *_hybris_hook_readdir(DIR *dirp)
  1710. {
  1711. /**
  1712. * readdir(3) manpage says:
  1713. * The data returned by readdir() may be overwritten by subsequent calls
  1714. * to readdir() for the same directory stream.
  1715. *
  1716. * XXX: At the moment, for us, the data will be overwritten even by
  1717. * subsequent calls to /different/ directory streams. Eventually fix that
  1718. * (e.g. by storing per-DIR * bionic_dirent structs, and removing them on
  1719. * closedir, requires hooking of all funcs returning/taking DIR *) and
  1720. * handling the additional data attachment there)
  1721. **/
  1722.  
  1723. static struct bionic_dirent result;
  1724.  
  1725. TRACE_HOOK("dirp %p", dirp);
  1726.  
  1727. struct dirent *real_result = readdir(dirp);
  1728. if (!real_result) {
  1729. return NULL;
  1730. }
  1731.  
  1732. result.d_ino = real_result->d_ino;
  1733. result.d_off = real_result->d_off;
  1734. result.d_reclen = real_result->d_reclen;
  1735. result.d_type = real_result->d_type;
  1736. memcpy(result.d_name, real_result->d_name, sizeof(result.d_name));
  1737.  
  1738. // Make sure the string is zero-terminated, even if cut off (which
  1739. // shouldn't happen, as both bionic and glibc have d_name defined
  1740. // as fixed array of 256 chars)
  1741. result.d_name[sizeof(result.d_name)-1] = '\0';
  1742. return &result;
  1743. }
  1744.  
  1745. static int _hybris_hook_readdir_r(DIR *dir, struct bionic_dirent *entry,
  1746. struct bionic_dirent **result)
  1747. {
  1748. struct dirent entry_r;
  1749. struct dirent *result_r;
  1750.  
  1751. TRACE_HOOK("dir %p entry %p result %p", dir, entry, result);
  1752.  
  1753. int res = readdir_r(dir, &entry_r, &result_r);
  1754.  
  1755. if (res == 0) {
  1756. if (result_r != NULL) {
  1757. *result = entry;
  1758.  
  1759. entry->d_ino = entry_r.d_ino;
  1760. entry->d_off = entry_r.d_off;
  1761. entry->d_reclen = entry_r.d_reclen;
  1762. entry->d_type = entry_r.d_type;
  1763. memcpy(entry->d_name, entry_r.d_name, sizeof(entry->d_name));
  1764.  
  1765. // Make sure the string is zero-terminated, even if cut off (which
  1766. // shouldn't happen, as both bionic and glibc have d_name defined
  1767. // as fixed array of 256 chars)
  1768. entry->d_name[sizeof(entry->d_name) - 1] = '\0';
  1769. } else {
  1770. *result = NULL;
  1771. }
  1772. }
  1773.  
  1774. return res;
  1775. }
  1776.  
  1777. static int _hybris_hook_alphasort(struct bionic_dirent **a,
  1778. struct bionic_dirent **b)
  1779. {
  1780. return strcoll((*a)->d_name, (*b)->d_name);
  1781. }
  1782.  
  1783. static int _hybris_hook_versionsort(struct bionic_dirent **a,
  1784. struct bionic_dirent **b)
  1785. {
  1786. return strverscmp((*a)->d_name, (*b)->d_name);
  1787. }
  1788.  
  1789. static int _hybris_hook_scandirat(int fd, const char *dir,
  1790. struct bionic_dirent ***namelist,
  1791. int (*filter) (const struct bionic_dirent *),
  1792. int (*compar) (const struct bionic_dirent **,
  1793. const struct bionic_dirent **))
  1794. {
  1795. struct dirent **namelist_r;
  1796. struct bionic_dirent **result;
  1797. struct bionic_dirent *filter_r;
  1798.  
  1799. int i = 0;
  1800. size_t nItems = 0;
  1801.  
  1802. int res = scandirat(fd, dir, &namelist_r, NULL, NULL);
  1803.  
  1804. if (res != 0 && namelist_r != NULL) {
  1805.  
  1806. result = malloc(res * sizeof(struct bionic_dirent));
  1807. if (!result)
  1808. return -1;
  1809.  
  1810. for (i = 0; i < res; i++) {
  1811. filter_r = malloc(sizeof(struct bionic_dirent));
  1812. if (!filter_r) {
  1813. while (i-- > 0)
  1814. free(result[i]);
  1815. free(result);
  1816. return -1;
  1817. }
  1818. filter_r->d_ino = namelist_r[i]->d_ino;
  1819. filter_r->d_off = namelist_r[i]->d_off;
  1820. filter_r->d_reclen = namelist_r[i]->d_reclen;
  1821. filter_r->d_type = namelist_r[i]->d_type;
  1822.  
  1823. strcpy(filter_r->d_name, namelist_r[i]->d_name);
  1824. filter_r->d_name[sizeof(namelist_r[i]->d_name) - 1] = '\0';
  1825.  
  1826. if (filter != NULL && !(*filter)(filter_r)) {//apply filter
  1827. free(filter_r);
  1828. continue;
  1829. }
  1830.  
  1831. result[nItems++] = filter_r;
  1832. }
  1833. if (nItems && compar != NULL) // sort
  1834. qsort(result, nItems, sizeof(struct bionic_dirent *), compar);
  1835.  
  1836. *namelist = result;
  1837. }
  1838.  
  1839. return res;
  1840. }
  1841.  
  1842. static int _hybris_hook_scandir(const char *dir,
  1843. struct bionic_dirent ***namelist,
  1844. int (*filter) (const struct bionic_dirent *),
  1845. int (*compar) (const struct bionic_dirent **,
  1846. const struct bionic_dirent **))
  1847. {
  1848. return _hybris_hook_scandirat(AT_FDCWD, dir, namelist, filter, compar);
  1849. }
  1850.  
  1851. /*
  1852. * utils, such as memcpy
  1853. *
  1854. * Useful to handle hacks such as the one applied for Nvidia, and to
  1855. * avoid crashes. Also we need to hook all memory allocation related
  1856. * ones to make sure all are using the same allocator implementation.
  1857. *
  1858. * */
  1859.  
  1860. static void *_hybris_hook_memcpy(void *dst, const void *src, size_t len)
  1861. {
  1862. TRACE_HOOK("dst %p src %p len %zu", dst, src, len);
  1863.  
  1864. if (src == NULL || dst == NULL)
  1865. return dst;
  1866.  
  1867. return memcpy(dst, src, len);
  1868. }
  1869.  
  1870. static int _hybris_hook_memcmp(const void *s1, const void *s2, size_t n)
  1871. {
  1872. TRACE_HOOK("s1 %p '%s' s2 %p '%s' n %zu", s1, (char*) s1, s2, (char*) s2, n);
  1873.  
  1874. return memcmp(s1, s2, n);
  1875. }
  1876.  
  1877. static size_t _hybris_hook_strlen(const char *s)
  1878. {
  1879. TRACE_HOOK("s '%s'", s);
  1880.  
  1881. if (s == NULL)
  1882. return -1;
  1883.  
  1884. return strlen(s);
  1885. }
  1886.  
  1887. static inline void swap(void **a, void **b)
  1888. {
  1889. void *tmp = *a;
  1890. *a = *b;
  1891. *b = tmp;
  1892. }
  1893.  
  1894. static int _hybris_hook_getaddrinfo(const char *hostname, const char *servname,
  1895. const struct addrinfo *hints, struct addrinfo **res)
  1896. {
  1897. struct addrinfo *fixed_hints = NULL;
  1898.  
  1899. TRACE_HOOK("hostname '%s' servname '%s' hints %p res %p",
  1900. hostname, servname, hints, res);
  1901.  
  1902. if (hints) {
  1903. fixed_hints = (struct addrinfo*) malloc(sizeof(struct addrinfo));
  1904. memcpy(fixed_hints, hints, sizeof(struct addrinfo));
  1905. // fix bionic -> glibc missmatch
  1906. swap((void**)&(fixed_hints->ai_canonname), (void**)&(fixed_hints->ai_addr));
  1907. }
  1908.  
  1909. int result = getaddrinfo(hostname, servname, fixed_hints, res);
  1910.  
  1911. if (fixed_hints)
  1912. free(fixed_hints);
  1913.  
  1914. // fix bionic <- glibc missmatch
  1915. struct addrinfo *it = *res;
  1916. while (it) {
  1917. swap((void**) &(it->ai_canonname), (void**) &(it->ai_addr));
  1918. it = it->ai_next;
  1919. }
  1920.  
  1921. return result;
  1922. }
  1923.  
  1924. static void _hybris_hook_freeaddrinfo(struct addrinfo *__ai)
  1925. {
  1926. TRACE_HOOK("ai %p", __ai);
  1927.  
  1928. if (__ai == NULL)
  1929. return;
  1930.  
  1931. struct addrinfo *it = __ai;
  1932. while (it) {
  1933. swap((void**) &(it->ai_canonname), (void**) &(it->ai_addr));
  1934. it = it->ai_next;
  1935. }
  1936.  
  1937. freeaddrinfo(__ai);
  1938. }
  1939.  
  1940. extern long _hybris_map_sysconf(int name);
  1941.  
  1942. long _hybris_hook_sysconf(int name)
  1943. {
  1944. TRACE_HOOK("name %d", name);
  1945.  
  1946. return _hybris_map_sysconf(name);
  1947. }
  1948.  
  1949. FP_ATTRIB static double _hybris_hook_strtod(const char *nptr, char **endptr)
  1950. {
  1951. TRACE_HOOK("nptr '%s' endptr %p", nptr, endptr);
  1952.  
  1953. if (locale_inited == 0) {
  1954. hybris_locale = newlocale(LC_ALL_MASK, "C", 0);
  1955. locale_inited = 1;
  1956. }
  1957.  
  1958. return strtod_l(nptr, endptr, hybris_locale);
  1959. }
  1960.  
  1961. static long int _hybris_hook_strtol(const char* str, char** endptr, int base)
  1962. {
  1963. TRACE_HOOK("str '%s' endptr %p base %i", str, endptr, base);
  1964.  
  1965. return strtol(str, endptr, base);
  1966. }
  1967.  
  1968. extern int __cxa_atexit(void (*)(void*), void*, void*);
  1969. extern void __cxa_finalize(void * d);
  1970.  
  1971. struct open_redirect {
  1972. const char *from;
  1973. const char *to;
  1974. };
  1975.  
  1976. struct open_redirect open_redirects[] = {
  1977. { "/dev/log/main", "/dev/alog/main" },
  1978. { "/dev/log/radio", "/dev/alog/radio" },
  1979. { "/dev/log/system", "/dev/alog/system" },
  1980. { "/dev/log/events", "/dev/alog/events" },
  1981. { NULL, NULL }
  1982. };
  1983.  
  1984. int _hybris_hook_open(const char *pathname, int flags, ...)
  1985. {
  1986. va_list ap;
  1987. mode_t mode = 0;
  1988. const char *target_path = pathname;
  1989.  
  1990. TRACE_HOOK("pathname '%s' flags %d", pathname, flags);
  1991.  
  1992. if (pathname != NULL) {
  1993. struct open_redirect *entry = &open_redirects[0];
  1994. while (entry->from != NULL) {
  1995. if (strcmp(pathname, entry->from) == 0) {
  1996. target_path = entry->to;
  1997. break;
  1998. }
  1999. entry++;
  2000. }
  2001. }
  2002.  
  2003. if (flags & O_CREAT) {
  2004. va_start(ap, flags);
  2005. mode = va_arg(ap, mode_t);
  2006. va_end(ap);
  2007. }
  2008.  
  2009. return open(target_path, flags, mode);
  2010. }
  2011.  
  2012. /**
  2013. * Wrap some GCC builtin functions, which don't have any address
  2014. */
  2015. __THROW int _hybris_hook___sprintf_chk (char *__restrict __s, int __flag, size_t __slen,
  2016. const char *__restrict __format, ...)
  2017. {
  2018. int ret = 0;
  2019. va_list args;
  2020. va_start(args,__format);
  2021. ret = __vsprintf_chk (__s, __flag, __slen, __format, args);
  2022. va_end(args);
  2023.  
  2024. return ret;
  2025. }
  2026. __THROW int _hybris_hook___snprintf_chk (char *__restrict __s, size_t __n, int __flag,
  2027. size_t __slen, const char *__restrict __format, ...)
  2028. {
  2029. int ret = 0;
  2030. va_list args;
  2031. va_start(args,__format);
  2032. ret = __vsnprintf_chk (__s, __n, __flag, __slen, __format, args);
  2033. va_end(args);
  2034.  
  2035. return ret;
  2036. }
  2037.  
  2038. int _hybris_hook_prctl(int option, unsigned long arg2, unsigned long arg3,
  2039. unsigned long arg4, unsigned long arg5)
  2040. {
  2041. TRACE_HOOK("option %d arg2 %lu arg3 %lu arg4 %lu arg5 %lu",
  2042. option, arg2, arg3, arg4, arg5);
  2043.  
  2044. #ifdef MALI_QUIRKS
  2045. if (option == PR_SET_NAME) {
  2046. char *name = (char*) arg2;
  2047.  
  2048. if (strcmp(name, MALI_HIST_DUMP_THREAD_NAME) == 0) {
  2049.  
  2050. // This can only work because prctl with PR_SET_NAME
  2051. // can be only called for the current thread and not
  2052. // for another thread so we can safely pause things.
  2053.  
  2054. HYBRIS_DEBUG_LOG(HOOKS, "%s: Found mali-hist-dump, killing thread ...",
  2055. __FUNCTION__);
  2056.  
  2057. pthread_exit(NULL);
  2058. }
  2059. }
  2060. #endif
  2061.  
  2062. return prctl(option, arg2, arg3, arg4, arg5);
  2063. }
  2064.  
  2065. static char* _hybris_hook_basename(const char *path)
  2066. {
  2067. static __thread char buf[PATH_MAX];
  2068.  
  2069. TRACE_HOOK("path '%s'", path);
  2070.  
  2071. memset(buf, 0, sizeof(buf));
  2072.  
  2073. if (path)
  2074. strncpy(buf, path, sizeof(buf));
  2075.  
  2076. buf[sizeof buf - 1] = '\0';
  2077.  
  2078. return basename(buf);
  2079. }
  2080.  
  2081. static char* _hybris_hook_dirname(char *path)
  2082. {
  2083. static __thread char buf[PATH_MAX];
  2084.  
  2085. TRACE_HOOK("path '%s'", path);
  2086.  
  2087. memset(buf, 0, sizeof(buf));
  2088.  
  2089. if (path)
  2090. strncpy(buf, path, sizeof(buf));
  2091.  
  2092. buf[sizeof buf - 1] = '\0';
  2093.  
  2094. return dirname(path);
  2095. }
  2096.  
  2097. static char* _hybris_hook_strerror(int errnum)
  2098. {
  2099. TRACE_HOOK("errnum %d", errnum);
  2100.  
  2101. return strerror(errnum);
  2102. }
  2103.  
  2104. static char* _hybris_hook__gnu_strerror_r(int errnum, char *buf, size_t buf_len)
  2105. {
  2106. TRACE_HOOK("errnum %d buf '%s' buf len %zu", errnum, buf, buf_len);
  2107.  
  2108. return strerror_r(errnum, buf, buf_len);
  2109. }
  2110.  
  2111. static int _hybris_hook_mprotect(void *addr, size_t len, int prot)
  2112. {
  2113. TRACE_HOOK("addr %p len %zu prot %d", addr, len, prot);
  2114.  
  2115. return mprotect(addr, len, prot);
  2116. }
  2117.  
  2118. static int _hybris_hook_posix_memalign(void **memptr, size_t alignment, size_t size)
  2119. {
  2120. TRACE_HOOK("memptr %p alignment %zu size %zu", memptr, alignment, size);
  2121.  
  2122. return posix_memalign(memptr, alignment, size);
  2123. }
  2124.  
  2125. static pid_t _hybris_hook_fork(void)
  2126. {
  2127. TRACE_HOOK("");
  2128.  
  2129. return fork();
  2130. }
  2131.  
  2132. static locale_t _hybris_hook_newlocale(int category_mask, const char *locale, locale_t base)
  2133. {
  2134. TRACE_HOOK("category mask %i locale '%s'", category_mask, locale);
  2135.  
  2136. return newlocale(category_mask, locale, base);
  2137. }
  2138.  
  2139. static void _hybris_hook_freelocale(locale_t locobj)
  2140. {
  2141. TRACE_HOOK("");
  2142.  
  2143. return freelocale(locobj);
  2144. }
  2145.  
  2146. static locale_t _hybris_hook_duplocale(locale_t locobj)
  2147. {
  2148. TRACE_HOOK("");
  2149.  
  2150. return duplocale(locobj);
  2151. }
  2152.  
  2153. static locale_t _hybris_hook_uselocale(locale_t newloc)
  2154. {
  2155. TRACE_HOOK("");
  2156.  
  2157. return uselocale(newloc);
  2158. }
  2159.  
  2160. static struct lconv* _hybris_hook_localeconv(void)
  2161. {
  2162. TRACE_HOOK("");
  2163.  
  2164. return localeconv();
  2165. }
  2166.  
  2167. static char* _hybris_hook_setlocale(int category, const char *locale)
  2168. {
  2169. TRACE_HOOK("category %i locale '%s'", category, locale);
  2170.  
  2171. return setlocale(category, locale);
  2172. }
  2173.  
  2174. static void* _hybris_hook_mmap(void *addr, size_t len, int prot,
  2175. int flags, int fd, off_t offset)
  2176. {
  2177. TRACE_HOOK("addr %p len %zu prot %i flags %i fd %i offset %jd",
  2178. addr, len, prot, flags, fd, offset);
  2179.  
  2180. return mmap(addr, len, prot, flags, fd, offset);
  2181. }
  2182.  
  2183. static int _hybris_hook_munmap(void *addr, size_t length)
  2184. {
  2185. TRACE_HOOK("addr %p length %zu", addr, length);
  2186.  
  2187. return munmap(addr, length);
  2188. }
  2189.  
  2190. extern size_t strlcat(char *dst, const char *src, size_t siz);
  2191. extern size_t strlcpy(char *dst, const char *src, size_t siz);
  2192.  
  2193. static int _hybris_hook_strcmp(const char *s1, const char *s2)
  2194. {
  2195. TRACE_HOOK("s1 '%s' s2 '%s'", s1, s2);
  2196.  
  2197. if ( s1 == NULL || s2 == NULL)
  2198. return -1;
  2199.  
  2200. return strcmp(s1, s2);
  2201. }
  2202.  
  2203. static FILE* _hybris_hook_setmntent(const char *filename, const char *type)
  2204. {
  2205. TRACE_HOOK("filename %s type %s", filename, type);
  2206.  
  2207. return setmntent(filename, type);
  2208. }
  2209.  
  2210. static struct mntent* _hybris_hook_getmntent(FILE *fp)
  2211. {
  2212. TRACE_HOOK("fp %p", fp);
  2213.  
  2214. /* glibc doesn't allow NULL fp here, but bionic does. */
  2215. if (fp == NULL)
  2216. return NULL;
  2217.  
  2218. return getmntent(_get_actual_fp(fp));
  2219. }
  2220.  
  2221. static struct mntent* _hybris_hook_getmntent_r(FILE *fp, struct mntent *e, char *buf, int buf_len)
  2222. {
  2223. TRACE_HOOK("fp %p e %p buf '%s' buf len %i",
  2224. fp, e, buf, buf_len);
  2225.  
  2226. /* glibc doesn't allow NULL fp here, but bionic does. */
  2227. if (fp == NULL)
  2228. return NULL;
  2229.  
  2230. return getmntent_r(_get_actual_fp(fp), e, buf, buf_len);
  2231. }
  2232.  
  2233. int _hybris_hook_endmntent(FILE *fp)
  2234. {
  2235. TRACE_HOOK("fp %p", fp);
  2236.  
  2237. return endmntent(_get_actual_fp(fp));
  2238. }
  2239.  
  2240. static int _hybris_hook_fputws(const wchar_t *ws, FILE *stream)
  2241. {
  2242. TRACE_HOOK("stream %p", stream);
  2243.  
  2244. return fputws(ws, _get_actual_fp(stream));
  2245. }
  2246.  
  2247. static int _hybris_hook_vfwprintf(FILE *stream, const wchar_t *format, va_list args)
  2248. {
  2249. TRACE_HOOK("stream %p", stream);
  2250.  
  2251. return vfwprintf(_get_actual_fp(stream), format, args);
  2252. }
  2253.  
  2254. static wint_t _hybris_hook_fputwc(wchar_t wc, FILE *stream)
  2255. {
  2256. TRACE_HOOK("stream %p", stream);
  2257.  
  2258. return fputwc(wc, _get_actual_fp(stream));
  2259. }
  2260.  
  2261. static wint_t _hybris_hook_putwc(wchar_t wc, FILE *stream)
  2262. {
  2263. TRACE_HOOK("stream %p", stream);
  2264.  
  2265. return putwc(wc, _get_actual_fp(stream));
  2266. }
  2267.  
  2268. static wint_t _hybris_hook_fgetwc(FILE *stream)
  2269. {
  2270. TRACE_HOOK("stream %p", stream);
  2271.  
  2272. return fgetwc(_get_actual_fp(stream));
  2273. }
  2274.  
  2275. static wint_t _hybris_hook_getwc(FILE *stream)
  2276. {
  2277. TRACE_HOOK("stream %p", stream);
  2278.  
  2279. return getwc(_get_actual_fp(stream));
  2280. }
  2281.  
  2282. #endif // WANT_INITIALIZE_BIONIC
  2283.  
  2284. static void *_hybris_hook_dlopen(const char *filename, int flag)
  2285. {
  2286. TRACE("filename %s flag %i", filename, flag);
  2287.  
  2288. return _android_dlopen(filename,flag);
  2289. }
  2290.  
  2291. static void *_hybris_hook_dlsym(void *handle, const char *symbol)
  2292. {
  2293. TRACE("handle %p symbol %s", handle, symbol);
  2294.  
  2295. return _android_dlsym(handle,symbol);
  2296. }
  2297.  
  2298. static void* _hybris_hook_dladdr(void *addr, Dl_info *info)
  2299. {
  2300. TRACE("addr %p info %p", addr, info);
  2301.  
  2302. return _android_dladdr(addr, info);
  2303. }
  2304.  
  2305. static int _hybris_hook_dlclose(void *handle)
  2306. {
  2307. TRACE("handle %p", handle);
  2308.  
  2309. return _android_dlclose(handle);
  2310. }
  2311.  
  2312. static const char *_hybris_hook_dlerror(void)
  2313. {
  2314. TRACE("");
  2315.  
  2316. return android_dlerror();
  2317. }
  2318.  
  2319. static int _hybris_hook___system_property_read(const void *pi, char *name, char *value)
  2320. {
  2321. TRACE_HOOK("pi %p name '%s' value '%s'", pi, name, value);
  2322.  
  2323. return property_get(name, value, NULL);
  2324. }
  2325.  
  2326. static int _hybris_hook___system_property_foreach(void (*propfn)(const void *pi, void *cookie), void *cookie)
  2327. {
  2328. TRACE_HOOK("propfn %p cookie %p", propfn, cookie);
  2329.  
  2330. return 0;
  2331. }
  2332.  
  2333. static const void *_hybris_hook___system_property_find(const char *name)
  2334. {
  2335. TRACE_HOOK("name '%s'", name);
  2336.  
  2337. return NULL;
  2338. }
  2339.  
  2340. static unsigned int _hybris_hook___system_property_serial(const void *pi)
  2341. {
  2342. TRACE_HOOK("pi %p", pi);
  2343.  
  2344. return 0;
  2345. }
  2346.  
  2347. static int _hybris_hook___system_property_wait(const void *pi)
  2348. {
  2349. TRACE_HOOK("pi %p", pi);
  2350.  
  2351. return 0;
  2352. }
  2353.  
  2354. static int _hybris_hook___system_property_update(void *pi, const char *value, unsigned int len)
  2355. {
  2356. TRACE_HOOK("pi %p value '%s' len %d", pi, value, len);
  2357.  
  2358. return 0;
  2359. }
  2360.  
  2361. static int _hybris_hook___system_property_add(const char *name, unsigned int namelen, const char *value, unsigned int valuelen)
  2362. {
  2363. TRACE_HOOK("name '%s' namelen %d value '%s' valuelen %d",
  2364. name, namelen, value, valuelen);
  2365. return 0;
  2366. }
  2367.  
  2368. static unsigned int _hybris_hook___system_property_wait_any(unsigned int serial)
  2369. {
  2370. TRACE_HOOK("serial %d", serial);
  2371.  
  2372. return 0;
  2373. }
  2374.  
  2375. static const void *_hybris_hook___system_property_find_nth(unsigned n)
  2376. {
  2377. TRACE_HOOK("n %d", n);
  2378.  
  2379. return NULL;
  2380. }
  2381.  
  2382. /**
  2383. * NOTE: Normally we don't have to wrap __system_property_get (libc.so) as it is only used
  2384. * through the property_get (libcutils.so) function. However when property_get is used
  2385. * internally in libcutils.so we don't have any chance to hook our replacement in.
  2386. * Therefore we have to hook __system_property_get too and just replace it with the
  2387. * implementation of our internal property handling
  2388. */
  2389.  
  2390. int _hybris_hook___system_property_get(const char *name, const char *value)
  2391. {
  2392. TRACE_HOOK("name '%s' value '%s'", name, value);
  2393.  
  2394. return property_get(name, (char*) value, NULL);
  2395. }
  2396.  
  2397. int _hybris_hook_property_get(const char *key, char *value, const char *default_value)
  2398. {
  2399. TRACE_HOOK("key '%s' value '%s' default value '%s'",
  2400. key, value, default_value);
  2401.  
  2402. return property_get(key, value, default_value);
  2403. }
  2404.  
  2405. int _hybris_hook_property_set(const char *key, const char *value)
  2406. {
  2407. TRACE_HOOK("key '%s' value '%s'", key, value);
  2408.  
  2409. return property_set(key, value);
  2410. }
  2411.  
  2412. #ifdef WANT_INITIALIZE_BIONIC
  2413. static void _hybris_hook___system_properties_init(void)
  2414. {
  2415. // stub
  2416. }
  2417. #endif
  2418.  
  2419. static __thread void *tls_hooks[16];
  2420.  
  2421. static void *_hybris_hook___get_tls_hooks()
  2422. {
  2423. TRACE_HOOK("");
  2424. return tls_hooks;
  2425. }
  2426.  
  2427. static pid_t _hybris_hook_gettid(void)
  2428. {
  2429. TRACE_HOOK("");
  2430.  
  2431. return syscall(__NR_gettid);
  2432. }
  2433.  
  2434. char *_hybris_hook_getenv(const char *name)
  2435. {
  2436. TRACE_HOOK("name '%s'", name);
  2437.  
  2438. return getenv(name);
  2439. }
  2440.  
  2441. int _hybris_hook_setenv(const char *name, const char *value, int overwrite)
  2442. {
  2443. TRACE_HOOK("name '%s' value '%s' overwrite %d", name, value, overwrite);
  2444.  
  2445. return setenv(name, value, overwrite);
  2446. }
  2447.  
  2448. int _hybris_hook_putenv(char *string)
  2449. {
  2450. TRACE_HOOK("string '%s'", string);
  2451.  
  2452. return putenv(string);
  2453. }
  2454.  
  2455. int _hybris_hook_clearenv(void)
  2456. {
  2457. TRACE_HOOK("");
  2458.  
  2459. return clearenv();
  2460. }
  2461.  
  2462. static void *_hybris_hook_malloc(size_t size)
  2463. {
  2464. TRACE_HOOK("size %zu", size);
  2465.  
  2466. #ifdef WANT_ADRENO_QUIRKS
  2467. if(size == 4) size = 5;
  2468. #endif
  2469.  
  2470. void *res = malloc(size);
  2471.  
  2472. TRACE_HOOK("res %p", res);
  2473.  
  2474. return res;
  2475. }
  2476.  
  2477. static size_t _hybris_hook_malloc_usable_size (void *ptr)
  2478. {
  2479. TRACE_HOOK("ptr %p", ptr);
  2480.  
  2481. return malloc_usable_size(ptr);
  2482. }
  2483.  
  2484.  
  2485. // hook to print messages from bionic libc (in order to debug invalid pthread calls)
  2486. // also useful for debugging
  2487. static int _hybris_hook_my_printf(const char *tmp, ...)
  2488. {
  2489. char buff[4096];
  2490. va_list args;
  2491. va_start(args,tmp);
  2492. vsnprintf (buff, 4096, tmp, args);
  2493. va_end(args);
  2494. return fprintf(stderr, "%d:%s", syscall(__NR_gettid), buff);
  2495. }
  2496.  
  2497. static struct _hook hooks_common[] = {
  2498. #ifdef WANT_INITIALIZE_BIONIC
  2499. HOOK_TO(glibc_malloc, malloc),
  2500. HOOK_INDIRECT(my_printf),
  2501. HOOK_DIRECT(property_get),
  2502. HOOK_DIRECT(property_set),
  2503. HOOK_INDIRECT(__system_property_get),
  2504. HOOK_INDIRECT(__system_property_read),
  2505. HOOK_TO(__system_property_set, _hybris_hook_property_set),
  2506. HOOK_INDIRECT(__system_property_foreach),
  2507. HOOK_INDIRECT(__system_property_find),
  2508. HOOK_INDIRECT(__system_property_serial),
  2509. HOOK_INDIRECT(__system_property_wait),
  2510. HOOK_INDIRECT(__system_property_update),
  2511. HOOK_INDIRECT(__system_property_add),
  2512. HOOK_INDIRECT(__system_property_wait_any),
  2513. HOOK_INDIRECT(__system_property_find_nth),
  2514. HOOK_INDIRECT(__system_properties_init), // stub
  2515. HOOK_INDIRECT(__get_tls_hooks),
  2516. HOOK_DIRECT_NO_DEBUG(getauxval),
  2517. HOOK_TO(__progname, &program_invocation_name),
  2518. HOOK_DIRECT_NO_DEBUG(brk),
  2519. HOOK_DIRECT_NO_DEBUG(sbrk),
  2520. HOOK_DIRECT_NO_DEBUG(clone),
  2521. HOOK_TO(__errno, __errno_location),
  2522.  
  2523. HOOK_TO(__register_atfork, pthread_atfork),
  2524.  
  2525. HOOK_INDIRECT(malloc),
  2526. HOOK_DIRECT_NO_DEBUG(mallinfo),
  2527. HOOK_DIRECT(malloc_usable_size),
  2528. HOOK_DIRECT_NO_DEBUG(posix_memalign),
  2529. // TODO: get_malloc_leak_info, free_malloc_leak_info
  2530. HOOK_DIRECT_NO_DEBUG(calloc),
  2531. HOOK_DIRECT_NO_DEBUG(realloc),
  2532. HOOK_DIRECT_NO_DEBUG(valloc),
  2533. HOOK_DIRECT_NO_DEBUG(pvalloc),
  2534. HOOK_DIRECT_NO_DEBUG(free),
  2535. HOOK_DIRECT_NO_DEBUG(memalign),
  2536. HOOK_DIRECT_NO_DEBUG(malloc_usable_size),
  2537. HOOK_DIRECT_NO_DEBUG(malloc_info),
  2538.  
  2539. /* pthread.h */
  2540. HOOK_DIRECT_NO_DEBUG(getauxval),
  2541. HOOK_INDIRECT(gettid),
  2542. HOOK_DIRECT_NO_DEBUG(getpid),
  2543. HOOK_DIRECT_NO_DEBUG(pthread_atfork),
  2544. HOOK_INDIRECT(pthread_create),
  2545. HOOK_INDIRECT(pthread_kill),
  2546. HOOK_DIRECT_NO_DEBUG(pthread_exit),
  2547. HOOK_DIRECT_NO_DEBUG(pthread_join),
  2548. HOOK_DIRECT_NO_DEBUG(pthread_detach),
  2549. HOOK_DIRECT_NO_DEBUG(pthread_self),
  2550. HOOK_DIRECT_NO_DEBUG(pthread_equal),
  2551. HOOK_DIRECT_NO_DEBUG(pthread_getschedparam),
  2552. HOOK_DIRECT_NO_DEBUG(pthread_setschedparam),
  2553. HOOK_INDIRECT(pthread_mutex_init),
  2554. HOOK_INDIRECT(pthread_mutex_destroy),
  2555. HOOK_INDIRECT(pthread_mutex_lock),
  2556. HOOK_INDIRECT(pthread_mutex_unlock),
  2557. HOOK_INDIRECT(pthread_mutex_trylock),
  2558. HOOK_INDIRECT(pthread_mutex_lock_timeout_np),
  2559. HOOK_INDIRECT(pthread_mutex_timedlock),
  2560. HOOK_DIRECT_NO_DEBUG(pthread_mutexattr_init),
  2561. HOOK_DIRECT_NO_DEBUG(pthread_mutexattr_destroy),
  2562. HOOK_DIRECT_NO_DEBUG(pthread_mutexattr_gettype),
  2563. HOOK_DIRECT_NO_DEBUG(pthread_mutexattr_settype),
  2564. HOOK_DIRECT_NO_DEBUG(pthread_mutexattr_getpshared),
  2565. HOOK_DIRECT(pthread_mutexattr_setpshared),
  2566. HOOK_DIRECT_NO_DEBUG(pthread_condattr_init),
  2567. HOOK_DIRECT_NO_DEBUG(pthread_condattr_getpshared),
  2568. HOOK_DIRECT_NO_DEBUG(pthread_condattr_setpshared),
  2569. HOOK_DIRECT_NO_DEBUG(pthread_condattr_destroy),
  2570. HOOK_DIRECT_NO_DEBUG(pthread_condattr_getclock),
  2571. HOOK_DIRECT_NO_DEBUG(pthread_condattr_setclock),
  2572. HOOK_INDIRECT(pthread_cond_init),
  2573. HOOK_INDIRECT(pthread_cond_destroy),
  2574. HOOK_INDIRECT(pthread_cond_broadcast),
  2575. HOOK_INDIRECT(pthread_cond_signal),
  2576. HOOK_INDIRECT(pthread_cond_wait),
  2577. HOOK_INDIRECT(pthread_cond_timedwait),
  2578. HOOK_TO(pthread_cond_timedwait_monotonic, _hybris_hook_pthread_cond_timedwait),
  2579. HOOK_TO(pthread_cond_timedwait_monotonic_np, _hybris_hook_pthread_cond_timedwait),
  2580. HOOK_INDIRECT(pthread_cond_timedwait_relative_np),
  2581. HOOK_INDIRECT(pthread_key_delete),
  2582. HOOK_INDIRECT(pthread_setname_np),
  2583. HOOK_DIRECT_NO_DEBUG(pthread_once),
  2584. HOOK_DIRECT_NO_DEBUG(pthread_key_create),
  2585. HOOK_INDIRECT(pthread_setspecific),
  2586. HOOK_INDIRECT(pthread_getspecific),
  2587. HOOK_INDIRECT(pthread_attr_init),
  2588. HOOK_INDIRECT(pthread_attr_destroy),
  2589. HOOK_INDIRECT(pthread_attr_setdetachstate),
  2590. HOOK_INDIRECT(pthread_attr_getdetachstate),
  2591. HOOK_INDIRECT(pthread_attr_setschedpolicy),
  2592. HOOK_INDIRECT(pthread_attr_getschedpolicy),
  2593. HOOK_INDIRECT(pthread_attr_setschedparam),
  2594. HOOK_INDIRECT(pthread_attr_getschedparam),
  2595. HOOK_INDIRECT(pthread_attr_setstacksize),
  2596. HOOK_INDIRECT(pthread_attr_getstacksize),
  2597. HOOK_INDIRECT(pthread_attr_setstackaddr),
  2598. HOOK_INDIRECT(pthread_attr_getstackaddr),
  2599. HOOK_INDIRECT(pthread_attr_setstack),
  2600. HOOK_INDIRECT(pthread_attr_getstack),
  2601. HOOK_INDIRECT(pthread_attr_setguardsize),
  2602. HOOK_INDIRECT(pthread_attr_getguardsize),
  2603. HOOK_INDIRECT(pthread_attr_setscope),
  2604. HOOK_INDIRECT(pthread_attr_getscope),
  2605. HOOK_INDIRECT(pthread_getattr_np),
  2606. HOOK_INDIRECT(pthread_rwlockattr_init),
  2607. HOOK_INDIRECT(pthread_rwlockattr_destroy),
  2608. HOOK_INDIRECT(pthread_rwlockattr_setpshared),
  2609. HOOK_INDIRECT(pthread_rwlockattr_getpshared),
  2610. HOOK_INDIRECT(pthread_rwlock_init),
  2611. HOOK_INDIRECT(pthread_rwlock_destroy),
  2612. HOOK_INDIRECT(pthread_rwlock_unlock),
  2613. HOOK_INDIRECT(pthread_rwlock_wrlock),
  2614. HOOK_INDIRECT(pthread_rwlock_rdlock),
  2615. HOOK_INDIRECT(pthread_rwlock_tryrdlock),
  2616. HOOK_INDIRECT(pthread_rwlock_trywrlock),
  2617. HOOK_INDIRECT(pthread_rwlock_timedrdlock),
  2618. HOOK_INDIRECT(pthread_rwlock_timedwrlock),
  2619. /* bionic-only pthread */
  2620. HOOK_TO(__pthread_gettid, _hybris_hook_pthread_gettid_np),
  2621. HOOK_INDIRECT(pthread_gettid_np),
  2622.  
  2623. HOOK_TO(__isthreaded, &_hybris_hook___isthreaded),
  2624.  
  2625. HOOK_INDIRECT(dlopen),
  2626. HOOK_INDIRECT(dlerror),
  2627. HOOK_INDIRECT(dlsym),
  2628. HOOK_INDIRECT(dladdr),
  2629. HOOK_INDIRECT(dlclose),
  2630.  
  2631. HOOK_DIRECT(getenv),
  2632. HOOK_DIRECT(setenv),
  2633. HOOK_DIRECT(putenv),
  2634. HOOK_DIRECT(clearenv),
  2635. #else
  2636. HOOK_DIRECT(property_get),
  2637. HOOK_DIRECT(property_set),
  2638. HOOK_INDIRECT(__system_property_get),
  2639. HOOK_DIRECT(getenv),
  2640. HOOK_DIRECT_NO_DEBUG(printf),
  2641. HOOK_DIRECT(malloc),
  2642. HOOK_DIRECT_NO_DEBUG(free),
  2643. HOOK_DIRECT_NO_DEBUG(calloc),
  2644. HOOK_DIRECT_NO_DEBUG(cfree),
  2645. HOOK_DIRECT_NO_DEBUG(realloc),
  2646. HOOK_DIRECT_NO_DEBUG(memalign),
  2647. HOOK_DIRECT_NO_DEBUG(valloc),
  2648. HOOK_DIRECT_NO_DEBUG(pvalloc),
  2649. HOOK_DIRECT(fread),
  2650. HOOK_DIRECT_NO_DEBUG(getxattr),
  2651. HOOK_DIRECT(mprotect),
  2652. /* string.h */
  2653. HOOK_DIRECT_NO_DEBUG(memccpy),
  2654. HOOK_DIRECT_NO_DEBUG(memchr),
  2655. HOOK_DIRECT_NO_DEBUG(memrchr),
  2656. HOOK_DIRECT(memcmp),
  2657. HOOK_INDIRECT(memcpy),
  2658. HOOK_DIRECT_NO_DEBUG(memmove),
  2659. HOOK_DIRECT_NO_DEBUG(memset),
  2660. HOOK_DIRECT_NO_DEBUG(memmem),
  2661. HOOK_DIRECT_NO_DEBUG(getlogin),
  2662. // HOOK_DIRECT(memswap),
  2663. HOOK_DIRECT_NO_DEBUG(index),
  2664. HOOK_DIRECT_NO_DEBUG(rindex),
  2665. HOOK_DIRECT_NO_DEBUG(strchr),
  2666. HOOK_DIRECT_NO_DEBUG(strrchr),
  2667. HOOK_INDIRECT(strlen),
  2668. HOOK_INDIRECT(strcmp),
  2669. HOOK_DIRECT_NO_DEBUG(strcpy),
  2670. HOOK_DIRECT_NO_DEBUG(strcat),
  2671. HOOK_DIRECT_NO_DEBUG(strcasecmp),
  2672. HOOK_DIRECT_NO_DEBUG(strncasecmp),
  2673. HOOK_DIRECT_NO_DEBUG(strdup),
  2674. HOOK_DIRECT_NO_DEBUG(strstr),
  2675. HOOK_DIRECT_NO_DEBUG(strtok),
  2676. HOOK_DIRECT_NO_DEBUG(strtok_r),
  2677. HOOK_DIRECT(strerror),
  2678. HOOK_DIRECT_NO_DEBUG(strerror_r),
  2679. HOOK_DIRECT_NO_DEBUG(strnlen),
  2680. HOOK_DIRECT_NO_DEBUG(strncat),
  2681. HOOK_DIRECT_NO_DEBUG(strndup),
  2682. HOOK_DIRECT_NO_DEBUG(strncmp),
  2683. HOOK_DIRECT_NO_DEBUG(strncpy),
  2684. HOOK_INDIRECT(strtod),
  2685. HOOK_DIRECT_NO_DEBUG(strcspn),
  2686. HOOK_DIRECT_NO_DEBUG(strpbrk),
  2687. HOOK_DIRECT_NO_DEBUG(strsep),
  2688. HOOK_DIRECT_NO_DEBUG(strspn),
  2689. HOOK_DIRECT_NO_DEBUG(strsignal),
  2690. HOOK_DIRECT_NO_DEBUG(getgrnam),
  2691. HOOK_DIRECT_NO_DEBUG(strcoll),
  2692. HOOK_DIRECT_NO_DEBUG(strxfrm),
  2693. /* strings.h */
  2694. HOOK_DIRECT_NO_DEBUG(bcmp),
  2695. HOOK_DIRECT_NO_DEBUG(bcopy),
  2696. HOOK_DIRECT_NO_DEBUG(bzero),
  2697. HOOK_DIRECT_NO_DEBUG(ffs),
  2698. HOOK_INDIRECT(__sprintf_chk),
  2699. HOOK_INDIRECT(__snprintf_chk),
  2700. /* pthread.h */
  2701. HOOK_DIRECT_NO_DEBUG(getauxval),
  2702. HOOK_INDIRECT(gettid),
  2703. HOOK_DIRECT_NO_DEBUG(getpid),
  2704. HOOK_DIRECT_NO_DEBUG(pthread_atfork),
  2705. HOOK_INDIRECT(pthread_create),
  2706. HOOK_INDIRECT(pthread_kill),
  2707. HOOK_DIRECT_NO_DEBUG(pthread_exit),
  2708. HOOK_DIRECT_NO_DEBUG(pthread_join),
  2709. HOOK_DIRECT_NO_DEBUG(pthread_detach),
  2710. HOOK_DIRECT_NO_DEBUG(pthread_self),
  2711. HOOK_DIRECT_NO_DEBUG(pthread_equal),
  2712. HOOK_DIRECT_NO_DEBUG(pthread_getschedparam),
  2713. HOOK_DIRECT_NO_DEBUG(pthread_setschedparam),
  2714. HOOK_INDIRECT(pthread_mutex_init),
  2715. HOOK_INDIRECT(pthread_mutex_destroy),
  2716. HOOK_INDIRECT(pthread_mutex_lock),
  2717. HOOK_INDIRECT(pthread_mutex_unlock),
  2718. HOOK_INDIRECT(pthread_mutex_trylock),
  2719. HOOK_INDIRECT(pthread_mutex_lock_timeout_np),
  2720. HOOK_INDIRECT(pthread_mutex_timedlock),
  2721. HOOK_DIRECT_NO_DEBUG(pthread_mutexattr_init),
  2722. HOOK_DIRECT_NO_DEBUG(pthread_mutexattr_destroy),
  2723. HOOK_DIRECT_NO_DEBUG(pthread_mutexattr_gettype),
  2724. HOOK_DIRECT_NO_DEBUG(pthread_mutexattr_settype),
  2725. HOOK_DIRECT_NO_DEBUG(pthread_mutexattr_getpshared),
  2726. HOOK_DIRECT(pthread_mutexattr_setpshared),
  2727. HOOK_DIRECT_NO_DEBUG(pthread_condattr_init),
  2728. HOOK_DIRECT_NO_DEBUG(pthread_condattr_getpshared),
  2729. HOOK_DIRECT_NO_DEBUG(pthread_condattr_setpshared),
  2730. HOOK_DIRECT_NO_DEBUG(pthread_condattr_destroy),
  2731. HOOK_DIRECT_NO_DEBUG(pthread_condattr_getclock),
  2732. HOOK_DIRECT_NO_DEBUG(pthread_condattr_setclock),
  2733. HOOK_INDIRECT(pthread_cond_init),
  2734. HOOK_INDIRECT(pthread_cond_destroy),
  2735. HOOK_INDIRECT(pthread_cond_broadcast),
  2736. HOOK_INDIRECT(pthread_cond_signal),
  2737. HOOK_INDIRECT(pthread_cond_wait),
  2738. HOOK_INDIRECT(pthread_cond_timedwait),
  2739. HOOK_TO(pthread_cond_timedwait_monotonic, _hybris_hook_pthread_cond_timedwait),
  2740. HOOK_TO(pthread_cond_timedwait_monotonic_np, _hybris_hook_pthread_cond_timedwait),
  2741. HOOK_INDIRECT(pthread_cond_timedwait_relative_np),
  2742. HOOK_INDIRECT(pthread_key_delete),
  2743. HOOK_INDIRECT(pthread_setname_np),
  2744. HOOK_DIRECT_NO_DEBUG(pthread_once),
  2745. HOOK_DIRECT_NO_DEBUG(pthread_key_create),
  2746. HOOK_INDIRECT(pthread_setspecific),
  2747. HOOK_INDIRECT(pthread_getspecific),
  2748. HOOK_INDIRECT(pthread_attr_init),
  2749. HOOK_INDIRECT(pthread_attr_destroy),
  2750. HOOK_INDIRECT(pthread_attr_setdetachstate),
  2751. HOOK_INDIRECT(pthread_attr_getdetachstate),
  2752. HOOK_INDIRECT(pthread_attr_setschedpolicy),
  2753. HOOK_INDIRECT(pthread_attr_getschedpolicy),
  2754. HOOK_INDIRECT(pthread_attr_setschedparam),
  2755. HOOK_INDIRECT(pthread_attr_getschedparam),
  2756. HOOK_INDIRECT(pthread_attr_setstacksize),
  2757. HOOK_INDIRECT(pthread_attr_getstacksize),
  2758. HOOK_INDIRECT(pthread_attr_setstackaddr),
  2759. HOOK_INDIRECT(pthread_attr_getstackaddr),
  2760. HOOK_INDIRECT(pthread_attr_setstack),
  2761. HOOK_INDIRECT(pthread_attr_getstack),
  2762. HOOK_INDIRECT(pthread_attr_setguardsize),
  2763. HOOK_INDIRECT(pthread_attr_getguardsize),
  2764. HOOK_INDIRECT(pthread_attr_setscope),
  2765. HOOK_INDIRECT(pthread_attr_getscope),
  2766. HOOK_INDIRECT(pthread_getattr_np),
  2767. HOOK_INDIRECT(pthread_rwlockattr_init),
  2768. HOOK_INDIRECT(pthread_rwlockattr_destroy),
  2769. HOOK_INDIRECT(pthread_rwlockattr_setpshared),
  2770. HOOK_INDIRECT(pthread_rwlockattr_getpshared),
  2771. HOOK_INDIRECT(pthread_rwlock_init),
  2772. HOOK_INDIRECT(pthread_rwlock_destroy),
  2773. HOOK_INDIRECT(pthread_rwlock_unlock),
  2774. HOOK_INDIRECT(pthread_rwlock_wrlock),
  2775. HOOK_INDIRECT(pthread_rwlock_rdlock),
  2776. HOOK_INDIRECT(pthread_rwlock_tryrdlock),
  2777. HOOK_INDIRECT(pthread_rwlock_trywrlock),
  2778. HOOK_INDIRECT(pthread_rwlock_timedrdlock),
  2779. HOOK_INDIRECT(pthread_rwlock_timedwrlock),
  2780. /* bionic-only pthread */
  2781. HOOK_TO(__pthread_gettid, _hybris_hook_pthread_gettid_np),
  2782. HOOK_INDIRECT(pthread_gettid_np),
  2783. /* stdio.h */
  2784. HOOK_TO(__isthreaded, &_hybris_hook___isthreaded),
  2785. HOOK_TO(__sF, _hybris_hook_sF),
  2786. HOOK_DIRECT_NO_DEBUG(fopen),
  2787. HOOK_DIRECT_NO_DEBUG(fdopen),
  2788. HOOK_DIRECT_NO_DEBUG(popen),
  2789. HOOK_DIRECT_NO_DEBUG(puts),
  2790. HOOK_DIRECT_NO_DEBUG(sprintf),
  2791. HOOK_DIRECT_NO_DEBUG(asprintf),
  2792. HOOK_DIRECT_NO_DEBUG(vasprintf),
  2793. HOOK_DIRECT_NO_DEBUG(snprintf),
  2794. HOOK_DIRECT_NO_DEBUG(vsprintf),
  2795. HOOK_DIRECT_NO_DEBUG(vsnprintf),
  2796. HOOK_INDIRECT(clearerr),
  2797. HOOK_INDIRECT(fclose),
  2798. HOOK_INDIRECT(feof),
  2799. HOOK_INDIRECT(ferror),
  2800. HOOK_INDIRECT(fflush),
  2801. HOOK_INDIRECT(fgetc),
  2802. HOOK_INDIRECT(fgetpos),
  2803. HOOK_INDIRECT(fgets),
  2804. HOOK_INDIRECT(fprintf),
  2805. HOOK_INDIRECT(fputc),
  2806. HOOK_INDIRECT(fputs),
  2807. HOOK_INDIRECT(fread),
  2808. HOOK_INDIRECT(freopen),
  2809. HOOK_INDIRECT(fscanf),
  2810. HOOK_INDIRECT(fseek),
  2811. HOOK_INDIRECT(fseeko),
  2812. HOOK_INDIRECT(fsetpos),
  2813. HOOK_INDIRECT(ftell),
  2814. HOOK_INDIRECT(ftello),
  2815. HOOK_INDIRECT(fwrite),
  2816. HOOK_INDIRECT(getc),
  2817. HOOK_INDIRECT(getdelim),
  2818. HOOK_INDIRECT(getline),
  2819. HOOK_INDIRECT(putc),
  2820. HOOK_INDIRECT(rewind),
  2821. HOOK_INDIRECT(setbuf),
  2822. HOOK_INDIRECT(setvbuf),
  2823. HOOK_INDIRECT(ungetc),
  2824. HOOK_INDIRECT(vfprintf),
  2825. HOOK_INDIRECT(vfscanf),
  2826. HOOK_INDIRECT(fileno),
  2827. HOOK_INDIRECT(pclose),
  2828. HOOK_INDIRECT(flockfile),
  2829. HOOK_INDIRECT(ftrylockfile),
  2830. HOOK_INDIRECT(funlockfile),
  2831. HOOK_INDIRECT(getc_unlocked),
  2832. HOOK_INDIRECT(putc_unlocked),
  2833. //HOOK(fgetln),
  2834. HOOK_INDIRECT(fpurge),
  2835. HOOK_INDIRECT(getw),
  2836. HOOK_INDIRECT(putw),
  2837. HOOK_INDIRECT(setbuffer),
  2838. HOOK_INDIRECT(setlinebuf),
  2839. HOOK_TO(__errno, __errno_location),
  2840. HOOK_INDIRECT(__set_errno),
  2841. HOOK_TO(__progname, &program_invocation_name),
  2842. /* net specifics, to avoid __res_get_state */
  2843. HOOK_INDIRECT(getaddrinfo),
  2844. HOOK_INDIRECT(freeaddrinfo),
  2845. HOOK_DIRECT_NO_DEBUG(gethostbyaddr),
  2846. HOOK_DIRECT_NO_DEBUG(gethostbyname),
  2847. HOOK_DIRECT_NO_DEBUG(gethostbyname2),
  2848. HOOK_DIRECT_NO_DEBUG(gethostent),
  2849. HOOK_DIRECT_NO_DEBUG(strftime),
  2850. HOOK_INDIRECT(sysconf),
  2851. HOOK_INDIRECT(dlopen),
  2852. HOOK_INDIRECT(dlerror),
  2853. HOOK_INDIRECT(dlsym),
  2854. HOOK_INDIRECT(dladdr),
  2855. HOOK_INDIRECT(dlclose),
  2856. /* dirent.h */
  2857. HOOK_DIRECT_NO_DEBUG(opendir),
  2858. HOOK_DIRECT_NO_DEBUG(fdopendir),
  2859. HOOK_DIRECT_NO_DEBUG(closedir),
  2860. HOOK_INDIRECT(readdir),
  2861. HOOK_INDIRECT(readdir_r),
  2862. HOOK_DIRECT_NO_DEBUG(rewinddir),
  2863. HOOK_DIRECT_NO_DEBUG(seekdir),
  2864. HOOK_DIRECT_NO_DEBUG(telldir),
  2865. HOOK_DIRECT_NO_DEBUG(dirfd),
  2866. HOOK_INDIRECT(scandir),
  2867. HOOK_INDIRECT(scandirat),
  2868. HOOK_INDIRECT(alphasort),
  2869. HOOK_INDIRECT(versionsort),
  2870. /* fcntl.h */
  2871. HOOK_INDIRECT(open),
  2872. // TODO: scandir, scandirat, alphasort, versionsort
  2873. HOOK_INDIRECT(__get_tls_hooks),
  2874. HOOK_DIRECT_NO_DEBUG(sscanf),
  2875. HOOK_DIRECT_NO_DEBUG(scanf),
  2876. HOOK_DIRECT_NO_DEBUG(vscanf),
  2877. HOOK_DIRECT_NO_DEBUG(vsscanf),
  2878. HOOK_DIRECT_NO_DEBUG(openlog),
  2879. HOOK_DIRECT_NO_DEBUG(syslog),
  2880. HOOK_DIRECT_NO_DEBUG(closelog),
  2881. HOOK_DIRECT_NO_DEBUG(vsyslog),
  2882. HOOK_DIRECT_NO_DEBUG(timer_create),
  2883. HOOK_DIRECT_NO_DEBUG(timer_settime),
  2884. HOOK_DIRECT_NO_DEBUG(timer_gettime),
  2885. HOOK_DIRECT_NO_DEBUG(timer_delete),
  2886. HOOK_DIRECT_NO_DEBUG(timer_getoverrun),
  2887. HOOK_DIRECT_NO_DEBUG(localtime),
  2888. HOOK_DIRECT_NO_DEBUG(localtime_r),
  2889. HOOK_DIRECT_NO_DEBUG(gmtime),
  2890. HOOK_DIRECT_NO_DEBUG(abort),
  2891. HOOK_DIRECT_NO_DEBUG(writev),
  2892. /* unistd.h */
  2893. HOOK_DIRECT_NO_DEBUG(access),
  2894. /* grp.h */
  2895. HOOK_DIRECT_NO_DEBUG(getgrgid),
  2896. HOOK_DIRECT_NO_DEBUG(__cxa_atexit),
  2897. HOOK_DIRECT_NO_DEBUG(__cxa_finalize),
  2898. HOOK_INDIRECT(__system_property_read),
  2899. HOOK_TO(__system_property_set, _hybris_hook_property_set),
  2900. HOOK_INDIRECT(__system_property_foreach),
  2901. HOOK_INDIRECT(__system_property_find),
  2902. HOOK_INDIRECT(__system_property_serial),
  2903. HOOK_INDIRECT(__system_property_wait),
  2904. HOOK_INDIRECT(__system_property_update),
  2905. HOOK_INDIRECT(__system_property_add),
  2906. HOOK_INDIRECT(__system_property_wait_any),
  2907. HOOK_INDIRECT(__system_property_find_nth),
  2908. /* sys/prctl.h */
  2909. HOOK_INDIRECT(prctl),
  2910. #endif
  2911. };
  2912.  
  2913. static struct _hook hooks_mm[] = {
  2914. #ifndef WANT_INITIALIZE_BIONIC
  2915. HOOK_DIRECT(strtol),
  2916. HOOK_DIRECT_NO_DEBUG(strlcat),
  2917. HOOK_DIRECT_NO_DEBUG(strlcpy),
  2918. HOOK_DIRECT(setenv),
  2919. HOOK_DIRECT(putenv),
  2920. HOOK_DIRECT(clearenv),
  2921. HOOK_DIRECT_NO_DEBUG(dprintf),
  2922. HOOK_DIRECT_NO_DEBUG(mallinfo),
  2923. HOOK_DIRECT(malloc_usable_size),
  2924. HOOK_DIRECT(posix_memalign),
  2925. HOOK_DIRECT(mprotect),
  2926. HOOK_TO(__gnu_strerror_r, _hybris_hook__gnu_strerror_r),
  2927. HOOK_INDIRECT(pthread_rwlockattr_getkind_np),
  2928. HOOK_INDIRECT(pthread_rwlockattr_setkind_np),
  2929. /* unistd.h */
  2930. HOOK_DIRECT(fork),
  2931. HOOK_DIRECT_NO_DEBUG(ttyname),
  2932. HOOK_DIRECT_NO_DEBUG(swprintf),
  2933. HOOK_DIRECT_NO_DEBUG(fmemopen),
  2934. HOOK_DIRECT_NO_DEBUG(open_memstream),
  2935. HOOK_DIRECT_NO_DEBUG(open_wmemstream),
  2936. HOOK_DIRECT_NO_DEBUG(ptsname),
  2937. HOOK_TO(__hybris_set_errno_internal, _hybris_hook___set_errno),
  2938. HOOK_DIRECT_NO_DEBUG(getservbyname),
  2939. /* libgen.h */
  2940. HOOK_INDIRECT(basename),
  2941. HOOK_INDIRECT(dirname),
  2942. /* locale.h */
  2943. HOOK_DIRECT(newlocale),
  2944. HOOK_DIRECT(freelocale),
  2945. HOOK_DIRECT(duplocale),
  2946. HOOK_DIRECT(uselocale),
  2947. HOOK_DIRECT(localeconv),
  2948. HOOK_DIRECT(setlocale),
  2949. /* sys/mman.h */
  2950. HOOK_DIRECT(mmap),
  2951. HOOK_DIRECT(munmap),
  2952. /* wchar.h */
  2953. HOOK_DIRECT_NO_DEBUG(wmemchr),
  2954. HOOK_DIRECT_NO_DEBUG(wmemcmp),
  2955. HOOK_DIRECT_NO_DEBUG(wmemcpy),
  2956. HOOK_DIRECT_NO_DEBUG(wmemmove),
  2957. HOOK_DIRECT_NO_DEBUG(wmemset),
  2958. HOOK_DIRECT_NO_DEBUG(wmempcpy),
  2959. HOOK_INDIRECT(fputws),
  2960. // It's enough to hook vfwprintf here as fwprintf will call it with a
  2961. // proper va_list in place so we don't have to handle this here.
  2962. HOOK_INDIRECT(vfwprintf),
  2963. HOOK_INDIRECT(fputwc),
  2964. HOOK_INDIRECT(putwc),
  2965. HOOK_INDIRECT(fgetwc),
  2966. HOOK_INDIRECT(getwc),
  2967. /* sched.h */
  2968. HOOK_DIRECT_NO_DEBUG(clone),
  2969. /* mntent.h */
  2970. HOOK_DIRECT(setmntent),
  2971. HOOK_INDIRECT(getmntent),
  2972. HOOK_INDIRECT(getmntent_r),
  2973. HOOK_INDIRECT(endmntent),
  2974. /* stdlib.h */
  2975. HOOK_DIRECT_NO_DEBUG(system),
  2976. /* pwd.h */
  2977. HOOK_DIRECT_NO_DEBUG(getpwuid),
  2978. HOOK_DIRECT_NO_DEBUG(getpwnam),
  2979. /* signal.h */
  2980. /* Hooks commented out for the moment as we need proper translations between
  2981. * bionic and glibc types for them to work (for instance, sigset_t has
  2982. * different definitions in each library).
  2983. */
  2984. #if 0
  2985. HOOK_INDIRECT(sigaction),
  2986. HOOK_INDIRECT(sigaddset),
  2987. HOOK_INDIRECT(sigaltstack),
  2988. HOOK_INDIRECT(sigblock),
  2989. HOOK_INDIRECT(sigdelset),
  2990. HOOK_INDIRECT(sigemptyset),
  2991. HOOK_INDIRECT(sigfillset),
  2992. HOOK_INDIRECT(siginterrupt),
  2993. HOOK_INDIRECT(sigismember),
  2994. HOOK_INDIRECT(siglongjmp),
  2995. HOOK_INDIRECT(signal),
  2996. HOOK_INDIRECT(signalfd),
  2997. HOOK_INDIRECT(sigpending),
  2998. HOOK_INDIRECT(sigprocmask),
  2999. HOOK_INDIRECT(sigqueue),
  3000. // setjmp.h defines segsetjmp via a #define and the real symbol
  3001. // we have to forward to is __sigsetjmp
  3002. {"sigsetjmp", __sigsetjmp},
  3003. HOOK_INDIRECT(sigsetmask),
  3004. HOOK_INDIRECT(sigsuspend),
  3005. HOOK_INDIRECT(sigtimedwait),
  3006. HOOK_INDIRECT(sigwait),
  3007. HOOK_INDIRECT(sigwaitinfo),
  3008. #endif
  3009. /* dirent.h */
  3010. HOOK_TO(readdir64, _hybris_hook_readdir),
  3011. HOOK_TO(readdir64_r, _hybris_hook_readdir_r),
  3012. HOOK_INDIRECT(scandir),
  3013. HOOK_INDIRECT(scandirat),
  3014. HOOK_TO(scandir64, _hybris_hook_scandir),
  3015. #endif
  3016. };
  3017.  
  3018.  
  3019. static int hook_cmp(const void *a, const void *b)
  3020. {
  3021. return strcmp(((struct _hook*)a)->name, ((struct _hook*)b)->name);
  3022. }
  3023.  
  3024. void hybris_set_hook_callback(hybris_hook_cb callback)
  3025. {
  3026. hook_callback = callback;
  3027. }
  3028.  
  3029. static int get_android_sdk_version()
  3030. {
  3031. static int sdk_version = -1;
  3032.  
  3033. if (sdk_version > 0)
  3034. return sdk_version;
  3035.  
  3036. char value[PROP_VALUE_MAX];
  3037. property_get("ro.build.version.sdk", value, "19");
  3038.  
  3039. sdk_version = 19;
  3040. if (strlen(value) > 0)
  3041. sdk_version = atoi(value);
  3042.  
  3043. #ifdef UBUNTU_LINKER_OVERRIDES
  3044. /* We override both frieza and turbo here until they are ready to be
  3045. * upgraded to the newer linker. */
  3046. char device_name[PROP_VALUE_MAX];
  3047. memset(device_name, 0, sizeof(device_name));
  3048. property_get("ro.build.product", device_name, "");
  3049. if (strlen(device_name) > 0) {
  3050. /* Force SDK version for both frieza/cooler and turbo for the time being */
  3051. if (strcmp(device_name, "frieza") == 0 ||
  3052. strcmp(device_name, "cooler") == 0 ||
  3053. strcmp(device_name, "turbo") == 0)
  3054. sdk_version = 19;
  3055. }
  3056. #endif
  3057.  
  3058. char *version_override = getenv("HYBRIS_ANDROID_SDK_VERSION");
  3059. if (version_override)
  3060. sdk_version = atoi(version_override);
  3061.  
  3062. LOGD("Using SDK API version %i\n", sdk_version);
  3063.  
  3064. return sdk_version;
  3065. }
  3066.  
  3067. #define HOOKS_SIZE(hooks) \
  3068. (sizeof(hooks) / sizeof(hooks[0]))
  3069.  
  3070.  
  3071. static void* __hybris_get_hooked_symbol(const char *sym, const char *requester)
  3072. {
  3073. static int sorted = 0;
  3074. static intptr_t counter = -1;
  3075. void *found = NULL;
  3076. struct _hook key;
  3077.  
  3078. /* First check if we have a callback registered which could
  3079. * give us a context specific hook implementation */
  3080. if (hook_callback)
  3081. {
  3082. found = hook_callback(sym, requester);
  3083. if (found)
  3084. return (void*) found;
  3085. }
  3086.  
  3087. if (!sorted)
  3088. {
  3089. qsort(hooks_common, HOOKS_SIZE(hooks_common), sizeof(hooks_common[0]), hook_cmp);
  3090. qsort(hooks_mm, HOOKS_SIZE(hooks_mm), sizeof(hooks_mm[0]), hook_cmp);
  3091. sorted = 1;
  3092. }
  3093.  
  3094. /* Allow newer hooks to override those which are available for all versions */
  3095. key.name = sym;
  3096. if (get_android_sdk_version() > 21)
  3097. found = bsearch(&key, hooks_mm, HOOKS_SIZE(hooks_mm), sizeof(hooks_mm[0]), hook_cmp);
  3098. if (!found)
  3099. found = bsearch(&key, hooks_common, HOOKS_SIZE(hooks_common), sizeof(hooks_common[0]), hook_cmp);
  3100.  
  3101. if (found)
  3102. {
  3103. if(hybris_should_trace(NULL, NULL))
  3104. return ((struct _hook*) found)->debug_func;
  3105. else
  3106. return ((struct _hook*) found)->func;
  3107. }
  3108.  
  3109. if (strncmp(sym, "pthread", 7) == 0 ||
  3110. strncmp(sym, "__pthread", 9) == 0)
  3111. {
  3112. /* safe */
  3113. if (strcmp(sym, "pthread_sigmask") == 0)
  3114. return NULL;
  3115. /* not safe */
  3116. counter--;
  3117. // If you're experiencing a crash later on check the address of the
  3118. // function pointer being call. If it matches the printed counter
  3119. // value here then you can easily find out which symbol is missing.
  3120. LOGD("Missing hook for pthread symbol %s (counter %" PRIiPTR ")\n", sym, counter);
  3121. return (void *) counter;
  3122. }
  3123.  
  3124. if (!getenv("HYBRIS_DONT_PRINT_SYMBOLS_WITHOUT_HOOK"))
  3125. LOGD("Could not find a hook for symbol %s", sym);
  3126.  
  3127. return NULL;
  3128. }
  3129.  
  3130. static void *linker_handle = NULL;
  3131.  
  3132. static void* __hybris_load_linker(const char *path)
  3133. {
  3134. void *handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
  3135. if (!handle) {
  3136. fprintf(stderr, "ERROR: Failed to load hybris linker for Android SDK version %d\n",
  3137. get_android_sdk_version());
  3138. return NULL;
  3139. }
  3140. return handle;
  3141. }
  3142.  
  3143. #define LINKER_NAME_JB "jb"
  3144. #define LINKER_NAME_MM "mm"
  3145.  
  3146. #if defined(WANT_LINKER_JB)
  3147. #define LINKER_NAME_DEFAULT LINKER_NAME_JB
  3148. #elif defined(WANT_LINKER_MM)
  3149. #define LINKER_NAME_DEFAULT LINKER_NAME_MM
  3150. #endif
  3151.  
  3152. static int linker_initialized = 0;
  3153.  
  3154. static void __hybris_linker_init()
  3155. {
  3156. LOGD("Linker initialization");
  3157.  
  3158. init_pthread_helpers();
  3159.  
  3160. int sdk_version = get_android_sdk_version();
  3161.  
  3162. char path[PATH_MAX];
  3163. const char *name = LINKER_NAME_DEFAULT;
  3164.  
  3165. /* See https://source.android.com/source/build-numbers.html for
  3166. * an overview over available SDK version numbers and which
  3167. * Android version they relate to. */
  3168. #if defined(WANT_LINKER_MM)
  3169. if (sdk_version <= 23)
  3170. name = LINKER_NAME_MM;
  3171. #endif
  3172. #if defined(WANT_LINKER_JB)
  3173. if (sdk_version < 21)
  3174. name = LINKER_NAME_JB;
  3175. #endif
  3176.  
  3177. const char *linker_dir = LINKER_PLUGIN_DIR;
  3178. const char *user_linker_dir = getenv("HYBRIS_LINKER_DIR");
  3179. if (user_linker_dir)
  3180. linker_dir = user_linker_dir;
  3181.  
  3182. snprintf(path, PATH_MAX, "%s/%s.so", linker_dir, name);
  3183.  
  3184. LOGD("Loading linker from %s..", path);
  3185.  
  3186. linker_handle = __hybris_load_linker(path);
  3187. if (!linker_handle)
  3188. exit(1);
  3189.  
  3190. /* Load all necessary symbols we need from the linker */
  3191. _android_linker_init = dlsym(linker_handle, "android_linker_init");
  3192. _android_dlopen = dlsym(linker_handle, "android_dlopen");
  3193. _android_dlsym = dlsym(linker_handle, "android_dlsym");
  3194. _android_dladdr = dlsym(linker_handle, "android_dladdr");
  3195. _android_dlclose = dlsym(linker_handle, "android_dlclose");
  3196. _android_dlerror = dlsym(linker_handle, "android_dlerror");
  3197.  
  3198. /* Now its time to setup the linker itself */
  3199. _android_linker_init(sdk_version, __hybris_get_hooked_symbol);
  3200.  
  3201. linker_initialized = 1;
  3202. }
  3203.  
  3204. #define ENSURE_LINKER_IS_LOADED() \
  3205. if (!linker_initialized) \
  3206. __hybris_linker_init();
  3207.  
  3208. /* NOTE: As we're not linking directly with the linker anymore
  3209. * but several users are using android_* functions directly we
  3210. * have to export them here. */
  3211.  
  3212. void *android_dlopen(const char *filename, int flag)
  3213. {
  3214. ENSURE_LINKER_IS_LOADED();
  3215.  
  3216. if (!_android_dlopen)
  3217. return NULL;
  3218.  
  3219. return _android_dlopen(filename,flag);
  3220. }
  3221.  
  3222. void *android_dlsym(void *handle, const char *symbol)
  3223. {
  3224. ENSURE_LINKER_IS_LOADED();
  3225.  
  3226. if (!_android_dlsym)
  3227. return NULL;
  3228.  
  3229. return _android_dlsym(handle,symbol);
  3230. }
  3231.  
  3232. int android_dlclose(void *handle)
  3233. {
  3234. ENSURE_LINKER_IS_LOADED();
  3235.  
  3236. if (!_android_dlclose)
  3237. return -1;
  3238.  
  3239. return _android_dlclose(handle);
  3240. }
  3241.  
  3242. const char *android_dlerror(void)
  3243. {
  3244. ENSURE_LINKER_IS_LOADED();
  3245.  
  3246. if (!_android_dlerror)
  3247. return NULL;
  3248.  
  3249. return _android_dlerror();
  3250. }
  3251.  
  3252. void *hybris_dlopen(const char *filename, int flag)
  3253. {
  3254. return android_dlopen(filename,flag);
  3255. }
  3256.  
  3257. void *hybris_dlsym(void *handle, const char *symbol)
  3258. {
  3259. return android_dlsym(handle,symbol);
  3260. }
  3261.  
  3262. int hybris_dlclose(void *handle)
  3263. {
  3264. return android_dlclose(handle);
  3265. }
  3266.  
  3267. const char *hybris_dlerror(void)
  3268. {
  3269. return android_dlerror();
  3270. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement