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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a6139852 was 15f2306, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: fixed misnamed runtime function

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