hc
2024-03-22 ac5f19e89dcbd5c7428fcc78a0d407c887564466
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
From a4e8936f010a8e928e973b80390c8f83ad6b8000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 15 Feb 2021 14:19:31 +0100
Subject: [PATCH] util/mkimage: Unify more of the PE32 and PE32+ header set-up
 
There's quite a bit of code duplication in the code that sets the optional
header for PE32 and PE32+. The two are very similar with the exception of
a few fields that have type grub_uint64_t instead of grub_uint32_t.
 
Factor out the common code and add a PE_OHDR() macro that simplifies the
set-up and make the code more readable.
 
Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
---
 util/mkimage.c | 111 ++++++++++++++++++++++++++-------------------------------
 1 file changed, 51 insertions(+), 60 deletions(-)
 
diff --git a/util/mkimage.c b/util/mkimage.c
index b94bfb7..a039039 100644
--- a/util/mkimage.c
+++ b/util/mkimage.c
@@ -816,6 +816,21 @@ grub_install_get_image_targets_string (void)
   return formats;
 }
 
+/*
+ * tmp_ is just here so the compiler knows we'll never derefernce a NULL.
+ * It should get fully optimized away.
+ */
+#define PE_OHDR(o32, o64, field) (*(        \
+{                        \
+  __typeof__((o64)->field) tmp_;        \
+  __typeof__((o64)->field) *ret_ = &tmp_;    \
+  if (o32)                    \
+    ret_ = (void *)(&((o32)->field));        \
+  else if (o64)                \
+    ret_ = (void *)(&((o64)->field));        \
+  ret_;                    \
+}))
+
 void
 grub_install_generate_image (const char *dir, const char *prefix,
                  FILE *out, const char *outname, char *mods[],
@@ -1252,6 +1267,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
     static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB;
     int header_size;
     int reloc_addr;
+    struct grub_pe32_optional_header *o32 = NULL;
+    struct grub_pe64_optional_header *o64 = NULL;
 
     if (image_target->voidp_sizeof == 4)
       header_size = EFI32_HEADER_SIZE;
@@ -1293,76 +1310,50 @@ grub_install_generate_image (const char *dir, const char *prefix,
     /* The PE Optional header.  */
     if (image_target->voidp_sizeof == 4)
       {
-        struct grub_pe32_optional_header *o;
-
         c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header));
 
-        o = (struct grub_pe32_optional_header *)
-          (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE
-           + sizeof (struct grub_pe32_coff_header));
-        o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC);
-        o->code_size = grub_host_to_target32 (layout.exec_size);
-        o->data_size = grub_host_to_target32 (reloc_addr - layout.exec_size
-                         - header_size);
-        o->entry_addr = grub_host_to_target32 (layout.start_address);
-        o->code_base = grub_host_to_target32 (header_size);
-
-        o->data_base = grub_host_to_target32 (header_size + layout.exec_size);
-
-        o->image_base = 0;
-        o->section_alignment = grub_host_to_target32 (image_target->section_align);
-        o->file_alignment = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT);
-        o->image_size = grub_host_to_target32 (pe_size);
-        o->header_size = grub_host_to_target32 (header_size);
-        o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);
-
-        /* Do these really matter? */
-        o->stack_reserve_size = grub_host_to_target32 (0x10000);
-        o->stack_commit_size = grub_host_to_target32 (0x10000);
-        o->heap_reserve_size = grub_host_to_target32 (0x10000);
-        o->heap_commit_size = grub_host_to_target32 (0x10000);
-    
-        o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
+        o32 = (struct grub_pe32_optional_header *)
+              (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE +
+               sizeof (struct grub_pe32_coff_header));
+        o32->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC);
+        o32->data_base = grub_host_to_target32 (header_size + layout.exec_size);
 
-        o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr);
-        o->base_relocation_table.size = grub_host_to_target32 (layout.reloc_size);
-        sections = o + 1;
+        sections = o32 + 1;
       }
     else
       {
-        struct grub_pe64_optional_header *o;
-
         c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header));
 
-        o = (struct grub_pe64_optional_header *) 
-          (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE
-           + sizeof (struct grub_pe32_coff_header));
-        o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC);
-        o->code_size = grub_host_to_target32 (layout.exec_size);
-        o->data_size = grub_host_to_target32 (reloc_addr - layout.exec_size
-                         - header_size);
-        o->entry_addr = grub_host_to_target32 (layout.start_address);
-        o->code_base = grub_host_to_target32 (header_size);
-        o->image_base = 0;
-        o->section_alignment = grub_host_to_target32 (image_target->section_align);
-        o->file_alignment = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT);
-        o->image_size = grub_host_to_target32 (pe_size);
-        o->header_size = grub_host_to_target32 (header_size);
-        o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);
-
-        /* Do these really matter? */
-        o->stack_reserve_size = grub_host_to_target32 (0x10000);
-        o->stack_commit_size = grub_host_to_target32 (0x10000);
-        o->heap_reserve_size = grub_host_to_target32 (0x10000);
-        o->heap_commit_size = grub_host_to_target32 (0x10000);
-    
-        o->num_data_directories
-          = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
+        o64 = (struct grub_pe64_optional_header *)
+          (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE +
+                   sizeof (struct grub_pe32_coff_header));
+        o64->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC);
 
-        o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr);
-        o->base_relocation_table.size = grub_host_to_target32 (layout.reloc_size);
-        sections = o + 1;
+        sections = o64 + 1;
       }
+
+    PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (layout.exec_size);
+    PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (reloc_addr - layout.exec_size - header_size);
+    PE_OHDR (o32, o64, entry_addr) = grub_host_to_target32 (layout.start_address);
+    PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (header_size);
+
+    PE_OHDR (o32, o64, image_base) = 0;
+    PE_OHDR (o32, o64, section_alignment) = grub_host_to_target32 (image_target->section_align);
+    PE_OHDR (o32, o64, file_alignment) = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT);
+    PE_OHDR (o32, o64, image_size) = grub_host_to_target32 (pe_size);
+    PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size);
+    PE_OHDR (o32, o64, subsystem) = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);
+
+    /* Do these really matter? */
+    PE_OHDR (o32, o64, stack_reserve_size) = grub_host_to_target32 (0x10000);
+    PE_OHDR (o32, o64, stack_commit_size) = grub_host_to_target32 (0x10000);
+    PE_OHDR (o32, o64, heap_reserve_size) = grub_host_to_target32 (0x10000);
+    PE_OHDR (o32, o64, heap_commit_size) = grub_host_to_target32 (0x10000);
+
+    PE_OHDR (o32, o64, num_data_directories) = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
+    PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (reloc_addr);
+    PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (layout.reloc_size);
+
     /* The sections.  */
     text_section = sections;
     strcpy (text_section->name, ".text");
-- 
2.14.2