source: mainline/uspace/lib/cpp/src/__bits/runtime.cpp@ c6f23a7

Last change on this file since c6f23a7 was b57ba05, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 3 years ago

Update headers in C++ files

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*
2 * SPDX-FileCopyrightText: 2018 Jaroslav Jindrak
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <__bits/abi.hpp>
8#include <cassert>
9#include <cstdlib>
10#include <cstdint>
11#include <exception>
12#include <mutex>
13
14void* __dso_handle = nullptr;
15
16namespace __cxxabiv1
17{
18 namespace aux
19 {
20 struct destructor_t
21 {
22 void (*func)(void*);
23 void* ptr;
24 void* dso;
25 };
26
27 destructor_t* destructors{nullptr};
28 std::size_t destructor_count{0};
29 std::size_t destructor_size{32};
30
31 /**
32 * C atexit does not pass any arguments,
33 * but __cxa_finalize requires one so we
34 * use a wrapper.
35 */
36 void atexit_destructors()
37 {
38 __cxa_finalize(nullptr);
39 }
40 }
41
42 /**
43 * No need for a body, this function is called when a virtual
44 * call of a pure virtual function cannot be made.
45 */
46 extern "C" void __cxa_pure_virtual()
47 {
48 std::terminate();
49 }
50
51#ifdef __arm__
52 extern "C" int __aeabi_atexit(void* p, void (*f)(void*), void* d)
53 {
54 return __cxa_atexit(f, p, d);
55 }
56#endif
57
58 extern "C" int __cxa_atexit(void (*f)(void*), void* p, void* d)
59 {
60 if (!aux::destructors)
61 {
62 aux::destructors = new aux::destructor_t[aux::destructor_size];
63 std::atexit(aux::atexit_destructors);
64 }
65 else if (aux::destructor_count >= aux::destructor_size)
66 {
67 auto tmp = std::realloc(aux::destructors, aux::destructor_size * 2);
68
69 if (!tmp)
70 return -1;
71
72 aux::destructors = static_cast<aux::destructor_t*>(tmp);
73 aux::destructor_size *= 2;
74 }
75
76 auto& destr = aux::destructors[aux::destructor_count++];
77 destr.func = f;
78 destr.ptr = p;
79 destr.dso = d;
80
81 return 0;
82 }
83
84 extern "C" void __cxa_finalize(void *f)
85 {
86 if (!f)
87 {
88 for (std::size_t i = aux::destructor_count; i > 0; --i)
89 {
90 if (aux::destructors[i - 1].func)
91 (*aux::destructors[i - 1].func)(aux::destructors[i - 1].ptr);
92 }
93 }
94 else
95 {
96 for (std::size_t i = aux::destructor_count; i > 0; --i)
97 {
98 if (aux::destructors[i - 1].func == f)
99 {
100 (*aux::destructors[i - 1].func)(aux::destructors[i - 1].ptr);
101 aux::destructors[i - 1].func = nullptr;
102 aux::destructors[i - 1].ptr = nullptr;
103 aux::destructors[i - 1].dso = nullptr;
104 // TODO: shift and decrement count
105 }
106 }
107 }
108 }
109
110 using guard_t = std::uint64_t;
111 std::mutex static_guard_mtx{};
112
113 extern "C" int __cxa_guard_acquire(guard_t* guard)
114 {
115 static_guard_mtx.lock();
116
117 return !*((std::uint8_t*)guard);
118 }
119
120 extern "C" void __cxa_guard_release(guard_t* guard)
121 {
122 *((std::uint8_t*)guard) = 1;
123
124 static_guard_mtx.unlock();
125 }
126
127 extern "C" void __cxa_guard_abort(guard_t* guard)
128 {
129 static_guard_mtx.unlock();
130 }
131
132 __fundamental_type_info::~__fundamental_type_info()
133 { /* DUMMY BODY */ }
134
135 __array_type_info::~__array_type_info()
136 { /* DUMMY BODY */ }
137
138 __function_type_info::~__function_type_info()
139 { /* DUMMY BODY */ }
140
141 __enum_type_info::~__enum_type_info()
142 { /* DUMMY BODY */ }
143
144 __class_type_info::~__class_type_info()
145 { /* DUMMY BODY */ }
146
147 __si_class_type_info::~__si_class_type_info()
148 { /* DUMMY BODY */ }
149
150 __vmi_class_type_info::~__vmi_class_type_info()
151 { /* DUMMY BODY */ }
152
153 __pbase_type_info::~__pbase_type_info()
154 { /* DUMMY BODY */ }
155
156 __pointer_type_info::~__pointer_type_info()
157 { /* DUMMY BODY */ }
158
159 __pointer_to_member_type_info::~__pointer_to_member_type_info()
160 { /* DUMMY BODY */ }
161
162 /**
163 * This structure represents part of the vtable segment
164 * that contains data related to dynamic_cast.
165 */
166 struct vtable
167 {
168 // Unimportant to us.
169
170 std::ptrdiff_t offset_to_top;
171 std::type_info* tinfo;
172
173 // Actual vtable.
174 };
175 extern "C" void* __dynamic_cast(const void* sub, const __class_type_info* src,
176 const __class_type_info* dst, std::ptrdiff_t offset)
177 {
178 // TODO: implement
179 // NOTE: as far as I understand it, we get vtable prefix from sub, get the type_info
180 // ptr from that and then climb the inheritance hierarchy upwards till we either
181 // fint dst or fail and return nullptr
182 return nullptr;
183 }
184
185 // Needed on arm.
186 extern "C" void __cxa_end_cleanup()
187 { /* DUMMY BODY */ }
188
189 extern "C" int __cxa_thread_atexit(void(*)(void*), void*, void*)
190 {
191 // TODO: needed for thread_local variables
192 __unimplemented();
193 return 0;
194 }
195}
Note: See TracBrowser for help on using the repository browser.