winebuild: Add a --builtin option to mark PE files as builtins.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2019-12-18 21:05:27 +01:00
parent 1eba86fccc
commit 9dc348a071
4 changed files with 51 additions and 6 deletions

View File

@ -320,6 +320,7 @@ extern void output_spec16_file( DLLSPEC *spec );
extern void output_fake_module16( DLLSPEC *spec16 );
extern void output_res_o_file( DLLSPEC *spec );
extern void output_asm_relays16(void);
extern void make_builtin_files( char *argv[] );
extern void add_16bit_exports( DLLSPEC *spec32, DLLSPEC *spec16 );
extern int parse_spec_file( FILE *file, DLLSPEC *spec );

View File

@ -113,6 +113,7 @@ enum exec_mode_values
MODE_EXE,
MODE_DEF,
MODE_IMPLIB,
MODE_BUILTIN,
MODE_RESOURCES
};
@ -291,11 +292,12 @@ static const char usage_str[] =
" --version Print the version and exit\n"
" -w, --warnings Turn on warnings\n"
"\nMode options:\n"
" --dll Build a .c file from a .spec or .def file\n"
" --dll Build a library from a .spec file and object files\n"
" --def Build a .def file from a .spec file\n"
" --exe Build a .c file for an executable\n"
" --exe Build an executable from object files\n"
" --implib Build an import library\n"
" --resources Build a .o file for the resource files\n\n"
" --builtin Mark a library as a Wine builtin\n"
" --resources Build a .o or .res file for the resource files\n\n"
"The mode options are mutually exclusive; you must specify one and only one.\n\n";
enum long_options_values
@ -304,6 +306,7 @@ enum long_options_values
LONG_OPT_DEF,
LONG_OPT_EXE,
LONG_OPT_IMPLIB,
LONG_OPT_BUILTIN,
LONG_OPT_ASCMD,
LONG_OPT_CCCMD,
LONG_OPT_EXTERNAL_SYMS,
@ -326,6 +329,7 @@ static const struct option long_options[] =
{ "def", 0, 0, LONG_OPT_DEF },
{ "exe", 0, 0, LONG_OPT_EXE },
{ "implib", 0, 0, LONG_OPT_IMPLIB },
{ "builtin", 0, 0, LONG_OPT_BUILTIN },
{ "as-cmd", 1, 0, LONG_OPT_ASCMD },
{ "cc-cmd", 1, 0, LONG_OPT_CCCMD },
{ "external-symbols", 0, 0, LONG_OPT_EXTERNAL_SYMS },
@ -494,6 +498,9 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec )
case LONG_OPT_IMPLIB:
set_exec_mode( MODE_IMPLIB );
break;
case LONG_OPT_BUILTIN:
set_exec_mode( MODE_BUILTIN );
break;
case LONG_OPT_ASCMD:
as_command = strarray_fromstring( optarg, " " );
break;
@ -677,6 +684,10 @@ int main(int argc, char **argv)
if (!parse_input_file( spec )) break;
output_import_lib( spec, argv );
break;
case MODE_BUILTIN:
if (!argv[0]) fatal_error( "missing file argument for --builtin option\n" );
make_builtin_files( argv );
break;
case MODE_RESOURCES:
load_resources( argv, spec );
output_res_o_file( spec );

View File

@ -48,6 +48,9 @@
int needs_get_pc_thunk = 0;
static const char builtin_signature[32] = "Wine builtin DLL";
static const char fakedll_signature[32] = "Wine placeholder DLL";
/* check if entry point needs a relay thunk */
static inline int needs_relay( const ORDDEF *odp )
{
@ -790,12 +793,11 @@ void output_fake_module( DLLSPEC *spec )
static const unsigned char exe_code_section[] = { 0xb8, 0x01, 0x00, 0x00, 0x00, /* movl $1,%eax */
0xc2, 0x04, 0x00 }; /* ret $4 */
static const char fakedll_signature[] = "Wine placeholder DLL";
const unsigned int page_size = get_page_size();
const unsigned int section_align = page_size;
const unsigned int file_align = 0x200;
const unsigned int reloc_size = 8;
const unsigned int lfanew = (0x40 + sizeof(fakedll_signature) + 15) & ~15;
const unsigned int lfanew = 0x40 + sizeof(fakedll_signature);
const unsigned int nb_sections = 2 + (spec->nb_resources != 0);
const unsigned int text_size = (spec->characteristics & IMAGE_FILE_DLL) ?
sizeof(dll_code_section) : sizeof(exe_code_section);
@ -837,7 +839,6 @@ void output_fake_module( DLLSPEC *spec )
put_dword( lfanew );
put_data( fakedll_signature, sizeof(fakedll_signature) );
align_output( 16 );
put_dword( 0x4550 ); /* Signature */
switch(target_cpu)
@ -1062,3 +1063,31 @@ void output_def_file( DLLSPEC *spec, int import_only )
if (!total) warning( "%s: Import library doesn't export anything\n", spec->file_name );
if (spec32) free_dll_spec( spec32 );
}
/*******************************************************************
* make_builtin_files
*/
void make_builtin_files( char *argv[] )
{
int i, fd;
struct
{
unsigned short e_magic;
unsigned short unused[29];
unsigned int e_lfanew;
} header;
for (i = 0; argv[i]; i++)
{
if ((fd = open( argv[i], O_RDWR | O_BINARY )) == -1) fatal_perror( "Cannot open %s", argv[i] );
if (read( fd, &header, sizeof(header) ) == sizeof(header) && !memcmp( &header.e_magic, "MZ", 2 ))
{
if (header.e_lfanew < sizeof(header) + sizeof(builtin_signature))
fatal_error( "%s: Not enough space (%x) for Wine signature\n", argv[i], header.e_lfanew );
write( fd, builtin_signature, sizeof(builtin_signature) );
}
else fatal_error( "%s: Unrecognized file format\n", argv[i] );
close( fd );
}
}

View File

@ -51,6 +51,10 @@ Build a .a import library from a spec file. The .spec file is
specified via the \fB-E\fR option. If the output library name ends
in .delay.a, a delayed import library is built.
.TP
.BI \--builtin
Mark a PE module as a Wine builtin module, by adding the "Wine builtin
DLL" signature string after the DOS header.
.TP
.B \--resources
Generate a .o file containing all the input resources. This is useful
when building with a PE compiler, since the PE binutils cannot handle