private static string AssemblySymbolName(PInvokeTarget target, string symbolName) { if (target == PInvokeTarget.WindowsX86) return '_' + symbolName; return symbolName; }
private static string AssemblySymbolName(PInvokeTarget target, string symbolName) { if (target == PInvokeTarget.WindowsX86) { return('_' + symbolName); } return(symbolName); }
private void PInvokeEmitThunk(PInvokeTarget target, StringBuilder pinvokeThunks, int i) { if (target == PInvokeTarget.WindowsX86 || target == PInvokeTarget.WindowsX64) { // Set eax to thunk id pinvokeThunks.AppendFormat(" movl ${0}, %eax\n", i); // Call thunkHelper dispatch function pinvokeThunks.AppendFormat(" jmp {0}\n", AssemblySymbolName(target, "thunkHelper")); } else { throw new NotImplementedException(); } }
private static void PInvokeEmitThunkHelper(PInvokeTarget target, StringBuilder pinvokeThunks) { if (target == PInvokeTarget.WindowsX86) { // TODO: Not sure which register can actually be modified (need something that works on every calling convention) // Seems %eax is best choice, but need to check more carefully // Save registers pinvokeThunks.AppendLine(" pushl %edx"); pinvokeThunks.AppendLine(" pushl %ecx"); // ThunkCurrentId = index (note: ThunkCurrentId is a TLS variable) pinvokeThunks.AppendLine(" movl __tls_index, %edx"); pinvokeThunks.AppendLine(" movl %fs:2Ch, %ecx"); pinvokeThunks.AppendLine(" movl (%ecx,%edx,4), %ecx"); pinvokeThunks.AppendLine(" movl %eax, _ThunkCurrentId@SECREL32(%ecx)"); // Load ThunkTargets[index] in eax pinvokeThunks.AppendLine(" leal _ThunkTargets, %ecx"); pinvokeThunks.AppendLine(" movl (%ecx,%eax,4), %eax"); // Restore registers pinvokeThunks.AppendLine(" popl %ecx"); pinvokeThunks.AppendLine(" popl %edx"); // Jump to eax = ThunkTargets[index] pinvokeThunks.AppendLine(" jmp *%eax"); } else if (target == PInvokeTarget.WindowsX64) { // Save registers pinvokeThunks.AppendLine(" pushq %rcx"); // ThunkCurrentId = index (note: ThunkCurrentId is a TLS variable) pinvokeThunks.AppendLine(" movl _tls_index(%rip), %r11d"); pinvokeThunks.AppendLine(" movq %gs:58h, %r10"); pinvokeThunks.AppendLine(" movq (%r10,%r11,8), %rcx"); pinvokeThunks.AppendLine(" movq %rax, ThunkCurrentId@SECREL32(%rcx)"); // Load ThunkTargets[index] in rax pinvokeThunks.AppendLine(" leaq ThunkTargets, %rcx"); pinvokeThunks.AppendLine(" movq (%rcx,%rax,8), %rax"); // Restore registers pinvokeThunks.AppendLine(" popq %rcx"); // Jump to eax = ThunkTargets[index] pinvokeThunks.AppendLine(" jmp *%rax"); } else { throw new NotImplementedException(); } }