1*4882a593SmuzhiyunFrom f60ba9e5945892e835e53f0619406d96002f7f70 Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Peter Jones <pjones@redhat.com>
3*4882a593SmuzhiyunDate: Mon, 15 Feb 2021 14:58:06 +0100
4*4882a593SmuzhiyunSubject: [PATCH] util/mkimage: Refactor section setup to use a helper
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunAdd a init_pe_section() helper function to setup PE sections. This makes
7*4882a593Smuzhiyunthe code simpler and easier to read.
8*4882a593Smuzhiyun
9*4882a593SmuzhiyunSigned-off-by: Peter Jones <pjones@redhat.com>
10*4882a593SmuzhiyunSigned-off-by: Javier Martinez Canillas <javierm@redhat.com>
11*4882a593SmuzhiyunReviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
12*4882a593SmuzhiyunSigned-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
13*4882a593Smuzhiyun---
14*4882a593Smuzhiyun util/mkimage.c | 143 +++++++++++++++++++++++++++++++--------------------------
15*4882a593Smuzhiyun 1 file changed, 77 insertions(+), 66 deletions(-)
16*4882a593Smuzhiyun
17*4882a593Smuzhiyundiff --git a/util/mkimage.c b/util/mkimage.c
18*4882a593Smuzhiyunindex 853a521..8b475a6 100644
19*4882a593Smuzhiyun--- a/util/mkimage.c
20*4882a593Smuzhiyun+++ b/util/mkimage.c
21*4882a593Smuzhiyun@@ -816,6 +816,38 @@ grub_install_get_image_targets_string (void)
22*4882a593Smuzhiyun   return formats;
23*4882a593Smuzhiyun }
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun+/*
26*4882a593Smuzhiyun+ * The image_target parameter is used by the grub_host_to_target32() macro.
27*4882a593Smuzhiyun+ */
28*4882a593Smuzhiyun+static struct grub_pe32_section_table *
29*4882a593Smuzhiyun+init_pe_section(const struct grub_install_image_target_desc *image_target,
30*4882a593Smuzhiyun+		struct grub_pe32_section_table *section,
31*4882a593Smuzhiyun+		const char * const name,
32*4882a593Smuzhiyun+		grub_uint32_t *vma, grub_uint32_t vsz, grub_uint32_t valign,
33*4882a593Smuzhiyun+		grub_uint32_t *rda, grub_uint32_t rsz,
34*4882a593Smuzhiyun+		grub_uint32_t characteristics)
35*4882a593Smuzhiyun+{
36*4882a593Smuzhiyun+  size_t len = strlen (name);
37*4882a593Smuzhiyun+
38*4882a593Smuzhiyun+  if (len > sizeof (section->name))
39*4882a593Smuzhiyun+    grub_util_error (_("section name %s length is bigger than %lu"),
40*4882a593Smuzhiyun+		     name, (unsigned long) sizeof (section->name));
41*4882a593Smuzhiyun+
42*4882a593Smuzhiyun+  memcpy (section->name, name, len);
43*4882a593Smuzhiyun+
44*4882a593Smuzhiyun+  section->virtual_address = grub_host_to_target32 (*vma);
45*4882a593Smuzhiyun+  section->virtual_size = grub_host_to_target32 (vsz);
46*4882a593Smuzhiyun+  (*vma) = ALIGN_UP (*vma + vsz, valign);
47*4882a593Smuzhiyun+
48*4882a593Smuzhiyun+  section->raw_data_offset = grub_host_to_target32 (*rda);
49*4882a593Smuzhiyun+  section->raw_data_size = grub_host_to_target32 (rsz);
50*4882a593Smuzhiyun+  (*rda) = ALIGN_UP (*rda + rsz, GRUB_PE32_FILE_ALIGNMENT);
51*4882a593Smuzhiyun+
52*4882a593Smuzhiyun+  section->characteristics = grub_host_to_target32 (characteristics);
53*4882a593Smuzhiyun+
54*4882a593Smuzhiyun+  return section + 1;
55*4882a593Smuzhiyun+}
56*4882a593Smuzhiyun+
57*4882a593Smuzhiyun /*
58*4882a593Smuzhiyun  * tmp_ is just here so the compiler knows we'll never derefernce a NULL.
59*4882a593Smuzhiyun  * It should get fully optimized away.
60*4882a593Smuzhiyun@@ -1257,17 +1289,13 @@ grub_install_generate_image (const char *dir, const char *prefix,
61*4882a593Smuzhiyun       break;
62*4882a593Smuzhiyun     case IMAGE_EFI:
63*4882a593Smuzhiyun       {
64*4882a593Smuzhiyun-	void *pe_img;
65*4882a593Smuzhiyun-	grub_uint8_t *header;
66*4882a593Smuzhiyun-	void *sections;
67*4882a593Smuzhiyun+	char *pe_img, *header;
68*4882a593Smuzhiyun+	struct grub_pe32_section_table *section;
69*4882a593Smuzhiyun 	size_t scn_size;
70*4882a593Smuzhiyun-	size_t pe_size;
71*4882a593Smuzhiyun+	grub_uint32_t vma, raw_data;
72*4882a593Smuzhiyun+	size_t pe_size, header_size;
73*4882a593Smuzhiyun 	struct grub_pe32_coff_header *c;
74*4882a593Smuzhiyun-	struct grub_pe32_section_table *text_section, *data_section;
75*4882a593Smuzhiyun-	struct grub_pe32_section_table *mods_section, *reloc_section;
76*4882a593Smuzhiyun 	static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB;
77*4882a593Smuzhiyun-	int header_size;
78*4882a593Smuzhiyun-	int reloc_addr;
79*4882a593Smuzhiyun 	struct grub_pe32_optional_header *o32 = NULL;
80*4882a593Smuzhiyun 	struct grub_pe64_optional_header *o64 = NULL;
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun@@ -1276,17 +1304,12 @@ grub_install_generate_image (const char *dir, const char *prefix,
83*4882a593Smuzhiyun 	else
84*4882a593Smuzhiyun 	  header_size = EFI64_HEADER_SIZE;
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun-	reloc_addr = ALIGN_UP (header_size + core_size,
87*4882a593Smuzhiyun-			       GRUB_PE32_FILE_ALIGNMENT);
88*4882a593Smuzhiyun+	vma = raw_data = header_size;
89*4882a593Smuzhiyun+	pe_size = ALIGN_UP (header_size + core_size, GRUB_PE32_FILE_ALIGNMENT) +
90*4882a593Smuzhiyun+          ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT);
91*4882a593Smuzhiyun+	header = pe_img = xcalloc (1, pe_size);
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun-	pe_size = ALIGN_UP (reloc_addr + layout.reloc_size,
94*4882a593Smuzhiyun-			    GRUB_PE32_FILE_ALIGNMENT);
95*4882a593Smuzhiyun-	pe_img = xmalloc (reloc_addr + layout.reloc_size);
96*4882a593Smuzhiyun-	memset (pe_img, 0, header_size);
97*4882a593Smuzhiyun-	memcpy ((char *) pe_img + header_size, core_img, core_size);
98*4882a593Smuzhiyun-	memset ((char *) pe_img + header_size + core_size, 0, reloc_addr - (header_size + core_size));
99*4882a593Smuzhiyun-	memcpy ((char *) pe_img + reloc_addr, layout.reloc_section, layout.reloc_size);
100*4882a593Smuzhiyun-	header = pe_img;
101*4882a593Smuzhiyun+	memcpy (pe_img + raw_data, core_img, core_size);
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun 	/* The magic.  */
104*4882a593Smuzhiyun 	memcpy (header, stub, GRUB_PE32_MSDOS_STUB_SIZE);
105*4882a593Smuzhiyun@@ -1319,18 +1342,17 @@ grub_install_generate_image (const char *dir, const char *prefix,
106*4882a593Smuzhiyun 	    o32->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC);
107*4882a593Smuzhiyun 	    o32->data_base = grub_host_to_target32 (header_size + layout.exec_size);
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun-	    sections = o32 + 1;
110*4882a593Smuzhiyun+	    section = (struct grub_pe32_section_table *)(o32 + 1);
111*4882a593Smuzhiyun 	  }
112*4882a593Smuzhiyun 	else
113*4882a593Smuzhiyun 	  {
114*4882a593Smuzhiyun 	    c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header));
115*4882a593Smuzhiyun-
116*4882a593Smuzhiyun 	    o64 = (struct grub_pe64_optional_header *)
117*4882a593Smuzhiyun 		  (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE +
118*4882a593Smuzhiyun                    sizeof (struct grub_pe32_coff_header));
119*4882a593Smuzhiyun 	    o64->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC);
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun-	    sections = o64 + 1;
122*4882a593Smuzhiyun+	    section = (struct grub_pe32_section_table *)(o64 + 1);
123*4882a593Smuzhiyun 	  }
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun 	PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size);
126*4882a593Smuzhiyun@@ -1350,58 +1372,47 @@ grub_install_generate_image (const char *dir, const char *prefix,
127*4882a593Smuzhiyun 	PE_OHDR (o32, o64, num_data_directories) = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun 	/* The sections.  */
130*4882a593Smuzhiyun-	PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (header_size);
131*4882a593Smuzhiyun+	PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (vma);
132*4882a593Smuzhiyun 	PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (layout.exec_size);
133*4882a593Smuzhiyun-	text_section = sections;
134*4882a593Smuzhiyun-	strcpy (text_section->name, ".text");
135*4882a593Smuzhiyun-	text_section->virtual_size = grub_host_to_target32 (layout.exec_size);
136*4882a593Smuzhiyun-	text_section->virtual_address = grub_host_to_target32 (header_size);
137*4882a593Smuzhiyun-	text_section->raw_data_size = grub_host_to_target32 (layout.exec_size);
138*4882a593Smuzhiyun-	text_section->raw_data_offset = grub_host_to_target32 (header_size);
139*4882a593Smuzhiyun-	text_section->characteristics = grub_cpu_to_le32_compile_time (
140*4882a593Smuzhiyun-						  GRUB_PE32_SCN_CNT_CODE
141*4882a593Smuzhiyun-						| GRUB_PE32_SCN_MEM_EXECUTE
142*4882a593Smuzhiyun-						| GRUB_PE32_SCN_MEM_READ);
143*4882a593Smuzhiyun+	section = init_pe_section (image_target, section, ".text",
144*4882a593Smuzhiyun+				   &vma, layout.exec_size,
145*4882a593Smuzhiyun+				   image_target->section_align,
146*4882a593Smuzhiyun+				   &raw_data, layout.exec_size,
147*4882a593Smuzhiyun+				   GRUB_PE32_SCN_CNT_CODE |
148*4882a593Smuzhiyun+				   GRUB_PE32_SCN_MEM_EXECUTE |
149*4882a593Smuzhiyun+				   GRUB_PE32_SCN_MEM_READ);
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun 	scn_size = ALIGN_UP (layout.kernel_size - layout.exec_size, GRUB_PE32_FILE_ALIGNMENT);
152*4882a593Smuzhiyun 	PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size +
153*4882a593Smuzhiyun 							       ALIGN_UP (total_module_size,
154*4882a593Smuzhiyun 									 GRUB_PE32_FILE_ALIGNMENT));
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun-	data_section = text_section + 1;
157*4882a593Smuzhiyun-	strcpy (data_section->name, ".data");
158*4882a593Smuzhiyun-	data_section->virtual_size = grub_host_to_target32 (layout.kernel_size - layout.exec_size);
159*4882a593Smuzhiyun-	data_section->virtual_address = grub_host_to_target32 (header_size + layout.exec_size);
160*4882a593Smuzhiyun-	data_section->raw_data_size = grub_host_to_target32 (layout.kernel_size - layout.exec_size);
161*4882a593Smuzhiyun-	data_section->raw_data_offset = grub_host_to_target32 (header_size + layout.exec_size);
162*4882a593Smuzhiyun-	data_section->characteristics
163*4882a593Smuzhiyun-	  = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
164*4882a593Smuzhiyun-			      | GRUB_PE32_SCN_MEM_READ
165*4882a593Smuzhiyun-			      | GRUB_PE32_SCN_MEM_WRITE);
166*4882a593Smuzhiyun-
167*4882a593Smuzhiyun-	mods_section = data_section + 1;
168*4882a593Smuzhiyun-	strcpy (mods_section->name, "mods");
169*4882a593Smuzhiyun-	mods_section->virtual_size = grub_host_to_target32 (reloc_addr - layout.kernel_size - header_size);
170*4882a593Smuzhiyun-	mods_section->virtual_address = grub_host_to_target32 (header_size + layout.kernel_size + layout.bss_size);
171*4882a593Smuzhiyun-	mods_section->raw_data_size = grub_host_to_target32 (reloc_addr - layout.kernel_size - header_size);
172*4882a593Smuzhiyun-	mods_section->raw_data_offset = grub_host_to_target32 (header_size + layout.kernel_size);
173*4882a593Smuzhiyun-	mods_section->characteristics
174*4882a593Smuzhiyun-	  = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
175*4882a593Smuzhiyun-			      | GRUB_PE32_SCN_MEM_READ
176*4882a593Smuzhiyun-			      | GRUB_PE32_SCN_MEM_WRITE);
177*4882a593Smuzhiyun-
178*4882a593Smuzhiyun-	PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (reloc_addr);
179*4882a593Smuzhiyun-	PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (layout.reloc_size);
180*4882a593Smuzhiyun-	reloc_section = mods_section + 1;
181*4882a593Smuzhiyun-	strcpy (reloc_section->name, ".reloc");
182*4882a593Smuzhiyun-	reloc_section->virtual_size = grub_host_to_target32 (layout.reloc_size);
183*4882a593Smuzhiyun-	reloc_section->virtual_address = grub_host_to_target32 (reloc_addr + layout.bss_size);
184*4882a593Smuzhiyun-	reloc_section->raw_data_size = grub_host_to_target32 (layout.reloc_size);
185*4882a593Smuzhiyun-	reloc_section->raw_data_offset = grub_host_to_target32 (reloc_addr);
186*4882a593Smuzhiyun-	reloc_section->characteristics
187*4882a593Smuzhiyun-	  = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
188*4882a593Smuzhiyun-			      | GRUB_PE32_SCN_MEM_DISCARDABLE
189*4882a593Smuzhiyun-			      | GRUB_PE32_SCN_MEM_READ);
190*4882a593Smuzhiyun+	section = init_pe_section (image_target, section, ".data",
191*4882a593Smuzhiyun+				   &vma, scn_size, image_target->section_align,
192*4882a593Smuzhiyun+				   &raw_data, scn_size,
193*4882a593Smuzhiyun+				   GRUB_PE32_SCN_CNT_INITIALIZED_DATA |
194*4882a593Smuzhiyun+				   GRUB_PE32_SCN_MEM_READ |
195*4882a593Smuzhiyun+				   GRUB_PE32_SCN_MEM_WRITE);
196*4882a593Smuzhiyun+
197*4882a593Smuzhiyun+	scn_size = pe_size - layout.reloc_size - raw_data;
198*4882a593Smuzhiyun+	section = init_pe_section (image_target, section, "mods",
199*4882a593Smuzhiyun+				   &vma, scn_size, image_target->section_align,
200*4882a593Smuzhiyun+				   &raw_data, scn_size,
201*4882a593Smuzhiyun+				   GRUB_PE32_SCN_CNT_INITIALIZED_DATA |
202*4882a593Smuzhiyun+				   GRUB_PE32_SCN_MEM_READ |
203*4882a593Smuzhiyun+				   GRUB_PE32_SCN_MEM_WRITE);
204*4882a593Smuzhiyun+
205*4882a593Smuzhiyun+	scn_size = layout.reloc_size;
206*4882a593Smuzhiyun+	PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (vma);
207*4882a593Smuzhiyun+	PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (scn_size);
208*4882a593Smuzhiyun+	memcpy (pe_img + raw_data, layout.reloc_section, scn_size);
209*4882a593Smuzhiyun+	init_pe_section (image_target, section, ".reloc",
210*4882a593Smuzhiyun+			 &vma, scn_size, image_target->section_align,
211*4882a593Smuzhiyun+			 &raw_data, scn_size,
212*4882a593Smuzhiyun+			 GRUB_PE32_SCN_CNT_INITIALIZED_DATA |
213*4882a593Smuzhiyun+			 GRUB_PE32_SCN_MEM_DISCARDABLE |
214*4882a593Smuzhiyun+			 GRUB_PE32_SCN_MEM_READ);
215*4882a593Smuzhiyun+
216*4882a593Smuzhiyun 	free (core_img);
217*4882a593Smuzhiyun 	core_img = pe_img;
218*4882a593Smuzhiyun 	core_size = pe_size;
219*4882a593Smuzhiyun--
220*4882a593Smuzhiyun2.14.2
221*4882a593Smuzhiyun
222