Commit ef4a3c3c authored by Alexandre Julliard's avatar Alexandre Julliard

winebuild: Add support for creating a fake dll at compile time.

parent 99037aa9
......@@ -247,10 +247,13 @@ extern void output_imports( DLLSPEC *spec );
extern void output_exports( DLLSPEC *spec );
extern int load_res32_file( const char *name, DLLSPEC *spec );
extern void output_resources( DLLSPEC *spec );
extern void output_bin_resources( DLLSPEC *spec, unsigned int start_rva );
extern void output_fake_module( DLLSPEC *spec );
extern void load_res16_file( const char *name, DLLSPEC *spec );
extern void output_res16_data( DLLSPEC *spec );
extern void output_res16_directory( DLLSPEC *spec );
extern void output_spec16_file( DLLSPEC *spec );
extern void output_fake_module16( DLLSPEC *spec16 );
extern void output_res_o_file( DLLSPEC *spec );
extern void BuildRelays16(void);
......
......@@ -80,6 +80,7 @@ char *spec_file_name = NULL;
FILE *output_file = NULL;
const char *output_file_name = NULL;
static const char *output_file_source_name;
static int fake_module;
char *as_command = NULL;
char *ld_command = NULL;
......@@ -216,6 +217,7 @@ static const char usage_str[] =
" --external-symbols Allow linking to external symbols\n"
" -f FLAGS Compiler flags (only -fPIC is supported)\n"
" -F, --filename=DLLFILE Set the DLL filename (default: from input file name)\n"
" --fake-module Create a fake binary module\n"
" -h, --help Display this help message\n"
" -H, --heap=SIZE Set the heap size for a Win16 dll\n"
" -i, --ignore=SYM[,SYM] Ignore specified symbols when resolving imports\n"
......@@ -255,6 +257,7 @@ enum long_options_values
LONG_OPT_EXE,
LONG_OPT_ASCMD,
LONG_OPT_EXTERNAL_SYMS,
LONG_OPT_FAKE_MODULE,
LONG_OPT_LARGE_ADDRESS_AWARE,
LONG_OPT_LDCMD,
LONG_OPT_NMCMD,
......@@ -276,6 +279,7 @@ static const struct option long_options[] =
{ "exe", 0, 0, LONG_OPT_EXE },
{ "as-cmd", 1, 0, LONG_OPT_ASCMD },
{ "external-symbols", 0, 0, LONG_OPT_EXTERNAL_SYMS },
{ "fake-module", 0, 0, LONG_OPT_FAKE_MODULE },
{ "large-address-aware", 0, 0, LONG_OPT_LARGE_ADDRESS_AWARE },
{ "ld-cmd", 1, 0, LONG_OPT_LDCMD },
{ "nm-cmd", 1, 0, LONG_OPT_NMCMD },
......@@ -451,6 +455,9 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec )
case LONG_OPT_ASCMD:
as_command = xstrdup( optarg );
break;
case LONG_OPT_FAKE_MODULE:
fake_module = 1;
break;
case LONG_OPT_EXTERNAL_SYMS:
link_ext_symbols = 1;
break;
......@@ -607,6 +614,12 @@ int main(int argc, char **argv)
load_resources( argv, spec );
load_import_libs( argv );
if (spec_file_name && !parse_input_file( spec )) break;
if (fake_module)
{
if (spec->type == SPEC_WIN16) output_fake_module16( spec );
else output_fake_module( spec );
break;
}
read_undef_symbols( spec, argv );
switch (spec->type)
{
......
......@@ -476,6 +476,109 @@ void output_resources( DLLSPEC *spec )
free_resource_tree( tree );
}
/* output a Unicode string in binary format */
static void output_bin_string( const WCHAR *name )
{
int i, len = strlenW(name);
put_word( len );
for (i = 0; i < len; i++) put_word( name[i] );
}
/* output a resource directory in binary format */
static inline void output_bin_res_dir( unsigned int nb_names, unsigned int nb_ids )
{
put_dword( 0 ); /* Characteristics */
put_dword( 0 ); /* TimeDateStamp */
put_word( 0 ); /* MajorVersion */
put_word( 0 ); /* MinorVersion */
put_word( nb_names ); /* NumberOfNamedEntries */
put_word( nb_ids ); /* NumberOfIdEntries */
}
/* output the resource definitions in binary format */
void output_bin_resources( DLLSPEC *spec, unsigned int start_rva )
{
int k, nb_id_types;
unsigned int i, n, data_offset;
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, &data_offset );
init_output_buffer();
/* output the resource directories */
for (i = nb_id_types = 0, type = tree->types; i < tree->nb_types; i++, type++)
if (!type->type->str) nb_id_types++;
output_bin_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++)
{
put_dword( type->name_offset );
put_dword( type->dir_offset | 0x80000000 );
}
/* dump the names and languages directories */
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
output_bin_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++)
{
put_dword( name->name_offset );
put_dword( name->dir_offset | 0x80000000 );
}
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
{
output_bin_res_dir( 0, name->nb_languages );
for (k = 0, res = name->res; k < name->nb_languages; k++, res++)
{
put_dword( res->lang );
put_dword( res->data_offset );
}
}
}
/* dump the resource data entries */
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
{
put_dword( data_offset + start_rva );
put_dword( (res->data_size + 3) & ~3 );
put_dword( 0 );
put_dword( 0 );
data_offset += (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_bin_string( type->type->str );
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
if (name->name->str) output_bin_string( name->name->str );
}
/* resource data */
align_output( 4 );
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
{
put_data( res->data, res->data_size );
align_output( 4 );
}
free_resource_tree( tree );
}
static unsigned int get_resource_header_size( const struct resource *res )
{
unsigned int size = 5 * sizeof(unsigned int) + 2 * sizeof(unsigned short);
......
......@@ -896,3 +896,13 @@ void output_spec16_file( DLLSPEC *spec16 )
output_gnu_stack_note();
free_dll_spec( spec32 );
}
/*******************************************************************
* output_fake_module16
*
* Create a fake 16-bit binary module.
*/
void output_fake_module16( DLLSPEC *spec16 )
{
warning( "not implemented yet\n" );
}
......@@ -108,6 +108,11 @@ specification must be used instead).
.BI \-f\ flags
Ignored for compatibility with the C compiler.
.TP
.B \--fake-module
Create a fake PE module for a dll or exe, instead of the normal
assembly or object file. The PE module contains the resources for the
module, but no executable code.
.TP
.BI \-F,\ --filename= filename
Set the file name of the module. The default is to use the base name
of the spec file (without any extension).
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment