Output the resource data in assembly too.
This commit is contained in:
parent
d7f6424199
commit
41177ca0bd
|
@ -199,7 +199,7 @@ extern int resolve_imports( DLLSPEC *spec );
|
|||
extern int has_imports(void);
|
||||
extern void output_imports( FILE *outfile, DLLSPEC *spec );
|
||||
extern int load_res32_file( const char *name, DLLSPEC *spec );
|
||||
extern int output_resources( FILE *outfile, DLLSPEC *spec );
|
||||
extern void output_resources( FILE *outfile, DLLSPEC *spec );
|
||||
extern void load_res16_file( const char *name, DLLSPEC *spec );
|
||||
extern unsigned int get_res16_data_size( DLLSPEC *spec, unsigned int res_offset,
|
||||
unsigned int alignment );
|
||||
|
|
|
@ -90,7 +90,7 @@ static const unsigned char *file_end; /* end of resource file */
|
|||
static const char *file_name; /* current resource file name */
|
||||
|
||||
/* size of a resource directory with n entries */
|
||||
#define RESDIR_SIZE(n) ((4 + 2 * (n)) * sizeof(int))
|
||||
#define RESDIR_SIZE(n) (sizeof(IMAGE_RESOURCE_DIRECTORY) + (n) * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY))
|
||||
|
||||
|
||||
inline static struct resource *add_resource( DLLSPEC *spec )
|
||||
|
@ -319,75 +319,55 @@ static void free_resource_tree( struct res_tree *tree )
|
|||
static void output_string( FILE *outfile, const WCHAR *name )
|
||||
{
|
||||
int i, len = strlenW(name);
|
||||
fprintf( outfile, "0x%04x", len );
|
||||
for (i = 0; i < len; i++) fprintf( outfile, ", 0x%04x", name[i] );
|
||||
fprintf( outfile, " /* " );
|
||||
fprintf( outfile, " \"\\t%s 0x%04x", get_asm_short_keyword(), len );
|
||||
for (i = 0; i < len; i++) fprintf( outfile, ",0x%04x", name[i] );
|
||||
fprintf( outfile, "\\n\" /* " );
|
||||
for (i = 0; i < len; i++) fprintf( outfile, "%c", isprint((char)name[i]) ? (char)name[i] : '?' );
|
||||
fprintf( outfile, " */" );
|
||||
fprintf( outfile, " */\n" );
|
||||
}
|
||||
|
||||
/* output a resource directory */
|
||||
static inline void output_res_dir( FILE *outfile, unsigned int nb_names, unsigned int nb_ids )
|
||||
{
|
||||
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* Characteristics */
|
||||
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* TimeDateStamp */
|
||||
fprintf( outfile, " \"\\t%s 0,0\\n\"\n", /* Major/MinorVersion */
|
||||
get_asm_short_keyword() );
|
||||
fprintf( outfile, " \"\\t%s %u,%u\\n\"\n", /* NumberOfNamed/IdEntries */
|
||||
get_asm_short_keyword(), nb_names, nb_ids );
|
||||
}
|
||||
|
||||
/* output the resource definitions */
|
||||
int output_resources( FILE *outfile, DLLSPEC *spec )
|
||||
void output_resources( FILE *outfile, DLLSPEC *spec )
|
||||
{
|
||||
int j, k, nb_id_types, total_size;
|
||||
int j, k, nb_id_types;
|
||||
unsigned int i, n, offset, data_offset;
|
||||
struct res_tree *tree;
|
||||
struct res_type *type;
|
||||
struct res_name *name;
|
||||
const struct resource *res;
|
||||
|
||||
if (!spec->nb_resources) return 0;
|
||||
if (!spec->nb_resources) return;
|
||||
|
||||
tree = build_resource_tree( spec );
|
||||
|
||||
/* directory structures */
|
||||
/* compute the offsets */
|
||||
|
||||
fprintf( outfile, "struct res_dir {\n" );
|
||||
fprintf( outfile, " unsigned int Characteristics;\n" );
|
||||
fprintf( outfile, " unsigned int TimeDateStamp;\n" );
|
||||
fprintf( outfile, " unsigned short MajorVersion, MinorVersion;\n" );
|
||||
fprintf( outfile, " unsigned short NumerOfNamedEntries, NumberOfIdEntries;\n};\n\n" );
|
||||
fprintf( outfile, "struct res_dir_entry {\n" );
|
||||
fprintf( outfile, " unsigned int Name;\n" );
|
||||
fprintf( outfile, " unsigned int OffsetToData;\n};\n\n" );
|
||||
fprintf( outfile, "struct res_data_entry {\n" );
|
||||
fprintf( outfile, " const unsigned int *OffsetToData;\n" );
|
||||
fprintf( outfile, " unsigned int Size;\n" );
|
||||
fprintf( outfile, " unsigned int CodePage;\n" );
|
||||
fprintf( outfile, " unsigned int ResourceHandle;\n};\n\n" );
|
||||
|
||||
/* resource directory definition */
|
||||
|
||||
fprintf( outfile, "static struct res_struct{\n" );
|
||||
fprintf( outfile, " struct res_dir type_dir;\n" );
|
||||
fprintf( outfile, " struct res_dir_entry type_entries[%d];\n", tree->nb_types );
|
||||
offset = RESDIR_SIZE( tree->nb_types );
|
||||
|
||||
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
|
||||
{
|
||||
offset += RESDIR_SIZE( type->nb_names );
|
||||
fprintf( outfile, " struct res_dir name_%d_dir;\n", i );
|
||||
fprintf( outfile, " struct res_dir_entry name_%d_entries[%d];\n", i, type->nb_names );
|
||||
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
|
||||
{
|
||||
offset += RESDIR_SIZE( name->nb_languages );
|
||||
fprintf( outfile, " struct res_dir lang_%d_%d_dir;\n", i, n );
|
||||
fprintf( outfile, " struct res_dir_entry lang_%d_%d_entries[%d];\n",
|
||||
i, n, name->nb_languages );
|
||||
}
|
||||
}
|
||||
|
||||
fprintf( outfile, " struct res_data_entry data_entries[%d];\n", spec->nb_resources );
|
||||
offset += spec->nb_resources * 4 * sizeof(int);
|
||||
offset += spec->nb_resources * sizeof(IMAGE_RESOURCE_DATA_ENTRY);
|
||||
|
||||
for (i = nb_id_types = 0, type = tree->types; i < tree->nb_types; i++, type++)
|
||||
{
|
||||
if (type->type->str)
|
||||
{
|
||||
type->name_offset = offset | 0x80000000;
|
||||
offset += (strlenW(type->type->str)+1) * sizeof(unsigned short);
|
||||
fprintf( outfile, " unsigned short type_%d_name[%d];\n",
|
||||
i, strlenW(type->type->str)+1 );
|
||||
offset += (strlenW(type->type->str)+1) * sizeof(WCHAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -400,110 +380,94 @@ int output_resources( FILE *outfile, DLLSPEC *spec )
|
|||
if (name->name->str)
|
||||
{
|
||||
name->name_offset = offset | 0x80000000;
|
||||
offset += (strlenW(name->name->str)+1) * sizeof(unsigned short);
|
||||
fprintf( outfile, " unsigned short name_%d_%d_name[%d];\n",
|
||||
i, n, strlenW(name->name->str)+1 );
|
||||
offset += (strlenW(name->name->str)+1) * sizeof(WCHAR);
|
||||
}
|
||||
else name->name_offset = name->name->id;
|
||||
}
|
||||
}
|
||||
total_size = offset;
|
||||
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
|
||||
{
|
||||
fprintf( outfile, " unsigned int res_%d[%d];\n", i, res->data_size / 4 );
|
||||
total_size += (res->data_size + 3) & ~3;
|
||||
}
|
||||
|
||||
/* resource directory contents */
|
||||
/* output the resource directories */
|
||||
|
||||
fprintf( outfile, "} __wine_spec_resources = {\n" );
|
||||
fprintf( outfile, " { 0, 0, 0, 0, %d, %d },\n", tree->nb_types - nb_id_types, nb_id_types );
|
||||
fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(get_ptr_size()) );
|
||||
fprintf( outfile, " \".L__wine_spec_resources:\\n\"\n" );
|
||||
|
||||
output_res_dir( outfile, tree->nb_types - nb_id_types, nb_id_types );
|
||||
|
||||
/* dump the type directory */
|
||||
|
||||
offset = RESDIR_SIZE( tree->nb_types );
|
||||
fprintf( outfile, " {\n" );
|
||||
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
|
||||
{
|
||||
fprintf( outfile, " { 0x%08x, 0x%08x },\n", type->name_offset, offset | 0x80000000 );
|
||||
fprintf( outfile, " \"\\t.long 0x%08x,0x%08x\\n\"\n",
|
||||
type->name_offset, offset | 0x80000000 );
|
||||
offset += RESDIR_SIZE( type->nb_names );
|
||||
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
|
||||
offset += RESDIR_SIZE( name->nb_languages );
|
||||
}
|
||||
fprintf( outfile, " },\n" );
|
||||
|
||||
data_offset = offset;
|
||||
offset = RESDIR_SIZE( tree->nb_types );
|
||||
|
||||
/* dump the names and languages directories */
|
||||
|
||||
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
|
||||
{
|
||||
fprintf( outfile, " { 0, 0, 0, 0, %d, %d }, /* name_%d_dir */\n {\n",
|
||||
type->nb_names - type->nb_id_names, type->nb_id_names, i );
|
||||
output_res_dir( outfile, type->nb_names - type->nb_id_names, type->nb_id_names );
|
||||
offset += RESDIR_SIZE( type->nb_names );
|
||||
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
|
||||
{
|
||||
fprintf( outfile, " { 0x%08x, 0x%08x },\n", name->name_offset, offset | 0x80000000 );
|
||||
fprintf( outfile, " \"\\t.long 0x%08x,0x%08x\\n\"\n",
|
||||
name->name_offset, offset | 0x80000000 );
|
||||
offset += RESDIR_SIZE( name->nb_languages );
|
||||
}
|
||||
fprintf( outfile, " },\n" );
|
||||
|
||||
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
|
||||
{
|
||||
fprintf( outfile, " { 0, 0, 0, 0, 0, %d }, /* lang_%d_%d_dir */\n {\n",
|
||||
name->nb_languages, i, n );
|
||||
output_res_dir( outfile, 0, name->nb_languages );
|
||||
for (k = 0, res = name->res; k < name->nb_languages; k++, res++)
|
||||
{
|
||||
fprintf( outfile, " { 0x%04x, 0x%08x },\n",
|
||||
res->lang, data_offset + (res - spec->resources) * 4 * sizeof(int) );
|
||||
fprintf( outfile, " \"\\t.long 0x%08x,0x%08x\\n\"\n", res->lang,
|
||||
data_offset + (res - spec->resources) * sizeof(IMAGE_RESOURCE_DATA_ENTRY) );
|
||||
}
|
||||
fprintf( outfile, " },\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/* dump the resource data entries */
|
||||
fprintf( outfile, " {\n" );
|
||||
|
||||
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
|
||||
{
|
||||
fprintf( outfile, " { __wine_spec_resources.res_%d, sizeof(__wine_spec_resources.res_%d), 0, 0 }, /* %08x */\n", i, i,
|
||||
data_offset + i * 4 * sizeof(int) );
|
||||
}
|
||||
fprintf( outfile, " \"\\t.long .L__wine_spec_res_%d,%u,0,0\\n\"\n",
|
||||
i, res->data_size );
|
||||
|
||||
/* dump the name strings */
|
||||
|
||||
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
|
||||
{
|
||||
if (type->type->str)
|
||||
{
|
||||
fprintf( outfile, " },\n { " );
|
||||
output_string( outfile, type->type->str );
|
||||
}
|
||||
if (type->type->str) output_string( outfile, type->type->str );
|
||||
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
|
||||
{
|
||||
if (name->name->str)
|
||||
{
|
||||
fprintf( outfile, " },\n { " );
|
||||
output_string( outfile, name->name->str );
|
||||
}
|
||||
}
|
||||
if (name->name->str) output_string( outfile, name->name->str );
|
||||
}
|
||||
fprintf( outfile, " },\n" );
|
||||
fprintf( outfile, ");\n" );
|
||||
|
||||
/* resource data */
|
||||
|
||||
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
|
||||
{
|
||||
const unsigned int *p = res->data;
|
||||
int size = res->data_size / 4;
|
||||
/* dump data as ints to ensure correct alignment */
|
||||
fprintf( outfile, " { /* res_%d */\n ", i );
|
||||
for (j = 0; j < size - 1; j++, p++)
|
||||
const unsigned char *p = res->data;
|
||||
fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(get_ptr_size()) );
|
||||
fprintf( outfile, " \".L__wine_spec_res_%d:\\n\"\n", i );
|
||||
fprintf( outfile, " \"\\t.byte " );
|
||||
for (j = 0; j < res->data_size - 1; j++, p++)
|
||||
{
|
||||
fprintf( outfile, "0x%08x,", *p );
|
||||
if ((j % 8) == 7) fprintf( outfile, "\n " );
|
||||
if ((j % 16) == 15) fprintf( outfile, "0x%02x\\n\"\n \"\\t.byte ", *p );
|
||||
else fprintf( outfile, "0x%02x,", *p );
|
||||
}
|
||||
fprintf( outfile, "0x%08x\n },\n", *p );
|
||||
fprintf( outfile, "0x%02x\\n\"\n", *p );
|
||||
fprintf( outfile, ");\n" );
|
||||
}
|
||||
fprintf( outfile, "};\n\n" );
|
||||
fprintf( outfile, "asm(\".data\\n\"\n" );
|
||||
fprintf( outfile, " \".L__wine_spec_resources_end:\\n\"\n" );
|
||||
fprintf( outfile, " \"\\t.byte 0\\n\"\n" );
|
||||
fprintf( outfile, ");\n" );
|
||||
|
||||
free_resource_tree( tree );
|
||||
return total_size;
|
||||
}
|
||||
|
|
|
@ -427,7 +427,7 @@ void output_dll_init( FILE *outfile, const char *constructor, const char *destru
|
|||
*/
|
||||
void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
||||
{
|
||||
int resources_size, machine = 0;
|
||||
int machine = 0;
|
||||
unsigned int page_size = get_page_size();
|
||||
|
||||
resolve_imports( spec );
|
||||
|
@ -436,8 +436,9 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
|||
/* Reserve some space for the PE header */
|
||||
|
||||
fprintf( outfile, "#ifndef __GNUC__\n" );
|
||||
fprintf( outfile, "static void __asm__dummy_header(void) {\n" );
|
||||
fprintf( outfile, "static void __asm__dummy(void) {\n" );
|
||||
fprintf( outfile, "#endif\n" );
|
||||
|
||||
fprintf( outfile, "asm(\".text\\n\\t\"\n" );
|
||||
fprintf( outfile, " \".align %d\\n\"\n", get_alignment(page_size) );
|
||||
fprintf( outfile, " \"__wine_spec_pe_header:\\t\"\n" );
|
||||
|
@ -445,28 +446,11 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
|||
fprintf( outfile, " \".space 65536\\n\\t\"\n" );
|
||||
else
|
||||
fprintf( outfile, " \".skip 65536\\n\\t\"\n" );
|
||||
fprintf( outfile, " \".data\\n\\t\"\n" );
|
||||
fprintf( outfile, " \".align %d\\n\"\n", get_alignment(4) );
|
||||
fprintf( outfile, " \".L__wine_spec_data_start:\\t.long 1\");\n" );
|
||||
fprintf( outfile, "#ifndef __GNUC__\n" );
|
||||
fprintf( outfile, "}\n" );
|
||||
fprintf( outfile, "#endif\n" );
|
||||
|
||||
if (target_platform == PLATFORM_APPLE)
|
||||
fprintf( outfile, "static char _end[4];\n" );
|
||||
|
||||
/* Output the resources */
|
||||
|
||||
resources_size = output_resources( outfile, spec );
|
||||
|
||||
/* Output the NT header */
|
||||
|
||||
fprintf( outfile, "#ifndef __GNUC__\n" );
|
||||
fprintf( outfile, "static void __asm__dummy(void) {\n" );
|
||||
fprintf( outfile, "#endif\n" );
|
||||
|
||||
fprintf( outfile, "/* NT header */\n" );
|
||||
fprintf( outfile, "asm(\".data\\n\\t.align %d\\n\"\n", get_alignment(4) );
|
||||
fprintf( outfile, " \"\\t.data\\n\\t\"\n" );
|
||||
fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(get_ptr_size()) );
|
||||
fprintf( outfile, " \"\\t.globl %s\\n\"\n", asm_name("__wine_spec_nt_header") );
|
||||
fprintf( outfile, " \"%s:\\n\"\n", asm_name("__wine_spec_nt_header"));
|
||||
|
||||
|
@ -502,7 +486,8 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
|||
fprintf( outfile, " \"\\t.long %s\\n\"\n", /* AddressOfEntryPoint */
|
||||
asm_name(spec->init_func) );
|
||||
fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* BaseOfCode */
|
||||
fprintf( outfile, " \"\\t.long .L__wine_spec_data_start\\n\"\n" ); /* BaseOfData */
|
||||
if (get_ptr_size() == 4)
|
||||
fprintf( outfile, " \"\\t.long %s\\n\"\n", asm_name("__wine_spec_nt_header") ); /* BaseOfData */
|
||||
fprintf( outfile, " \"\\t%s __wine_spec_pe_header\\n\"\n", /* ImageBase */
|
||||
get_asm_ptr_keyword() );
|
||||
fprintf( outfile, " \"\\t.long %u\\n\"\n", page_size ); /* SectionAlignment */
|
||||
|
@ -539,8 +524,10 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
|||
else
|
||||
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" );
|
||||
|
||||
fprintf( outfile, " \"\\t.long %s,%u\\n\"\n", /* DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] */
|
||||
resources_size ? asm_name("__wine_spec_resources") : "0", resources_size );
|
||||
if (spec->nb_resources) /* DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] */
|
||||
fprintf( outfile, " \"\\t.long .L__wine_spec_resources, .L__wine_spec_resources_end-.L__wine_spec_resources\\n\"\n" );
|
||||
else
|
||||
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" );
|
||||
|
||||
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); /* DataDirectory[3] */
|
||||
fprintf( outfile, " \"\\t.long 0,0\\n\"\n" ); /* DataDirectory[4] */
|
||||
|
@ -561,11 +548,15 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
|
|||
fprintf( outfile, " \"\\t.globl %s\\n\"\n", asm_name("__wine_spec_file_name") );
|
||||
fprintf( outfile, " \"%s:\\n\"\n", asm_name("__wine_spec_file_name"));
|
||||
fprintf( outfile, " \"\\t%s \\\"%s\\\"\\n\"\n", get_asm_string_keyword(), spec->file_name );
|
||||
if (target_platform == PLATFORM_APPLE)
|
||||
fprintf( outfile, " \"\\t.comm %s,4\\n\"\n", asm_name("_end") );
|
||||
|
||||
fprintf( outfile, ");\n" );
|
||||
|
||||
output_stubs( outfile, spec );
|
||||
output_exports( outfile, spec );
|
||||
output_imports( outfile, spec );
|
||||
output_resources( outfile, spec );
|
||||
output_dll_init( outfile, "__wine_spec_init_ctor", NULL );
|
||||
|
||||
fprintf( outfile, "#ifndef __GNUC__\n" );
|
||||
|
|
Loading…
Reference in New Issue