-
Ben Avison authored
Later versions of the toolchain move on from the CFront model for static object construction and destruction (which used symbols called '__link' in object files which the linker manipulated into a linked list pointed at by the symbol '__head'). Now, global or file-scope constructors are indicated by function pointers emitted into the area C$$ctorvec, with the function bodies being emitted into the area C$$ctor. The C library supports the calling of global or file-scope destructors in two ways: either they can be registered using atexit() calls from within the corresponding constructor (these are issued first) or function pointers can be provided in the area C$$dtorvec (with function bodies in the area C$$dtor). Function- or block-scope static-storage-duration destructors are a bit more complicated, since they are only constructed when the block in which they are declared comes into scope at run-time. For a module client, this means that they may be constructed in either USR or SVC mode. However, the destruction must be deferred until module finalisation in SVC mode, since there is no way for a USR mode constructor to know whether the scope will later be re-entered from SVC mode. For this scenario, atexit() will not suffice, and new entry _clib_at_destruction() must be used. (It is also valid to use this entry from global or file-scope constructors.) We add this 1 new function to cl_entry5. This chunk has not yet appeared in a stable release, nor included in a DDE release. Annotate these events too. The locations of the C$$ctor, C$$ctorvec, C$$dtor and C$$dtorvec areas are not established until client link time, so to convey this information to the shared C library, we need to extend its interface with the stubs. This is done by adding 8 additional words onto the end of the language description struct. Furthermore, so that this information is passed from the shared library kernel to the language-specific part (clib), the InitProc() entry in the language description struct is now passed a pointer to that struct. Similarly, _clib_initialise(), which previously took no arguments, now takes that pointer (but performs sanity checks on it and its contents, so that it can confidently handle old stubs for which the value of a1 is undefined). Add test programs to exercise the new functionality, without requiring the use of a C++ compiler.
d8b72a18