Changeset c4049e6 in mainline


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

Files:
9 edited

Legend:

Unmodified
Added
Removed
  • abi/include/abi/elf.h

    r9396c52 rc4049e6  
    110110 * ELF section types
    111111 */
    112 #define SHT_NULL      0
    113 #define SHT_PROGBITS  1
    114 #define SHT_SYMTAB    2
    115 #define SHT_STRTAB    3
    116 #define SHT_RELA      4
    117 #define SHT_HASH      5
    118 #define SHT_DYNAMIC   6
    119 #define SHT_NOTE      7
    120 #define SHT_NOBITS    8
    121 #define SHT_REL       9
    122 #define SHT_SHLIB     10
    123 #define SHT_DYNSYM    11
     112#define SHT_NULL       0
     113#define SHT_PROGBITS   1
     114#define SHT_SYMTAB     2
     115#define SHT_STRTAB     3
     116#define SHT_RELA       4
     117#define SHT_HASH       5
     118#define SHT_DYNAMIC    6
     119#define SHT_NOTE       7
     120#define SHT_NOBITS     8
     121#define SHT_REL        9
     122#define SHT_SHLIB      10
     123#define SHT_DYNSYM     11
    124124#define SHT_LOOS      0x60000000
    125125#define SHT_HIOS      0x6fffffff
  • uspace/lib/c/arch/amd64/_link.ld.in

    r9396c52 rc4049e6  
    5555        } :data
    5656
     57    __dso_handle = .;
     58
     59        .init_array : {
     60                PROVIDE_HIDDEN (__init_array_start = .);
     61                KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
     62                KEEP (*(.init_array .ctors))
     63                PROVIDE_HIDDEN (__init_array_end = .);
     64        }
     65
     66        .fini_array : {
     67                PROVIDE_HIDDEN (__fini_array_start = .);
     68                KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
     69                KEEP (*(.fini_array .dtors))
     70                PROVIDE_HIDDEN (__fini_array_end = .);
     71        }
     72
    5773        _end = .;
    5874
  • uspace/lib/c/generic/elf/elf_load.c

    r9396c52 rc4049e6  
    112112        pcb->dynamic = info->finfo.dynamic;
    113113        pcb->rtld_runtime = info->env;
     114        pcb->cpp_data = info->finfo.cpp_data;
    114115}
    115116
  • uspace/lib/c/generic/elf/elf_mod.c

    r9396c52 rc4049e6  
    198198        size_t phdr_len = header->e_phnum * header->e_phentsize;
    199199
     200        elf->info->interp = NULL;
     201        elf->info->dynamic = NULL;
     202        elf->info->cpp_data.ctors_count = 0;
     203        elf->info->cpp_data.dtors_count = 0;
     204
    200205        if (phdr_len > sizeof(phdr)) {
    201206                DPRINTF("more than %d program headers\n", phdr_cap);
  • uspace/lib/c/generic/libc.c

    r9396c52 rc4049e6  
    6161#endif
    6262
     63static bool env_setup = false;
    6364
    64 static bool env_setup = false;
     65/**
     66 * Used for C++ constructors/destructors
     67 * and the GCC constructor/destructor extension.
     68 */
     69typedef void (*init_array_entry_t)();
     70extern init_array_entry_t __init_array_start[];
     71extern init_array_entry_t __init_array_end[];
     72typedef void (*fini_array_entry_t)();
     73extern fini_array_entry_t __fini_array_start[];
     74extern fini_array_entry_t __fini_array_end[];
    6575
    6676void __libc_main(void *pcb_ptr)
     
    115125
    116126        /*
     127         * C++ Static constructor calls.
     128         */
     129        ptrdiff_t init_array_entries = (__init_array_end - __init_array_start);
     130
     131        for (int i = init_array_entries - 1; i > 0; --i)
     132                __init_array_start[i]();
     133
     134        /*
    117135         * Run main() and set task return value
    118136         * according the result
     
    124142void __libc_exit(int status)
    125143{
     144        /*
     145         * GCC extension __attribute__((destructor)),
     146         * C++ destructors are added to __cxa_finalize call
     147         * when the respective constructor is called.
     148         */
     149        ptrdiff_t fini_array_entries = (__fini_array_end - __fini_array_start);
     150
     151        for (int i = 0; i < fini_array_entries; ++i)
     152                __fini_array_start[i]();
     153
    126154        if (env_setup) {
    127155                __stdio_done();
  • uspace/lib/c/include/loader/pcb.h

    r9396c52 rc4049e6  
    3636#ifndef LIBC_PCB_H_
    3737#define LIBC_PCB_H_
    38 
    3938
    4039typedef void (*entry_point_t)(void);
     
    7675        /** Pointer to dynamic linker state structure (rtld_t). */
    7776        void *rtld_runtime;
     77        /** C++ related data. */
     78        cpp_data_t cpp_data;
    7879} pcb_t;
    7980
  • uspace/lib/cpp/include/internal/abi.hpp

    r9396c52 rc4049e6  
    3232namespace __cxxabiv1
    3333{
     34    /**
     35     * Static constructor/destructor helpers.
     36     */
     37
     38    extern "C" int __cxa_atexit(void (*)(void*), void*, void*);
     39
     40    extern "C" void __cxa_finalize(void*);
     41
    3442    /**
    3543     * Itanium C++ ABI type infos.
  • 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()
  • uspace/lib/cpp/src/internal/unwind.cpp

    r9396c52 rc4049e6  
    219219        // TODO: implement
    220220    }
     221
     222    extern "C" void __cxa_throw_bad_array_new_length()
     223    {
     224        // TODO: implement
     225    }
    221226}
Note: See TracChangeset for help on using the changeset viewer.