Ignore:
Timestamp:
2018-07-05T21:41:20Z (6 years ago)
Author:
Dzejrou <dzejrou@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9283830
Parents:
9396c52
git-author:
Dzejrou <dzejrou@…> (2018-03-15 10:40:53)
git-committer:
Dzejrou <dzejrou@…> (2018-07-05 21:41:20)
Message:

c+cpp: added support for global static constructors destructors

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/cpp/src/internal/runtime.cpp

    r9396c52 rc4049e6  
    2727 */
    2828
     29#include <cstdlib>
     30#include <cstdint>
    2931#include <internal/abi.hpp>
     32#include <exception>
    3033
    3134namespace __cxxabiv1
    3235{
     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    }
    3359
    3460    /**
     
    3662     * call of a pure virtual function cannot be made.
    3763     */
    38     // TODO: terminate in this
    3964    extern "C" void __cxa_pure_call()
    40     { /* DUMMY BODY */ }
     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    }
    41120
    42121    __fundamental_type_info::~__fundamental_type_info()
Note: See TracChangeset for help on using the changeset viewer.