source: mainline/uspace/lib/cpp/src/internal/runtime.cpp@ 9283830

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

c+cpp: added support for global static constructors destructors

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