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