1 /** 2 * Compiler runtime function symbols 3 * 4 * Compiler implementation of the 5 * $(LINK2 https://www.dlang.org, D programming language). 6 * 7 * Copyright: Copyright (C) 1996-1998 by Symantec 8 * Copyright (C) 2000-2023 by The D Language Foundation, All Rights Reserved 9 * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) 10 * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 11 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/drtlsym.d, backend/drtlsym.d) 12 */ 13 14 module dmd.backend.drtlsym; 15 16 version (SCPP) 17 version = COMPILE; 18 version (MARS) 19 version = COMPILE; 20 version (HTOD) 21 version = COMPILE; 22 23 version (COMPILE) 24 { 25 26 import core.stdc.stdio; 27 import core.stdc.stdlib; 28 import core.stdc.string; 29 30 import dmd.backend.cc; 31 import dmd.backend.cdef; 32 import dmd.backend.code; 33 import dmd.backend.code_x86; 34 import dmd.backend.global; 35 import dmd.backend.rtlsym; 36 import dmd.backend.symtab; 37 import dmd.backend.ty; 38 import dmd.backend.type; 39 40 extern (C++): 41 42 nothrow: 43 44 version (HTOD) 45 __gshared uint ALLREGS; 46 47 private __gshared Symbol*[RTLSYM.max + 1] rtlsym; 48 49 version (MARS) 50 // This varies depending on C ABI 51 alias FREGSAVED = fregsaved; 52 else 53 enum FREGSAVED = (mBP | mBX | mSI | mDI); 54 55 56 /****************************************** 57 * Get Symbol corresponding to Dwarf "personality" function. 58 * Returns: 59 * Personality function 60 */ 61 Symbol* getRtlsymPersonality() { return getRtlsym(RTLSYM.PERSONALITY); } 62 63 64 /****************************************** 65 * Get Symbol corresponding to i. 66 * Params: 67 * i = RTLSYM.xxxx 68 * Returns: 69 * runtime library Symbol 70 */ 71 Symbol *getRtlsym(RTLSYM i) 72 { 73 Symbol** ps = &rtlsym[i]; 74 if (*ps) 75 return *ps; 76 77 __gshared type* t; 78 __gshared type* tv; 79 80 if (!t) 81 { 82 t = type_fake(TYnfunc); 83 t.Tmangle = mTYman_c; 84 t.Tcount++; 85 86 // Variadic function 87 tv = type_fake(TYnfunc); 88 tv.Tmangle = mTYman_c; 89 tv.Tcount++; 90 } 91 92 // Lazilly initialize only what we use 93 switch (i) 94 { 95 case RTLSYM.THROWC: symbolz(ps,FLfunc,(mES | mBP),"_d_throwc", SFLexit, t); break; 96 case RTLSYM.THROWDWARF: symbolz(ps,FLfunc,(mES | mBP),"_d_throwdwarf", SFLexit, t); break; 97 case RTLSYM.MONITOR_HANDLER: symbolz(ps,FLfunc,FREGSAVED,"_d_monitor_handler", 0, tsclib); break; 98 case RTLSYM.MONITOR_PROLOG: symbolz(ps,FLfunc,FREGSAVED,"_d_monitor_prolog",0,t); break; 99 case RTLSYM.MONITOR_EPILOG: symbolz(ps,FLfunc,FREGSAVED,"_d_monitor_epilog",0,t); break; 100 case RTLSYM.DCOVER2: symbolz(ps,FLfunc,FREGSAVED,"_d_cover_register2", 0, t); break; 101 case RTLSYM.DASSERT: symbolz(ps,FLfunc,FREGSAVED,"_d_assert", SFLexit, t); break; 102 case RTLSYM.DASSERTP: symbolz(ps,FLfunc,FREGSAVED,"_d_assertp", SFLexit, t); break; 103 case RTLSYM.DASSERT_MSG: symbolz(ps,FLfunc,FREGSAVED,"_d_assert_msg", SFLexit, t); break; 104 case RTLSYM.DUNITTEST: symbolz(ps,FLfunc,FREGSAVED,"_d_unittest", 0, t); break; 105 case RTLSYM.DUNITTESTP: symbolz(ps,FLfunc,FREGSAVED,"_d_unittestp", 0, t); break; 106 case RTLSYM.DUNITTEST_MSG: symbolz(ps,FLfunc,FREGSAVED,"_d_unittest_msg", 0, t); break; 107 case RTLSYM.DARRAYP: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayboundsp", SFLexit, t); break; 108 case RTLSYM.DARRAY_SLICEP: symbolz(ps,FLfunc,FREGSAVED,"_d_arraybounds_slicep", SFLexit, t); break; 109 case RTLSYM.DARRAY_INDEXP: symbolz(ps,FLfunc,FREGSAVED,"_d_arraybounds_indexp", SFLexit, t); break; 110 case RTLSYM.DINVARIANT: symbolz(ps,FLfunc,FREGSAVED,"_D9invariant12_d_invariantFC6ObjectZv", 0, tsdlib); break; 111 case RTLSYM.MEMCPY: symbolz(ps,FLfunc,FREGSAVED,"memcpy", 0, t); break; 112 case RTLSYM.MEMSET8: symbolz(ps,FLfunc,FREGSAVED,"memset", 0, t); break; 113 case RTLSYM.MEMSET16: symbolz(ps,FLfunc,FREGSAVED,"_memset16", 0, t); break; 114 case RTLSYM.MEMSET32: symbolz(ps,FLfunc,FREGSAVED,"_memset32", 0, t); break; 115 case RTLSYM.MEMSET64: symbolz(ps,FLfunc,FREGSAVED,"_memset64", 0, t); break; 116 case RTLSYM.MEMSET128: symbolz(ps,FLfunc,FREGSAVED,"_memset128",0, t); break; 117 case RTLSYM.MEMSET128ii: symbolz(ps,FLfunc,FREGSAVED,"_memset128ii",0, t); break; 118 case RTLSYM.MEMSET80: symbolz(ps,FLfunc,FREGSAVED,"_memset80", 0, t); break; 119 case RTLSYM.MEMSET160: symbolz(ps,FLfunc,FREGSAVED,"_memset160",0, t); break; 120 case RTLSYM.MEMSETFLOAT: symbolz(ps,FLfunc,FREGSAVED,"_memsetFloat", 0, t); break; 121 case RTLSYM.MEMSETDOUBLE: symbolz(ps,FLfunc,FREGSAVED,"_memsetDouble", 0, t); break; 122 case RTLSYM.MEMSETSIMD: symbolz(ps,FLfunc,FREGSAVED,"_memsetSIMD",0, t); break; 123 case RTLSYM.MEMSETN: symbolz(ps,FLfunc,FREGSAVED,"_memsetn", 0, t); break; 124 case RTLSYM.NEWCLASS: symbolz(ps,FLfunc,FREGSAVED,"_d_newclass", 0, t); break; 125 case RTLSYM.NEWTHROW: symbolz(ps,FLfunc,FREGSAVED,"_d_newThrowable", 0, t); break; 126 case RTLSYM.NEWARRAYT: symbolz(ps,FLfunc,FREGSAVED,"_d_newarrayT", 0, t); break; 127 case RTLSYM.NEWARRAYIT: symbolz(ps,FLfunc,FREGSAVED,"_d_newarrayiT", 0, t); break; 128 case RTLSYM.NEWITEMT: symbolz(ps,FLfunc,FREGSAVED,"_d_newitemT", 0, t); break; 129 case RTLSYM.NEWITEMIT: symbolz(ps,FLfunc,FREGSAVED,"_d_newitemiT", 0, t); break; 130 case RTLSYM.NEWARRAYMTX: symbolz(ps,FLfunc,FREGSAVED,"_d_newarraymTX", 0, t); break; 131 case RTLSYM.NEWARRAYMITX: symbolz(ps,FLfunc,FREGSAVED,"_d_newarraymiTX", 0, t); break; 132 case RTLSYM.ARRAYLITERALTX: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayliteralTX", 0, t); break; 133 case RTLSYM.ASSOCARRAYLITERALTX: symbolz(ps,FLfunc,FREGSAVED,"_d_assocarrayliteralTX", 0, t); break; 134 case RTLSYM.CALLFINALIZER: symbolz(ps,FLfunc,FREGSAVED,"_d_callfinalizer", 0, t); break; 135 case RTLSYM.CALLINTERFACEFINALIZER: symbolz(ps,FLfunc,FREGSAVED,"_d_callinterfacefinalizer", 0, t); break; 136 case RTLSYM.ALLOCMEMORY: symbolz(ps,FLfunc,FREGSAVED,"_d_allocmemory", 0, t); break; 137 case RTLSYM.DYNAMIC_CAST: symbolz(ps,FLfunc,FREGSAVED,"_d_dynamic_cast", 0, t); break; 138 case RTLSYM.INTERFACE_CAST: symbolz(ps,FLfunc,FREGSAVED,"_d_interface_cast", 0, t); break; 139 case RTLSYM.ARRAYCATT: symbolz(ps,FLfunc,FREGSAVED,"_d_arraycatT", 0, t); break; 140 case RTLSYM.ARRAYCATNTX: symbolz(ps,FLfunc,FREGSAVED,"_d_arraycatnTX", 0, t); break; 141 case RTLSYM.ARRAYAPPENDT: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayappendT", 0, t); break; 142 case RTLSYM.ARRAYAPPENDCTX: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayappendcTX", 0, t); break; 143 case RTLSYM.ARRAYAPPENDCD: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayappendcd", 0, t); break; 144 case RTLSYM.ARRAYAPPENDWD: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayappendwd", 0, t); break; 145 case RTLSYM.ARRAYSETLENGTHT: symbolz(ps,FLfunc,FREGSAVED,"_d_arraysetlengthT", 0, t); break; 146 case RTLSYM.ARRAYSETLENGTHIT: symbolz(ps,FLfunc,FREGSAVED,"_d_arraysetlengthiT", 0, t); break; 147 case RTLSYM.ARRAYCOPY: symbolz(ps,FLfunc,FREGSAVED,"_d_arraycopy", 0, t); break; 148 case RTLSYM.ARRAYASSIGN: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayassign", 0, t); break; 149 case RTLSYM.ARRAYASSIGN_R: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayassign_r", 0, t); break; 150 case RTLSYM.ARRAYASSIGN_L: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayassign_l", 0, t); break; 151 case RTLSYM.ARRAYSETASSIGN: symbolz(ps,FLfunc,FREGSAVED,"_d_arraysetassign", 0, t); break; 152 case RTLSYM.ARRAYEQ2: symbolz(ps,FLfunc,FREGSAVED,"_adEq2", 0, t); break; 153 154 case RTLSYM.EXCEPT_HANDLER3: symbolz(ps,FLfunc,fregsaved,"_except_handler3", 0, tsclib); break; 155 case RTLSYM.CPP_HANDLER: symbolz(ps,FLfunc,FREGSAVED,"_cpp_framehandler", 0, tsclib); break; 156 case RTLSYM.D_HANDLER: symbolz(ps,FLfunc,FREGSAVED,"_d_framehandler", 0, tsclib); break; 157 case RTLSYM.D_LOCAL_UNWIND2: symbolz(ps,FLfunc,FREGSAVED,"_d_local_unwind2", 0, tsclib); break; 158 case RTLSYM.LOCAL_UNWIND2: symbolz(ps,FLfunc,FREGSAVED,"_local_unwind2", 0, tsclib); break; 159 case RTLSYM.UNWIND_RESUME: symbolz(ps,FLfunc,FREGSAVED,"_Unwind_Resume", SFLexit, t); break; 160 case RTLSYM.PERSONALITY: symbolz(ps,FLfunc,FREGSAVED,"__dmd_personality_v0", 0, t); break; 161 case RTLSYM.BEGIN_CATCH: symbolz(ps,FLfunc,FREGSAVED,"__dmd_begin_catch", 0, t); break; 162 case RTLSYM.CXA_BEGIN_CATCH: symbolz(ps,FLfunc,FREGSAVED,"__cxa_begin_catch", 0, t); break; 163 case RTLSYM.CXA_END_CATCH: symbolz(ps,FLfunc,FREGSAVED,"__cxa_end_catch", 0, t); break; 164 165 case RTLSYM.TLS_INDEX: symbolz(ps,FLextern,0,"_tls_index",0,tstypes[TYint]); break; 166 case RTLSYM.TLS_ARRAY: symbolz(ps,FLextern,0,"_tls_array",0,tspvoid); break; 167 case RTLSYM.AHSHIFT: symbolz(ps,FLfunc,0,"_AHSHIFT",0,tstrace); break; 168 169 case RTLSYM.HDIFFN: symbolz(ps,FLfunc,mBX|mCX|mSI|mDI|mBP|mES,"_aNahdiff", 0, tsclib); break; 170 case RTLSYM.HDIFFF: symbolz(ps,FLfunc,mBX|mCX|mSI|mDI|mBP|mES,"_aFahdiff", 0, tsclib); break; 171 case RTLSYM.INTONLY: symbolz(ps,FLfunc,mSI|mDI,"_intonly", 0, tsclib); break; 172 173 case RTLSYM.EXCEPT_LIST: symbolz(ps,FLextern,0,"_except_list",0,tstypes[TYint]); break; 174 case RTLSYM.SETJMP3: symbolz(ps,FLfunc,FREGSAVED,"_setjmp3", 0, tsclib); break; 175 case RTLSYM.LONGJMP: symbolz(ps,FLfunc,FREGSAVED,"_seh_longjmp_unwind@4", 0, tsclib); break; 176 case RTLSYM.ALLOCA: symbolz(ps,FLfunc,fregsaved,"__alloca", 0, tsclib); break; 177 case RTLSYM.CPP_LONGJMP: symbolz(ps,FLfunc,FREGSAVED,"_cpp_longjmp_unwind@4", 0, tsclib); break; 178 case RTLSYM.PTRCHK: symbolz(ps,FLfunc,fregsaved,"_ptrchk", 0, tsclib); break; 179 case RTLSYM.CHKSTK: symbolz(ps,FLfunc,fregsaved,"_chkstk", 0, tsclib); break; 180 case RTLSYM.TRACE_PRO_N: symbolz(ps,FLfunc,ALLREGS|mBP|mES,"_trace_pro_n",0,tstrace); break; 181 case RTLSYM.TRACE_PRO_F: symbolz(ps,FLfunc,ALLREGS|mBP|mES,"_trace_pro_f",0,tstrace); break; 182 case RTLSYM.TRACE_EPI_N: symbolz(ps,FLfunc,ALLREGS|mBP|mES,"_trace_epi_n",0,tstrace); break; 183 case RTLSYM.TRACE_EPI_F: symbolz(ps,FLfunc,ALLREGS|mBP|mES,"_trace_epi_f",0,tstrace); break; 184 185 case RTLSYM.TRACENEWCLASS: symbolz(ps,FLfunc,FREGSAVED,"_d_newclassTrace", 0, t); break; 186 case RTLSYM.TRACENEWARRAYT: symbolz(ps,FLfunc,FREGSAVED,"_d_newarrayTTrace", 0, t); break; 187 case RTLSYM.TRACENEWARRAYIT: symbolz(ps,FLfunc,FREGSAVED,"_d_newarrayiTTrace", 0, t); break; 188 case RTLSYM.TRACENEWARRAYMTX: symbolz(ps,FLfunc,FREGSAVED,"_d_newarraymTXTrace", 0, t); break; 189 case RTLSYM.TRACENEWARRAYMITX: symbolz(ps,FLfunc,FREGSAVED,"_d_newarraymiTXTrace", 0, t); break; 190 case RTLSYM.TRACENEWITEMT: symbolz(ps,FLfunc,FREGSAVED,"_d_newitemTTrace", 0, t); break; 191 case RTLSYM.TRACENEWITEMIT: symbolz(ps,FLfunc,FREGSAVED,"_d_newitemiTTrace", 0, t); break; 192 case RTLSYM.TRACECALLFINALIZER: symbolz(ps,FLfunc,FREGSAVED,"_d_callfinalizerTrace", 0, t); break; 193 case RTLSYM.TRACECALLINTERFACEFINALIZER: symbolz(ps,FLfunc,FREGSAVED,"_d_callinterfacefinalizerTrace", 0, t); break; 194 case RTLSYM.TRACEARRAYLITERALTX: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayliteralTXTrace", 0, t); break; 195 case RTLSYM.TRACEASSOCARRAYLITERALTX: symbolz(ps,FLfunc,FREGSAVED,"_d_assocarrayliteralTXTrace", 0, t); break; 196 case RTLSYM.TRACEARRAYCATT: symbolz(ps,FLfunc,FREGSAVED,"_d_arraycatTTrace", 0, t); break; 197 case RTLSYM.TRACEARRAYCATNTX: symbolz(ps,FLfunc,FREGSAVED,"_d_arraycatnTXTrace", 0, t); break; 198 case RTLSYM.TRACEARRAYAPPENDT: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayappendTTrace", 0, t); break; 199 case RTLSYM.TRACEARRAYAPPENDCTX: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayappendcTXTrace", 0, t); break; 200 case RTLSYM.TRACEARRAYAPPENDCD: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayappendcdTrace", 0, t); break; 201 case RTLSYM.TRACEARRAYAPPENDWD: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayappendwdTrace", 0, t); break; 202 case RTLSYM.TRACEARRAYSETLENGTHT: symbolz(ps,FLfunc,FREGSAVED,"_d_arraysetlengthTTrace", 0, t); break; 203 case RTLSYM.TRACEARRAYSETLENGTHIT: symbolz(ps,FLfunc,FREGSAVED,"_d_arraysetlengthiTTrace", 0, t); break; 204 case RTLSYM.TRACEALLOCMEMORY: symbolz(ps,FLfunc,FREGSAVED,"_d_allocmemoryTrace", 0, t); break; 205 case RTLSYM.C_ASSERT: symbolz(ps,FLfunc,FREGSAVED,"_assert", SFLexit, t); break; 206 case RTLSYM.C__ASSERT: symbolz(ps,FLfunc,FREGSAVED,"__assert", SFLexit, t); break; 207 case RTLSYM.C__ASSERT_FAIL: symbolz(ps,FLfunc,FREGSAVED,"__assert_fail", SFLexit, t); break; 208 case RTLSYM.C__ASSERT_RTN: symbolz(ps,FLfunc,FREGSAVED,"__assert_rtn", SFLexit, t); break; 209 210 case RTLSYM.CXA_ATEXIT: symbolz(ps,FLfunc,FREGSAVED,"__cxa_atexit", 0, t); break; 211 default: 212 assert(0); 213 } 214 return *ps; 215 } 216 217 218 /****************************************** 219 * Create and initialize Symbol for runtime function. 220 * Params: 221 * ps = where to store initialized Symbol pointer 222 * f = FLxxx 223 * regsaved = registers not altered by function 224 * name = name of function 225 * flags = value for Sflags 226 * t = type of function 227 */ 228 private void symbolz(Symbol** ps, int fl, regm_t regsaved, const(char)* name, SYMFLGS flags, type *t) 229 { 230 Symbol *s = symbol_calloc(name[0 .. strlen(name)]); 231 s.Stype = t; 232 s.Ssymnum = SYMIDX.max; 233 s.Sclass = SC.extern_; 234 s.Sfl = cast(char)fl; 235 s.Sregsaved = regsaved; 236 s.Sflags = flags; 237 *ps = s; 238 } 239 240 /****************************************** 241 * Initialize rtl symbols. 242 */ 243 244 void rtlsym_init() 245 { 246 } 247 248 /******************************* 249 * Reset the symbols for the case when we are generating multiple 250 * .OBJ files from one compile. 251 */ 252 version (MARS) 253 { 254 void rtlsym_reset() 255 { 256 clib_inited = 0; // reset CLIB symbols, too 257 for (size_t i = 0; i <= RTLSYM.max; i++) 258 { 259 if (rtlsym[i]) 260 { 261 rtlsym[i].Sxtrnnum = 0; 262 rtlsym[i].Stypidx = 0; 263 } 264 } 265 } 266 267 } 268 269 /******************************* 270 */ 271 272 void rtlsym_term() 273 { 274 } 275 276 }