winebuild: Add support for generating data-only DLLs.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3eca3516ad
commit
39f6ab55a9
|
@ -283,6 +283,7 @@ extern void output_resources( DLLSPEC *spec );
|
||||||
extern void output_bin_resources( DLLSPEC *spec, unsigned int start_rva );
|
extern void output_bin_resources( DLLSPEC *spec, unsigned int start_rva );
|
||||||
extern void output_spec32_file( DLLSPEC *spec );
|
extern void output_spec32_file( DLLSPEC *spec );
|
||||||
extern void output_fake_module( DLLSPEC *spec );
|
extern void output_fake_module( DLLSPEC *spec );
|
||||||
|
extern void output_data_module( DLLSPEC *spec );
|
||||||
extern void output_def_file( DLLSPEC *spec, int import_only );
|
extern void output_def_file( DLLSPEC *spec, int import_only );
|
||||||
extern void load_res16_file( const char *name, DLLSPEC *spec );
|
extern void load_res16_file( const char *name, DLLSPEC *spec );
|
||||||
extern void output_res16_data( DLLSPEC *spec );
|
extern void output_res16_data( DLLSPEC *spec );
|
||||||
|
@ -329,6 +330,7 @@ extern int use_msvcrt;
|
||||||
extern int unix_lib;
|
extern int unix_lib;
|
||||||
extern int safe_seh;
|
extern int safe_seh;
|
||||||
extern int prefer_native;
|
extern int prefer_native;
|
||||||
|
extern int data_only;
|
||||||
|
|
||||||
extern char *input_file_name;
|
extern char *input_file_name;
|
||||||
extern char *spec_file_name;
|
extern char *spec_file_name;
|
||||||
|
|
|
@ -46,6 +46,7 @@ int use_msvcrt = 0;
|
||||||
int unix_lib = 0;
|
int unix_lib = 0;
|
||||||
int safe_seh = 0;
|
int safe_seh = 0;
|
||||||
int prefer_native = 0;
|
int prefer_native = 0;
|
||||||
|
int data_only = 0;
|
||||||
|
|
||||||
struct target target = { 0 };
|
struct target target = { 0 };
|
||||||
|
|
||||||
|
@ -198,6 +199,7 @@ static const char usage_str[] =
|
||||||
" -b, --target=TARGET Specify target CPU and platform for cross-compiling\n"
|
" -b, --target=TARGET Specify target CPU and platform for cross-compiling\n"
|
||||||
" -B PREFIX Look for build tools in the PREFIX directory\n"
|
" -B PREFIX Look for build tools in the PREFIX directory\n"
|
||||||
" --cc-cmd=CC C compiler to use for assembling (default: fall back to --as-cmd)\n"
|
" --cc-cmd=CC C compiler to use for assembling (default: fall back to --as-cmd)\n"
|
||||||
|
" --data-only Generate a data-only dll (i.e. without any executable code)\n"
|
||||||
" -d, --delay-lib=LIB Import the specified library in delayed mode\n"
|
" -d, --delay-lib=LIB Import the specified library in delayed mode\n"
|
||||||
" -D SYM Ignored for C flags compatibility\n"
|
" -D SYM Ignored for C flags compatibility\n"
|
||||||
" -e, --entry=FUNC Set the DLL entry point function (default: DllMain)\n"
|
" -e, --entry=FUNC Set the DLL entry point function (default: DllMain)\n"
|
||||||
|
@ -251,6 +253,7 @@ enum long_options_values
|
||||||
LONG_OPT_BUILTIN,
|
LONG_OPT_BUILTIN,
|
||||||
LONG_OPT_ASCMD,
|
LONG_OPT_ASCMD,
|
||||||
LONG_OPT_CCCMD,
|
LONG_OPT_CCCMD,
|
||||||
|
LONG_OPT_DATA_ONLY,
|
||||||
LONG_OPT_EXTERNAL_SYMS,
|
LONG_OPT_EXTERNAL_SYMS,
|
||||||
LONG_OPT_FAKE_MODULE,
|
LONG_OPT_FAKE_MODULE,
|
||||||
LONG_OPT_FIXUP_CTORS,
|
LONG_OPT_FIXUP_CTORS,
|
||||||
|
@ -284,6 +287,7 @@ static const struct long_option long_options[] =
|
||||||
/* other long options */
|
/* other long options */
|
||||||
{ "as-cmd", 1, LONG_OPT_ASCMD },
|
{ "as-cmd", 1, LONG_OPT_ASCMD },
|
||||||
{ "cc-cmd", 1, LONG_OPT_CCCMD },
|
{ "cc-cmd", 1, LONG_OPT_CCCMD },
|
||||||
|
{ "data-only", 0, LONG_OPT_DATA_ONLY },
|
||||||
{ "external-symbols", 0, LONG_OPT_EXTERNAL_SYMS },
|
{ "external-symbols", 0, LONG_OPT_EXTERNAL_SYMS },
|
||||||
{ "fake-module", 0, LONG_OPT_FAKE_MODULE },
|
{ "fake-module", 0, LONG_OPT_FAKE_MODULE },
|
||||||
{ "large-address-aware", 0, LONG_OPT_LARGE_ADDRESS_AWARE },
|
{ "large-address-aware", 0, LONG_OPT_LARGE_ADDRESS_AWARE },
|
||||||
|
@ -483,6 +487,9 @@ static void option_callback( int optc, char *optarg )
|
||||||
case LONG_OPT_CCCMD:
|
case LONG_OPT_CCCMD:
|
||||||
cc_command = strarray_fromstring( optarg, " " );
|
cc_command = strarray_fromstring( optarg, " " );
|
||||||
break;
|
break;
|
||||||
|
case LONG_OPT_DATA_ONLY:
|
||||||
|
data_only = 1;
|
||||||
|
break;
|
||||||
case LONG_OPT_FAKE_MODULE:
|
case LONG_OPT_FAKE_MODULE:
|
||||||
fake_module = 1;
|
fake_module = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -637,6 +644,11 @@ int main(int argc, char **argv)
|
||||||
output_fake_module( spec );
|
output_fake_module( spec );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (data_only)
|
||||||
|
{
|
||||||
|
output_data_module( spec );
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (!is_pe())
|
if (!is_pe())
|
||||||
{
|
{
|
||||||
files = load_import_libs( files );
|
files = load_import_libs( files );
|
||||||
|
|
|
@ -628,6 +628,12 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data_only && !(odp->flags & FLAG_FORWARD))
|
||||||
|
{
|
||||||
|
error( "Only forwarded entry points are allowed in data-only mode\n" );
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (ordinal != -1)
|
if (ordinal != -1)
|
||||||
{
|
{
|
||||||
if (!ordinal)
|
if (!ordinal)
|
||||||
|
|
|
@ -796,6 +796,7 @@ static struct
|
||||||
unsigned int file_align;
|
unsigned int file_align;
|
||||||
unsigned int sec_count;
|
unsigned int sec_count;
|
||||||
unsigned int exp_count;
|
unsigned int exp_count;
|
||||||
|
unsigned int code_size;
|
||||||
struct dir_data dir[16];
|
struct dir_data dir[16];
|
||||||
struct sec_data sec[8];
|
struct sec_data sec[8];
|
||||||
struct exp_data exp[8];
|
struct exp_data exp[8];
|
||||||
|
@ -846,94 +847,97 @@ static unsigned int flush_output_to_section( const char *name, int dir_idx, unsi
|
||||||
return sec->size;
|
return sec->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
static void output_pe_exports( DLLSPEC *spec )
|
||||||
* output_fake_module
|
|
||||||
*
|
|
||||||
* Build a fake binary module from a spec file.
|
|
||||||
*/
|
|
||||||
void output_fake_module( DLLSPEC *spec )
|
|
||||||
{
|
{
|
||||||
static const unsigned char dll_code_section[] = { 0x31, 0xc0, /* xor %eax,%eax */
|
unsigned int i, exp_count = get_exports_count( spec );
|
||||||
0xc2, 0x0c, 0x00 }; /* ret $12 */
|
unsigned int exp_rva = current_rva() + 40; /* sizeof(IMAGE_EXPORT_DIRECTORY) */
|
||||||
|
unsigned int pos, str_rva = exp_rva + 4 * exp_count + 6 * spec->nb_names;
|
||||||
|
|
||||||
static const unsigned char exe_code_section[] = { 0xb8, 0x01, 0x00, 0x00, 0x00, /* movl $1,%eax */
|
if (!spec->nb_entry_points) return;
|
||||||
0xc2, 0x04, 0x00 }; /* ret $4 */
|
|
||||||
const unsigned int page_size = get_page_size();
|
|
||||||
const unsigned int lfanew = 0x40 + sizeof(fakedll_signature);
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
resolve_imports( spec );
|
|
||||||
init_output_buffer();
|
init_output_buffer();
|
||||||
|
put_dword( 0 ); /* Characteristics */
|
||||||
pe.section_align = page_size;
|
put_dword( hash_filename(spec->file_name) ); /* TimeDateStamp */
|
||||||
pe.file_align = 0x200;
|
put_word( 0 ); /* MajorVersion */
|
||||||
|
put_word( 0 ); /* MinorVersion */
|
||||||
/* .text section */
|
put_dword( str_rva ); /* Name */
|
||||||
if (spec->characteristics & IMAGE_FILE_DLL) put_data( dll_code_section, sizeof(dll_code_section) );
|
put_dword( spec->base ); /* Base */
|
||||||
else put_data( exe_code_section, sizeof(exe_code_section) );
|
put_dword( exp_count ); /* NumberOfFunctions */
|
||||||
flush_output_to_section( ".text", -1, 0x60000020 /* CNT_CODE|MEM_EXECUTE|MEM_READ */ );
|
put_dword( spec->nb_names ); /* NumberOfNames */
|
||||||
|
put_dword( exp_rva ); /* AddressOfFunctions */
|
||||||
if (spec->type == SPEC_WIN16)
|
if (spec->nb_names)
|
||||||
{
|
{
|
||||||
add_export( current_rva(), "__wine_spec_dos_header" );
|
put_dword( exp_rva + 4 * exp_count ); /* AddressOfNames */
|
||||||
|
put_dword( exp_rva + 4 * exp_count + 4 * spec->nb_names ); /* AddressOfNameOrdinals */
|
||||||
/* .rodata section */
|
}
|
||||||
output_fake_module16( spec );
|
else
|
||||||
if (spec->main_module)
|
{
|
||||||
{
|
put_dword( 0 ); /* AddressOfNames */
|
||||||
add_export( current_rva() + output_buffer_pos, "__wine_spec_main_module" );
|
put_dword( 0 ); /* AddressOfNameOrdinals */
|
||||||
put_data( spec->main_module, strlen(spec->main_module) + 1 );
|
|
||||||
}
|
|
||||||
flush_output_to_section( ".rodata", -1, 0x40000040 /* CNT_INITIALIZED_DATA|MEM_READ */ );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pe.exp_count)
|
/* functions */
|
||||||
|
for (i = 0, pos = str_rva + strlen(spec->file_name) + 1; i < spec->nb_names; i++)
|
||||||
|
pos += strlen( spec->names[i]->name ) + 1;
|
||||||
|
for (i = spec->base; i <= spec->limit; i++)
|
||||||
{
|
{
|
||||||
/* .edata section */
|
ORDDEF *odp = spec->ordinals[i];
|
||||||
unsigned int exp_rva = current_rva() + 40; /* sizeof(IMAGE_EXPORT_DIRECTORY) */
|
if (odp && (odp->flags & FLAG_FORWARD))
|
||||||
unsigned int pos, str_rva = exp_rva + 10 * pe.exp_count;
|
|
||||||
|
|
||||||
put_dword( 0 ); /* Characteristics */
|
|
||||||
put_dword( hash_filename(spec->file_name) ); /* TimeDateStamp */
|
|
||||||
put_word( 0 ); /* MajorVersion */
|
|
||||||
put_word( 0 ); /* MinorVersion */
|
|
||||||
put_dword( str_rva ); /* Name */
|
|
||||||
put_dword( 1 ); /* Base */
|
|
||||||
put_dword( pe.exp_count ); /* NumberOfFunctions */
|
|
||||||
put_dword( pe.exp_count ); /* NumberOfNames */
|
|
||||||
put_dword( exp_rva ); /* AddressOfFunctions */
|
|
||||||
put_dword( exp_rva + 4 * pe.exp_count ); /* AddressOfNames */
|
|
||||||
put_dword( exp_rva + 8 * pe.exp_count ); /* AddressOfNameOrdinals */
|
|
||||||
|
|
||||||
/* functions */
|
|
||||||
for (i = 0; i < pe.exp_count; i++) put_dword( pe.exp[i].rva );
|
|
||||||
/* names */
|
|
||||||
for (i = 0, pos = str_rva + strlen(spec->file_name) + 1; i < pe.exp_count; i++)
|
|
||||||
{
|
{
|
||||||
put_dword( pos );
|
put_dword( pos );
|
||||||
pos += strlen( pe.exp[i].name ) + 1;
|
pos += strlen(odp->link_name) + 1;
|
||||||
}
|
}
|
||||||
/* ordinals */
|
else put_dword( 0 );
|
||||||
for (i = 0; i < pe.exp_count; i++) put_word( i );
|
}
|
||||||
/* strings */
|
|
||||||
put_data( spec->file_name, strlen(spec->file_name) + 1 );
|
/* names */
|
||||||
for (i = 0; i < pe.exp_count; i++) put_data( pe.exp[i].name, strlen(pe.exp[i].name) + 1 );
|
for (i = 0, pos = str_rva + strlen(spec->file_name) + 1; i < spec->nb_names; i++)
|
||||||
flush_output_to_section( ".edata", 0 /* IMAGE_DIRECTORY_ENTRY_EXPORT */,
|
{
|
||||||
|
put_dword( pos );
|
||||||
|
pos += strlen(spec->names[i]->name) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ordinals */
|
||||||
|
for (i = 0; i < spec->nb_names; i++) put_word( spec->names[i]->ordinal - spec->base );
|
||||||
|
|
||||||
|
/* strings */
|
||||||
|
put_data( spec->file_name, strlen(spec->file_name) + 1 );
|
||||||
|
for (i = 0; i < spec->nb_names; i++)
|
||||||
|
put_data( spec->names[i]->name, strlen(spec->names[i]->name) + 1 );
|
||||||
|
|
||||||
|
for (i = spec->base; i <= spec->limit; i++)
|
||||||
|
{
|
||||||
|
ORDDEF *odp = spec->ordinals[i];
|
||||||
|
if (odp && (odp->flags & FLAG_FORWARD)) put_data( odp->link_name, strlen(odp->link_name) + 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
flush_output_to_section( ".edata", 0 /* IMAGE_DIRECTORY_ENTRY_EXPORT */,
|
||||||
|
0x40000040 /* CNT_INITIALIZED_DATA|MEM_READ */ );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void output_pe_file( DLLSPEC *spec, const char signature[32] )
|
||||||
|
{
|
||||||
|
const unsigned int lfanew = 0x40 + 32;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
init_output_buffer();
|
||||||
|
|
||||||
|
/* .rsrc section */
|
||||||
|
if (spec->type == SPEC_WIN32)
|
||||||
|
{
|
||||||
|
output_bin_resources( spec, current_rva() );
|
||||||
|
flush_output_to_section( ".rsrc", 2 /* IMAGE_DIRECTORY_ENTRY_RESOURCE */,
|
||||||
0x40000040 /* CNT_INITIALIZED_DATA|MEM_READ */ );
|
0x40000040 /* CNT_INITIALIZED_DATA|MEM_READ */ );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .reloc section */
|
/* .reloc section */
|
||||||
put_dword( 0 ); /* VirtualAddress */
|
if (pe.code_size)
|
||||||
put_dword( 0 ); /* Size */
|
|
||||||
flush_output_to_section( ".reloc", 5 /* IMAGE_DIRECTORY_ENTRY_BASERELOC */,
|
|
||||||
0x42000040 /* CNT_INITIALIZED_DATA|MEM_DISCARDABLE|MEM_READ */ );
|
|
||||||
|
|
||||||
if (spec->type == SPEC_WIN32)
|
|
||||||
{
|
{
|
||||||
/* .rsrc section */
|
put_dword( 0 ); /* VirtualAddress */
|
||||||
output_bin_resources( spec, current_rva() );
|
put_dword( 0 ); /* Size */
|
||||||
flush_output_to_section( ".rsrc", 2 /* IMAGE_DIRECTORY_ENTRY_RESOURCE */,
|
flush_output_to_section( ".reloc", 5 /* IMAGE_DIRECTORY_ENTRY_BASERELOC */,
|
||||||
0x40000040 /* CNT_INITIALIZED_DATA|MEM_READ */ );
|
0x42000040 /* CNT_INITIALIZED_DATA|MEM_DISCARDABLE|MEM_READ */ );
|
||||||
}
|
}
|
||||||
|
|
||||||
put_word( 0x5a4d ); /* e_magic */
|
put_word( 0x5a4d ); /* e_magic */
|
||||||
|
@ -961,7 +965,7 @@ void output_fake_module( DLLSPEC *spec )
|
||||||
put_dword( 0 );
|
put_dword( 0 );
|
||||||
put_dword( lfanew );
|
put_dword( lfanew );
|
||||||
|
|
||||||
put_data( fakedll_signature, sizeof(fakedll_signature) );
|
put_data( signature, 32 );
|
||||||
|
|
||||||
put_dword( 0x4550 ); /* Signature */
|
put_dword( 0x4550 ); /* Signature */
|
||||||
switch (target.cpu)
|
switch (target.cpu)
|
||||||
|
@ -984,11 +988,11 @@ void output_fake_module( DLLSPEC *spec )
|
||||||
IMAGE_NT_OPTIONAL_HDR32_MAGIC ); /* Magic */
|
IMAGE_NT_OPTIONAL_HDR32_MAGIC ); /* Magic */
|
||||||
put_byte( 7 ); /* MajorLinkerVersion */
|
put_byte( 7 ); /* MajorLinkerVersion */
|
||||||
put_byte( 10 ); /* MinorLinkerVersion */
|
put_byte( 10 ); /* MinorLinkerVersion */
|
||||||
put_dword( pe.sec[0].size ); /* SizeOfCode */
|
put_dword( pe.code_size ); /* SizeOfCode */
|
||||||
put_dword( 0 ); /* SizeOfInitializedData */
|
put_dword( 0 ); /* SizeOfInitializedData */
|
||||||
put_dword( 0 ); /* SizeOfUninitializedData */
|
put_dword( 0 ); /* SizeOfUninitializedData */
|
||||||
put_dword( pe.sec[0].rva ); /* AddressOfEntryPoint */
|
put_dword( pe.code_size ? pe.sec[0].rva : 0 ); /* AddressOfEntryPoint */
|
||||||
put_dword( pe.sec[0].rva ); /* BaseOfCode */
|
put_dword( pe.code_size ? pe.sec[0].rva : 0 ); /* BaseOfCode */
|
||||||
if (get_ptr_size() == 4) put_dword( 0 ); /* BaseOfData */
|
if (get_ptr_size() == 4) put_dword( 0 ); /* BaseOfData */
|
||||||
put_pword( 0x10000000 ); /* ImageBase */
|
put_pword( 0x10000000 ); /* ImageBase */
|
||||||
put_dword( pe.section_align ); /* SectionAlignment */
|
put_dword( pe.section_align ); /* SectionAlignment */
|
||||||
|
@ -1006,9 +1010,9 @@ void output_fake_module( DLLSPEC *spec )
|
||||||
put_word( spec->subsystem ); /* Subsystem */
|
put_word( spec->subsystem ); /* Subsystem */
|
||||||
put_word( spec->dll_characteristics ); /* DllCharacteristics */
|
put_word( spec->dll_characteristics ); /* DllCharacteristics */
|
||||||
put_pword( (spec->stack_size ? spec->stack_size : 1024) * 1024 ); /* SizeOfStackReserve */
|
put_pword( (spec->stack_size ? spec->stack_size : 1024) * 1024 ); /* SizeOfStackReserve */
|
||||||
put_pword( page_size ); /* SizeOfStackCommit */
|
put_pword( pe.section_align ); /* SizeOfStackCommit */
|
||||||
put_pword( (spec->heap_size ? spec->heap_size : 1024) * 1024 ); /* SizeOfHeapReserve */
|
put_pword( (spec->heap_size ? spec->heap_size : 1024) * 1024 ); /* SizeOfHeapReserve */
|
||||||
put_pword( page_size ); /* SizeOfHeapCommit */
|
put_pword( pe.section_align ); /* SizeOfHeapCommit */
|
||||||
put_dword( 0 ); /* LoaderFlags */
|
put_dword( 0 ); /* LoaderFlags */
|
||||||
put_dword( 16 ); /* NumberOfRvaAndSizes */
|
put_dword( 16 ); /* NumberOfRvaAndSizes */
|
||||||
|
|
||||||
|
@ -1044,6 +1048,97 @@ void output_fake_module( DLLSPEC *spec )
|
||||||
flush_output_buffer( output_file_name ? output_file_name : spec->file_name );
|
flush_output_buffer( output_file_name ? output_file_name : spec->file_name );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* output_fake_module
|
||||||
|
*
|
||||||
|
* Build a fake binary module from a spec file.
|
||||||
|
*/
|
||||||
|
void output_fake_module( DLLSPEC *spec )
|
||||||
|
{
|
||||||
|
static const unsigned char dll_code_section[] = { 0x31, 0xc0, /* xor %eax,%eax */
|
||||||
|
0xc2, 0x0c, 0x00 }; /* ret $12 */
|
||||||
|
|
||||||
|
static const unsigned char exe_code_section[] = { 0xb8, 0x01, 0x00, 0x00, 0x00, /* movl $1,%eax */
|
||||||
|
0xc2, 0x04, 0x00 }; /* ret $4 */
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
resolve_imports( spec );
|
||||||
|
pe.section_align = get_page_size();
|
||||||
|
pe.file_align = 0x200;
|
||||||
|
init_output_buffer();
|
||||||
|
|
||||||
|
/* .text section */
|
||||||
|
if (spec->characteristics & IMAGE_FILE_DLL) put_data( dll_code_section, sizeof(dll_code_section) );
|
||||||
|
else put_data( exe_code_section, sizeof(exe_code_section) );
|
||||||
|
pe.code_size = output_buffer_pos;
|
||||||
|
flush_output_to_section( ".text", -1, 0x60000020 /* CNT_CODE|MEM_EXECUTE|MEM_READ */ );
|
||||||
|
|
||||||
|
if (spec->type == SPEC_WIN16)
|
||||||
|
{
|
||||||
|
add_export( current_rva(), "__wine_spec_dos_header" );
|
||||||
|
|
||||||
|
/* .rdata section */
|
||||||
|
output_fake_module16( spec );
|
||||||
|
if (spec->main_module)
|
||||||
|
{
|
||||||
|
add_export( current_rva() + output_buffer_pos, "__wine_spec_main_module" );
|
||||||
|
put_data( spec->main_module, strlen(spec->main_module) + 1 );
|
||||||
|
}
|
||||||
|
flush_output_to_section( ".rdata", -1, 0x40000040 /* CNT_INITIALIZED_DATA|MEM_READ */ );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .edata section */
|
||||||
|
if (pe.exp_count)
|
||||||
|
{
|
||||||
|
unsigned int exp_rva = current_rva() + 40; /* sizeof(IMAGE_EXPORT_DIRECTORY) */
|
||||||
|
unsigned int pos, str_rva = exp_rva + 10 * pe.exp_count;
|
||||||
|
|
||||||
|
put_dword( 0 ); /* Characteristics */
|
||||||
|
put_dword( hash_filename(spec->file_name) ); /* TimeDateStamp */
|
||||||
|
put_word( 0 ); /* MajorVersion */
|
||||||
|
put_word( 0 ); /* MinorVersion */
|
||||||
|
put_dword( str_rva ); /* Name */
|
||||||
|
put_dword( 1 ); /* Base */
|
||||||
|
put_dword( pe.exp_count ); /* NumberOfFunctions */
|
||||||
|
put_dword( pe.exp_count ); /* NumberOfNames */
|
||||||
|
put_dword( exp_rva ); /* AddressOfFunctions */
|
||||||
|
put_dword( exp_rva + 4 * pe.exp_count ); /* AddressOfNames */
|
||||||
|
put_dword( exp_rva + 8 * pe.exp_count ); /* AddressOfNameOrdinals */
|
||||||
|
|
||||||
|
/* functions */
|
||||||
|
for (i = 0; i < pe.exp_count; i++) put_dword( pe.exp[i].rva );
|
||||||
|
/* names */
|
||||||
|
for (i = 0, pos = str_rva + strlen(spec->file_name) + 1; i < pe.exp_count; i++)
|
||||||
|
{
|
||||||
|
put_dword( pos );
|
||||||
|
pos += strlen( pe.exp[i].name ) + 1;
|
||||||
|
}
|
||||||
|
/* ordinals */
|
||||||
|
for (i = 0; i < pe.exp_count; i++) put_word( i );
|
||||||
|
/* strings */
|
||||||
|
put_data( spec->file_name, strlen(spec->file_name) + 1 );
|
||||||
|
for (i = 0; i < pe.exp_count; i++) put_data( pe.exp[i].name, strlen(pe.exp[i].name) + 1 );
|
||||||
|
flush_output_to_section( ".edata", 0 /* IMAGE_DIRECTORY_ENTRY_EXPORT */,
|
||||||
|
0x40000040 /* CNT_INITIALIZED_DATA|MEM_READ */ );
|
||||||
|
}
|
||||||
|
|
||||||
|
output_pe_file( spec, fakedll_signature );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* output_data_module
|
||||||
|
*
|
||||||
|
* Build a data-only module from a spec file.
|
||||||
|
*/
|
||||||
|
void output_data_module( DLLSPEC *spec )
|
||||||
|
{
|
||||||
|
pe.section_align = pe.file_align = get_page_size();
|
||||||
|
|
||||||
|
output_pe_exports( spec );
|
||||||
|
output_pe_file( spec, builtin_signature );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* output_def_file
|
* output_def_file
|
||||||
|
|
|
@ -644,7 +644,7 @@ DLLSPEC *alloc_dll_spec(void)
|
||||||
spec->type = SPEC_WIN32;
|
spec->type = SPEC_WIN32;
|
||||||
spec->base = MAX_ORDINALS;
|
spec->base = MAX_ORDINALS;
|
||||||
spec->characteristics = IMAGE_FILE_EXECUTABLE_IMAGE;
|
spec->characteristics = IMAGE_FILE_EXECUTABLE_IMAGE;
|
||||||
spec->subsystem = 0;
|
spec->subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
||||||
spec->subsystem_major = 4;
|
spec->subsystem_major = 4;
|
||||||
spec->subsystem_minor = 0;
|
spec->subsystem_minor = 0;
|
||||||
spec->syscall_table = 0;
|
spec->syscall_table = 0;
|
||||||
|
|
|
@ -89,6 +89,11 @@ like \fBas\fR, \fBnm\fR and \fBld\fR.
|
||||||
Specify the C compiler to use to compile assembly files; the default
|
Specify the C compiler to use to compile assembly files; the default
|
||||||
is to instead use the assembler specified with \fB--as-cmd\fR.
|
is to instead use the assembler specified with \fB--as-cmd\fR.
|
||||||
.TP
|
.TP
|
||||||
|
.B \--data-only
|
||||||
|
Build a module that contains only data and resources, and no
|
||||||
|
executable code. With this option, \fBwinebuild\fR directly outputs a
|
||||||
|
PE file, instead of an assembly or object file.
|
||||||
|
.TP
|
||||||
.BI \-d,\ --delay-lib= name
|
.BI \-d,\ --delay-lib= name
|
||||||
Set the delayed import mode for the specified library, which must be
|
Set the delayed import mode for the specified library, which must be
|
||||||
one of the libraries imported with the \fB-l\fR option. Delayed mode
|
one of the libraries imported with the \fB-l\fR option. Delayed mode
|
||||||
|
|
Loading…
Reference in New Issue