xref: /aosp_15_r20/trusty/kernel/lib/libc-trusty/libc_state.c (revision 344aa361028b423587d4ef3fa52a23d194628137)
1*344aa361SAndroid Build Coastguard Worker /*
2*344aa361SAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
3*344aa361SAndroid Build Coastguard Worker  *
4*344aa361SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*344aa361SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*344aa361SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*344aa361SAndroid Build Coastguard Worker  *
8*344aa361SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*344aa361SAndroid Build Coastguard Worker  *
10*344aa361SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*344aa361SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*344aa361SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*344aa361SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*344aa361SAndroid Build Coastguard Worker  * limitations under the License.
15*344aa361SAndroid Build Coastguard Worker  */
16*344aa361SAndroid Build Coastguard Worker 
17*344aa361SAndroid Build Coastguard Worker #include <err.h>
18*344aa361SAndroid Build Coastguard Worker #include <errno.h>
19*344aa361SAndroid Build Coastguard Worker #include <kernel/thread.h>
20*344aa361SAndroid Build Coastguard Worker #include <stdlib.h>
21*344aa361SAndroid Build Coastguard Worker #include <trusty/libc_state.h>
22*344aa361SAndroid Build Coastguard Worker #include "locale_impl.h"
23*344aa361SAndroid Build Coastguard Worker 
libc_state_create(void)24*344aa361SAndroid Build Coastguard Worker static struct libc_state* libc_state_create(void) {
25*344aa361SAndroid Build Coastguard Worker     struct libc_state* state = calloc(1, sizeof(struct libc_state));
26*344aa361SAndroid Build Coastguard Worker     if (state != NULL) {
27*344aa361SAndroid Build Coastguard Worker         state->errno_val = 0;
28*344aa361SAndroid Build Coastguard Worker         state->locale = C_LOCALE;
29*344aa361SAndroid Build Coastguard Worker     }
30*344aa361SAndroid Build Coastguard Worker     return state;
31*344aa361SAndroid Build Coastguard Worker }
32*344aa361SAndroid Build Coastguard Worker 
libc_state_thread_init(thread_t * t)33*344aa361SAndroid Build Coastguard Worker int libc_state_thread_init(thread_t* t) {
34*344aa361SAndroid Build Coastguard Worker     if (t == NULL) {
35*344aa361SAndroid Build Coastguard Worker         return ERR_INVALID_ARGS;
36*344aa361SAndroid Build Coastguard Worker     }
37*344aa361SAndroid Build Coastguard Worker     struct libc_state* state = libc_state_create();
38*344aa361SAndroid Build Coastguard Worker     if (state == NULL) {
39*344aa361SAndroid Build Coastguard Worker         return ERR_NO_RESOURCES;
40*344aa361SAndroid Build Coastguard Worker     }
41*344aa361SAndroid Build Coastguard Worker     thread_tls_set(t, TLS_ENTRY_LIBC, (uintptr_t)state);
42*344aa361SAndroid Build Coastguard Worker     return NO_ERROR;
43*344aa361SAndroid Build Coastguard Worker }
44*344aa361SAndroid Build Coastguard Worker 
libc_state_thread_free(thread_t * t)45*344aa361SAndroid Build Coastguard Worker int libc_state_thread_free(thread_t* t) {
46*344aa361SAndroid Build Coastguard Worker     if (t == NULL) {
47*344aa361SAndroid Build Coastguard Worker         return ERR_INVALID_ARGS;
48*344aa361SAndroid Build Coastguard Worker     }
49*344aa361SAndroid Build Coastguard Worker     struct libc_state* state =
50*344aa361SAndroid Build Coastguard Worker             (struct libc_state*)thread_tls_get(t, TLS_ENTRY_LIBC);
51*344aa361SAndroid Build Coastguard Worker     ASSERT(state);
52*344aa361SAndroid Build Coastguard Worker     free(state);
53*344aa361SAndroid Build Coastguard Worker 
54*344aa361SAndroid Build Coastguard Worker     /* Replace the old TLS entry with NULL to remove the dangling pointer and
55*344aa361SAndroid Build Coastguard Worker      * catch double frees */
56*344aa361SAndroid Build Coastguard Worker     thread_tls_set(t, TLS_ENTRY_LIBC, (uintptr_t)NULL);
57*344aa361SAndroid Build Coastguard Worker 
58*344aa361SAndroid Build Coastguard Worker     return NO_ERROR;
59*344aa361SAndroid Build Coastguard Worker }
60*344aa361SAndroid Build Coastguard Worker 
current_thread_libc_state(void)61*344aa361SAndroid Build Coastguard Worker struct libc_state* current_thread_libc_state(void) {
62*344aa361SAndroid Build Coastguard Worker     return (struct libc_state*)tls_get(TLS_ENTRY_LIBC);
63*344aa361SAndroid Build Coastguard Worker }
64*344aa361SAndroid Build Coastguard Worker 
__errno_location(void)65*344aa361SAndroid Build Coastguard Worker int* __errno_location(void) {
66*344aa361SAndroid Build Coastguard Worker     struct libc_state* state = current_thread_libc_state();
67*344aa361SAndroid Build Coastguard Worker     DEBUG_ASSERT(state);
68*344aa361SAndroid Build Coastguard Worker     return &state->errno_val;
69*344aa361SAndroid Build Coastguard Worker }
70*344aa361SAndroid Build Coastguard Worker 
71*344aa361SAndroid Build Coastguard Worker weak_alias(__errno_location, ___errno_location);
72