mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 20:50:41 +03:00
Workaround for platforms lacking crt_destructor (#13364)
Workaround for platforms lacking crt_destructor Signed-off-by: Iain Buclaw <ibuclaw@users.noreply.github.com> Signed-off-by: Razvan Nitu <RazvanN7@users.noreply.github.com> Merged-on-behalf-of: Razvan Nitu <RazvanN7@users.noreply.github.com>
This commit is contained in:
parent
dba01aec93
commit
93108bb9ea
7 changed files with 102 additions and 5 deletions
16
.cirrus.yml
16
.cirrus.yml
|
@ -82,6 +82,22 @@ task:
|
|||
<< : *COMMON_STEPS_TEMPLATE
|
||||
|
||||
# Mac
|
||||
task:
|
||||
name: macOS 12.x x64, $TASK_NAME_SUFFIX
|
||||
osx_instance:
|
||||
image: monterey-xcode
|
||||
timeout_in: 60m
|
||||
environment:
|
||||
OS_NAME: darwin
|
||||
# override Cirrus default OS (`darwin`)
|
||||
OS: osx
|
||||
# 12 CPU cores and 24 GB of memory are available
|
||||
N: 12
|
||||
matrix:
|
||||
- TASK_NAME_SUFFIX: DMD (latest)
|
||||
- TASK_NAME_SUFFIX: DMD (coverage)
|
||||
<< : *COVERAGE_ENVIRONMENT_TEMPLATE
|
||||
<< : *COMMON_STEPS_TEMPLATE
|
||||
task:
|
||||
name: macOS 11.x x64, $TASK_NAME_SUFFIX
|
||||
osx_instance:
|
||||
|
|
|
@ -238,6 +238,7 @@ Symbol *getRtlsym(RTLSYM i)
|
|||
case RTLSYM.C__ASSERT_FAIL: symbolz(ps,FLfunc,FREGSAVED,"__assert_fail", SFLexit, t); break;
|
||||
case RTLSYM.C__ASSERT_RTN: symbolz(ps,FLfunc,FREGSAVED,"__assert_rtn", SFLexit, t); break;
|
||||
|
||||
case RTLSYM.CXA_ATEXIT: symbolz(ps,FLfunc,FREGSAVED,"__cxa_atexit", 0, t); break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
@ -169,7 +169,9 @@ enum RTLSYM
|
|||
C_ASSERT,
|
||||
C__ASSERT,
|
||||
C__ASSERT_FAIL,
|
||||
C__ASSERT_RTN
|
||||
C__ASSERT_RTN,
|
||||
|
||||
CXA_ATEXIT
|
||||
}
|
||||
|
||||
extern (C++):
|
||||
|
|
|
@ -5031,18 +5031,21 @@ struct TargetC final
|
|||
Gcc_Clang = 3u,
|
||||
};
|
||||
|
||||
bool crtDestructorsSupported;
|
||||
uint8_t longsize;
|
||||
uint8_t long_doublesize;
|
||||
uint8_t wchar_tsize;
|
||||
Runtime runtime;
|
||||
BitFieldStyle bitFieldStyle;
|
||||
TargetC() :
|
||||
crtDestructorsSupported(true),
|
||||
longsize(),
|
||||
long_doublesize(),
|
||||
wchar_tsize()
|
||||
{
|
||||
}
|
||||
TargetC(uint8_t longsize, uint8_t long_doublesize = 0u, uint8_t wchar_tsize = 0u, Runtime runtime = (Runtime)0u, BitFieldStyle bitFieldStyle = (BitFieldStyle)0u) :
|
||||
TargetC(bool crtDestructorsSupported, uint8_t longsize = 0u, uint8_t long_doublesize = 0u, uint8_t wchar_tsize = 0u, Runtime runtime = (Runtime)0u, BitFieldStyle bitFieldStyle = (BitFieldStyle)0u) :
|
||||
crtDestructorsSupported(crtDestructorsSupported),
|
||||
longsize(longsize),
|
||||
long_doublesize(long_doublesize),
|
||||
wchar_tsize(wchar_tsize),
|
||||
|
@ -7821,7 +7824,7 @@ public:
|
|||
RealProperties()
|
||||
{
|
||||
}
|
||||
Target(OS os, uint8_t osMajor = 0u, uint8_t ptrsize = 0u, uint8_t realsize = 0u, uint8_t realpad = 0u, uint8_t realalignsize = 0u, uint8_t classinfosize = 0u, uint64_t maxStaticDataSize = 0LLU, TargetC c = TargetC(0u, 0u, 0u, (TargetC::Runtime)0u, (TargetC::BitFieldStyle)0u), TargetCPP cpp = TargetCPP(false, false, false, false, (TargetCPP::Runtime)0u), TargetObjC objc = TargetObjC(false), _d_dynamicArray< const char > architectureName = {}, CPU cpu = (CPU)11u, bool is64bit = true, bool isLP64 = false, _d_dynamicArray< const char > obj_ext = {}, _d_dynamicArray< const char > lib_ext = {}, _d_dynamicArray< const char > dll_ext = {}, bool run_noext = false, bool mscoff = false, FPTypeProperties<float > FloatProperties = FPTypeProperties<float >(NAN, NAN, NAN, NAN, NAN, 0LL, 0LL, 0LL, 0LL, 0LL, 0LL), FPTypeProperties<double > DoubleProperties = FPTypeProperties<double >(NAN, NAN, NAN, NAN, NAN, 0LL, 0LL, 0LL, 0LL, 0LL, 0LL), FPTypeProperties<_d_real > RealProperties = FPTypeProperties<_d_real >(NAN, NAN, NAN, NAN, NAN, 0LL, 0LL, 0LL, 0LL, 0LL, 0LL)) :
|
||||
Target(OS os, uint8_t osMajor = 0u, uint8_t ptrsize = 0u, uint8_t realsize = 0u, uint8_t realpad = 0u, uint8_t realalignsize = 0u, uint8_t classinfosize = 0u, uint64_t maxStaticDataSize = 0LLU, TargetC c = TargetC(true, 0u, 0u, 0u, (TargetC::Runtime)0u, (TargetC::BitFieldStyle)0u), TargetCPP cpp = TargetCPP(false, false, false, false, (TargetCPP::Runtime)0u), TargetObjC objc = TargetObjC(false), _d_dynamicArray< const char > architectureName = {}, CPU cpu = (CPU)11u, bool is64bit = true, bool isLP64 = false, _d_dynamicArray< const char > obj_ext = {}, _d_dynamicArray< const char > lib_ext = {}, _d_dynamicArray< const char > dll_ext = {}, bool run_noext = false, bool mscoff = false, FPTypeProperties<float > FloatProperties = FPTypeProperties<float >(NAN, NAN, NAN, NAN, NAN, 0LL, 0LL, 0LL, 0LL, 0LL, 0LL), FPTypeProperties<double > DoubleProperties = FPTypeProperties<double >(NAN, NAN, NAN, NAN, NAN, 0LL, 0LL, 0LL, 0LL, 0LL, 0LL), FPTypeProperties<_d_real > RealProperties = FPTypeProperties<_d_real >(NAN, NAN, NAN, NAN, NAN, 0LL, 0LL, 0LL, 0LL, 0LL, 0LL)) :
|
||||
os(os),
|
||||
osMajor(osMajor),
|
||||
ptrsize(ptrsize),
|
||||
|
|
|
@ -1170,8 +1170,75 @@ void FuncDeclaration_toObjFile(FuncDeclaration fd, bool multiobj)
|
|||
|
||||
if (fd.isCrtCtorDtor & 1)
|
||||
objmod.setModuleCtorDtor(s, true);
|
||||
|
||||
if (fd.isCrtCtorDtor & 2)
|
||||
objmod.setModuleCtorDtor(s, false);
|
||||
{
|
||||
//See TargetC.initialize
|
||||
if(target.c.crtDestructorsSupported)
|
||||
{
|
||||
objmod.setModuleCtorDtor(s, false);
|
||||
} else
|
||||
{
|
||||
/*
|
||||
https://issues.dlang.org/show_bug.cgi?id=22520
|
||||
|
||||
Apple radar: https://openradar.appspot.com/FB9733712
|
||||
|
||||
Apple deprecated the mechanism used to implement `crt_destructor`
|
||||
on MacOS Monterey. This works around that by generating a new function
|
||||
(crt_destructor_thunk_NNN, run as a constructor) which registers
|
||||
the destructor-to-be using __cxa_atexit()
|
||||
|
||||
This workaround may need a further look at when it comes to
|
||||
shared library support, however there is no bridge for
|
||||
that spilt milk to flow under yet.
|
||||
|
||||
This relies on the Itanium ABI so is portable to any
|
||||
platform it, if needed.
|
||||
*/
|
||||
__gshared uint nthDestructor = 0;
|
||||
char* buf = cast(char*) calloc(50, 1);
|
||||
assert(buf);
|
||||
const ret = snprintf(buf, 100, "_dmd_crt_destructor_thunk.%u", nthDestructor++);
|
||||
assert(ret >= 0 && ret < 100, "snprintf either failed or overran buffer");
|
||||
//Function symbol
|
||||
auto newConstructor = symbol_calloc(buf);
|
||||
//Build type
|
||||
newConstructor.Stype = type_function(TYnfunc, [], false, type_alloc(TYvoid));
|
||||
//Tell it it's supposed to be a C function. Does it do anything? Not sure.
|
||||
type_setmangle(&newConstructor.Stype, mTYman_c);
|
||||
symbol_func(newConstructor);
|
||||
//Global SC for now.
|
||||
newConstructor.Sclass = SCstatic;
|
||||
func_t* funcState = newConstructor.Sfunc;
|
||||
//Init start block
|
||||
funcState.Fstartblock = block_calloc();
|
||||
block* startBlk = funcState.Fstartblock;
|
||||
//Make that block run __cxa_atexit(&func);
|
||||
auto atexitSym = getRtlsym(RTLSYM.CXA_ATEXIT);
|
||||
Symbol* dso_handle = symbol_calloc("__dso_handle");
|
||||
dso_handle.Stype = type_fake(TYint);
|
||||
//Try to get MacOS _ prefix-ism right.
|
||||
type_setmangle(&dso_handle.Stype, mTYman_c);
|
||||
dso_handle.Sfl = FLextern;
|
||||
dso_handle.Sclass = SCextern;
|
||||
dso_handle.Stype.Tcount++;
|
||||
auto handlePtr = el_ptr(dso_handle);
|
||||
//Build parameter pack - __cxa_atexit(&func, null, null)
|
||||
auto paramPack = el_params(handlePtr, el_long(TYnptr, 0), el_ptr(s), null);
|
||||
auto exec = el_bin(OPcall, TYvoid, el_var(atexitSym), paramPack);
|
||||
block_appendexp(startBlk, exec); //payload
|
||||
startBlk.BC = BCgoto;
|
||||
auto next = block_calloc();
|
||||
startBlk.appendSucc(next);
|
||||
startBlk.Bnext = next;
|
||||
next.BC = BCret;
|
||||
//Emit in binary
|
||||
writefunc(newConstructor);
|
||||
//Mark as a CONSTRUCTOR because our thunk implements the destructor
|
||||
objmod.setModuleCtorDtor(newConstructor, true);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (sd; *irs.deferToObj)
|
||||
{
|
||||
|
|
|
@ -1192,7 +1192,7 @@ struct TargetC
|
|||
/// https://docs.microsoft.com/en-us/cpp/cpp/cpp-bit-fields?view=msvc-160
|
||||
Gcc_Clang, /// gcc and clang
|
||||
}
|
||||
|
||||
bool crtDestructorsSupported = true; /// Not all platforms support crt_destructor
|
||||
ubyte longsize; /// size of a C `long` or `unsigned long` type
|
||||
ubyte long_doublesize; /// size of a C `long double`
|
||||
ubyte wchar_tsize; /// size of a C `wchar_t` type
|
||||
|
@ -1245,6 +1245,13 @@ struct TargetC
|
|||
bitFieldStyle = BitFieldStyle.Gcc_Clang;
|
||||
else
|
||||
assert(0);
|
||||
/*
|
||||
MacOS Monterey (12) does not support C runtime destructors.
|
||||
*/
|
||||
if (os == Target.OS.OSX)
|
||||
{
|
||||
crtDestructorsSupported = false;
|
||||
}
|
||||
}
|
||||
|
||||
void addRuntimePredefinedGlobalIdent() const
|
||||
|
|
|
@ -70,6 +70,7 @@ struct TargetC
|
|||
Gcc_Clang, // gcc and clang
|
||||
};
|
||||
|
||||
uint8_t crtDestructorsSupported; // Not all platforms support crt_destructor
|
||||
uint8_t longsize; // size of a C 'long' or 'unsigned long' type
|
||||
uint8_t long_doublesize; // size of a C 'long double'
|
||||
uint8_t wchar_tsize; // size of a C 'wchar_t' type
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue