blob: 8dff8d7efcc32263353cf6f7c5dd57f8bf88f137 [file] [log] [blame]
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -07001/*
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 */
28#include <pthread.h>
29
30struct user_desc {
31 unsigned int entry_number;
32 unsigned long base_addr;
33 unsigned int limit;
34 unsigned int seg_32bit:1;
35 unsigned int contents:2;
36 unsigned int read_exec_only:1;
37 unsigned int limit_in_pages:1;
38 unsigned int seg_not_present:1;
39 unsigned int useable:1;
40 unsigned int empty:25;
41};
42
43/* the following can't be const, since the first call will
44 * update the 'entry_number' field
45 */
46static struct user_desc _tls_desc =
47{
48 -1,
49 0,
50 0x1000,
51 1,
52 0,
53 0,
54 1,
55 0,
56 1,
57 0
58};
59
60/* we implement thread local storage through the fs: segment descriptor
61 * we create a segment descriptor for the tls
62 */
63int __set_tls(void *ptr)
64{
65 int rc, segment;
66
67 _tls_desc.base_addr = (unsigned long)ptr;
68
69 rc = __set_thread_area( &_tls_desc );
70 if (rc != 0)
71 {
72 /* could not set thread local area */
73 return -1;
74 }
75
76 /* this weird computation comes from GLibc */
77 segment = _tls_desc.entry_number*8 + 3;
78 asm __volatile__ (
79 " movw %w0, %%fs" :: "r"(segment)
80 );
81 return 0;
82}
83
84
85