aboutsummaryrefslogtreecommitdiff
path: root/emulators/wine-devel/files/extra-patch-tools-winebuild-res32
blob: 7c6c62b9fe586deb6a8f4ba60c364a581cb3ca3e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
The upstream change

  commit 0b3f90ab1485d5bd32bd72d41c7fd8213b3b95b9
  Author: Rémi Bernon <rbernon@codeweavers.com>
  Date:   Sat Feb 11 11:05:22 2023 +0100

    winebuild: Use .incbin instead of printf for resource data.

apparently causes some (not completely reproducible) build
issues on i386 due to resource exhaustion by the compiler,
cf.  https://bugs.winehq.org/show_bug.cgi?id=54889 .

https://github.com/llvm/llvm-project/issues/62339 tracks this on
the LLVM side, alas has not really seen progress since April 2003.
So for now this reverts the upstream commit (alas on i386 only as
to minimize divergence and risk on 64-bit x86).


--- tools/winebuild/res32.c
+++ tools/winebuild/res32.c
@@ -44,8 +44,6 @@ struct resource
 {
     struct string_id type;
     struct string_id name;
-    const char      *input_name;
-    unsigned int     input_offset;
     const void      *data;
     unsigned int     data_size;
     unsigned int     data_offset;
@@ -158,6 +156,28 @@ static void put_string( const struct string_id *str )
     }
 }
 
+static void dump_res_data( const struct resource *res )
+{
+    unsigned int i = 0;
+    unsigned int size = (res->data_size + 3) & ~3;
+
+    if (!size) return;
+
+    input_buffer = res->data;
+    input_buffer_pos  = 0;
+    input_buffer_size = size;
+
+    output( "\t.long " );
+    while (size > 4)
+    {
+        if ((i++ % 16) == 15) output( "0x%08x\n\t.long ", get_dword() );
+        else output( "0x%08x,", get_dword() );
+        size -= 4;
+    }
+    output( "0x%08x\n", get_dword() );
+    assert( input_buffer_pos == input_buffer_size );
+}
+
 /* check the file header */
 /* all values must be zero except header size */
 static int check_header(void)
@@ -179,7 +199,7 @@ static int check_header(void)
 }
 
 /* load the next resource from the current file */
-static void load_next_resource( DLLSPEC *spec, const char *name )
+static void load_next_resource( DLLSPEC *spec )
 {
     unsigned int hdr_size;
     struct resource *res = add_resource( spec );
@@ -189,9 +209,6 @@ static void load_next_resource( DLLSPEC *spec, const char *name )
     if (hdr_size & 3) fatal_error( "%s header size not aligned\n", input_buffer_filename );
     if (hdr_size < 32) fatal_error( "%s invalid header size %u\n", input_buffer_filename, hdr_size );
 
-    res->input_name = xstrdup( name );
-    res->input_offset = input_buffer_pos - 2*sizeof(unsigned int) + hdr_size;
-
     res->data = input_buffer + input_buffer_pos - 2*sizeof(unsigned int) + hdr_size;
     if ((const unsigned char *)res->data < input_buffer ||
         (const unsigned char *)res->data >= input_buffer + input_buffer_size)
@@ -220,7 +237,7 @@ int load_res32_file( const char *name, DLLSPEC *spec )
 
     if ((ret = check_header()))
     {
-        while (input_buffer_pos < input_buffer_size) load_next_resource( spec, name );
+        while (input_buffer_pos < input_buffer_size) load_next_resource( spec );
     }
     return ret;
 }
@@ -473,7 +490,7 @@ void output_resources( DLLSPEC *spec )
     {
         output( "\n\t.balign 4\n" );
         output( ".L__wine_spec_res_%d:\n", i );
-        output( "\t.incbin \"%s\",%d,%d\n", res->input_name, res->input_offset, res->data_size );
+        dump_res_data( res );
     }
 
     if (!is_pe())