source: mainline/uspace/lib/c/generic/libc.c@ 40abf56

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 40abf56 was 40abf56, checked in by Jiří Zárevúcky <jiri.zarevucky@…>, 7 years ago

Make sure that a thread with uninitialized TLS does not need to call malloc()
to initialize it.

For threads and tasks created by loader, we create TLS beforehand and pass
it to the child. For tasks spawned directly by the kernel, we require it is
a static executable and allocate the initial TLS using as_area_create() instead
of the libc allocator.

  • Property mode set to 100644
File size: 4.3 KB
RevLine 
[3eddaff]1/*
[df4ed85]2 * Copyright (c) 2005 Martin Decky
[3eddaff]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 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[b2951e2]27 */
[a46da63]28
29/** @addtogroup lc Libc
[433131d]30 * @brief HelenOS C library
[a46da63]31 * @{
32 * @}
33 */
[433131d]34
[a46da63]35/** @addtogroup libc generic
36 * @ingroup lc
[b2951e2]37 * @{
38 */
[433131d]39
[b2951e2]40/** @file
[433131d]41 */
[3eddaff]42
[153c7a29]43#include <errno.h>
[3eddaff]44#include <libc.h>
[76d0981d]45#include <stdbool.h>
[47b7006]46#include <stdlib.h>
[fa23560]47#include <tls.h>
[bc1f1c2]48#include <fibril.h>
[47b7006]49#include <task.h>
[c98e6ee]50#include <loader/pcb.h>
[5126f80]51#include <vfs/vfs.h>
52#include <vfs/inbox.h>
[e26a4633]53#include "private/libc.h"
[fc5f7a8]54#include "private/async.h"
[47b7006]55#include "private/malloc.h"
56#include "private/io.h"
[d73d992]57#include "private/fibril.h"
[d54b303]58
[7fb3f1c]59#ifdef CONFIG_RTLD
[8a1fb09]60#include <rtld/rtld.h>
[7fb3f1c]61#endif
[1ea99cc]62
[2eadda9]63progsymbols_t __progsymbols;
64
[40abf56]65static bool env_setup;
66static fibril_t main_fibril;
[350514c]67
[7148abf]68void __libc_main(void *pcb_ptr)
[a46da63]69{
[40abf56]70 assert(!__tcb_is_set());
[a35b458]71
[91e4567]72 __pcb = (pcb_t *) pcb_ptr;
[a35b458]73
[40abf56]74 if (__pcb) {
75 main_fibril.tcb = __pcb->tcb;
76 } else {
77 /*
78 * Loaded by kernel, not the loader.
79 * Kernel only supports loading fully static binaries,
80 * so we can do basic initialization without worrying about
81 * dynamic libraries.
82 */
83
84 main_fibril.tcb = tls_make_initial(__progsymbols.elfstart);
85 }
86
87 assert(main_fibril.tcb);
88
89 /* Initialize the fibril. */
90 main_fibril.tcb->fibril_data = &main_fibril;
91 __tcb_set(main_fibril.tcb);
92 fibril_setup(&main_fibril);
93
94 /* Initialize user task run-time environment */
95 __malloc_init();
96
[91e4567]97#ifdef CONFIG_RTLD
98 if (__pcb != NULL && __pcb->rtld_runtime != NULL) {
99 runtime_env = (rtld_t *) __pcb->rtld_runtime;
[153c7a29]100 } else {
101 if (rtld_init_static() != EOK)
102 abort();
[91e4567]103 }
104#endif
[a35b458]105
[49a796f1]106 __async_server_init();
107 __async_client_init();
108 __async_ports_init();
[a35b458]109
[47b7006]110 /* The basic run-time environment is setup */
111 env_setup = true;
[a35b458]112
[433131d]113 int argc;
114 char **argv;
[a35b458]115
[47b7006]116 /*
117 * Get command line arguments and initialize
118 * standard input and output
119 */
[c98e6ee]120 if (__pcb == NULL) {
121 argc = 0;
122 argv = NULL;
[bb9ec2d]123 __stdio_init();
[c98e6ee]124 } else {
125 argc = __pcb->argc;
126 argv = __pcb->argv;
[bb9ec2d]127 __inbox_init(__pcb->inbox, __pcb->inbox_entries);
128 __stdio_init();
[5126f80]129 vfs_root_set(inbox_get("root"));
[d96d9bc]130 (void) vfs_cwd_set(__pcb->cwd);
[c98e6ee]131 }
[a35b458]132
[c4049e6]133 /*
134 * C++ Static constructor calls.
135 */
136
[2eadda9]137 if (__progsymbols.preinit_array) {
138 for (int i = __progsymbols.preinit_array_len - 1; i >= 0; --i)
139 __progsymbols.preinit_array[i]();
140 }
141
142 if (__progsymbols.init_array) {
143 for (int i = __progsymbols.init_array_len - 1; i >= 0; --i)
144 __progsymbols.init_array[i]();
145 }
[c4049e6]146
[47b7006]147 /*
148 * Run main() and set task return value
149 * according the result
150 */
[2eadda9]151 int retval = __progsymbols.main(argc, argv);
[47b7006]152 exit(retval);
153}
[7114d83]154
[099c834]155void __libc_exit(int status)
[47b7006]156{
[c4049e6]157 /*
158 * GCC extension __attribute__((destructor)),
159 * C++ destructors are added to __cxa_finalize call
160 * when the respective constructor is called.
161 */
162
[2eadda9]163 for (int i = 0; i < __progsymbols.fini_array_len; ++i)
164 __progsymbols.fini_array[i]();
[c4049e6]165
[47b7006]166 if (env_setup) {
167 __stdio_done();
168 task_retval(status);
169 }
[a35b458]170
[47b7006]171 __SYSCALL1(SYS_TASK_EXIT, false);
[2eadda9]172 __builtin_unreachable();
[3eddaff]173}
174
[099c834]175void __libc_abort(void)
[a46da63]176{
[47b7006]177 __SYSCALL1(SYS_TASK_EXIT, true);
[2eadda9]178 __builtin_unreachable();
[3eddaff]179}
[b2951e2]180
[a46da63]181/** @}
[b2951e2]182 */
Note: See TracBrowser for help on using the repository browser.