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

Last change on this file since e49d0ac 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
RevLine 
[1b6477e]1/*
[b57ba05]2 * SPDX-FileCopyrightText: 2018 Jaroslav Jindrak
[1b6477e]3 *
[b57ba05]4 * SPDX-License-Identifier: BSD-3-Clause
[1b6477e]5 */
6
[b57a3ee]7#include <__bits/abi.hpp>
[46c66f8]8#include <cassert>
[c4049e6]9#include <cstdlib>
10#include <cstdint>
11#include <exception>
[4bea22a]12#include <mutex>
[1b6477e]13
[7dcce0a]14void* __dso_handle = nullptr;
15
[1b6477e]16namespace __cxxabiv1
17{
[c4049e6]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 }
[1b6477e]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 */
[15f2306]46 extern "C" void __cxa_pure_virtual()
[c4049e6]47 {
48 std::terminate();
49 }
50
[59d8235]51#ifdef __arm__
[fd244cd]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
[c4049e6]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 }
[1b6477e]109
[4bea22a]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
[1b6477e]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 */ }
[ef9d0988]161
[4c58668]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 };
[ef9d0988]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
[4c58668]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
[ef9d0988]182 return nullptr;
183 }
[09553a0]184
185 // Needed on arm.
186 extern "C" void __cxa_end_cleanup()
187 { /* DUMMY BODY */ }
[d3ba97d]188
189 extern "C" int __cxa_thread_atexit(void(*)(void*), void*, void*)
190 {
191 // TODO: needed for thread_local variables
[46c66f8]192 __unimplemented();
[d3ba97d]193 return 0;
194 }
[1b6477e]195}
Note: See TracBrowser for help on using the repository browser.