Ejemplo n.º 1
0
static void output_import_thunk (FILE *outfile, const char *pName, const char *pTable, int Pos)
{
   output_function_name (outfile, pName);
   fprintf( outfile, "    \"\\t.globl " PREFIX "%s\\n\"\n", pName);

   fprintf( outfile, "    \"" PREFIX "%s:\\n\\t", pName );

#if defined(__i386__)
   if (!UsePIC)
      fprintf( outfile,
               "jmp *(" __ASM_NAME("%s")
               "+%d)\\n\\tmovl %%esi,%%esi\\n",
               pTable, Pos );
   else
   {
      fprintf( outfile, "call %s\\n",
               __ASM_NAME("__wine_spec_get_pc_thunk_eax") );
      fprintf( outfile, "1:\\tjmp *" __ASM_NAME ("%s") "+%d-1b(%%eax)\\n",
               pTable, Pos);
   }
#elif defined(__sparc__)
   if ( !UsePIC )
   {
      fprintf( outfile, "sethi %%hi(" __ASM_NAME ("%s") "+%d), %%g1\\n\\t", pTable, Pos );
      fprintf( outfile, "ld [%%g1+%%lo(" __ASM_NAME ("%s") "+%d)], %%g1\\n\\t", pTable, Pos );
      fprintf( outfile, "jmp %%g1\\n\\tnop\\n" );
   }
   else
   {
      /* Hmpf.  Stupid sparc assembler always interprets global variable
         names as GOT offsets, so we have to do it the long way ... */
      fprintf( outfile, "save %%sp, -96, %%sp\\n" );
      fprintf( outfile, "0:\\tcall 1f\\n\\tnop\\n" );
      fprintf( outfile, "1:\\tsethi %%hi(" __ASM_NAME ("%s") "+%d-0b), %%g1\\n\\t", pTable, Pos );
      fprintf( outfile, "or %%g1, %%lo(" __ASM_NAME ("%s") "+%d-0b), %%g1\\n\\t", pTable, Pos );
      fprintf( outfile, "ld [%%g1+%%o7], %%g1\\n\\t" );
      fprintf( outfile, "jmp %%g1\\n\\trestore\\n" );
   }
#elif defined(__PPC__)
   fprintf(outfile, "\taddis r11,0,ha16(" __ASM_NAME ("%s") "+%d)\\n\"\n", pTable, Pos); 
   fprintf(outfile, "\t\"\\tla r12,lo16(" __ASM_NAME ("%s") "+%d)(r11)\\n\"\n", pTable, Pos);
   fprintf(outfile, "\t\"\\tlwz r11, 0(r12)\\n\"\n");
   fprintf(outfile, "\t\"\\tmtctr r11\\n\"\n");
   fprintf(outfile, "\t\"\\tbctr\\n");
#else
#error You need to define import thunks for your architecture!
#endif
   fprintf( outfile, "\"\n" );
}
Ejemplo n.º 2
0
void output_get_pc_thunk (FILE *outfile)
{
#ifndef __i386__
   return;
#else
   if (!UsePIC)
      return;
   fprintf( outfile, "asm(\"\\n\\t.text\\n\"\n" );
   fprintf( outfile, "\"\\t.align %d\\n\"\n", get_alignment(4) );
   output_function_name (outfile, "__wine_spec_get_pc_thunk_eax");
   fprintf( outfile, "\"%s:\\n\"\n",
            __ASM_NAME("__wine_spec_get_pc_thunk_eax") );
   fprintf( outfile, "\"\\tpopl %%eax\\n\"\n" );
   fprintf( outfile, "\"\\tpushl %%eax\\n\"\n" );
   fprintf( outfile, "\"\\tret\\n\"\n" );
   fprintf( outfile, ");\n");
#endif
}
Ejemplo n.º 3
0
                  "movl (%ecx),%ecx\n\t"          /* This->lpVtbl */
                  "movl -8(%ecx),%ecx\n\t"        /* MIDL_STUBLESS_PROXY_INFO */
                  "movl 8(%ecx),%edx\n\t"         /* info->FormatStringOffset */
                  "movzwl (%edx,%eax,2),%edx\n\t" /* FormatStringOffset[index] */
                  "addl 4(%ecx),%edx\n\t"         /* info->ProcFormatString + offset */
                  "movzwl 8(%edx),%eax\n\t"       /* arguments size */
                  "pushl %eax\n\t"
                  __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
                  "leal 8(%esp),%eax\n\t"         /* &This */
                  "pushl %eax\n\t"
                  __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
                  "pushl %edx\n\t"                /* format string */
                  __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
                  "pushl (%ecx)\n\t"              /* info->pStubDesc */
                  __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
                  "call " __ASM_NAME("ndr_client_call") "\n\t"
                  "leal 12(%esp),%esp\n\t"
                  __ASM_CFI(".cfi_adjust_cfa_offset -12\n\t")
                  "popl %edx\n\t"                 /* arguments size */
                  __ASM_CFI(".cfi_adjust_cfa_offset -4\n\t")
                  "movl (%esp),%ecx\n\t"  /* return address */
                  "addl %edx,%esp\n\t"
                  "jmp *%ecx" );

#include "pshpack1.h"
struct thunk
{
  BYTE mov_eax;
  DWORD index;
  BYTE jmp;
  LONG handler;
Ejemplo n.º 4
0
 *
 * NOTE
 * On x86, Shrinker, an executable compressor, depends on the
 * "call access_resource" instruction being there.
 */
#ifdef __i386__
__ASM_STDCALL_FUNC( LdrAccessResource, 16,
    "pushl %ebp\n\t"
    "movl %esp, %ebp\n\t"
    "subl $4,%esp\n\t"
    "pushl 24(%ebp)\n\t"
    "pushl 20(%ebp)\n\t"
    "pushl 16(%ebp)\n\t"
    "pushl 12(%ebp)\n\t"
    "pushl 8(%ebp)\n\t"
    "call " __ASM_NAME("access_resource") "\n\t"
    "leave\n\t"
    "ret $16"
)
#else
NTSTATUS WINAPI LdrAccessResource( HMODULE hmod, const IMAGE_RESOURCE_DATA_ENTRY *entry,
                                   void **ptr, ULONG *size )
{
    return access_resource( hmod, entry, ptr, size );
}
#endif

/**********************************************************************
 *	RtlFindMessage  (NTDLL.@)
 */
NTSTATUS WINAPI RtlFindMessage( HMODULE hmod, ULONG type, ULONG lang,
Ejemplo n.º 5
0
/*********************************************************************
 *		__CxxQueryExceptionSize (MSVCRT.@)
 */
unsigned int CDECL __CxxQueryExceptionSize(void)
{
    return sizeof(cxx_exception_type);
}


/*******************************************************************
 *		_setjmp (MSVCRT.@)
 */
__ASM_GLOBAL_FUNC(MSVCRT__setjmp,
                  "mov r1, #0\n\t"  /* frame */
                  "b " __ASM_NAME("MSVCRT__setjmpex"));

/*******************************************************************
 *		_setjmpex (MSVCRT.@)
 */
__ASM_GLOBAL_FUNC(MSVCRT__setjmpex,
                  "str r1, [r0]\n\t"              /* jmp_buf->Frame */
                  "str r4, [r0, #0x4]\n\t"        /* jmp_buf->R4 */
                  "str r5, [r0, #0x8]\n\t"        /* jmp_buf->R5 */
                  "str r6, [r0, #0xc]\n\t"        /* jmp_buf->R6 */
                  "str r7, [r0, #0x10]\n\t"       /* jmp_buf->R7 */
                  "str r8, [r0, #0x14]\n\t"       /* jmp_buf->R8 */
                  "str r9, [r0, #0x18]\n\t"       /* jmp_buf->R9 */
                  "str r10, [r0, #0x1c]\n\t"      /* jmp_buf->R10 */
                  "str r11, [r0, #0x20]\n\t"      /* jmp_buf->R11 */
                  "str sp, [r0, #0x24]\n\t"       /* jmp_buf->Sp */
Ejemplo n.º 6
0
Archivo: misc.c Proyecto: mikekap/wine
# ifdef __GNUC__

__ASM_GLOBAL_FUNC(_chkesp,
                  "jnz 1f\n\t"
                  "ret\n"
                  "1:\tpushl %ebp\n\t"
                  __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
                  __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
                  "movl %esp,%ebp\n\t"
                  __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
                  "subl $12,%esp\n\t"
                  "pushl %eax\n\t"
                  "pushl %ecx\n\t"
                  "pushl %edx\n\t"
                  "call " __ASM_NAME("MSVCRT_chkesp_fail") "\n\t"
                  "popl %edx\n\t"
                  "popl %ecx\n\t"
                  "popl %eax\n\t"
                  "leave\n\t"
                  __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
                  __ASM_CFI(".cfi_same_value %ebp\n\t")
                  "ret")

void CDECL MSVCRT_chkesp_fail(void)
{
    ERR("Stack pointer incorrect after last function call - Bad prototype/spec entry?\n");
    DebugBreak();
}

# else  /* __GNUC__ */
Ejemplo n.º 7
0
/* output the delayed import table of a Win32 module */
static int output_delayed_imports( FILE *outfile )
{
    int i, idx, j, pos;

    if (!nb_delayed) goto done;

    for (i = 0; i < nb_imports; i++)
    {
        if (!dll_imports[i]->delay) continue;
        fprintf( outfile, "static void *__wine_delay_imp_%d_hmod;\n", i);
        for (j = 0; j < dll_imports[i]->nb_imports; j++)
        {
            fprintf( outfile, "void __wine_delay_imp_%d_%s();\n",
                     i, dll_imports[i]->imports[j] );
        }
    }
    fprintf( outfile, "\n" );
    fprintf( outfile, "static struct {\n" );
    fprintf( outfile, "  struct ImgDelayDescr {\n" );
    fprintf( outfile, "    unsigned int  grAttrs;\n" );
    fprintf( outfile, "    const char   *szName;\n" );
    fprintf( outfile, "    void        **phmod;\n" );
    fprintf( outfile, "    void        **pIAT;\n" );
    fprintf( outfile, "    const char  **pINT;\n" );
    fprintf( outfile, "    void*         pBoundIAT;\n" );
    fprintf( outfile, "    void*         pUnloadIAT;\n" );
    fprintf( outfile, "    unsigned long dwTimeStamp;\n" );
    fprintf( outfile, "  } imp[%d];\n", nb_delayed );
    fprintf( outfile, "  void         *IAT[%d];\n", total_delayed );
    fprintf( outfile, "  const char   *INT[%d];\n", total_delayed );
    fprintf( outfile, "} delay_imports = {\n" );
    fprintf( outfile, "  {\n" );
    for (i = j = 0; i < nb_imports; i++)
    {
        if (!dll_imports[i]->delay) continue;
        fprintf( outfile, "    { 0, \"%s\", &__wine_delay_imp_%d_hmod, &delay_imports.IAT[%d], &delay_imports.INT[%d], 0, 0, 0 },\n",
                 dll_imports[i]->dll, i, j, j );
        j += dll_imports[i]->nb_imports;
    }
    fprintf( outfile, "  },\n  {\n" );
    for (i = 0; i < nb_imports; i++)
    {
        if (!dll_imports[i]->delay) continue;
        fprintf( outfile, "    /* %s */\n", dll_imports[i]->dll );
        for (j = 0; j < dll_imports[i]->nb_imports; j++)
        {
            fprintf( outfile, "    &__wine_delay_imp_%d_%s,\n", i, dll_imports[i]->imports[j] );
        }
    }
    fprintf( outfile, "  },\n  {\n" );
    for (i = 0; i < nb_imports; i++)
    {
        if (!dll_imports[i]->delay) continue;
        fprintf( outfile, "    /* %s */\n", dll_imports[i]->dll );
        for (j = 0; j < dll_imports[i]->nb_imports; j++)
        {
            fprintf( outfile, "    \"\\0\\0%s\",\n", dll_imports[i]->imports[j] );
        }
    }
    fprintf( outfile, "  }\n};\n\n" );

    /* check if there's some stub defined. if so, exception struct
     *  is already defined, so don't emit it twice
     */
    for (i = 0; i < nb_entry_points; i++) if (EntryPoints[i]->type == TYPE_STUB) break;

    if (i == nb_entry_points) {
       fprintf( outfile, "struct exc_record {\n" );
       fprintf( outfile, "  unsigned int code, flags;\n" );
       fprintf( outfile, "  void *rec, *addr;\n" );
       fprintf( outfile, "  unsigned int params;\n" );
       fprintf( outfile, "  const void *info[15];\n" );
       fprintf( outfile, "};\n\n" );
       fprintf( outfile, "extern void __stdcall RtlRaiseException( struct exc_record * );\n" );
    }

    fprintf( outfile, "extern void * __stdcall LoadLibraryA(const char*);\n");
    fprintf( outfile, "extern void * __stdcall GetProcAddress(void *, const char*);\n");
    fprintf( outfile, "\n" );

    fprintf( outfile, "void *__stdcall __wine_delay_load( int idx_nr )\n" );
    fprintf( outfile, "{\n" );
    fprintf( outfile, "  int idx = idx_nr >> 16, nr = idx_nr & 0xffff;\n" );
    fprintf( outfile, "  struct ImgDelayDescr *imd = delay_imports.imp + idx;\n" );
    fprintf( outfile, "  void **pIAT = imd->pIAT + nr;\n" );
    fprintf( outfile, "  const char** pINT = imd->pINT + nr;\n" );
    fprintf( outfile, "  void *fn;\n\n" );

    fprintf( outfile, "  if (!*imd->phmod) *imd->phmod = LoadLibraryA(imd->szName);\n" );
    fprintf( outfile, "  if (*imd->phmod && (fn = GetProcAddress(*imd->phmod, *pINT + 2)))\n");
    fprintf( outfile, "    /* patch IAT with final value */\n" );
    fprintf( outfile, "    return *pIAT = fn;\n" );
    fprintf( outfile, "  else {\n");
    fprintf( outfile, "    struct exc_record rec;\n" );
    fprintf( outfile, "    rec.code    = 0x80000100;\n" );
    fprintf( outfile, "    rec.flags   = 1;\n" );
    fprintf( outfile, "    rec.rec     = 0;\n" );
    fprintf( outfile, "    rec.params  = 2;\n" );
    fprintf( outfile, "    rec.info[0] = imd->szName;\n" );
    fprintf( outfile, "    rec.info[1] = *pINT + 2;\n" );
    fprintf( outfile, "#ifdef __GNUC__\n" );
    fprintf( outfile, "    rec.addr = __builtin_return_address(1);\n" );
    fprintf( outfile, "#else\n" );
    fprintf( outfile, "    rec.addr = 0;\n" );
    fprintf( outfile, "#endif\n" );
    fprintf( outfile, "    for (;;) RtlRaiseException( &rec );\n" );
    fprintf( outfile, "    return 0; /* shouldn't go here */\n" );
    fprintf( outfile, "  }\n}\n\n" );

    fprintf( outfile, "#ifndef __GNUC__\n" );
    fprintf( outfile, "static void __asm__dummy_delay_import(void) {\n" );
    fprintf( outfile, "#endif\n" );

    fprintf( outfile, "asm(\".align %d\\n\"\n", get_alignment(8) );
    output_function_name (outfile, "__wine_delay_load_asm");
    fprintf( outfile, "    \"" PREFIX "__wine_delay_load_asm:\\n\"\n" );
#if defined(__i386__)
    fprintf( outfile, "    \"\\tpushl %%ecx\\n\\tpushl %%edx\\n\\tpushl %%eax\\n\"\n" );
    fprintf( outfile, "    \"\\tcall " __ASM_NAME("__wine_delay_load") "\\n\"\n" );
    fprintf( outfile, "    \"\\tpopl %%edx\\n\\tpopl %%ecx\\n\\tjmp *%%eax\\n\"\n" );
#elif defined(__sparc__)
    fprintf( outfile, "    \"\\tsave %%sp, -96, %%sp\\n\"\n" );
    fprintf( outfile, "    \"\\tcall __wine_delay_load\\n\"\n" );
    fprintf( outfile, "    \"\\tmov %%g1, %%o0\\n\"\n" );
    fprintf( outfile, "    \"\\tjmp %%o0\\n\\trestore\\n\"\n" );
#elif defined(__PPC__)
    fprintf(outfile, "#error: DELAYED IMPORTS NOT SUPPORTED ON PPC!!!\n");
#else
#error You need to defined delayed import thunks for your architecture!
#endif

    for (i = idx = 0; i < nb_imports; i++)
    {
        if (!dll_imports[i]->delay) continue;
        for (j = 0; j < dll_imports[i]->nb_imports; j++)
        {
            char buffer[128];
            sprintf( buffer, "__wine_delay_imp_%d_%s", i, dll_imports[i]->imports[j]);
            output_function_name (outfile, buffer);
            fprintf( outfile, "    \"" PREFIX "%s:\\n\"\n", buffer );
#if defined(__i386__)
            fprintf( outfile, "    \"\\tmovl $%d, %%eax\\n\"\n", (idx << 16) | j );
            fprintf( outfile, "    \"\\tjmp " __ASM_NAME("__wine_delay_load_asm")"\\n\"\n" );
#elif defined(__sparc__)
            fprintf( outfile, "    \"\\tset %d, %%g1\\n\"\n", (idx << 16) | j );
            fprintf( outfile, "    \"\\tb,a __wine_delay_load_asm\\n\"\n" );
#elif defined(__PPC__)
            fprintf(outfile, "#error: DELAYED IMPORTS NOT SUPPORTED ON PPC!!!\n");
#else
#error You need to defined delayed import thunks for your architecture!
#endif
        }
        idx++;
    }

    fprintf( outfile, "\n    \".align %d\\n\"\n", get_alignment(8) );
    pos = nb_delayed * 32;
    for (i = 0; i < nb_imports; i++)
    {
        if (!dll_imports[i]->delay) continue;
        for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += 4)
            output_import_thunk (outfile, dll_imports[i]->imports[j], "delay_imports", pos);
    }
    fprintf( outfile, ");\n" );
    fprintf( outfile, "#ifndef __GNUC__\n" );
    fprintf( outfile, "}\n" );
    fprintf( outfile, "#endif\n" );
    fprintf( outfile, "\n" );

 done:
    return nb_delayed;
}
Ejemplo n.º 8
0
    if (!RtlUnicodeStringToAnsiString( &strA, &strW, TRUE ))
    {
        OutputDebugStringA( strA.Buffer );
        RtlFreeAnsiString( &strA );
    }
}


/***********************************************************************
 *           DebugBreak   (KERNEL32.@)
 *
 *  Raises an exception so that a debugger (if attached)
 *  can take some action.
 */
#if defined(__i386__) || defined(__x86_64__)
__ASM_STDCALL_FUNC( DebugBreak, 0, "jmp " __ASM_NAME("DbgBreakPoint") )
#else
void WINAPI DebugBreak(void)
{
    DbgBreakPoint();
}
#endif

/***********************************************************************
 *           DebugBreakProcess   (KERNEL32.@)
 *
 *  Raises an exception so that a debugger (if attached)
 *  can take some action. Same as DebugBreak, but applies to any process.
 *
 * PARAMS
 *  hProc [I] Process to break into.