/******************************************************************* * BuildSpec32File * * Build a Win32 C file from a spec file. */ void BuildSpec32File( DLLSPEC *spec ) { resolve_imports( spec ); output_standard_file_header(); output_module( spec ); output_stubs( spec ); output_exports( spec ); output_imports( spec ); if (is_undefined( "__wine_call_from_regs" )) output_asm_relays(); output_resources( spec ); output_gnu_stack_note(); }
void generate_stubs(int argc, char *argv[]) { for (int i = 2; i < argc; ++i) process_file(argv[i]); try { load_nids(argv[1]); } catch (const std::runtime_error &e) { std::cerr << argv[2] << ": " << e.what() << std::endl; exit(1); } output_stubs("__stubs.S"); }
/******************************************************************* * output_spec16_file * * Output the complete data for a spec 16-bit file. */ void output_spec16_file( DLLSPEC *spec16 ) { DLLSPEC *spec32 = alloc_dll_spec(); resolve_imports( spec16 ); add_16bit_exports( spec32, spec16 ); output_standard_file_header(); output_module( spec32 ); output_module16( spec16 ); output_stubs( spec16 ); output_exports( spec32 ); output_imports( spec16 ); if (is_undefined( "__wine_call_from_16" )) output_asm_relays16(); if (spec16->main_module) { output( "\n\t%s\n", get_asm_string_section() ); output( ".L__wine_spec_main_module:\n" ); output( "\t%s \"%s\"\n", get_asm_string_keyword(), spec16->main_module ); } output_gnu_stack_note(); free_dll_spec( spec32 ); output("%s:/*?*/\n", asm_name("_end")); }
/******************************************************************* * BuildSpec32File * * Build a Win32 C file from a spec file. */ void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) { int machine = 0; unsigned int page_size = get_page_size(); resolve_imports( spec ); output_standard_file_header( outfile ); /* Reserve some space for the PE header */ fprintf( outfile, "\t.text\n" ); fprintf( outfile, "\t.align %d\n", get_alignment(page_size) ); fprintf( outfile, "__wine_spec_pe_header:\n" ); if (target_platform == PLATFORM_APPLE) fprintf( outfile, "\t.space 65536\n" ); else fprintf( outfile, "\t.skip 65536\n" ); /* Output the NT header */ fprintf( outfile, "\n\t.data\n" ); fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) ); fprintf( outfile, "%s\n", asm_globl("__wine_spec_nt_header") ); fprintf( outfile, ".L__wine_spec_rva_base:\n" ); fprintf( outfile, "\t.long 0x%04x\n", IMAGE_NT_SIGNATURE ); /* Signature */ switch(target_cpu) { case CPU_x86: machine = IMAGE_FILE_MACHINE_I386; break; case CPU_x86_64: machine = IMAGE_FILE_MACHINE_AMD64; break; case CPU_POWERPC: machine = IMAGE_FILE_MACHINE_POWERPC; break; case CPU_ALPHA: machine = IMAGE_FILE_MACHINE_ALPHA; break; case CPU_SPARC: machine = IMAGE_FILE_MACHINE_UNKNOWN; break; } fprintf( outfile, "\t%s 0x%04x\n", /* Machine */ get_asm_short_keyword(), machine ); fprintf( outfile, "\t%s 0\n", /* NumberOfSections */ get_asm_short_keyword() ); fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */ fprintf( outfile, "\t.long 0\n" ); /* PointerToSymbolTable */ fprintf( outfile, "\t.long 0\n" ); /* NumberOfSymbols */ fprintf( outfile, "\t%s %d\n", /* SizeOfOptionalHeader */ get_asm_short_keyword(), get_ptr_size() == 8 ? IMAGE_SIZEOF_NT_OPTIONAL64_HEADER : IMAGE_SIZEOF_NT_OPTIONAL32_HEADER ); fprintf( outfile, "\t%s 0x%04x\n", /* Characteristics */ get_asm_short_keyword(), spec->characteristics ); fprintf( outfile, "\t%s 0x%04x\n", /* Magic */ get_asm_short_keyword(), get_ptr_size() == 8 ? IMAGE_NT_OPTIONAL_HDR64_MAGIC : IMAGE_NT_OPTIONAL_HDR32_MAGIC ); fprintf( outfile, "\t.byte 0\n" ); /* MajorLinkerVersion */ fprintf( outfile, "\t.byte 0\n" ); /* MinorLinkerVersion */ fprintf( outfile, "\t.long 0\n" ); /* SizeOfCode */ fprintf( outfile, "\t.long 0\n" ); /* SizeOfInitializedData */ fprintf( outfile, "\t.long 0\n" ); /* SizeOfUninitializedData */ /* note: we expand the AddressOfEntryPoint field on 64-bit by overwriting the BaseOfCode field */ fprintf( outfile, "\t%s %s\n", /* AddressOfEntryPoint */ get_asm_ptr_keyword(), asm_name(spec->init_func) ); if (get_ptr_size() == 4) { fprintf( outfile, "\t.long 0\n" ); /* BaseOfCode */ fprintf( outfile, "\t.long 0\n" ); /* BaseOfData */ } fprintf( outfile, "\t%s __wine_spec_pe_header\n", /* ImageBase */ get_asm_ptr_keyword() ); fprintf( outfile, "\t.long %u\n", page_size ); /* SectionAlignment */ fprintf( outfile, "\t.long %u\n", page_size ); /* FileAlignment */ fprintf( outfile, "\t%s 1,0\n", /* Major/MinorOperatingSystemVersion */ get_asm_short_keyword() ); fprintf( outfile, "\t%s 0,0\n", /* Major/MinorImageVersion */ get_asm_short_keyword() ); fprintf( outfile, "\t%s %u,%u\n", /* Major/MinorSubsystemVersion */ get_asm_short_keyword(), spec->subsystem_major, spec->subsystem_minor ); fprintf( outfile, "\t.long 0\n" ); /* Win32VersionValue */ fprintf( outfile, "\t.long %s-.L__wine_spec_rva_base\n", /* SizeOfImage */ asm_name("_end") ); fprintf( outfile, "\t.long %u\n", page_size ); /* SizeOfHeaders */ fprintf( outfile, "\t.long 0\n" ); /* CheckSum */ fprintf( outfile, "\t%s 0x%04x\n", /* Subsystem */ get_asm_short_keyword(), spec->subsystem ); fprintf( outfile, "\t%s 0\n", /* DllCharacteristics */ get_asm_short_keyword() ); fprintf( outfile, "\t%s %u,%u\n", /* SizeOfStackReserve/Commit */ get_asm_ptr_keyword(), (spec->stack_size ? spec->stack_size : 1024) * 1024, page_size ); fprintf( outfile, "\t%s %u,%u\n", /* SizeOfHeapReserve/Commit */ get_asm_ptr_keyword(), (spec->heap_size ? spec->heap_size : 1024) * 1024, page_size ); fprintf( outfile, "\t.long 0\n" ); /* LoaderFlags */ fprintf( outfile, "\t.long 16\n" ); /* NumberOfRvaAndSizes */ if (spec->base <= spec->limit) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] */ fprintf( outfile, "\t.long .L__wine_spec_exports-.L__wine_spec_rva_base," ".L__wine_spec_exports_end-.L__wine_spec_exports\n" ); else fprintf( outfile, "\t.long 0,0\n" ); if (has_imports()) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] */ fprintf( outfile, "\t.long .L__wine_spec_imports-.L__wine_spec_rva_base," ".L__wine_spec_imports_end-.L__wine_spec_imports\n" ); else fprintf( outfile, "\t.long 0,0\n" ); if (spec->nb_resources) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] */ fprintf( outfile, "\t.long .L__wine_spec_resources-.L__wine_spec_rva_base," ".L__wine_spec_resources_end-.L__wine_spec_resources\n" ); else fprintf( outfile, "\t.long 0,0\n" ); fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[3] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[4] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[5] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[6] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[7] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[8] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[9] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[10] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[11] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[12] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[13] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[14] */ fprintf( outfile, "\t.long 0,0\n" ); /* DataDirectory[15] */ fprintf( outfile, "\n\t%s\n", get_asm_string_section() ); fprintf( outfile, "%s\n", asm_globl("__wine_spec_file_name") ); fprintf( outfile, ".L__wine_spec_file_name:\n" ); fprintf( outfile, "\t%s \"%s\"\n", get_asm_string_keyword(), spec->file_name ); if (target_platform == PLATFORM_APPLE) fprintf( outfile, "\t.lcomm %s,4\n", asm_name("_end") ); output_stubs( outfile, spec ); output_exports( outfile, spec ); output_imports( outfile, spec ); output_resources( outfile, spec ); output_asm_constructor( outfile, "__wine_spec_init_ctor" ); output_gnu_stack_note( outfile ); }