예제 #1
0
/* output import stubs for exported entry points that link to external symbols */
static void output_external_link_imports( DLLSPEC *spec )
{
    unsigned int i, pos;

    if (!ext_link_imports.count) return;  /* nothing to do */

    sort_names( &ext_link_imports );

    /* get rid of duplicate names */
    for (i = 1; i < ext_link_imports.count; i++)
    {
        if (!strcmp( ext_link_imports.names[i-1], ext_link_imports.names[i] ))
            remove_name( &ext_link_imports, i-- );
    }

    output( "\n/* external link thunks */\n\n" );
    output( "\t.data\n" );
    output( "\t.align %d\n", get_alignment(get_ptr_size()) );
    output( ".L__wine_spec_external_links:\n" );
    for (i = 0; i < ext_link_imports.count; i++)
        output( "\t%s %s\n", get_asm_ptr_keyword(), asm_name(ext_link_imports.names[i]) );

    output( "\n\t.text\n" );
    output( "\t.align %d\n", get_alignment(get_ptr_size()) );
    output( "%s:\n", asm_name("__wine_spec_external_link_thunks") );

    for (i = pos = 0; i < ext_link_imports.count; i++)
    {
        char *buffer = strmake( "__wine_spec_ext_link_%s", ext_link_imports.names[i] );
        output_import_thunk( buffer, ".L__wine_spec_external_links", pos );
        free( buffer );
        pos += get_ptr_size();
    }
    output_function_size( "__wine_spec_external_link_thunks" );
}
예제 #2
0
파일: spec32.c 프로젝트: otya128/winevdm
/*******************************************************************
 *         output_asm_constructor
 *
 * Output code for calling a dll constructor.
 */
static void output_asm_constructor( const char *constructor )
{
    if (target_platform == PLATFORM_APPLE)
    {
        /* Mach-O doesn't have an init section */
        output( "\n\t.mod_init_func\n" );
        output( "\t.align %d\n", get_alignment(get_ptr_size()) );
        output( "\t%s %s\n", get_asm_ptr_keyword(), asm_name(constructor) );
    }
    else
    {
        switch(target_cpu)
        {
        case CPU_x86:
		case CPU_x86_64:
//            output( "\n\t.section \".init\",\"ax\"\n" );
            output( "\n\t.section .init,\"ax\"\n" );
            output( "\tcall %s\n", asm_name(constructor) );
            break;
        case CPU_ARM:
            output( "\n\t.section \".text\",\"ax\"\n" );
            output( "\tblx %s\n", asm_name(constructor) );
            break;
        case CPU_ARM64:
        case CPU_POWERPC:
            output( "\n\t.section \".init\",\"ax\"\n" );
            output( "\tbl %s\n", asm_name(constructor) );
            break;
        }
    }
}
예제 #3
0
파일: spec32.c 프로젝트: Sunmonds/wine
/*******************************************************************
 *         output_asm_constructor
 *
 * Output code for calling a dll constructor.
 */
static void output_asm_constructor( const char *constructor )
{
    if (target_platform == PLATFORM_APPLE)
    {
        /* Mach-O doesn't have an init section */
        output( "\n\t.mod_init_func\n" );
        output( "\t.align %d\n", get_alignment(4) );
        output( "\t.long %s\n", asm_name(constructor) );
    }
    else
    {
        output( "\n\t.section \".init\",\"ax\"\n" );
        switch(target_cpu)
        {
        case CPU_x86:
        case CPU_x86_64:
            output( "\tcall %s\n", asm_name(constructor) );
            break;
        case CPU_SPARC:
            output( "\tcall %s\n", asm_name(constructor) );
            output( "\tnop\n" );
            break;
        case CPU_ARM:
        case CPU_POWERPC:
            output( "\tbl %s\n", asm_name(constructor) );
            break;
        }
    }
}
예제 #4
0
파일: gl.c 프로젝트: magicseb/RetroArch
static void gl_update_input_size(gl_t *gl, unsigned width, unsigned height, unsigned pitch)
{
   // Res change. Need to clear out texture.
   if ((width != gl->last_width[gl->tex_index] || height != gl->last_height[gl->tex_index]) && gl->empty_buf)
   {
      gl->last_width[gl->tex_index] = width;
      gl->last_height[gl->tex_index] = height;
      glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(pitch));
      glPixelStorei(GL_UNPACK_ROW_LENGTH, gl->tex_w);

      glTexSubImage2D(GL_TEXTURE_2D,
            0, 0, 0, gl->tex_w, gl->tex_h, gl->texture_type,
            gl->texture_fmt, gl->empty_buf);

      GLfloat xamt = (GLfloat)width / gl->tex_w;
      GLfloat yamt = (GLfloat)height / gl->tex_h;

      set_texture_coords(gl->tex_coords, xamt, yamt);
   }
   // We might have used different texture coordinates last frame. Edge case if resolution changes very rapidly.
   else if (width != gl->last_width[(gl->tex_index - 1) & TEXTURES_MASK] ||
         height != gl->last_height[(gl->tex_index - 1) & TEXTURES_MASK])
   {
      GLfloat xamt = (GLfloat)width / gl->tex_w;
      GLfloat yamt = (GLfloat)height / gl->tex_h;
      set_texture_coords(gl->tex_coords, xamt, yamt);
   }
}
예제 #5
0
static bool pack_align(lima_symbol_t* symbol, void* data)
{
	align_pack_state_t* state = (align_pack_state_t*) data;
	unsigned alignment = get_alignment(symbol);
	
	state->pos = ALIGN(state->pos, alignment);
	symbol->offset = state->pos;
	
	if (symbol->type == lima_symbol_struct)
	{
		unsigned old_pos = state->pos;
		state->pos = 0;
		
		for (unsigned i = 0; i < symbol->num_children; i++)
		{
			if (!pack_align(symbol->children[i], data))
				return false;
		}
		
		state->pos = ALIGN(state->pos, alignment);
		symbol->stride = state->pos;
		
		state->pos = old_pos;
	}
	else
		symbol->stride = sizes[symbol->type];
	
	unsigned array_elems = symbol->array_elems ? symbol->array_elems : 1;
	state->pos += symbol->stride * array_elems;
	
	return true;
}
예제 #6
0
파일: gl.c 프로젝트: magicseb/RetroArch
// Old style "blitting", so we can render all the fonts in one go.
// TODO: Is it possible that fonts could overlap if we blit without alpha blending?
static void blit_fonts(gl_t *gl, const struct font_output *head, const struct font_rect *geom)
{
   // Clear out earlier fonts.
   glPixelStorei(GL_UNPACK_ALIGNMENT, 8);
   glPixelStorei(GL_UNPACK_ROW_LENGTH, gl->font_tex_w);
   glTexSubImage2D(GL_TEXTURE_2D,
         0, 0, 0, gl->font_tex_w, gl->font_tex_h,
         GL_LUMINANCE, GL_UNSIGNED_BYTE, gl->font_tex_empty_buf);

   while (head)
   {
      // head has top-left oriented coords.
      int x = head->off_x - geom->x;
      int y = head->off_y - geom->y;
      y = gl->font_tex_h - head->height - y - 1;

      glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(head->pitch));
      glPixelStorei(GL_UNPACK_ROW_LENGTH, head->pitch);
      glTexSubImage2D(GL_TEXTURE_2D,
            0, x, y, head->width, head->height,
            GL_LUMINANCE, GL_UNSIGNED_BYTE, head->output);

      head = head->next;
   }
}
예제 #7
0
CL_CollisionOutline CL_CollisionOutline::clone() const
{
	CL_CollisionOutline copy;
	copy.impl->contours.clear();
	copy.impl->contours.reserve(impl->contours.size());
	for (size_t i = 0; i < impl->contours.size(); i++)
		copy.impl->contours.push_back(impl->contours[i].clone());
	copy.impl->do_inside_test = get_inside_test();
	copy.impl->width = get_width();
	copy.impl->height = get_height();
	copy.impl->position = get_translation();
	copy.impl->scale_factor = get_scale();
	copy.impl->angle = get_angle();
	copy.impl->minimum_enclosing_disc = get_minimum_enclosing_disc();

	bool points, normals, metadata, pendepths;
	get_collision_info_state(points,normals,metadata,pendepths);
	copy.enable_collision_info(points,normals,metadata,pendepths);

	CL_Origin origin;
	float x, y;

	get_alignment(origin,x,y);
	copy.impl->translation_origin = origin;
	copy.impl->translation_offset.x = x;
	copy.impl->translation_offset.y = y;

	get_rotation_hotspot(origin,x,y);
	copy.impl->rotation_origin = origin;
	copy.impl->rotation_hotspot.x = x;
	copy.impl->rotation_hotspot.y = y;
	return copy;
}
예제 #8
0
/* output the import thunks of a Win32 module */
static void output_immediate_import_thunks(void)
{
    int i, j, pos;
    int nb_imm = nb_imports - nb_delayed;
    static const char import_thunks[] = "__wine_spec_import_thunks";

    if (!nb_imm) return;

    output( "\n/* immediate import thunks */\n\n" );
    output( "\t.text\n" );
    output( "\t.align %d\n", get_alignment(8) );
    output( "%s:\n", asm_name(import_thunks));

    for (i = pos = 0; i < nb_imports; i++)
    {
        if (dll_imports[i]->delay) continue;
        for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += get_ptr_size())
        {
            ORDDEF *odp = dll_imports[i]->imports[j];
            output_import_thunk( odp->name ? odp->name : odp->export_name,
                                 ".L__wine_spec_import_data_ptrs", pos );
        }
        pos += get_ptr_size();
    }
    output_function_size( import_thunks );
}
예제 #9
0
파일: import.c 프로젝트: Eltechs/wine
/* output a single import thunk */
static void output_import_thunk( const char *name, const char *table, int pos )
{
    output( "\n\t.align %d\n", get_alignment(4) );
    output( "\t%s\n", func_declaration(name) );
    output( "%s\n", asm_globl(name) );
    output_cfi( ".cfi_startproc" );

    switch(target_cpu)
    {
    case CPU_x86:
        if (!UsePIC)
        {
            output( "\tjmp *(%s+%d)\n", table, pos );
        }
        else
        {
            output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
            output( "1:\tjmp *%s+%d-1b(%%eax)\n", table, pos );
        }
        break;
    case CPU_x86_64:
        output( "\tjmpq *%s+%d(%%rip)\n", table, pos );
        break;
    case CPU_ARM:
        output( "\tldr IP,1f\n");
        output( "\tldr PC,[PC,IP]\n" );
        output( "1:\t.long %s+%u-(1b+4)\n", table, pos );
        break;
    case CPU_ARM64:
        output( "\tadr x9, 1f\n" );
        output( "\tldur x9, [x9, #0]\n" );
        if (pos & 0xf000) output( "\tadd x9, x9, #%u\n", pos & 0xf000 );
        if (pos & 0x0f00) output( "\tadd x9, x9, #%u\n", pos & 0x0f00 );
        if (pos & 0x00f0) output( "\tadd x9, x9, #%u\n", pos & 0x00f0 );
        if (pos & 0x000f) output( "\tadd x9, x9, #%u\n", pos & 0x000f );
        output( "\tldur x9, [x9, #0]\n" );
        output( "\tbr x9\n" );
        output( "1:\t.quad %s\n", table );
        break;
    case CPU_POWERPC:
        output( "\tmr %s, %s\n", ppc_reg(0), ppc_reg(31) );
        if (target_platform == PLATFORM_APPLE)
        {
            output( "\tlis %s, ha16(%s+%d+32768)\n", ppc_reg(31), table, pos );
            output( "\tla  %s, lo16(%s+%d)(%s)\n", ppc_reg(31), table, pos, ppc_reg(31) );
        }
        else
        {
            output( "\tlis %s, (%s+%d+32768)@h\n", ppc_reg(31), table, pos );
            output( "\tla  %s, (%s+%d)@l(%s)\n", ppc_reg(31), table, pos, ppc_reg(31) );
        }
        output( "\tlwz   %s, 0(%s)\n", ppc_reg(31), ppc_reg(31) );
        output( "\tmtctr %s\n", ppc_reg(31) );
        output( "\tmr    %s, %s\n", ppc_reg(31), ppc_reg(0) );
        output( "\tbctr\n" );
        break;
    }
    output_cfi( ".cfi_endproc" );
    output_function_size( name );
}
예제 #10
0
void* VariableBlockHeap::alloc( size_t size, Align align, const char* name, int lineNum )
{
	// Ensure that the low level heap is valid before the allocation
#ifdef _DEBUG
	this->lowLevelHeap.CheckValidity();
	GameAssert( this->heapInfo.currNumAlloc + 1 == this->lowLevelHeap.CountAllocations() );
#endif

	unsigned int alignment = get_alignment( align );
	unsigned int alignedSize = size + sizeof( TrackingBlock ) + alignment - 1;

	void* ptr = this->lowLevelHeap.Allocate( alignedSize );
	TrackingBlock* block = new(ptr) TrackingBlock( name, lineNum );
	block->allocIndex = ++this->mem->memInfo.currAllocIndex;
	block->allocSize = alignedSize;

	block->gNext = this->mem->globalTrackingBlockHead;
	if( this->mem->globalTrackingBlockHead != 0 )
		this->mem->globalTrackingBlockHead->gPrev = block;
	this->mem->globalTrackingBlockHead = block;

	block->hNext = this->trackingBlockHead;
	if( this->trackingBlockHead != 0 )
		this->trackingBlockHead->hPrev = block;
	this->trackingBlockHead = block;

	this->heapInfo.currNumAlloc++;
	this->heapInfo.peakNumAlloc = max( this->heapInfo.currNumAlloc, this->heapInfo.peakNumAlloc );

	this->heapInfo.currBytesUsed += alignedSize;
	this->heapInfo.peakBytesUsed = max( this->heapInfo.currBytesUsed, this->heapInfo.peakBytesUsed );
	this->heapInfo.currBytesFree -= alignedSize;

	// Have we exceeded the amount of memory specified for heap size?
	GameAssert( ( this->heapInfo.totalHeapSize - sizeof( VariableBlockHeap ) ) >= this->heapInfo.currBytesUsed );

	this->mem->memInfo.currBytesUsed += alignedSize;
	this->mem->memInfo.peakBytesUsed = max( this->mem->memInfo.currBytesUsed, this->mem->memInfo.peakBytesUsed );

	this->mem->memInfo.currNumAlloc++;
	this->mem->memInfo.peakNumAlloc = max( this->mem->memInfo.peakNumAlloc, this->mem->memInfo.currNumAlloc );

	void* p = block + 1;

	void* alignedAddr = (void*) ( ( (unsigned int) p + alignment - 1 ) & ~( alignment - 1 ) );
	TrackingBlock** topPtr = (TrackingBlock**) ( (size_t) alignedAddr - sizeof( TrackingBlock* ) );
	*topPtr = block;

	// Make sure the low level heap is valid after the allocation
#ifdef _DEBUG
	this->lowLevelHeap.CheckValidity();
	GameAssert( this->heapInfo.currNumAlloc + 1 == this->lowLevelHeap.CountAllocations() );
#endif

	return alignedAddr;
}
예제 #11
0
/*******************************************************************
 *         BuildRelays16
 *
 * Build all the 16-bit relay callbacks
 */
void BuildRelays16(void)
{
    if (target_cpu != CPU_x86)
    {
        output( "/* File not used with this architecture. Do not edit! */\n\n" );
        return;
    }

    /* File header */

    output( "/* File generated automatically. Do not edit! */\n\n" );
    output( "\t.text\n" );

    output( "%s:\n\n", asm_name("__wine_spec_thunk_text_16") );

    output( "%s\n", asm_globl("__wine_call16_start") );

    /* Standard CallFrom16 routine */
    BuildCallFrom16Core( FALSE, FALSE );

    /* Register CallFrom16 routine */
    BuildCallFrom16Core( TRUE, FALSE );

    /* C16ThkSL CallFrom16 routine */
    BuildCallFrom16Core( FALSE, TRUE );

    /* Standard CallTo16 routine */
    BuildCallTo16Core( 0 );

    /* Register CallTo16 routine */
    BuildCallTo16Core( 1 );

    /* Standard CallTo16 return stub */
    BuildRet16Func();

    /* CBClientThunkSL routine */
    BuildCallTo32CBClient( FALSE );

    /* CBClientThunkSLEx routine */
    BuildCallTo32CBClient( TRUE  );

    /* Pending DPMI events check stub */
    BuildPendingEventCheck();

    output( "%s\n", asm_globl("__wine_call16_end") );
    output_function_size( "__wine_spec_thunk_text_16" );

    /* Declare the return address and data selector variables */
    output( "\n\t.data\n\t.align %d\n", get_alignment(4) );
    output( "%s\n\t.long 0\n", asm_globl("CallTo16_DataSelector") );
    output( "%s\n\t.long 0\n", asm_globl("CallTo16_TebSelector") );
    if (UsePIC) output( "wine_ldt_copy_ptr:\t.long %s\n", asm_name("wine_ldt_copy") );
    output_gnu_stack_note();
}
예제 #12
0
static PyObject *ffi_alignof(FFIObject *self, PyObject *arg)
{
    int align;
    CTypeDescrObject *ct = _ffi_type(self, arg, ACCEPT_ALL);
    if (ct == NULL)
        return NULL;

    align = get_alignment(ct);
    if (align < 0)
        return NULL;
    return PyInt_FromLong(align);
}
예제 #13
0
ssize_t write_blockwise(int fd, void *orig_buf, size_t count)
{
	void *hangover_buf, *hangover_buf_base = NULL;
	void *buf, *buf_base = NULL;
	int r, hangover, solid, bsize, alignment;
	ssize_t ret = -1;

	if ((bsize = sector_size(fd)) < 0)
		return bsize;

	hangover = count % bsize;
	solid = count - hangover;
	alignment = get_alignment(fd);

	if ((long)orig_buf & (alignment - 1)) {
		buf = aligned_malloc(&buf_base, count, alignment);
		if (!buf)
			goto out;
		memcpy(buf, orig_buf, count);
	} else
		buf = orig_buf;

	r = write(fd, buf, solid);
	if (r < 0 || r != solid)
		goto out;

	if (hangover) {
		hangover_buf = aligned_malloc(&hangover_buf_base, bsize, alignment);
		if (!hangover_buf)
			goto out;

		r = read(fd, hangover_buf, bsize);
		if (r < 0 || r != bsize)
			goto out;

		r = lseek(fd, -bsize, SEEK_CUR);
		if (r < 0)
			goto out;
		memcpy(hangover_buf, (char*)buf + solid, hangover);

		r = write(fd, hangover_buf, bsize);
		if (r < 0 || r != bsize)
			goto out;
	}
	ret = count;
out:
	free(hangover_buf_base);
	if (buf != orig_buf)
		free(buf_base);
	return ret;
}
예제 #14
0
/* output the get_pc thunk if needed */
void output_get_pc_thunk(void)
{
    if (target_cpu != CPU_x86) return;
    if (!UsePIC) return;
    output( "\n\t.text\n" );
    output( "\t.align %d\n", get_alignment(4) );
    output( "\t%s\n", func_declaration("__wine_spec_get_pc_thunk_eax") );
    output( "%s:\n", asm_name("__wine_spec_get_pc_thunk_eax") );
    output_cfi( ".cfi_startproc" );
    output( "\tmovl (%%esp),%%eax\n" );
    output( "\tret\n" );
    output_cfi( ".cfi_endproc" );
    output_function_size( "__wine_spec_get_pc_thunk_eax" );
}
예제 #15
0
파일: relay.c 프로젝트: NVIDIA/winex_lgpl
static void function_header( FILE *outfile, const char *name )
{
    fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
#ifdef USE_STABS
    fprintf( outfile, "\t.stabs \"%s:F1\",36,0,0," PREFIX "%s\n", name, name);
#endif
#ifdef TYPE_ASM_SUPPORTED
    fprintf( outfile, "\t.type " PREFIX "%s,@function\n", name );
#elif defined(NEED_TYPE_IN_DEF)
    fprintf( outfile, "\t.def " PREFIX "%s; .scl 2; .type 32; .endef\n", name );
#endif
    fprintf( outfile, "\t.globl " PREFIX "%s\n", name );
    fprintf( outfile, PREFIX "%s:\n", name );
}
예제 #16
0
/*
 * Combines llseek with blockwise write. write_blockwise can already deal with short writes
 * but we also need a function to deal with short writes at the start. But this information
 * is implicitly included in the read/write offset, which can not be set to non-aligned
 * boundaries. Hence, we combine llseek with write.
 */
ssize_t write_lseek_blockwise(int fd, char *buf, size_t count, off_t offset) {
	char *frontPadBuf;
	void *frontPadBuf_base = NULL;
	int r, bsize, frontHang;
	size_t innerCount = 0;
	ssize_t ret = -1;

	if ((bsize = sector_size(fd)) < 0)
		return bsize;

	frontHang = offset % bsize;

	if (lseek(fd, offset - frontHang, SEEK_SET) < 0)
		goto out;

	if (frontHang) {
		frontPadBuf = aligned_malloc(&frontPadBuf_base,
					     bsize, get_alignment(fd));
		if (!frontPadBuf)
			goto out;

		r = read(fd, frontPadBuf, bsize);
		if (r < 0 || r != bsize)
			goto out;

		innerCount = bsize - frontHang;
		if (innerCount > count)
			innerCount = count;

		memcpy(frontPadBuf + frontHang, buf, innerCount);

		if (lseek(fd, offset - frontHang, SEEK_SET) < 0)
			goto out;

		r = write(fd, frontPadBuf, bsize);
		if (r < 0 || r != bsize)
			goto out;

		buf += innerCount;
		count -= innerCount;
	}

	ret = count ? write_blockwise(fd, buf, count) : 0;
	if (ret >= 0)
		ret += innerCount;
out:
	free(frontPadBuf_base);

	return ret;
}
예제 #17
0
void CreatureType::make_creature(Creature& cr) const
{
    cr.type_idname=idname_;
    cr.align=get_alignment();
    cr.age=age_.roll();
    cr.juice=juice_.roll();
    cr.gender_liberal=cr.gender_conservative=roll_gender();
    cr.infiltration=roll_infiltration();
    cr.money=money_.roll();
    strcpy(cr.name,get_encounter_name());
    for(int i=0; i<SKILLNUM; i++) cr.set_skill(i,skills_[i].roll());
    give_armor(cr);
    give_weapon(cr);
}
예제 #18
0
파일: relay.c 프로젝트: NVIDIA/winex_lgpl
/*******************************************************************
 *         BuildRet16Func
 *
 * Build the return code for 16-bit callbacks
 */
static void BuildRet16Func( FILE *outfile )
{
    /*
     *  Note: This must reside in the .data section to allow
     *        run-time relocation of the SYSLEVEL_Win16CurrentTeb symbol
     */

    function_header( outfile, "CallTo16_Ret" );

    /* Save %esp into %esi */
    fprintf( outfile, "\tmovl %%esp,%%esi\n" );

    /* Restore 32-bit segment registers */

    fprintf( outfile, "\t.byte 0x2e\n\tmovl " PREFIX "CallTo16_DataSelector-" PREFIX "Call16_Ret_Start,%%edi\n" );
#ifdef __svr4__
    fprintf( outfile, "\tdata16\n");
#endif
    fprintf( outfile, "\tmovw %%di,%%ds\n" );
#ifdef __svr4__
    fprintf( outfile, "\tdata16\n");
#endif
    fprintf( outfile, "\tmovw %%di,%%es\n" );

    fprintf( outfile, "\tmovw " PREFIX "SYSLEVEL_Win16CurrentTeb,%%fs\n" );

    /* Restore the 32-bit stack */

#ifdef __svr4__
    fprintf( outfile, "\tdata16\n");
#endif
    fprintf( outfile, "\tmovw %%di,%%ss\n" );
    fprintf( outfile, "\t.byte 0x64\n\tmovl (%d),%%esp\n", STACKOFFSET );
    fprintf( outfile, "\t.byte 0x64\n\tpopl (%d)\n", STACKOFFSET );

    /* Return to caller */

    fprintf( outfile, "\tlret\n" );

    /* Declare the return address and data selector variables */

    fprintf( outfile, "\n\t.align %d\n", get_alignment(4) );
    fprintf( outfile, "\t.globl " PREFIX "CallTo16_DataSelector\n" );
    fprintf( outfile, PREFIX "CallTo16_DataSelector:\t.long 0\n" );
    fprintf( outfile, "\t.globl " PREFIX "CallTo16_RetAddr\n" );
    fprintf( outfile, PREFIX "CallTo16_RetAddr:\t.long 0\n" );
    fprintf( outfile, "\t.globl " PREFIX "SYSLEVEL_Win16CurrentTeb\n" );
    fprintf( outfile, PREFIX "SYSLEVEL_Win16CurrentTeb:\t.long 0\n" );
}
예제 #19
0
파일: gl.c 프로젝트: ToadKing/RetroArch-Rpi
static bool gl_read_viewport(void *data, uint8_t *buffer)
{
   (void)data;

   GLint vp[4];
   glGetIntegerv(GL_VIEWPORT, vp);

   glPixelStorei(GL_PACK_ALIGNMENT, get_alignment(vp[2]));
   glPixelStorei(GL_PACK_ROW_LENGTH, vp[2]);

   glReadPixels(vp[0], vp[1],
         vp[2], vp[3],
         GL_BGR, GL_UNSIGNED_BYTE, buffer);

   return true;
}
예제 #20
0
static unsigned get_alignment(lima_symbol_t* symbol)
{
	if (symbol->type == lima_symbol_struct)
	{
		unsigned alignment = 1;
		for (unsigned i = 0; i < symbol->num_children; i++)
		{
			unsigned new_alignment = get_alignment(symbol->children[i]);
			if (new_alignment > alignment)
				alignment = new_alignment;
		}
		
		return alignment;
	}
	
	return alignments[symbol->type];
}
예제 #21
0
파일: import.c 프로젝트: NVIDIA/winex_lgpl
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
}
예제 #22
0
파일: relay.c 프로젝트: ccpgames/wine
/*******************************************************************
 *         output_asm_relays16
 *
 * Build all the 16-bit relay callbacks
 */
void output_asm_relays16(void)
{
    /* File header */

    output( "\t.text\n" );
    output( "%s:\n\n", asm_name("__wine_spec_thunk_text_16") );

    output( "%s\n", asm_globl("__wine_call16_start") );

    /* Standard CallFrom16 routine */
    BuildCallFrom16Core( 0, 0 );

    /* Register CallFrom16 routine */
    BuildCallFrom16Core( 1, 0 );

    /* C16ThkSL CallFrom16 routine */
    BuildCallFrom16Core( 0, 1 );

    /* Standard CallTo16 routine */
    BuildCallTo16Core( 0 );

    /* Register CallTo16 routine */
    BuildCallTo16Core( 1 );

    /* Standard CallTo16 return stub */
    BuildRet16Func();

    /* CBClientThunkSL routine */
    BuildCallTo32CBClient( 0 );

    /* CBClientThunkSLEx routine */
    BuildCallTo32CBClient( 1  );

    output( "%s\n", asm_globl("__wine_call16_end") );
    output_function_size( "__wine_spec_thunk_text_16" );

    /* Declare the return address and data selector variables */
    output( "\n\t.data\n\t.align %d\n", get_alignment(4) );
    output( "%s\n\t.long 0\n", asm_globl("CallTo16_DataSelector") );
    output( "%s\n\t.long 0\n", asm_globl("CallTo16_TebSelector") );
}
예제 #23
0
파일: busio.c 프로젝트: joaohf/dtree
void *bus_devmem_access(uint32_t base, uint32_t mlen, int *fd)
{
	*fd = open("/dev/mem", O_RDWR);
	if(*fd == -1) {
		perror("open(/dev/mem)");
		return NULL;
	}

	uint32_t aligned_base = base - get_alignment(base);

	// Get number of pages for mmap
	pagenum = mlen / getpagesize();
	pagenum += (mlen % getpagesize() == 0) ? 0: 1;
    
	void *m = mmap(NULL, pagenum * getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, *fd, aligned_base);
	if(m == NULL) {
		perror("mmap(NULL, pagenum * getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, aligned_base)");
		close(*fd);
		return NULL;
	}

	return m;
}
예제 #24
0
파일: text.cpp 프로젝트: GamingAtheist/ogui
void TextWidget::redraw()
{
  Image& target=get_redraw_target();
  target.fill(m_BGColor);
  Rect rect=get_rect();
  const xstring& text = get_text();
  str_vec lines(1, text);
  Rect bounds=m_Font->get_bounds(text);
  if (bounds.get_width() > rect.get_width())
  {
    break_text_lines(m_Font, text, rect.get_width(),lines);
    bounds = Rect(0, 0, 0, 0);
    for (auto& line : lines)
    {
      Rect b = m_Font->get_bounds(line);
      bounds.right = Max(bounds.right, b.get_width());
      bounds.bottom += b.get_height();
    }
  }
  Point d(rect.get_width()-bounds.get_width(),rect.get_height()-bounds.get_height());
  if ((get_alignment() & ALIGN_HCENTER)==ALIGN_HCENTER) bounds.offset(Point(d.x/2,0));
  else
  if ((get_alignment() & ALIGN_RIGHT)==ALIGN_RIGHT) bounds.offset(Point(d.x,0));

  if ((get_alignment() & ALIGN_VCENTER)==ALIGN_VCENTER) bounds.offset(Point(0,d.y/2));
  else
  if ((get_alignment() & ALIGN_BOTTOM)==ALIGN_BOTTOM) bounds.offset(Point(0,d.y));
  int x = bounds.left, y = bounds.top;
  for (auto& line : lines)
  {
    Rect line_bounds = m_Font->get_bounds(line);
    int dx = 0;
    if ((get_alignment() & ALIGN_HCENTER) == ALIGN_HCENTER) dx = (bounds.get_width() - line_bounds.get_width()) / 2;
    else
    if ((get_alignment() & ALIGN_RIGHT) == ALIGN_RIGHT) dx = (bounds.get_width() - line_bounds.get_width());
    m_Font->draw(target, Point(x + dx, y), line, m_Color);
    y += line_bounds.get_height();
  }
}
예제 #25
0
/* output the delayed import thunks of a Win32 module */
static void output_delayed_import_thunks( const DLLSPEC *spec )
{
    int i, idx, j, pos, extra_stack_storage = 0;
    static const char delayed_import_loaders[] = "__wine_spec_delayed_import_loaders";
    static const char delayed_import_thunks[] = "__wine_spec_delayed_import_thunks";

    if (!nb_delayed) return;

    output( "\n/* delayed import thunks */\n\n" );
    output( "\t.text\n" );
    output( "\t.align %d\n", get_alignment(8) );
    output( "%s:\n", asm_name(delayed_import_loaders));
    output( "\t%s\n", func_declaration("__wine_delay_load_asm") );
    output( "%s:\n", asm_name("__wine_delay_load_asm") );
    output_cfi( ".cfi_startproc" );
    switch(target_cpu)
    {
    case CPU_x86:
        output( "\tpushl %%ecx\n" );
        output_cfi( ".cfi_adjust_cfa_offset 4" );
        output( "\tpushl %%edx\n" );
        output_cfi( ".cfi_adjust_cfa_offset 4" );
        output( "\tpushl %%eax\n" );
        output_cfi( ".cfi_adjust_cfa_offset 4" );
        output( "\tcall %s\n", asm_name("__wine_spec_delay_load") );
        output_cfi( ".cfi_adjust_cfa_offset -4" );
        output( "\tpopl %%edx\n" );
        output_cfi( ".cfi_adjust_cfa_offset -4" );
        output( "\tpopl %%ecx\n" );
        output_cfi( ".cfi_adjust_cfa_offset -4" );
        output( "\tjmp *%%eax\n" );
        break;
    case CPU_x86_64:
        output( "\tsubq $88,%%rsp\n" );
        output_cfi( ".cfi_adjust_cfa_offset 88" );
        output( "\tmovq %%rdx,80(%%rsp)\n" );
        output( "\tmovq %%rcx,72(%%rsp)\n" );
        output( "\tmovq %%r8,64(%%rsp)\n" );
        output( "\tmovq %%r9,56(%%rsp)\n" );
        output( "\tmovq %%r10,48(%%rsp)\n" );
        output( "\tmovq %%r11,40(%%rsp)\n" );
        output( "\tmovq %%rax,%%rcx\n" );
        output( "\tcall %s\n", asm_name("__wine_spec_delay_load") );
        output( "\tmovq 40(%%rsp),%%r11\n" );
        output( "\tmovq 48(%%rsp),%%r10\n" );
        output( "\tmovq 56(%%rsp),%%r9\n" );
        output( "\tmovq 64(%%rsp),%%r8\n" );
        output( "\tmovq 72(%%rsp),%%rcx\n" );
        output( "\tmovq 80(%%rsp),%%rdx\n" );
        output( "\taddq $88,%%rsp\n" );
        output_cfi( ".cfi_adjust_cfa_offset -88" );
        output( "\tjmp *%%rax\n" );
        break;
    case CPU_SPARC:
        output( "\tsave %%sp, -96, %%sp\n" );
        output( "\tcall %s\n", asm_name("__wine_spec_delay_load") );
        output( "\tmov %%g1, %%o0\n" );
        output( "\tjmp %%o0\n" );
        output( "\trestore\n" );
        break;
    case CPU_ARM:
        output( "\tstmfd  SP!, {r4-r10,FP,LR}\n" );
        output( "\tmov LR,PC\n");
        output( "\tadd LR,LR,#8\n");
        output( "\tldr PC,[PC,#-4]\n");
        output( "\t.long %s\n", asm_name("__wine_spec_delay_load") );
        output( "\tmov IP,r0\n");
        output( "\tldmfd  SP!, {r4-r10,FP,LR}\n" );
        output( "\tldmfd  SP!, {r0-r3}\n" );
        output( "\tmov PC,IP\n");
        break;
    case CPU_ARM64:
        output( "\tstp x29, x30, [sp,#-16]!\n" );
        output( "\tmov x29, sp\n" );
        output( "\tadr x9, 1f\n" );
        output( "\tldur x9, [x9, #0]\n" );
        output( "\tblr x9\n" );
        output( "\tmov x9, x0\n" );
        output( "\tldp x29, x30, [sp],#16\n" );
        output( "\tldp x0, x1, [sp,#16]\n" );
        output( "\tldp x2, x3, [sp,#32]\n" );
        output( "\tldp x4, x5, [sp,#48]\n" );
        output( "\tldp x6, x7, [sp],#80\n" );
        output( "\tbr x9\n" ); /* or "ret x9" */
        output( "1:\t.quad %s\n", asm_name("__wine_spec_delay_load") );
        break;
    case CPU_POWERPC:
        if (target_platform == PLATFORM_APPLE) extra_stack_storage = 56;

        /* Save all callee saved registers into a stackframe. */
        output( "\tstwu %s, -%d(%s)\n",ppc_reg(1), 48+extra_stack_storage, ppc_reg(1));
        output( "\tstw  %s, %d(%s)\n", ppc_reg(3),  4+extra_stack_storage, ppc_reg(1));
        output( "\tstw  %s, %d(%s)\n", ppc_reg(4),  8+extra_stack_storage, ppc_reg(1));
        output( "\tstw  %s, %d(%s)\n", ppc_reg(5), 12+extra_stack_storage, ppc_reg(1));
        output( "\tstw  %s, %d(%s)\n", ppc_reg(6), 16+extra_stack_storage, ppc_reg(1));
        output( "\tstw  %s, %d(%s)\n", ppc_reg(7), 20+extra_stack_storage, ppc_reg(1));
        output( "\tstw  %s, %d(%s)\n", ppc_reg(8), 24+extra_stack_storage, ppc_reg(1));
        output( "\tstw  %s, %d(%s)\n", ppc_reg(9), 28+extra_stack_storage, ppc_reg(1));
        output( "\tstw  %s, %d(%s)\n", ppc_reg(10),32+extra_stack_storage, ppc_reg(1));
        output( "\tstw  %s, %d(%s)\n", ppc_reg(11),36+extra_stack_storage, ppc_reg(1));
        output( "\tstw  %s, %d(%s)\n", ppc_reg(12),40+extra_stack_storage, ppc_reg(1));

        /* r0 -> r3 (arg1) */
        output( "\tmr %s, %s\n", ppc_reg(3), ppc_reg(0));

        /* save return address */
        output( "\tmflr %s\n", ppc_reg(0));
        output( "\tstw  %s, %d(%s)\n", ppc_reg(0), 44+extra_stack_storage, ppc_reg(1));

        /* Call the __wine_delay_load function, arg1 is arg1. */
        output( "\tbl %s\n", asm_name("__wine_spec_delay_load") );

        /* Load return value from call into ctr register */
        output( "\tmtctr %s\n", ppc_reg(3));

        /* restore all saved registers and drop stackframe. */
        output( "\tlwz  %s, %d(%s)\n", ppc_reg(3),  4+extra_stack_storage, ppc_reg(1));
        output( "\tlwz  %s, %d(%s)\n", ppc_reg(4),  8+extra_stack_storage, ppc_reg(1));
        output( "\tlwz  %s, %d(%s)\n", ppc_reg(5), 12+extra_stack_storage, ppc_reg(1));
        output( "\tlwz  %s, %d(%s)\n", ppc_reg(6), 16+extra_stack_storage, ppc_reg(1));
        output( "\tlwz  %s, %d(%s)\n", ppc_reg(7), 20+extra_stack_storage, ppc_reg(1));
        output( "\tlwz  %s, %d(%s)\n", ppc_reg(8), 24+extra_stack_storage, ppc_reg(1));
        output( "\tlwz  %s, %d(%s)\n", ppc_reg(9), 28+extra_stack_storage, ppc_reg(1));
        output( "\tlwz  %s, %d(%s)\n", ppc_reg(10),32+extra_stack_storage, ppc_reg(1));
        output( "\tlwz  %s, %d(%s)\n", ppc_reg(11),36+extra_stack_storage, ppc_reg(1));
        output( "\tlwz  %s, %d(%s)\n", ppc_reg(12),40+extra_stack_storage, ppc_reg(1));

        /* Load return value from call into return register */
        output( "\tlwz  %s,  %d(%s)\n", ppc_reg(0), 44+extra_stack_storage, ppc_reg(1));
        output( "\tmtlr %s\n", ppc_reg(0));
        output( "\taddi %s, %s, %d\n", ppc_reg(1), ppc_reg(1),  48+extra_stack_storage);

        /* branch to ctr register. */
        output( "\tbctr\n");
        break;
    }
    output_cfi( ".cfi_endproc" );
    output_function_size( "__wine_delay_load_asm" );
    output( "\n" );

    for (i = idx = 0; i < nb_imports; i++)
    {
        if (!dll_imports[i]->delay) continue;
        for (j = 0; j < dll_imports[i]->nb_imports; j++)
        {
            ORDDEF *odp = dll_imports[i]->imports[j];
            const char *name = odp->name ? odp->name : odp->export_name;

            output( ".L__wine_delay_imp_%d_%s:\n", i, name );
            output_cfi( ".cfi_startproc" );
            switch(target_cpu)
            {
            case CPU_x86:
                output( "\tmovl $%d, %%eax\n", (idx << 16) | j );
                output( "\tjmp %s\n", asm_name("__wine_delay_load_asm") );
                break;
            case CPU_x86_64:
                output( "\tmovq $%d,%%rax\n", (idx << 16) | j );
                output( "\tjmp %s\n", asm_name("__wine_delay_load_asm") );
                break;
            case CPU_SPARC:
                output( "\tset %d, %%g1\n", (idx << 16) | j );
                output( "\tb,a %s\n", asm_name("__wine_delay_load_asm") );
                output( "\tnop\n" );
                break;
            case CPU_ARM:
                output( "\tstmfd  SP!, {r0-r3}\n" );
                output( "\tmov r0, #%d\n", idx );
                output( "\tmov r1, #16384\n" );
                output( "\tmul r1, r0, r1\n" );
                output( "\tmov r0, r1\n" );
                output( "\tmov r1, #4\n" );
                output( "\tmul r1, r0, r1\n" );
                output( "\tmov r0, r1\n" );
                output( "\tadd r0, #%d\n", j );
                output( "\tldr PC,[PC,#-4]\n");
                output( "\t.long %s\n", asm_name("__wine_delay_load_asm") );
                break;
            case CPU_ARM64:
                output( "\tstp x6, x7, [sp,#-80]!\n" );
                output( "\tstp x4, x5, [sp,#48]\n" );
                output( "\tstp x2, x3, [sp,#32]\n" );
                output( "\tstp x0, x1, [sp,#16]\n" );
                output( "\tmov x0, #%d\n", idx );
                output( "\tmov x1, #16384\n" );
                output( "\tmul x1, x0, x1\n" );
                output( "\tmov x0, x1\n" );
                output( "\tmov x1, #4\n" );
                output( "\tmul x1, x0, x1\n" );
                output( "\tmov x0, x1\n" );
                output( "\tadd x0, x0, #%d\n", j );
                output( "\tadr x9, 1f\n" );
                output( "\tldur x9, [x9, #0]\n" );
                output( "\tbr x9\n" );
                output( "1:\t.quad %s\n", asm_name("__wine_delay_load_asm") );
                break;
            case CPU_POWERPC:
                switch(target_platform)
                {
                case PLATFORM_APPLE:
                    /* On Darwin we can use r0 and r2 */
                    /* Upper part in r2 */
                    output( "\tlis %s, %d\n", ppc_reg(2), idx);
                    /* Lower part + r2 -> r0, Note we can't use r0 directly */
                    output( "\taddi %s, %s, %d\n", ppc_reg(0), ppc_reg(2), j);
                    output( "\tb %s\n", asm_name("__wine_delay_load_asm") );
                    break;
                default:
                    /* On linux we can't use r2 since r2 is not a scratch register (hold the TOC) */
                    /* Save r13 on the stack */
                    output( "\taddi %s, %s, -0x4\n", ppc_reg(1), ppc_reg(1));
                    output( "\tstw  %s, 0(%s)\n",    ppc_reg(13), ppc_reg(1));
                    /* Upper part in r13 */
                    output( "\tlis %s, %d\n", ppc_reg(13), idx);
                    /* Lower part + r13 -> r0, Note we can't use r0 directly */
                    output( "\taddi %s, %s, %d\n", ppc_reg(0), ppc_reg(13), j);
                    /* Restore r13 */
                    output( "\tstw  %s, 0(%s)\n",    ppc_reg(13), ppc_reg(1));
                    output( "\taddic %s, %s, 0x4\n", ppc_reg(1), ppc_reg(1));
                    output( "\tb %s\n", asm_name("__wine_delay_load_asm") );
                    break;
                }
                break;
            }
            output_cfi( ".cfi_endproc" );
        }
        idx++;
    }
    output_function_size( delayed_import_loaders );

    output( "\n\t.align %d\n", get_alignment(get_ptr_size()) );
    output( "%s:\n", asm_name(delayed_import_thunks));
    for (i = pos = 0; i < nb_imports; i++)
    {
        if (!dll_imports[i]->delay) continue;
        for (j = 0; j < dll_imports[i]->nb_imports; j++, pos += get_ptr_size())
        {
            ORDDEF *odp = dll_imports[i]->imports[j];
            output_import_thunk( odp->name ? odp->name : odp->export_name,
                                 ".L__wine_delay_IAT", pos );
        }
    }
    output_function_size( delayed_import_thunks );
}
예제 #26
0
/* output the delayed import table of a Win32 module */
static void output_delayed_imports( const DLLSPEC *spec )
{
    int i, j, mod;

    if (!nb_delayed) return;

    output( "\n/* delayed imports */\n\n" );
    output( "\t.data\n" );
    output( "\t.align %d\n", get_alignment(get_ptr_size()) );
    output( "%s\n", asm_globl("__wine_spec_delay_imports") );

    /* list of dlls */

    for (i = j = mod = 0; i < nb_imports; i++)
    {
        if (!dll_imports[i]->delay) continue;
        output( "\t%s 0\n", get_asm_ptr_keyword() );   /* grAttrs */
        output( "\t%s .L__wine_delay_name_%d\n",       /* szName */
                get_asm_ptr_keyword(), i );
        output( "\t%s .L__wine_delay_modules+%d\n",    /* phmod */
                get_asm_ptr_keyword(), mod * get_ptr_size() );
        output( "\t%s .L__wine_delay_IAT+%d\n",        /* pIAT */
                get_asm_ptr_keyword(), j * get_ptr_size() );
        output( "\t%s .L__wine_delay_INT+%d\n",        /* pINT */
                get_asm_ptr_keyword(), j * get_ptr_size() );
        output( "\t%s 0\n", get_asm_ptr_keyword() );   /* pBoundIAT */
        output( "\t%s 0\n", get_asm_ptr_keyword() );   /* pUnloadIAT */
        output( "\t%s 0\n", get_asm_ptr_keyword() );   /* dwTimeStamp */
        j += dll_imports[i]->nb_imports;
        mod++;
    }
    output( "\t%s 0\n", get_asm_ptr_keyword() );   /* grAttrs */
    output( "\t%s 0\n", get_asm_ptr_keyword() );   /* szName */
    output( "\t%s 0\n", get_asm_ptr_keyword() );   /* phmod */
    output( "\t%s 0\n", get_asm_ptr_keyword() );   /* pIAT */
    output( "\t%s 0\n", get_asm_ptr_keyword() );   /* pINT */
    output( "\t%s 0\n", get_asm_ptr_keyword() );   /* pBoundIAT */
    output( "\t%s 0\n", get_asm_ptr_keyword() );   /* pUnloadIAT */
    output( "\t%s 0\n", get_asm_ptr_keyword() );   /* dwTimeStamp */

    output( "\n.L__wine_delay_IAT:\n" );
    for (i = 0; i < nb_imports; i++)
    {
        if (!dll_imports[i]->delay) continue;
        for (j = 0; j < dll_imports[i]->nb_imports; j++)
        {
            ORDDEF *odp = dll_imports[i]->imports[j];
            const char *name = odp->name ? odp->name : odp->export_name;
            output( "\t%s .L__wine_delay_imp_%d_%s\n",
                    get_asm_ptr_keyword(), i, name );
        }
    }

    output( "\n.L__wine_delay_INT:\n" );
    for (i = 0; i < nb_imports; i++)
    {
        if (!dll_imports[i]->delay) continue;
        for (j = 0; j < dll_imports[i]->nb_imports; j++)
        {
            ORDDEF *odp = dll_imports[i]->imports[j];
            if (!odp->name)
                output( "\t%s %d\n", get_asm_ptr_keyword(), odp->ordinal );
            else
                output( "\t%s .L__wine_delay_data_%d_%s\n",
                        get_asm_ptr_keyword(), i, odp->name );
        }
    }

    output( "\n.L__wine_delay_modules:\n" );
    for (i = 0; i < nb_imports; i++)
    {
        if (dll_imports[i]->delay) output( "\t%s 0\n", get_asm_ptr_keyword() );
    }

    for (i = 0; i < nb_imports; i++)
    {
        if (!dll_imports[i]->delay) continue;
        output( ".L__wine_delay_name_%d:\n", i );
        output( "\t%s \"%s\"\n",
                get_asm_string_keyword(), dll_imports[i]->spec->file_name );
    }

    for (i = 0; i < nb_imports; i++)
    {
        if (!dll_imports[i]->delay) continue;
        for (j = 0; j < dll_imports[i]->nb_imports; j++)
        {
            ORDDEF *odp = dll_imports[i]->imports[j];
            if (!odp->name) continue;
            output( ".L__wine_delay_data_%d_%s:\n", i, odp->name );
            output( "\t%s \"%s\"\n", get_asm_string_keyword(), odp->name );
        }
    }
    output_function_size( "__wine_spec_delay_imports" );
}
예제 #27
0
/* output the import table of a Win32 module */
static void output_immediate_imports(void)
{
    int i, j;
    const char *dll_name;

    if (nb_imports == nb_delayed) return;  /* no immediate imports */

    /* main import header */

    output( "\n/* import table */\n" );
    output( "\n\t.data\n" );
    output( "\t.align %d\n", get_alignment(4) );
    output( ".L__wine_spec_imports:\n" );

    /* list of dlls */

    for (i = j = 0; i < nb_imports; i++)
    {
        if (dll_imports[i]->delay) continue;
        dll_name = make_c_identifier( dll_imports[i]->spec->file_name );
        output( "\t.long .L__wine_spec_import_data_names+%d-.L__wine_spec_rva_base\n",  /* OriginalFirstThunk */
                j * get_ptr_size() );
        output( "\t.long 0\n" );     /* TimeDateStamp */
        output( "\t.long 0\n" );     /* ForwarderChain */
        output( "\t.long .L__wine_spec_import_name_%s-.L__wine_spec_rva_base\n", /* Name */
                dll_name );
        output( "\t.long .L__wine_spec_import_data_ptrs+%d-.L__wine_spec_rva_base\n",  /* FirstThunk */
                j * get_ptr_size() );
        j += dll_imports[i]->nb_imports + 1;
    }
    output( "\t.long 0\n" );     /* OriginalFirstThunk */
    output( "\t.long 0\n" );     /* TimeDateStamp */
    output( "\t.long 0\n" );     /* ForwarderChain */
    output( "\t.long 0\n" );     /* Name */
    output( "\t.long 0\n" );     /* FirstThunk */

    output( "\n\t.align %d\n", get_alignment(get_ptr_size()) );
    output( ".L__wine_spec_import_data_names:\n" );
    for (i = 0; i < nb_imports; i++)
    {
        if (dll_imports[i]->delay) continue;
        dll_name = make_c_identifier( dll_imports[i]->spec->file_name );
        for (j = 0; j < dll_imports[i]->nb_imports; j++)
        {
            ORDDEF *odp = dll_imports[i]->imports[j];
            if (!(odp->flags & FLAG_NONAME))
                output( "\t%s .L__wine_spec_import_data_%s_%s-.L__wine_spec_rva_base\n",
                        get_asm_ptr_keyword(), dll_name, odp->name );
            else
            {
                if (get_ptr_size() == 8)
                    output( "\t.quad 0x800000000000%04x\n", odp->ordinal );
                else
                    output( "\t.long 0x8000%04x\n", odp->ordinal );
            }
        }
        output( "\t%s 0\n", get_asm_ptr_keyword() );
    }
    output( ".L__wine_spec_import_data_ptrs:\n" );
    for (i = 0; i < nb_imports; i++)
    {
        if (dll_imports[i]->delay) continue;
        for (j = 0; j < dll_imports[i]->nb_imports; j++) output( "\t%s 0\n", get_asm_ptr_keyword() );
        output( "\t%s 0\n", get_asm_ptr_keyword() );
    }
    output( ".L__wine_spec_imports_end:\n" );

    for (i = 0; i < nb_imports; i++)
    {
        if (dll_imports[i]->delay) continue;
        dll_name = make_c_identifier( dll_imports[i]->spec->file_name );
        for (j = 0; j < dll_imports[i]->nb_imports; j++)
        {
            ORDDEF *odp = dll_imports[i]->imports[j];
            if (!(odp->flags & FLAG_NONAME))
            {
                output( "\t.align %d\n", get_alignment(2) );
                output( ".L__wine_spec_import_data_%s_%s:\n", dll_name, odp->name );
                output( "\t%s %d\n", get_asm_short_keyword(), odp->ordinal );
                output( "\t%s \"%s\"\n", get_asm_string_keyword(), odp->name );
            }
        }
    }

    for (i = 0; i < nb_imports; i++)
    {
        if (dll_imports[i]->delay) continue;
        dll_name = make_c_identifier( dll_imports[i]->spec->file_name );
        output( ".L__wine_spec_import_name_%s:\n\t%s \"%s\"\n",
                dll_name, get_asm_string_keyword(), dll_imports[i]->spec->file_name );
    }
}
예제 #28
0
/* output a single import thunk */
static void output_import_thunk( const char *name, const char *table, int pos )
{
    output( "\n\t.align %d\n", get_alignment(4) );
    output( "\t%s\n", func_declaration(name) );
    output( "%s\n", asm_globl(name) );
    output_cfi( ".cfi_startproc" );

    switch(target_cpu)
    {
    case CPU_x86:
        if (!UsePIC)
        {
            output( "\tjmp *(%s+%d)\n", table, pos );
        }
        else
        {
            output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
            output( "1:\tjmp *%s+%d-1b(%%eax)\n", table, pos );
        }
        break;
    case CPU_x86_64:
        output( "\tjmpq *%s+%d(%%rip)\n", table, pos );
        break;
    case CPU_SPARC:
        if ( !UsePIC )
        {
            output( "\tsethi %%hi(%s+%d), %%g1\n", table, pos );
            output( "\tld [%%g1+%%lo(%s+%d)], %%g1\n", table, pos );
            output( "\tjmp %%g1\n" );
            output( "\tnop\n" );
        }
        else
        {
            /* Hmpf.  Stupid sparc assembler always interprets global variable
               names as GOT offsets, so we have to do it the long way ... */
            output( "\tsave %%sp, -96, %%sp\n" );
            output( "0:\tcall 1f\n" );
            output( "\tnop\n" );
            output( "1:\tsethi %%hi(%s+%d-0b), %%g1\n", table, pos );
            output( "\tor %%g1, %%lo(%s+%d-0b), %%g1\n", table, pos );
            output( "\tld [%%g1+%%o7], %%g1\n" );
            output( "\tjmp %%g1\n" );
            output( "\trestore\n" );
        }
        break;
    case CPU_ARM:
        output( "\tldr IP,[PC,#0]\n");
        output( "\tldr PC,[IP,#%d]\n", pos);
        output( "\t.long %s\n", table );
        break;
    case CPU_ARM64:
        output( "\tadr x9, 1f\n" );
        output( "\tldur x9, [x9, #0]\n" );
        if (pos & 0xf000) output( "\tadd x9, x9, #%u\n", pos & 0xf000 );
        if (pos & 0x0f00) output( "\tadd x9, x9, #%u\n", pos & 0x0f00 );
        if (pos & 0x00f0) output( "\tadd x9, x9, #%u\n", pos & 0x00f0 );
        if (pos & 0x000f) output( "\tadd x9, x9, #%u\n", pos & 0x000f );
        output( "\tldur x9, [x9, #0]\n" );
        output( "\tbr x9\n" );
        output( "1:\t.quad %s\n", table );
        break;
    case CPU_POWERPC:
        output( "\tmr %s, %s\n", ppc_reg(0), ppc_reg(31) );
        if (target_platform == PLATFORM_APPLE)
        {
            output( "\tlis %s, ha16(%s+%d+32768)\n", ppc_reg(31), table, pos );
            output( "\tla  %s, lo16(%s+%d)(%s)\n", ppc_reg(31), table, pos, ppc_reg(31) );
        }
        else
        {
            output( "\tlis %s, (%s+%d+32768)@h\n", ppc_reg(31), table, pos );
            output( "\tla  %s, (%s+%d)@l(%s)\n", ppc_reg(31), table, pos, ppc_reg(31) );
        }
        output( "\tlwz   %s, 0(%s)\n", ppc_reg(31), ppc_reg(31) );
        output( "\tmtctr %s\n", ppc_reg(31) );
        output( "\tmr    %s, %s\n", ppc_reg(31), ppc_reg(0) );
        output( "\tbctr\n" );
        break;
    }
    output_cfi( ".cfi_endproc" );
    output_function_size( name );
}
예제 #29
0
파일: res32.c 프로젝트: bilboed/wine
/* output the resource definitions */
void output_resources( DLLSPEC *spec )
{
    int k, nb_id_types;
    unsigned int i, n;
    struct res_tree *tree;
    struct res_type *type;
    struct res_name *name;
    const struct resource *res;

    if (!spec->nb_resources) return;

    tree = build_resource_tree( spec, NULL );

    /* output the resource directories */

    output( "\n/* resources */\n\n" );
    output( "\t.data\n" );
    output( "\t.align %d\n", get_alignment(get_ptr_size()) );
    output( ".L__wine_spec_resources:\n" );

    for (i = nb_id_types = 0, type = tree->types; i < tree->nb_types; i++, type++)
        if (!type->type->str) nb_id_types++;

    output_res_dir( tree->nb_types - nb_id_types, nb_id_types );

    /* dump the type directory */

    for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
        output( "\t.long 0x%08x,0x%08x\n",
                 type->name_offset, type->dir_offset | 0x80000000 );

    /* dump the names and languages directories */

    for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
    {
        output_res_dir( type->nb_names - type->nb_id_names, type->nb_id_names );
        for (n = 0, name = type->names; n < type->nb_names; n++, name++)
            output( "\t.long 0x%08x,0x%08x\n",
                     name->name_offset, name->dir_offset | 0x80000000 );

        for (n = 0, name = type->names; n < type->nb_names; n++, name++)
        {
            output_res_dir( 0, name->nb_languages );
            for (k = 0, res = name->res; k < name->nb_languages; k++, res++)
                output( "\t.long 0x%08x,0x%08x\n", res->lang, res->data_offset );
        }
    }

    /* dump the resource data entries */

    for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
        output( "\t.long .L__wine_spec_res_%d-.L__wine_spec_rva_base,%u,0,0\n",
                i, (res->data_size + 3) & ~3 );

    /* dump the name strings */

    for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
    {
        if (type->type->str) output_string( type->type->str );
        for (n = 0, name = type->names; n < type->nb_names; n++, name++)
            if (name->name->str) output_string( name->name->str );
    }

    /* resource data */

    for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
    {
        output( "\n\t.align %d\n", get_alignment(get_ptr_size()) );
        output( ".L__wine_spec_res_%d:\n", i );
        dump_res_data( res );
    }
    output( ".L__wine_spec_resources_end:\n" );
    output( "\t.byte 0\n" );

    free_resource_tree( tree );
}
예제 #30
0
/*******************************************************************
 *         output_stubs
 *
 * Output the functions for stub entry points
 */
void output_stubs( DLLSPEC *spec )
{
    const char *name, *exp_name;
    int i, count;

    if (!has_stubs( spec )) return;

    output( "\n/* stub functions */\n\n" );
    output( "\t.text\n" );

    for (i = count = 0; i < spec->nb_entry_points; i++)
    {
        ORDDEF *odp = &spec->entry_points[i];
        if (odp->type != TYPE_STUB) continue;

        name = get_stub_name( odp, spec );
        exp_name = odp->name ? odp->name : odp->export_name;
        output( "\t.align %d\n", get_alignment(4) );
        output( "\t%s\n", func_declaration(name) );
        output( "%s:\n", asm_name(name) );
        output_cfi( ".cfi_startproc" );

        switch (target_cpu)
        {
        case CPU_x86:
            /* flesh out the stub a bit to make safedisc happy */
            output(" \tnop\n" );
            output(" \tnop\n" );
            output(" \tnop\n" );
            output(" \tnop\n" );
            output(" \tnop\n" );
            output(" \tnop\n" );
            output(" \tnop\n" );
            output(" \tnop\n" );
            output(" \tnop\n" );

            output( "\tsubl $12,%%esp\n" );
            output_cfi( ".cfi_adjust_cfa_offset 12" );
            if (UsePIC)
            {
                output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") );
                output( "1:" );
                if (exp_name)
                {
                    output( "\tleal .L%s_string-1b(%%eax),%%ecx\n", name );
                    output( "\tmovl %%ecx,4(%%esp)\n" );
                    count++;
                }
                else
                    output( "\tmovl $%d,4(%%esp)\n", odp->ordinal );
                output( "\tleal .L__wine_spec_file_name-1b(%%eax),%%ecx\n" );
                output( "\tmovl %%ecx,(%%esp)\n" );
            }
            else
            {
                if (exp_name)
                {
                    output( "\tmovl $.L%s_string,4(%%esp)\n", name );
                    count++;
                }
                else
                    output( "\tmovl $%d,4(%%esp)\n", odp->ordinal );
                output( "\tmovl $.L__wine_spec_file_name,(%%esp)\n" );
            }
            output( "\tcall %s\n", asm_name("__wine_spec_unimplemented_stub") );
            break;
        case CPU_x86_64:
            output( "\tsubq $8,%%rsp\n" );
            output_cfi( ".cfi_adjust_cfa_offset 8" );
            output( "\tleaq .L__wine_spec_file_name(%%rip),%%rdi\n" );
            if (exp_name)
            {
                output( "leaq .L%s_string(%%rip),%%rsi\n", name );
                count++;
            }
            else
                output( "\tmovq $%d,%%rsi\n", odp->ordinal );
            output( "\tcall %s\n", asm_name("__wine_spec_unimplemented_stub") );
            break;
        case CPU_ARM:
            output( "\tldr r0,[PC,#0]\n");
            output( "\tmov PC,PC\n");
            output( "\t.long .L__wine_spec_file_name\n" );
            output( "\tldr r1,[PC,#0]\n");
            output( "\tmov PC,PC\n");
            if (exp_name)
            {
                output( "\t.long .L%s_string\n", name );
                count++;
            }
            else
                output( "\t.long %d\n", odp->ordinal );
            output( "\tbl %s\n", asm_name("__wine_spec_unimplemented_stub") );
            break;
        default:
            assert(0);
        }
        output_cfi( ".cfi_endproc" );
        output_function_size( name );
    }

    if (count)
    {
        output( "\t%s\n", get_asm_string_section() );
        for (i = 0; i < spec->nb_entry_points; i++)
        {
            ORDDEF *odp = &spec->entry_points[i];
            if (odp->type != TYPE_STUB) continue;
            exp_name = odp->name ? odp->name : odp->export_name;
            if (exp_name)
            {
                name = get_stub_name( odp, spec );
                output( ".L%s_string:\n", name );
                output( "\t%s \"%s\"\n", get_asm_string_keyword(), exp_name );
            }
        }
    }
}