1 /** 2 * Compiler implementation of the 3 * $(LINK2 http://www.dlang.org, D programming language). 4 * 5 * Copyright: Copyright (C) 1996-1998 by Symantec 6 * Copyright (C) 2000-2020 by The D Language Foundation, All Rights Reserved 7 * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright) 8 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 9 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/drtlsym.d, backend/drtlsym.d) 10 */ 11 12 module dmd.backend.drtlsym; 13 14 version (SCPP) 15 version = COMPILE; 16 version (MARS) 17 version = COMPILE; 18 version (HTOD) 19 version = COMPILE; 20 21 version (COMPILE) 22 { 23 24 import core.stdc.stdio; 25 import core.stdc.stdlib; 26 import core.stdc.string; 27 28 import dmd.backend.cc; 29 import dmd.backend.cdef; 30 import dmd.backend.code; 31 import dmd.backend.code_x86; 32 import dmd.backend.global; 33 import dmd.backend.rtlsym; 34 import dmd.backend.symtab; 35 import dmd.backend.ty; 36 import dmd.backend.type; 37 38 extern (C++): 39 40 nothrow: 41 42 version (HTOD) 43 __gshared uint ALLREGS; 44 45 private __gshared Symbol*[RTLSYM_MAX] rtlsym; 46 47 version (MARS) 48 // This varies depending on C ABI 49 alias FREGSAVED = fregsaved; 50 else 51 enum FREGSAVED = (mBP | mBX | mSI | mDI); 52 53 54 /****************************************** 55 * Get Symbol corresponding to Dwarf "personality" function. 56 * Returns: 57 * Personality function 58 */ 59 Symbol* getRtlsymPersonality() { return getRtlsym(RTLSYM_PERSONALITY); } 60 61 62 /****************************************** 63 * Get Symbol corresponding to i. 64 * Params: 65 * i = RTLSYM_xxxx 66 * Returns: 67 * runtime library Symbol 68 */ 69 Symbol *getRtlsym(int i) 70 { 71 Symbol** ps = &rtlsym[i]; 72 if (*ps) 73 return *ps; 74 75 __gshared type* t; 76 __gshared type* tv; 77 78 if (!t) 79 { 80 t = type_fake(TYnfunc); 81 t.Tmangle = mTYman_c; 82 t.Tcount++; 83 84 // Variadic function 85 tv = type_fake(TYnfunc); 86 tv.Tmangle = mTYman_c; 87 tv.Tcount++; 88 } 89 90 // Only used by dmd1 for RTLSYM_THROW 91 type *tw = null; 92 93 // Lazilly initialize only what we use 94 switch (i) 95 { 96 case RTLSYM_THROW: symbolz(ps,FLfunc,(mES | mBP),"_d_throw@4", SFLexit, tw); break; 97 case RTLSYM_THROWC: symbolz(ps,FLfunc,(mES | mBP),"_d_throwc", SFLexit, t); break; 98 case RTLSYM_THROWDWARF: symbolz(ps,FLfunc,(mES | mBP),"_d_throwdwarf", SFLexit, t); break; 99 case RTLSYM_MONITOR_HANDLER: symbolz(ps,FLfunc,FREGSAVED,"_d_monitor_handler", 0, tsclib); break; 100 case RTLSYM_MONITOR_PROLOG: symbolz(ps,FLfunc,FREGSAVED,"_d_monitor_prolog",0,t); break; 101 case RTLSYM_MONITOR_EPILOG: symbolz(ps,FLfunc,FREGSAVED,"_d_monitor_epilog",0,t); break; 102 case RTLSYM_DCOVER: symbolz(ps,FLfunc,FREGSAVED,"_d_cover_register", 0, t); break; 103 case RTLSYM_DCOVER2: symbolz(ps,FLfunc,FREGSAVED,"_d_cover_register2", 0, t); break; 104 case RTLSYM_DASSERT: symbolz(ps,FLfunc,FREGSAVED,"_d_assert", SFLexit, t); break; 105 case RTLSYM_DASSERTP: symbolz(ps,FLfunc,FREGSAVED,"_d_assertp", SFLexit, t); break; 106 case RTLSYM_DASSERT_MSG: symbolz(ps,FLfunc,FREGSAVED,"_d_assert_msg", SFLexit, t); break; 107 case RTLSYM_DUNITTEST: symbolz(ps,FLfunc,FREGSAVED,"_d_unittest", 0, t); break; 108 case RTLSYM_DUNITTESTP: symbolz(ps,FLfunc,FREGSAVED,"_d_unittestp", 0, t); break; 109 case RTLSYM_DUNITTEST_MSG: symbolz(ps,FLfunc,FREGSAVED,"_d_unittest_msg", 0, t); break; 110 case RTLSYM_DARRAY: symbolz(ps,FLfunc,FREGSAVED,"_d_arraybounds", SFLexit, t); break; 111 case RTLSYM_DARRAYP: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayboundsp", SFLexit, t); break; 112 case RTLSYM_DINVARIANT: symbolz(ps,FLfunc,FREGSAVED,"_D9invariant12_d_invariantFC6ObjectZv", 0, tsdlib); break; 113 case RTLSYM_MEMCPY: symbolz(ps,FLfunc,FREGSAVED,"memcpy", 0, t); break; 114 case RTLSYM_MEMSET8: symbolz(ps,FLfunc,FREGSAVED,"memset", 0, t); break; 115 case RTLSYM_MEMSET16: symbolz(ps,FLfunc,FREGSAVED,"_memset16", 0, t); break; 116 case RTLSYM_MEMSET32: symbolz(ps,FLfunc,FREGSAVED,"_memset32", 0, t); break; 117 case RTLSYM_MEMSET64: symbolz(ps,FLfunc,FREGSAVED,"_memset64", 0, t); break; 118 case RTLSYM_MEMSET128: symbolz(ps,FLfunc,FREGSAVED,"_memset128",0, t); break; 119 case RTLSYM_MEMSET128ii: symbolz(ps,FLfunc,FREGSAVED,"_memset128ii",0, t); break; 120 case RTLSYM_MEMSET80: symbolz(ps,FLfunc,FREGSAVED,"_memset80", 0, t); break; 121 case RTLSYM_MEMSET160: symbolz(ps,FLfunc,FREGSAVED,"_memset160",0, t); break; 122 case RTLSYM_MEMSETFLOAT: symbolz(ps,FLfunc,FREGSAVED,"_memsetFloat", 0, t); break; 123 case RTLSYM_MEMSETDOUBLE: symbolz(ps,FLfunc,FREGSAVED,"_memsetDouble", 0, t); break; 124 case RTLSYM_MEMSETSIMD: symbolz(ps,FLfunc,FREGSAVED,"_memsetSIMD",0, t); break; 125 case RTLSYM_MEMSETN: symbolz(ps,FLfunc,FREGSAVED,"_memsetn", 0, t); break; 126 case RTLSYM_MODULO: symbolz(ps,FLfunc,FREGSAVED,"_modulo", 0, t); break; 127 case RTLSYM_MONITORENTER: symbolz(ps,FLfunc,FREGSAVED,"_d_monitorenter",0, t); break; 128 case RTLSYM_MONITOREXIT: symbolz(ps,FLfunc,FREGSAVED,"_d_monitorexit",0, t); break; 129 case RTLSYM_CRITICALENTER: symbolz(ps,FLfunc,FREGSAVED,"_d_criticalenter",0, t); break; 130 case RTLSYM_CRITICALEXIT: symbolz(ps,FLfunc,FREGSAVED,"_d_criticalexit",0, t); break; 131 case RTLSYM_DSWITCHERR: symbolz(ps,FLfunc,FREGSAVED,"_d_switch_error", SFLexit, t); break; 132 case RTLSYM_DHIDDENFUNC: symbolz(ps,FLfunc,FREGSAVED,"_d_hidden_func", 0, t); break; 133 case RTLSYM_NEWCLASS: symbolz(ps,FLfunc,FREGSAVED,"_d_newclass", 0, t); break; 134 case RTLSYM_NEWTHROW: symbolz(ps,FLfunc,FREGSAVED,"_d_newThrowable", 0, t); break; 135 case RTLSYM_NEWARRAYT: symbolz(ps,FLfunc,FREGSAVED,"_d_newarrayT", 0, t); break; 136 case RTLSYM_NEWARRAYIT: symbolz(ps,FLfunc,FREGSAVED,"_d_newarrayiT", 0, t); break; 137 case RTLSYM_NEWITEMT: symbolz(ps,FLfunc,FREGSAVED,"_d_newitemT", 0, t); break; 138 case RTLSYM_NEWITEMIT: symbolz(ps,FLfunc,FREGSAVED,"_d_newitemiT", 0, t); break; 139 case RTLSYM_NEWARRAYMTX: symbolz(ps,FLfunc,FREGSAVED,"_d_newarraymTX", 0, t); break; 140 case RTLSYM_NEWARRAYMITX: symbolz(ps,FLfunc,FREGSAVED,"_d_newarraymiTX", 0, t); break; 141 case RTLSYM_ARRAYLITERALTX: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayliteralTX", 0, t); break; 142 case RTLSYM_ASSOCARRAYLITERALTX: symbolz(ps,FLfunc,FREGSAVED,"_d_assocarrayliteralTX", 0, t); break; 143 case RTLSYM_CALLFINALIZER: symbolz(ps,FLfunc,FREGSAVED,"_d_callfinalizer", 0, t); break; 144 case RTLSYM_CALLINTERFACEFINALIZER: symbolz(ps,FLfunc,FREGSAVED,"_d_callinterfacefinalizer", 0, t); break; 145 case RTLSYM_DELCLASS: symbolz(ps,FLfunc,FREGSAVED,"_d_delclass", 0, t); break; 146 case RTLSYM_DELINTERFACE: symbolz(ps,FLfunc,FREGSAVED,"_d_delinterface", 0, t); break; 147 case RTLSYM_DELSTRUCT: symbolz(ps,FLfunc,FREGSAVED,"_d_delstruct", 0, t); break; 148 case RTLSYM_ALLOCMEMORY: symbolz(ps,FLfunc,FREGSAVED,"_d_allocmemory", 0, t); break; 149 case RTLSYM_DELARRAYT: symbolz(ps,FLfunc,FREGSAVED,"_d_delarray_t", 0, t); break; 150 case RTLSYM_DELMEMORY: symbolz(ps,FLfunc,FREGSAVED,"_d_delmemory", 0, t); break; 151 case RTLSYM_INTERFACE: symbolz(ps,FLfunc,FREGSAVED,"_d_interface_vtbl", 0, t); break; 152 case RTLSYM_DYNAMIC_CAST: symbolz(ps,FLfunc,FREGSAVED,"_d_dynamic_cast", 0, t); break; 153 case RTLSYM_INTERFACE_CAST: symbolz(ps,FLfunc,FREGSAVED,"_d_interface_cast", 0, t); break; 154 case RTLSYM_FATEXIT: symbolz(ps,FLfunc,FREGSAVED,"_fatexit", 0, t); break; 155 case RTLSYM_ARRAYCATT: symbolz(ps,FLfunc,FREGSAVED,"_d_arraycatT", 0, t); break; 156 case RTLSYM_ARRAYCATNTX: symbolz(ps,FLfunc,FREGSAVED,"_d_arraycatnTX", 0, t); break; 157 case RTLSYM_ARRAYAPPENDT: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayappendT", 0, t); break; 158 case RTLSYM_ARRAYAPPENDCTX: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayappendcTX", 0, t); break; 159 case RTLSYM_ARRAYAPPENDCD: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayappendcd", 0, t); break; 160 case RTLSYM_ARRAYAPPENDWD: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayappendwd", 0, t); break; 161 case RTLSYM_ARRAYSETLENGTHT: symbolz(ps,FLfunc,FREGSAVED,"_d_arraysetlengthT", 0, t); break; 162 case RTLSYM_ARRAYSETLENGTHIT: symbolz(ps,FLfunc,FREGSAVED,"_d_arraysetlengthiT", 0, t); break; 163 case RTLSYM_ARRAYCOPY: symbolz(ps,FLfunc,FREGSAVED,"_d_arraycopy", 0, t); break; 164 case RTLSYM_ARRAYASSIGN: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayassign", 0, t); break; 165 case RTLSYM_ARRAYASSIGN_R: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayassign_r", 0, t); break; 166 case RTLSYM_ARRAYASSIGN_L: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayassign_l", 0, t); break; 167 case RTLSYM_ARRAYCTOR: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayctor", 0, t); break; 168 case RTLSYM_ARRAYSETASSIGN: symbolz(ps,FLfunc,FREGSAVED,"_d_arraysetassign", 0, t); break; 169 case RTLSYM_ARRAYSETCTOR: symbolz(ps,FLfunc,FREGSAVED,"_d_arraysetctor", 0, t); break; 170 case RTLSYM_ARRAYEQ2: symbolz(ps,FLfunc,FREGSAVED,"_adEq2", 0, t); break; 171 case RTLSYM_ARRAYCMPCHAR: symbolz(ps,FLfunc,FREGSAVED,"_adCmpChar", 0, t); break; 172 173 case RTLSYM_EXCEPT_HANDLER2: symbolz(ps,FLfunc,fregsaved,"_except_handler2", 0, tsclib); break; 174 case RTLSYM_EXCEPT_HANDLER3: symbolz(ps,FLfunc,fregsaved,"_except_handler3", 0, tsclib); break; 175 case RTLSYM_CPP_HANDLER: symbolz(ps,FLfunc,FREGSAVED,"_cpp_framehandler", 0, tsclib); break; 176 case RTLSYM_D_HANDLER: symbolz(ps,FLfunc,FREGSAVED,"_d_framehandler", 0, tsclib); break; 177 case RTLSYM_D_LOCAL_UNWIND2: symbolz(ps,FLfunc,FREGSAVED,"_d_local_unwind2", 0, tsclib); break; 178 case RTLSYM_LOCAL_UNWIND2: symbolz(ps,FLfunc,FREGSAVED,"_local_unwind2", 0, tsclib); break; 179 case RTLSYM_UNWIND_RESUME: symbolz(ps,FLfunc,FREGSAVED,"_Unwind_Resume", SFLexit, t); break; 180 case RTLSYM_PERSONALITY: symbolz(ps,FLfunc,FREGSAVED,"__dmd_personality_v0", 0, t); break; 181 case RTLSYM_BEGIN_CATCH: symbolz(ps,FLfunc,FREGSAVED,"__dmd_begin_catch", 0, t); break; 182 case RTLSYM_CXA_BEGIN_CATCH: symbolz(ps,FLfunc,FREGSAVED,"__cxa_begin_catch", 0, t); break; 183 case RTLSYM_CXA_END_CATCH: symbolz(ps,FLfunc,FREGSAVED,"__cxa_end_catch", 0, t); break; 184 185 case RTLSYM_TLS_INDEX: symbolz(ps,FLextern,0,"_tls_index",0,tstypes[TYint]); break; 186 case RTLSYM_TLS_ARRAY: symbolz(ps,FLextern,0,"_tls_array",0,tspvoid); break; 187 case RTLSYM_AHSHIFT: symbolz(ps,FLfunc,0,"_AHSHIFT",0,tstrace); break; 188 189 case RTLSYM_HDIFFN: symbolz(ps,FLfunc,mBX|mCX|mSI|mDI|mBP|mES,"_aNahdiff", 0, tsclib); break; 190 case RTLSYM_HDIFFF: symbolz(ps,FLfunc,mBX|mCX|mSI|mDI|mBP|mES,"_aFahdiff", 0, tsclib); break; 191 case RTLSYM_INTONLY: symbolz(ps,FLfunc,mSI|mDI,"_intonly", 0, tsclib); break; 192 193 case RTLSYM_EXCEPT_LIST: symbolz(ps,FLextern,0,"_except_list",0,tstypes[TYint]); break; 194 case RTLSYM_SETJMP3: symbolz(ps,FLfunc,FREGSAVED,"_setjmp3", 0, tsclib); break; 195 case RTLSYM_LONGJMP: symbolz(ps,FLfunc,FREGSAVED,"_seh_longjmp_unwind@4", 0, tsclib); break; 196 case RTLSYM_ALLOCA: symbolz(ps,FLfunc,fregsaved,"__alloca", 0, tsclib); break; 197 case RTLSYM_CPP_LONGJMP: symbolz(ps,FLfunc,FREGSAVED,"_cpp_longjmp_unwind@4", 0, tsclib); break; 198 case RTLSYM_PTRCHK: symbolz(ps,FLfunc,fregsaved,"_ptrchk", 0, tsclib); break; 199 case RTLSYM_CHKSTK: symbolz(ps,FLfunc,fregsaved,"_chkstk", 0, tsclib); break; 200 case RTLSYM_TRACE_PRO_N: symbolz(ps,FLfunc,ALLREGS|mBP|mES,"_trace_pro_n",0,tstrace); break; 201 case RTLSYM_TRACE_PRO_F: symbolz(ps,FLfunc,ALLREGS|mBP|mES,"_trace_pro_f",0,tstrace); break; 202 case RTLSYM_TRACE_EPI_N: symbolz(ps,FLfunc,ALLREGS|mBP|mES,"_trace_epi_n",0,tstrace); break; 203 case RTLSYM_TRACE_EPI_F: symbolz(ps,FLfunc,ALLREGS|mBP|mES,"_trace_epi_f",0,tstrace); break; 204 case RTLSYM_TRACE_CPRO: symbolz(ps,FLfunc,FREGSAVED,"_c_trace_pro",0,t); break; 205 case RTLSYM_TRACE_CEPI: symbolz(ps,FLfunc,FREGSAVED,"_c_trace_epi",0,t); break; 206 207 case RTLSYM_TRACENEWCLASS: symbolz(ps,FLfunc,FREGSAVED,"_d_newclassTrace", 0, t); break; 208 case RTLSYM_TRACENEWARRAYT: symbolz(ps,FLfunc,FREGSAVED,"_d_newarrayTTrace", 0, t); break; 209 case RTLSYM_TRACENEWARRAYIT: symbolz(ps,FLfunc,FREGSAVED,"_d_newarrayiTTrace", 0, t); break; 210 case RTLSYM_TRACENEWARRAYMTX: symbolz(ps,FLfunc,FREGSAVED,"_d_newarraymTXTrace", 0, t); break; 211 case RTLSYM_TRACENEWARRAYMITX: symbolz(ps,FLfunc,FREGSAVED,"_d_newarraymiTXTrace", 0, t); break; 212 case RTLSYM_TRACENEWITEMT: symbolz(ps,FLfunc,FREGSAVED,"_d_newitemTTrace", 0, t); break; 213 case RTLSYM_TRACENEWITEMIT: symbolz(ps,FLfunc,FREGSAVED,"_d_newitemiTTrace", 0, t); break; 214 case RTLSYM_TRACECALLFINALIZER: symbolz(ps,FLfunc,FREGSAVED,"_d_callfinalizerTrace", 0, t); break; 215 case RTLSYM_TRACECALLINTERFACEFINALIZER: symbolz(ps,FLfunc,FREGSAVED,"_d_callinterfacefinalizerTrace", 0, t); break; 216 case RTLSYM_TRACEDELCLASS: symbolz(ps,FLfunc,FREGSAVED,"_d_delclassTrace", 0, t); break; 217 case RTLSYM_TRACEDELINTERFACE: symbolz(ps,FLfunc,FREGSAVED,"_d_delinterfaceTrace", 0, t); break; 218 case RTLSYM_TRACEDELSTRUCT: symbolz(ps,FLfunc,FREGSAVED,"_d_delstructTrace", 0, t); break; 219 case RTLSYM_TRACEDELARRAYT: symbolz(ps,FLfunc,FREGSAVED,"_d_delarray_tTrace", 0, t); break; 220 case RTLSYM_TRACEDELMEMORY: symbolz(ps,FLfunc,FREGSAVED,"_d_delmemoryTrace", 0, t); break; 221 case RTLSYM_TRACEARRAYLITERALTX: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayliteralTXTrace", 0, t); break; 222 case RTLSYM_TRACEASSOCARRAYLITERALTX: symbolz(ps,FLfunc,FREGSAVED,"_d_assocarrayliteralTXTrace", 0, t); break; 223 case RTLSYM_TRACEARRAYCATT: symbolz(ps,FLfunc,FREGSAVED,"_d_arraycatTTrace", 0, t); break; 224 case RTLSYM_TRACEARRAYCATNTX: symbolz(ps,FLfunc,FREGSAVED,"_d_arraycatnTXTrace", 0, t); break; 225 case RTLSYM_TRACEARRAYAPPENDT: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayappendTTrace", 0, t); break; 226 case RTLSYM_TRACEARRAYAPPENDCTX: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayappendcTXTrace", 0, t); break; 227 case RTLSYM_TRACEARRAYAPPENDCD: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayappendcdTrace", 0, t); break; 228 case RTLSYM_TRACEARRAYAPPENDWD: symbolz(ps,FLfunc,FREGSAVED,"_d_arrayappendwdTrace", 0, t); break; 229 case RTLSYM_TRACEARRAYSETLENGTHT: symbolz(ps,FLfunc,FREGSAVED,"_d_arraysetlengthTTrace", 0, t); break; 230 case RTLSYM_TRACEARRAYSETLENGTHIT: symbolz(ps,FLfunc,FREGSAVED,"_d_arraysetlengthiTTrace", 0, t); break; 231 case RTLSYM_TRACEALLOCMEMORY: symbolz(ps,FLfunc,FREGSAVED,"_d_allocmemoryTrace", 0, t); break; 232 case RTLSYM_C_ASSERT: symbolz(ps,FLfunc,FREGSAVED,"_assert", SFLexit, t); break; 233 case RTLSYM_C__ASSERT: symbolz(ps,FLfunc,FREGSAVED,"__assert", SFLexit, t); break; 234 case RTLSYM_C__ASSERT_FAIL: symbolz(ps,FLfunc,FREGSAVED,"__assert_fail", SFLexit, t); break; 235 case RTLSYM_C__ASSERT_RTN: symbolz(ps,FLfunc,FREGSAVED,"__assert_rtn", SFLexit, t); break; 236 237 default: 238 assert(0); 239 } 240 return *ps; 241 } 242 243 244 /****************************************** 245 * Create and initialize Symbol for runtime function. 246 * Params: 247 * ps = where to store initialized Symbol pointer 248 * f = FLxxx 249 * regsaved = registers not altered by function 250 * name = name of function 251 * flags = value for Sflags 252 * t = type of function 253 */ 254 private void symbolz(Symbol** ps, int fl, regm_t regsaved, const(char)* name, SYMFLGS flags, type *t) 255 { 256 Symbol *s = symbol_calloc(name); 257 s.Stype = t; 258 s.Ssymnum = SYMIDX.max; 259 s.Sclass = SCextern; 260 s.Sfl = cast(char)fl; 261 s.Sregsaved = regsaved; 262 s.Sflags = flags; 263 *ps = s; 264 } 265 266 /****************************************** 267 * Initialize rtl symbols. 268 */ 269 270 void rtlsym_init() 271 { 272 } 273 274 /******************************* 275 * Reset the symbols for the case when we are generating multiple 276 * .OBJ files from one compile. 277 */ 278 version (MARS) 279 { 280 void rtlsym_reset() 281 { 282 clib_inited = 0; // reset CLIB symbols, too 283 for (size_t i = 0; i < RTLSYM_MAX; i++) 284 { 285 if (rtlsym[i]) 286 { 287 rtlsym[i].Sxtrnnum = 0; 288 rtlsym[i].Stypidx = 0; 289 } 290 } 291 } 292 293 } 294 295 /******************************* 296 */ 297 298 void rtlsym_term() 299 { 300 } 301 302 }