The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2008 The Android Open Source Project |
| 3 | * All rights reserved. |
| 4 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions |
| 7 | * are met: |
| 8 | * * Redistributions of source code must retain the above copyright |
| 9 | * notice, this list of conditions and the following disclaimer. |
| 10 | * * Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in |
| 12 | * the documentation and/or other materials provided with the |
| 13 | * distribution. |
| 14 | * |
| 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
| 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
| 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 26 | * SUCH DAMAGE. |
| 27 | */ |
Elliott Hughes | 2a0b873 | 2013-10-08 18:50:24 -0700 | [diff] [blame] | 28 | |
Ryan Prichard | 45d1349 | 2019-01-03 02:51:30 -0800 | [diff] [blame] | 29 | #pragma once |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 30 | |
Josh Gao | 5e2285d | 2017-02-22 12:19:05 -0800 | [diff] [blame] | 31 | #include <locale.h> |
| 32 | #include <mntent.h> |
| 33 | #include <stdio.h> |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 34 | #include <sys/cdefs.h> |
Josh Gao | 5e2285d | 2017-02-22 12:19:05 -0800 | [diff] [blame] | 35 | #include <sys/param.h> |
Elliott Hughes | fc69a8a | 2016-03-04 11:53:09 -0800 | [diff] [blame] | 36 | |
Christopher Ferris | c5d3a43 | 2019-09-25 17:50:36 -0700 | [diff] [blame] | 37 | #include <platform/bionic/tls.h> |
| 38 | |
Josh Gao | 4956c37 | 2019-12-19 16:35:51 -0800 | [diff] [blame] | 39 | #include "platform/bionic/macros.h" |
Josh Gao | 5e2285d | 2017-02-22 12:19:05 -0800 | [diff] [blame] | 40 | #include "grp_pwd.h" |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 41 | |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 42 | /** WARNING WARNING WARNING |
| 43 | ** |
Ryan Prichard | 45d1349 | 2019-01-03 02:51:30 -0800 | [diff] [blame] | 44 | ** This header file is *NOT* part of the public Bionic ABI/API and should not |
| 45 | ** be used/included by user-serviceable parts of the system (e.g. |
| 46 | ** applications). |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 47 | **/ |
| 48 | |
Ryan Prichard | 45d1349 | 2019-01-03 02:51:30 -0800 | [diff] [blame] | 49 | class pthread_internal_t; |
Ryan Prichard | 37754cd | 2018-12-07 01:47:00 -0800 | [diff] [blame] | 50 | |
Ryan Prichard | 45d1349 | 2019-01-03 02:51:30 -0800 | [diff] [blame] | 51 | // This struct is small, so the linker can allocate a temporary copy on its |
| 52 | // stack. It can't be combined with pthread_internal_t because: |
| 53 | // - native bridge requires pthread_internal_t to have the same layout across |
| 54 | // architectures, and |
| 55 | // - On x86, this struct would have to be placed at the front of |
| 56 | // pthread_internal_t, moving fields like `tid`. |
| 57 | // - We'd like to avoid having a temporary pthread_internal_t object that |
| 58 | // needs to be transferred once the final size of static TLS is known. |
| 59 | struct bionic_tcb { |
| 60 | void* raw_slots_storage[BIONIC_TLS_SLOTS]; |
Elliott Hughes | 3e89847 | 2013-02-12 16:40:24 +0000 | [diff] [blame] | 61 | |
Ryan Prichard | 45d1349 | 2019-01-03 02:51:30 -0800 | [diff] [blame] | 62 | // Return a reference to a slot given its TP-relative TLS_SLOT_xxx index. |
| 63 | // The thread pointer (i.e. __get_tls()) points at &tls_slot(0). |
| 64 | void*& tls_slot(size_t tpindex) { |
| 65 | return raw_slots_storage[tpindex - MIN_TLS_SLOT]; |
| 66 | } |
Elliott Hughes | 3e89847 | 2013-02-12 16:40:24 +0000 | [diff] [blame] | 67 | |
Ryan Prichard | 45d1349 | 2019-01-03 02:51:30 -0800 | [diff] [blame] | 68 | // Initialize the main thread's final object using its bootstrap object. |
| 69 | void copy_from_bootstrap(const bionic_tcb* boot) { |
| 70 | // Copy everything. Problematic slots will be reinitialized. |
| 71 | *this = *boot; |
| 72 | } |
Elliott Hughes | 34583c1 | 2018-11-13 15:30:07 -0800 | [diff] [blame] | 73 | |
Ryan Prichard | 45d1349 | 2019-01-03 02:51:30 -0800 | [diff] [blame] | 74 | pthread_internal_t* thread() { |
| 75 | return static_cast<pthread_internal_t*>(tls_slot(TLS_SLOT_THREAD_ID)); |
| 76 | } |
Elliott Hughes | 44b53ad | 2013-02-11 20:18:47 +0000 | [diff] [blame] | 77 | }; |
Elliott Hughes | 5419b94 | 2012-10-16 15:54:46 -0700 | [diff] [blame] | 78 | |
Elliott Hughes | 3e89847 | 2013-02-12 16:40:24 +0000 | [diff] [blame] | 79 | /* |
Yabin Cui | 5e2bd71 | 2015-02-20 16:15:33 -0800 | [diff] [blame] | 80 | * Bionic uses some pthread keys internally. All pthread keys used internally |
Elliott Hughes | 6170693 | 2015-03-31 10:56:58 -0700 | [diff] [blame] | 81 | * should be created in constructors, except for keys that may be used in or |
| 82 | * before constructors. |
| 83 | * |
Yabin Cui | 5e2bd71 | 2015-02-20 16:15:33 -0800 | [diff] [blame] | 84 | * We need to manually maintain the count of pthread keys used internally, but |
| 85 | * pthread_test should fail if we forget. |
Elliott Hughes | 6170693 | 2015-03-31 10:56:58 -0700 | [diff] [blame] | 86 | * |
| 87 | * These are the pthread keys currently used internally by libc: |
Elliott Hughes | 6170693 | 2015-03-31 10:56:58 -0700 | [diff] [blame] | 88 | * _res_key libc (constructor in BSD code) |
Yabin Cui | 5e2bd71 | 2015-02-20 16:15:33 -0800 | [diff] [blame] | 89 | */ |
| 90 | |
Josh Gao | 5e2285d | 2017-02-22 12:19:05 -0800 | [diff] [blame] | 91 | #define LIBC_PTHREAD_KEY_RESERVED_COUNT 1 |
Yabin Cui | 5e2bd71 | 2015-02-20 16:15:33 -0800 | [diff] [blame] | 92 | |
Christopher Ferris | c0f8928 | 2015-04-15 16:34:57 -0700 | [diff] [blame] | 93 | /* Internally, jemalloc uses a single key for per thread data. */ |
| 94 | #define JEMALLOC_PTHREAD_KEY_RESERVED_COUNT 1 |
Yabin Cui | 5e2bd71 | 2015-02-20 16:15:33 -0800 | [diff] [blame] | 95 | #define BIONIC_PTHREAD_KEY_RESERVED_COUNT (LIBC_PTHREAD_KEY_RESERVED_COUNT + JEMALLOC_PTHREAD_KEY_RESERVED_COUNT) |
Christopher Ferris | 72bbd42 | 2014-05-08 11:14:03 -0700 | [diff] [blame] | 96 | |
Elliott Hughes | 1887621 | 2013-12-12 11:02:41 -0800 | [diff] [blame] | 97 | /* |
Yabin Cui | 5e2bd71 | 2015-02-20 16:15:33 -0800 | [diff] [blame] | 98 | * Maximum number of pthread keys allocated. |
| 99 | * This includes pthread keys used internally and externally. |
Elliott Hughes | 1887621 | 2013-12-12 11:02:41 -0800 | [diff] [blame] | 100 | */ |
Yabin Cui | 5e2bd71 | 2015-02-20 16:15:33 -0800 | [diff] [blame] | 101 | #define BIONIC_PTHREAD_KEY_COUNT (BIONIC_PTHREAD_KEY_RESERVED_COUNT + PTHREAD_KEYS_MAX) |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 102 | |
Ryan Prichard | 45d1349 | 2019-01-03 02:51:30 -0800 | [diff] [blame] | 103 | class pthread_key_data_t { |
| 104 | public: |
| 105 | uintptr_t seq; // Use uintptr_t just for alignment, as we use pointer below. |
| 106 | void* data; |
| 107 | }; |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 108 | |
Ryan Prichard | 45d1349 | 2019-01-03 02:51:30 -0800 | [diff] [blame] | 109 | // ~3 pages. This struct is allocated as static TLS memory (i.e. at a fixed |
| 110 | // offset from the thread pointer). |
| 111 | struct bionic_tls { |
| 112 | pthread_key_data_t key_data[BIONIC_PTHREAD_KEY_COUNT]; |
| 113 | |
| 114 | locale_t locale; |
| 115 | |
| 116 | char basename_buf[MAXPATHLEN]; |
| 117 | char dirname_buf[MAXPATHLEN]; |
| 118 | |
| 119 | mntent mntent_buf; |
| 120 | char mntent_strings[BUFSIZ]; |
| 121 | |
| 122 | char ptsname_buf[32]; |
| 123 | char ttyname_buf[64]; |
| 124 | |
| 125 | char strerror_buf[NL_TEXTMAX]; |
| 126 | char strsignal_buf[NL_TEXTMAX]; |
| 127 | |
| 128 | group_state_t group; |
| 129 | passwd_state_t passwd; |
| 130 | |
Josh Gao | 9727192 | 2019-11-06 13:15:00 -0800 | [diff] [blame] | 131 | char fdtrack_disabled; |
Daniele Di Proietto | f5f04b1 | 2022-01-25 18:52:04 +0000 | [diff] [blame] | 132 | char bionic_systrace_disabled; |
| 133 | char padding[2]; |
Josh Gao | 9727192 | 2019-11-06 13:15:00 -0800 | [diff] [blame] | 134 | |
Ryan Prichard | 45d1349 | 2019-01-03 02:51:30 -0800 | [diff] [blame] | 135 | // Initialize the main thread's final object using its bootstrap object. |
| 136 | void copy_from_bootstrap(const bionic_tls* boot __attribute__((unused))) { |
| 137 | // Nothing in bionic_tls needs to be preserved in the transition to the |
| 138 | // final TLS objects, so don't copy anything. |
| 139 | } |
| 140 | }; |
| 141 | |
Bernhard Rosenkraenzer | edad1e1 | 2013-09-18 23:37:00 +0200 | [diff] [blame] | 142 | class KernelArgumentBlock; |
Ryan Prichard | 45d1349 | 2019-01-03 02:51:30 -0800 | [diff] [blame] | 143 | extern "C" void __libc_init_main_thread_early(const KernelArgumentBlock& args, bionic_tcb* temp_tcb); |
| 144 | extern "C" void __libc_init_main_thread_late(); |
| 145 | extern "C" void __libc_init_main_thread_final(); |