| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | |
| 3 * Use of this source code is governed by a BSD-style license that can be | |
| 4 * found in the LICENSE file. | |
| 5 */ | |
| 6 | |
| 7 /* | |
| 8 * Native Client support for thread local storage. | |
| 9 * | |
| 10 * This is a highly experimental hack which will work with glibc's ld.so. | |
| 11 * Note: it probably wont work for ARM as is but we have no way | |
| 12 * of testing this at this point. As we are lacking a dynamic loader | |
| 13 * for that platform. | |
| 14 */ | |
| 15 | |
| 16 #include <stdint.h> | |
| 17 | |
| 18 #include "native_client/src/untrusted/nacl/nacl_thread.h" | |
| 19 #include "native_client/src/untrusted/nacl/tls.h" | |
| 20 #include "native_client/src/untrusted/nacl/tls_params.h" | |
| 21 | |
| 22 /* | |
| 23 * These are part of ld.so's API and use a non-standard calling convention | |
| 24 */ | |
| 25 #define REGPARM(n) __attribute__((regparm(n))) | |
| 26 | |
| 27 extern REGPARM(2) void _dl_get_tls_static_info(int *static_tls_size, | |
| 28 int *static_tls_align); | |
| 29 extern void *_dl_allocate_tls (void *mem); | |
| 30 | |
| 31 /* | |
| 32 * In case there is some mismatch between the combined areas of | |
| 33 * glibc's and our pthread/tls code we add some safety margin on both ends | |
| 34 * of the combined area. | |
| 35 * This is probably not needed, especially since we believe that | |
| 36 * the part of the (glibc) tdb which is accessed by ld.so is smaller than | |
| 37 * our tdb. | |
| 38 * On the other hand, we have not tried this we a big code bases | |
| 39 * yet and if there were problems without the safty paddding | |
| 40 * those would be really hard to track down. So it seems prudent | |
| 41 * to leave them in for a while. | |
| 42 * | |
| 43 * TODO(robertm): set safety paddding to zero after we have tried | |
| 44 * this with big apps | |
| 45 */ | |
| 46 | |
| 47 #define SAFETY_PADDING 256 | |
| 48 | |
| 49 static size_t aligned_size(size_t size, size_t alignment) { | |
| 50 return (size + alignment - 1) & -alignment; | |
| 51 } | |
| 52 | |
| 53 static char *aligned_addr(void *start, size_t alignment) { | |
| 54 return (void *) aligned_size((size_t) start, alignment); | |
| 55 } | |
| 56 | |
| 57 /* | |
| 58 * this is ugly, but we need a way to communicate these from | |
| 59 * _dl_get_tls_static_info() to | |
| 60 * __nacl_tls_initialize_memory() | |
| 61 */ | |
| 62 static int tls_size; | |
| 63 static int tls_align; | |
| 64 | |
| 65 size_t __nacl_tls_combined_size(size_t tdb_size) { | |
| 66 _dl_get_tls_static_info (&tls_size, &tls_align); | |
| 67 /* | |
| 68 * Disregarding the SAFETY_PADDING we need enough space | |
| 69 * to align the tdb which is sort of in the middle of combined area | |
| 70 * hence the extra "tls_size - 1" | |
| 71 * TODO(robertm): this may need to be adapted for ARM | |
| 72 */ | |
| 73 return tls_size + tdb_size + (tls_size - 1) + 2 * SAFETY_PADDING; | |
| 74 } | |
| 75 | |
| 76 void *__nacl_tls_initialize_memory(void *combined_area, size_t tdb_size) { | |
| 77 if (__nacl_tp_tdb_offset(tdb_size) != 0) { | |
| 78 /* | |
| 79 * This needs more work for ARM. | |
| 80 * For now abort via null pointer dereference. | |
| 81 */ | |
| 82 while (1) *(volatile int *) 0; | |
| 83 } else { | |
| 84 void *tdb = aligned_addr(((char *) combined_area) + tls_size + | |
| 85 SAFETY_PADDING , tls_align); | |
| 86 return _dl_allocate_tls(tdb); | |
| 87 } | |
| 88 } | |
| OLD | NEW |