1 /* grub-mkimage.c - make a bootable image */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
21 #include <grub/types.h>
23 #include <grub/aout.h>
24 #include <grub/i18n.h>
25 #include <grub/kernel.h>
26 #include <grub/disk.h>
27 #include <grub/emu/misc.h>
28 #include <grub/util/misc.h>
29 #include <grub/util/resolve.h>
30 #include <grub/misc.h>
31 #include <grub/offsets.h>
32 #include <grub/crypto.h>
35 #include <multiboot.h>
42 #include <grub/efi/pe32.h>
43 #include <grub/uboot/image.h>
44 #include <grub/arm/reloc.h>
45 #include <grub/arm64/reloc.h>
46 #include <grub/ia64/reloc.h>
47 #include <grub/loongarch64/reloc.h>
48 #include <grub/osdep/hostfile.h>
49 #include <grub/util/install.h>
50 #include <grub/util/mkimage.h>
52 #include <xen/elfnote.h>
54 #pragma GCC diagnostic ignored "-Wcast-align"
56 #define GRUB_MKIMAGEXX
57 #if !defined(MKIMAGE_ELF32) && !defined(MKIMAGE_ELF64)
58 #if __SIZEOF_POINTER__ == 8
59 #include "grub-mkimage64.c"
61 #include "grub-mkimage32.c"
65 /* These structures are defined according to the CHRP binding to IEEE1275,
66 "Client Program Format" section. */
68 struct grub_ieee1275_note_desc
70 grub_uint32_t real_mode
;
71 grub_uint32_t real_base
;
72 grub_uint32_t real_size
;
73 grub_uint32_t virt_base
;
74 grub_uint32_t virt_size
;
75 grub_uint32_t load_base
;
78 #define GRUB_IEEE1275_NOTE_NAME "PowerPC"
79 #define GRUB_IEEE1275_NOTE_TYPE 0x1275
81 struct grub_ieee1275_note
84 char name
[ALIGN_UP(sizeof (GRUB_IEEE1275_NOTE_NAME
), 4)];
85 struct grub_ieee1275_note_desc descriptor
;
88 #define GRUB_XEN_NOTE_NAME "Xen"
90 struct fixup_block_list
92 struct fixup_block_list
*next
;
94 struct grub_pe32_fixup_block b
;
97 #define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof))
99 struct section_metadata
101 Elf_Half num_sections
;
105 Elf_Half section_entsize
;
110 #define GRUB_SBAT_NOTE_NAME ".sbat"
111 #define GRUB_SBAT_NOTE_TYPE 0x53424154 /* "SBAT" */
113 struct grub_sbat_note
{
115 char name
[ALIGN_UP(sizeof(GRUB_SBAT_NOTE_NAME
), 4)];
119 is_relocatable (const struct grub_install_image_target_desc
*image_target
)
121 return image_target
->id
== IMAGE_EFI
|| image_target
->id
== IMAGE_UBOOT
122 || (image_target
->id
== IMAGE_COREBOOT
&& image_target
->elf_target
== EM_ARM
);
128 * R_ARM_THM_CALL/THM_JUMP24
130 * Relocate Thumb (T32) instruction set relative branches:
134 grub_arm_reloc_thm_call (grub_uint16_t
*target
, Elf32_Addr sym_addr
)
138 offset
= grub_arm_thm_call_get_offset (target
);
140 grub_dprintf ("dl", " sym_addr = 0x%08x", sym_addr
);
144 grub_dprintf("dl", " BL*: target=%p, sym_addr=0x%08x, offset=%d\n",
145 target
, sym_addr
, offset
);
147 /* Keep traditional (pre-Thumb2) limits on blx. In any case if the kernel
148 is bigger than 2M (currently under 150K) then we probably have a problem
150 if (offset
< -0x200000 || offset
>= 0x200000)
151 return grub_error (GRUB_ERR_BAD_MODULE
,
152 "THM_CALL Relocation out of range.");
154 grub_dprintf ("dl", " relative destination = %p",
155 (char *) target
+ offset
);
157 return grub_arm_thm_call_set_offset (target
, offset
);
163 * Relocate conditional Thumb (T32) B<c>.W
166 grub_arm_reloc_thm_jump19 (grub_uint16_t
*target
, Elf32_Addr sym_addr
)
171 return grub_error (GRUB_ERR_BAD_MODULE
,
172 "Relocation targeting wrong execution state");
174 offset
= grub_arm_thm_jump19_get_offset (target
);
176 /* Adjust and re-truncate offset */
179 if (!grub_arm_thm_jump19_check_offset (offset
))
180 return grub_error (GRUB_ERR_BAD_MODULE
,
181 "THM_JUMP19 Relocation out of range.");
183 grub_arm_thm_jump19_set_offset (target
, offset
);
185 return GRUB_ERR_NONE
;
191 * Relocate ARM (A32) B
194 grub_arm_reloc_jump24 (grub_uint32_t
*target
, Elf32_Addr sym_addr
)
199 return grub_error (GRUB_ERR_BAD_MODULE
,
200 "Relocation targeting wrong execution state");
202 offset
= grub_arm_jump24_get_offset (target
);
205 if (!grub_arm_jump24_check_offset (offset
))
206 return grub_error (GRUB_ERR_BAD_MODULE
,
207 "JUMP24 Relocation out of range.");
210 grub_arm_jump24_set_offset (target
, offset
);
212 return GRUB_ERR_NONE
;
218 SUFFIX (grub_mkimage_generate_elf
) (const struct grub_install_image_target_desc
*image_target
,
219 int note
, char *sbat
, char **core_img
, size_t *core_size
,
220 Elf_Addr target_addr
,
221 struct grub_mkimage_layout
*layout
)
228 int header_size
, footer_size
= 0, footer_offset
= 0;
231 int string_size
= sizeof (".text") + sizeof ("mods") + 1;
237 footer_size
+= ALIGN_UP (sizeof (struct grub_sbat_note
) + layout
->sbat_size
, 4);
240 if (image_target
->id
!= IMAGE_LOONGSON_ELF
)
246 footer_size
+= sizeof (struct grub_ieee1275_note
);
248 if (image_target
->id
== IMAGE_XEN
|| image_target
->id
== IMAGE_XEN_PVH
)
252 string_size
+= sizeof (".xen");
253 footer_size
+= (image_target
->id
== IMAGE_XEN
) ? XEN_NOTE_SIZE
: XEN_PVH_NOTE_SIZE
;
255 header_size
= ALIGN_UP (sizeof (*ehdr
) + phnum
* sizeof (*phdr
)
256 + shnum
* sizeof (*shdr
) + string_size
, layout
->align
);
258 program_size
= ALIGN_ADDR (*core_size
);
260 elf_img
= xmalloc (program_size
+ header_size
+ footer_size
);
261 memset (elf_img
, 0, program_size
+ header_size
+ footer_size
);
262 memcpy (elf_img
+ header_size
, *core_img
, *core_size
);
263 ehdr
= (void *) elf_img
;
264 phdr
= (void *) (elf_img
+ sizeof (*ehdr
));
265 shdr
= (void *) (elf_img
+ sizeof (*ehdr
) + phnum
* sizeof (*phdr
));
266 footer
= elf_img
+ program_size
+ header_size
;
267 memcpy (ehdr
->e_ident
, ELFMAG
, SELFMAG
);
268 ehdr
->e_ident
[EI_CLASS
] = ELFCLASSXX
;
269 if (!image_target
->bigendian
)
270 ehdr
->e_ident
[EI_DATA
] = ELFDATA2LSB
;
272 ehdr
->e_ident
[EI_DATA
] = ELFDATA2MSB
;
273 ehdr
->e_ident
[EI_VERSION
] = EV_CURRENT
;
274 ehdr
->e_ident
[EI_OSABI
] = ELFOSABI_NONE
;
275 ehdr
->e_type
= grub_host_to_target16 (ET_EXEC
);
276 ehdr
->e_machine
= grub_host_to_target16 (image_target
->elf_target
);
277 ehdr
->e_version
= grub_host_to_target32 (EV_CURRENT
);
279 ehdr
->e_phoff
= grub_host_to_target32 ((char *) phdr
- (char *) ehdr
);
280 ehdr
->e_phentsize
= grub_host_to_target16 (sizeof (*phdr
));
281 ehdr
->e_phnum
= grub_host_to_target16 (phnum
);
283 ehdr
->e_shoff
= grub_host_to_target32 ((grub_uint8_t
*) shdr
284 - (grub_uint8_t
*) ehdr
);
285 if (image_target
->id
== IMAGE_LOONGSON_ELF
)
286 ehdr
->e_shentsize
= grub_host_to_target16 (0);
288 ehdr
->e_shentsize
= grub_host_to_target16 (sizeof (Elf_Shdr
));
289 ehdr
->e_shnum
= grub_host_to_target16 (shnum
);
290 ehdr
->e_shstrndx
= grub_host_to_target16 (1);
292 ehdr
->e_ehsize
= grub_host_to_target16 (sizeof (*ehdr
));
294 phdr
->p_type
= grub_host_to_target32 (PT_LOAD
);
295 phdr
->p_offset
= grub_host_to_target32 (header_size
);
296 phdr
->p_flags
= grub_host_to_target32 (PF_R
| PF_W
| PF_X
);
298 ehdr
->e_entry
= grub_host_to_target32 (target_addr
);
299 phdr
->p_vaddr
= grub_host_to_target32 (target_addr
);
300 phdr
->p_paddr
= grub_host_to_target32 (target_addr
);
301 phdr
->p_align
= grub_host_to_target32 (layout
->align
> image_target
->link_align
?
302 layout
->align
: image_target
->link_align
);
303 if (image_target
->id
== IMAGE_LOONGSON_ELF
)
304 ehdr
->e_flags
= grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER
305 | EF_MIPS_PIC
| EF_MIPS_CPIC
);
308 if (image_target
->id
== IMAGE_LOONGSON_ELF
)
310 phdr
->p_filesz
= grub_host_to_target32 (*core_size
);
311 phdr
->p_memsz
= grub_host_to_target32 (*core_size
);
315 grub_uint32_t target_addr_mods
;
316 phdr
->p_filesz
= grub_host_to_target32 (layout
->kernel_size
);
317 if (image_target
->id
== IMAGE_COREBOOT
&& image_target
->elf_target
== EM_ARM
)
318 phdr
->p_memsz
= grub_host_to_target32 (layout
->kernel_size
);
320 phdr
->p_memsz
= grub_host_to_target32 (layout
->kernel_size
+ layout
->bss_size
);
323 phdr
->p_type
= grub_host_to_target32 (PT_GNU_STACK
);
324 phdr
->p_offset
= grub_host_to_target32 (header_size
+ layout
->kernel_size
);
325 phdr
->p_paddr
= phdr
->p_vaddr
= phdr
->p_filesz
= phdr
->p_memsz
= 0;
326 phdr
->p_flags
= grub_host_to_target32 (PF_R
| PF_W
| PF_X
);
327 phdr
->p_align
= grub_host_to_target32 (image_target
->link_align
);
330 phdr
->p_type
= grub_host_to_target32 (PT_LOAD
);
331 phdr
->p_offset
= grub_host_to_target32 (header_size
+ layout
->kernel_size
);
332 phdr
->p_flags
= grub_host_to_target32 (PF_R
| PF_W
| PF_X
);
333 phdr
->p_filesz
= phdr
->p_memsz
334 = grub_host_to_target32 (*core_size
- layout
->kernel_size
);
336 if (image_target
->id
== IMAGE_COREBOOT
&& image_target
->elf_target
== EM_386
)
337 target_addr_mods
= GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR
;
338 else if (image_target
->id
== IMAGE_COREBOOT
&& image_target
->elf_target
== EM_ARM
)
339 target_addr_mods
= ALIGN_UP (target_addr
+ layout
->end
340 + image_target
->mod_gap
,
341 image_target
->mod_align
);
343 target_addr_mods
= ALIGN_UP (target_addr
+ layout
->kernel_size
+ layout
->bss_size
344 + image_target
->mod_gap
,
345 image_target
->mod_align
);
346 phdr
->p_vaddr
= grub_host_to_target_addr (target_addr_mods
);
347 phdr
->p_paddr
= grub_host_to_target_addr (target_addr_mods
);
348 phdr
->p_align
= grub_host_to_target32 (image_target
->link_align
);
351 if (image_target
->id
== IMAGE_XEN
)
353 char *note_start
= (elf_img
+ program_size
+ header_size
);
355 char *ptr
= (char *) note_start
;
357 grub_util_info ("adding XEN NOTE segment");
360 note_ptr
= (Elf_Nhdr
*) ptr
;
361 note_ptr
->n_namesz
= grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME
));
362 note_ptr
->n_descsz
= grub_host_to_target32 (sizeof (PACKAGE_NAME
));
363 note_ptr
->n_type
= grub_host_to_target32 (XEN_ELFNOTE_GUEST_OS
);
364 ptr
+= sizeof (Elf_Nhdr
);
365 memcpy (ptr
, GRUB_XEN_NOTE_NAME
, sizeof (GRUB_XEN_NOTE_NAME
));
366 ptr
+= ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME
), 4);
367 memcpy (ptr
, PACKAGE_NAME
, sizeof (PACKAGE_NAME
));
368 ptr
+= ALIGN_UP (sizeof (PACKAGE_NAME
), 4);
371 note_ptr
= (Elf_Nhdr
*) ptr
;
372 note_ptr
->n_namesz
= grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME
));
373 note_ptr
->n_descsz
= grub_host_to_target32 (sizeof ("generic"));
374 note_ptr
->n_type
= grub_host_to_target32 (XEN_ELFNOTE_LOADER
);
375 ptr
+= sizeof (Elf_Nhdr
);
376 memcpy (ptr
, GRUB_XEN_NOTE_NAME
, sizeof (GRUB_XEN_NOTE_NAME
));
377 ptr
+= ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME
), 4);
378 memcpy (ptr
, "generic", sizeof ("generic"));
379 ptr
+= ALIGN_UP (sizeof ("generic"), 4);
382 note_ptr
= (Elf_Nhdr
*) ptr
;
383 note_ptr
->n_namesz
= grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME
));
384 note_ptr
->n_descsz
= grub_host_to_target32 (sizeof ("xen-3.0"));
385 note_ptr
->n_type
= grub_host_to_target32 (XEN_ELFNOTE_XEN_VERSION
);
386 ptr
+= sizeof (Elf_Nhdr
);
387 memcpy (ptr
, GRUB_XEN_NOTE_NAME
, sizeof (GRUB_XEN_NOTE_NAME
));
388 ptr
+= ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME
), 4);
389 memcpy (ptr
, "xen-3.0", sizeof ("xen-3.0"));
390 ptr
+= ALIGN_UP (sizeof ("xen-3.0"), 4);
393 note_ptr
= (Elf_Nhdr
*) ptr
;
394 note_ptr
->n_namesz
= grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME
));
395 note_ptr
->n_descsz
= grub_host_to_target32 (image_target
->voidp_sizeof
);
396 note_ptr
->n_type
= grub_host_to_target32 (XEN_ELFNOTE_ENTRY
);
397 ptr
+= sizeof (Elf_Nhdr
);
398 memcpy (ptr
, GRUB_XEN_NOTE_NAME
, sizeof (GRUB_XEN_NOTE_NAME
));
399 ptr
+= ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME
), 4);
400 memset (ptr
, 0, image_target
->voidp_sizeof
);
401 ptr
+= image_target
->voidp_sizeof
;
404 note_ptr
= (Elf_Nhdr
*) ptr
;
405 note_ptr
->n_namesz
= grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME
));
406 note_ptr
->n_descsz
= grub_host_to_target32 (image_target
->voidp_sizeof
);
407 note_ptr
->n_type
= grub_host_to_target32 (XEN_ELFNOTE_VIRT_BASE
);
408 ptr
+= sizeof (Elf_Nhdr
);
409 memcpy (ptr
, GRUB_XEN_NOTE_NAME
, sizeof (GRUB_XEN_NOTE_NAME
));
410 ptr
+= ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME
), 4);
411 memset (ptr
, 0, image_target
->voidp_sizeof
);
412 ptr
+= image_target
->voidp_sizeof
;
415 if (image_target
->elf_target
== EM_386
)
417 note_ptr
= (Elf_Nhdr
*) ptr
;
418 note_ptr
->n_namesz
= grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME
));
419 note_ptr
->n_descsz
= grub_host_to_target32 (sizeof ("yes,bimodal"));
420 note_ptr
->n_type
= grub_host_to_target32 (XEN_ELFNOTE_PAE_MODE
);
421 ptr
+= sizeof (Elf_Nhdr
);
422 memcpy (ptr
, GRUB_XEN_NOTE_NAME
, sizeof (GRUB_XEN_NOTE_NAME
));
423 ptr
+= ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME
), 4);
424 memcpy (ptr
, "yes", sizeof ("yes"));
425 ptr
+= ALIGN_UP (sizeof ("yes"), 4);
428 assert (XEN_NOTE_SIZE
== (ptr
- note_start
));
431 phdr
->p_type
= grub_host_to_target32 (PT_NOTE
);
432 phdr
->p_flags
= grub_host_to_target32 (PF_R
);
433 phdr
->p_align
= grub_host_to_target32 (image_target
->voidp_sizeof
);
436 phdr
->p_filesz
= grub_host_to_target32 (XEN_NOTE_SIZE
);
438 phdr
->p_offset
= grub_host_to_target32 (header_size
+ program_size
);
440 footer_offset
= XEN_NOTE_SIZE
;
443 if (image_target
->id
== IMAGE_XEN_PVH
)
445 char *note_start
= (elf_img
+ program_size
+ header_size
);
447 char *ptr
= (char *) note_start
;
449 grub_util_info ("adding XEN NOTE segment");
452 note_ptr
= (Elf_Nhdr
*) ptr
;
453 note_ptr
->n_namesz
= grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME
));
454 note_ptr
->n_descsz
= grub_host_to_target32 (image_target
->voidp_sizeof
);
455 note_ptr
->n_type
= grub_host_to_target32 (XEN_ELFNOTE_PHYS32_ENTRY
);
456 ptr
+= sizeof (Elf_Nhdr
);
457 memcpy (ptr
, GRUB_XEN_NOTE_NAME
, sizeof (GRUB_XEN_NOTE_NAME
));
458 ptr
+= ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME
), 4);
459 memset (ptr
, 0, image_target
->voidp_sizeof
);
460 *(grub_uint32_t
*) ptr
= GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR
;
461 ptr
+= image_target
->voidp_sizeof
;
463 assert (XEN_PVH_NOTE_SIZE
== (ptr
- note_start
));
466 phdr
->p_type
= grub_host_to_target32 (PT_NOTE
);
467 phdr
->p_flags
= grub_host_to_target32 (PF_R
);
468 phdr
->p_align
= grub_host_to_target32 (image_target
->voidp_sizeof
);
471 phdr
->p_filesz
= grub_host_to_target32 (XEN_PVH_NOTE_SIZE
);
473 phdr
->p_offset
= grub_host_to_target32 (header_size
+ program_size
);
475 footer_offset
= XEN_PVH_NOTE_SIZE
;
480 int note_size
= sizeof (struct grub_ieee1275_note
);
481 struct grub_ieee1275_note
*note_ptr
= (struct grub_ieee1275_note
*)
482 (elf_img
+ program_size
+ header_size
);
484 grub_util_info ("adding CHRP NOTE segment");
486 note_ptr
->header
.n_namesz
= grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME
));
487 note_ptr
->header
.n_descsz
= grub_host_to_target32 (sizeof (struct grub_ieee1275_note_desc
));
488 note_ptr
->header
.n_type
= grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE
);
489 strcpy (note_ptr
->name
, GRUB_IEEE1275_NOTE_NAME
);
490 note_ptr
->descriptor
.real_mode
= grub_host_to_target32 (0xffffffff);
491 note_ptr
->descriptor
.real_base
= grub_host_to_target32 (0x00c00000);
492 note_ptr
->descriptor
.real_size
= grub_host_to_target32 (0xffffffff);
493 note_ptr
->descriptor
.virt_base
= grub_host_to_target32 (0xffffffff);
494 note_ptr
->descriptor
.virt_size
= grub_host_to_target32 (0xffffffff);
495 note_ptr
->descriptor
.load_base
= grub_host_to_target32 (0x00004000);
498 phdr
->p_type
= grub_host_to_target32 (PT_NOTE
);
499 phdr
->p_flags
= grub_host_to_target32 (PF_R
);
500 phdr
->p_align
= grub_host_to_target32 (image_target
->voidp_sizeof
);
503 phdr
->p_filesz
= grub_host_to_target32 (note_size
);
505 phdr
->p_offset
= grub_host_to_target32 (header_size
+ program_size
);
506 footer
= (elf_img
+ program_size
+ header_size
+ note_size
);
507 footer_offset
+= note_size
;
512 int note_size
= ALIGN_UP (sizeof (struct grub_sbat_note
) + layout
->sbat_size
, 4);
513 struct grub_sbat_note
*note_ptr
= (struct grub_sbat_note
*) footer
;
515 note_ptr
->header
.n_namesz
= grub_host_to_target32 (sizeof (GRUB_SBAT_NOTE_NAME
));
516 note_ptr
->header
.n_descsz
= grub_host_to_target32 (ALIGN_UP(layout
->sbat_size
, 4));
517 note_ptr
->header
.n_type
= grub_host_to_target32 (GRUB_SBAT_NOTE_TYPE
);
518 memcpy (note_ptr
->name
, GRUB_SBAT_NOTE_NAME
, sizeof (GRUB_SBAT_NOTE_NAME
));
519 memcpy ((char *)(note_ptr
+ 1), sbat
, layout
->sbat_size
);
522 phdr
->p_type
= grub_host_to_target32 (PT_NOTE
);
523 phdr
->p_flags
= grub_host_to_target32 (PF_R
);
524 phdr
->p_align
= grub_host_to_target32 (image_target
->voidp_sizeof
);
527 phdr
->p_filesz
= grub_host_to_target32 (note_size
);
529 phdr
->p_offset
= grub_host_to_target32 (header_size
+ program_size
+ footer_offset
);
533 char *str_start
= (elf_img
+ sizeof (*ehdr
) + phnum
* sizeof (*phdr
)
534 + shnum
* sizeof (*shdr
));
535 char *ptr
= str_start
+ 1;
539 shdr
->sh_name
= grub_host_to_target32 (0);
540 shdr
->sh_type
= grub_host_to_target32 (SHT_STRTAB
);
541 shdr
->sh_addr
= grub_host_to_target_addr (0);
542 shdr
->sh_offset
= grub_host_to_target_addr (str_start
- elf_img
);
543 shdr
->sh_size
= grub_host_to_target32 (string_size
);
544 shdr
->sh_link
= grub_host_to_target32 (0);
545 shdr
->sh_info
= grub_host_to_target32 (0);
546 shdr
->sh_addralign
= grub_host_to_target32 (layout
->align
);
547 shdr
->sh_entsize
= grub_host_to_target32 (0);
550 memcpy (ptr
, ".text", sizeof (".text"));
552 shdr
->sh_name
= grub_host_to_target32 (ptr
- str_start
);
553 ptr
+= sizeof (".text");
554 shdr
->sh_type
= grub_host_to_target32 (SHT_PROGBITS
);
555 shdr
->sh_addr
= grub_host_to_target_addr (target_addr
);
556 shdr
->sh_offset
= grub_host_to_target_addr (header_size
);
557 shdr
->sh_size
= grub_host_to_target32 (layout
->kernel_size
);
558 shdr
->sh_link
= grub_host_to_target32 (0);
559 shdr
->sh_info
= grub_host_to_target32 (0);
560 shdr
->sh_addralign
= grub_host_to_target32 (layout
->align
);
561 shdr
->sh_entsize
= grub_host_to_target32 (0);
564 memcpy (ptr
, "mods", sizeof ("mods"));
565 shdr
->sh_name
= grub_host_to_target32 (ptr
- str_start
);
566 ptr
+= sizeof ("mods");
567 shdr
->sh_type
= grub_host_to_target32 (SHT_PROGBITS
);
568 shdr
->sh_addr
= grub_host_to_target_addr (target_addr
+ layout
->kernel_size
);
569 shdr
->sh_offset
= grub_host_to_target_addr (header_size
+ layout
->kernel_size
);
570 shdr
->sh_size
= grub_host_to_target32 (*core_size
- layout
->kernel_size
);
571 shdr
->sh_link
= grub_host_to_target32 (0);
572 shdr
->sh_info
= grub_host_to_target32 (0);
573 shdr
->sh_addralign
= grub_host_to_target32 (image_target
->voidp_sizeof
);
574 shdr
->sh_entsize
= grub_host_to_target32 (0);
577 if (image_target
->id
== IMAGE_XEN
|| image_target
->id
== IMAGE_XEN_PVH
)
579 memcpy (ptr
, ".xen", sizeof (".xen"));
580 shdr
->sh_name
= grub_host_to_target32 (ptr
- str_start
);
581 ptr
+= sizeof (".xen");
582 shdr
->sh_type
= grub_host_to_target32 (SHT_PROGBITS
);
583 shdr
->sh_addr
= grub_host_to_target_addr (target_addr
+ layout
->kernel_size
);
584 shdr
->sh_offset
= grub_host_to_target_addr (program_size
+ header_size
);
585 if (image_target
->id
== IMAGE_XEN
)
586 shdr
->sh_size
= grub_host_to_target32 (XEN_NOTE_SIZE
);
588 shdr
->sh_size
= grub_host_to_target32 (XEN_PVH_NOTE_SIZE
);
589 shdr
->sh_link
= grub_host_to_target32 (0);
590 shdr
->sh_info
= grub_host_to_target32 (0);
591 shdr
->sh_addralign
= grub_host_to_target32 (image_target
->voidp_sizeof
);
592 shdr
->sh_entsize
= grub_host_to_target32 (0);
599 *core_size
= program_size
+ header_size
+ footer_size
;
602 /* Relocate symbols; note that this function overwrites the symbol table.
603 Return the address of a start symbol. */
605 SUFFIX (relocate_symbols
) (Elf_Ehdr
*e
, struct section_metadata
*smd
,
606 void *jumpers
, Elf_Addr jumpers_addr
,
607 Elf_Addr bss_start
, Elf_Addr end
,
608 const struct grub_install_image_target_desc
*image_target
)
610 Elf_Word symtab_size
, sym_size
, num_syms
;
611 Elf_Off symtab_offset
;
612 Elf_Addr start_address
= (Elf_Addr
) -1;
615 Elf_Shdr
*symtab_section
;
617 grub_uint64_t
*jptr
= jumpers
;
619 symtab_section
= (Elf_Shdr
*) ((char *) smd
->sections
620 + grub_target_to_host32 (smd
->symtab
->sh_link
)
621 * smd
->section_entsize
);
622 symtab
= (char *) e
+ grub_target_to_host (symtab_section
->sh_offset
);
624 symtab_size
= grub_target_to_host (smd
->symtab
->sh_size
);
625 sym_size
= grub_target_to_host (smd
->symtab
->sh_entsize
);
626 symtab_offset
= grub_target_to_host (smd
->symtab
->sh_offset
);
627 num_syms
= symtab_size
/ sym_size
;
629 for (i
= 0, sym
= (Elf_Sym
*) ((char *) e
+ symtab_offset
);
631 i
++, sym
= (Elf_Sym
*) ((char *) sym
+ sym_size
))
633 Elf_Section cur_index
;
636 name
= symtab
+ grub_target_to_host32 (sym
->st_name
);
638 cur_index
= grub_target_to_host16 (sym
->st_shndx
);
639 if (cur_index
== STN_ABS
)
643 else if (cur_index
== STN_UNDEF
)
645 if (sym
->st_name
&& grub_strcmp (name
, "__bss_start") == 0)
646 sym
->st_value
= bss_start
;
647 else if (sym
->st_name
&& grub_strcmp (name
, "_end") == 0)
649 else if (sym
->st_name
)
650 grub_util_error ("undefined symbol %s", name
);
654 else if (cur_index
>= smd
->num_sections
)
655 grub_util_error ("section %d does not exist", cur_index
);
658 sym
->st_value
= (grub_target_to_host (sym
->st_value
)
659 + smd
->vaddrs
[cur_index
]);
662 if (image_target
->elf_target
== EM_IA_64
&& ELF_ST_TYPE (sym
->st_info
)
665 *jptr
= grub_host_to_target64 (sym
->st_value
);
666 sym
->st_value
= (char *) jptr
- (char *) jumpers
+ jumpers_addr
;
671 grub_util_info ("locating %s at 0x%" GRUB_HOST_PRIxLONG_LONG
672 " (0x%" GRUB_HOST_PRIxLONG_LONG
")", name
,
673 (unsigned long long) sym
->st_value
,
674 (unsigned long long) smd
->vaddrs
[cur_index
]);
676 if (start_address
== (Elf_Addr
)-1)
677 if (strcmp (name
, "_start") == 0 || strcmp (name
, "start") == 0)
678 start_address
= sym
->st_value
;
681 return start_address
;
684 /* Return the address of a symbol at the index I in the section S. */
686 SUFFIX (get_symbol_address
) (Elf_Ehdr
*e
, Elf_Shdr
*s
, Elf_Word i
,
687 const struct grub_install_image_target_desc
*image_target
)
691 sym
= (Elf_Sym
*) ((char *) e
692 + grub_target_to_host (s
->sh_offset
)
693 + i
* grub_target_to_host (s
->sh_entsize
));
694 return sym
->st_value
;
697 /* Return the address of a modified value. */
699 SUFFIX (get_target_address
) (Elf_Ehdr
*e
, Elf_Shdr
*s
, Elf_Addr offset
,
700 const struct grub_install_image_target_desc
*image_target
)
702 return (Elf_Addr
*) ((char *) e
+ grub_target_to_host (s
->sh_offset
) + offset
);
707 SUFFIX (count_funcs
) (Elf_Ehdr
*e
, Elf_Shdr
*symtab_section
,
708 const struct grub_install_image_target_desc
*image_target
)
710 Elf_Word symtab_size
, sym_size
, num_syms
;
711 Elf_Off symtab_offset
;
716 symtab_size
= grub_target_to_host (symtab_section
->sh_size
);
717 sym_size
= grub_target_to_host (symtab_section
->sh_entsize
);
718 symtab_offset
= grub_target_to_host (symtab_section
->sh_offset
);
719 num_syms
= symtab_size
/ sym_size
;
721 for (i
= 0, sym
= (Elf_Sym
*) ((char *) e
+ symtab_offset
);
723 i
++, sym
= (Elf_Sym
*) ((char *) sym
+ sym_size
))
724 if (ELF_ST_TYPE (sym
->st_info
) == STT_FUNC
)
732 /* Deal with relocation information. This function relocates addresses
733 within the virtual address space starting from 0. So only relative
734 addresses can be fully resolved. Absolute addresses must be relocated
735 again by a PE32 relocator when loaded. */
737 arm_get_trampoline_size (Elf_Ehdr
*e
,
739 Elf_Half section_entsize
,
740 Elf_Half num_sections
,
741 const struct grub_install_image_target_desc
*image_target
)
747 for (i
= 0, s
= sections
;
749 i
++, s
= (Elf_Shdr
*) ((char *) s
+ section_entsize
))
750 if ((s
->sh_type
== grub_host_to_target32 (SHT_REL
)) ||
751 (s
->sh_type
== grub_host_to_target32 (SHT_RELA
)))
754 Elf_Word rtab_size
, r_size
, num_rs
;
756 Elf_Shdr
*symtab_section
;
759 symtab_section
= (Elf_Shdr
*) ((char *) sections
760 + (grub_target_to_host32 (s
->sh_link
)
763 rtab_size
= grub_target_to_host (s
->sh_size
);
764 r_size
= grub_target_to_host (s
->sh_entsize
);
765 rtab_offset
= grub_target_to_host (s
->sh_offset
);
766 num_rs
= rtab_size
/ r_size
;
768 for (j
= 0, r
= (Elf_Rela
*) ((char *) e
+ rtab_offset
);
770 j
++, r
= (Elf_Rela
*) ((char *) r
+ r_size
))
775 info
= grub_target_to_host (r
->r_info
);
776 sym_addr
= SUFFIX (get_symbol_address
) (e
, symtab_section
,
777 ELF_R_SYM (info
), image_target
);
779 sym_addr
+= (s
->sh_type
== grub_target_to_host32 (SHT_RELA
)) ?
780 grub_target_to_host (r
->r_addend
) : 0;
782 switch (ELF_R_TYPE (info
))
788 case R_ARM_THM_JUMP24
:
789 case R_ARM_THM_JUMP19
:
801 grub_util_error (_("relocation 0x%x is not implemented yet"),
802 (unsigned int) ELF_R_TYPE (info
));
812 SUFFIX (is_kept_section
) (Elf_Shdr
*s
, const struct grub_install_image_target_desc
*image_target
);
814 SUFFIX (is_kept_reloc_section
) (Elf_Shdr
*s
, const struct grub_install_image_target_desc
*image_target
,
815 struct section_metadata
*smd
);
817 /* Deal with relocation information. This function relocates addresses
818 within the virtual address space starting from 0. So only relative
819 addresses can be fully resolved. Absolute addresses must be relocated
820 again by a PE32 relocator when loaded. */
822 SUFFIX (relocate_addrs
) (Elf_Ehdr
*e
, struct section_metadata
*smd
,
823 char *pe_target
, Elf_Addr tramp_off
, Elf_Addr got_off
,
824 const struct grub_install_image_target_desc
*image_target
)
829 struct grub_ia64_trampoline
*tr
= (void *) (pe_target
+ tramp_off
);
830 grub_uint64_t
*gpptr
= (void *) (pe_target
+ got_off
);
831 unsigned unmatched_adr_got_page
= 0;
832 struct grub_loongarch64_stack stack
;
833 grub_loongarch64_stack_init (&stack
);
834 #define MASK19 ((1 << 19) - 1)
836 grub_uint32_t
*tr
= (void *) (pe_target
+ tramp_off
);
839 for (i
= 0, s
= smd
->sections
;
840 i
< smd
->num_sections
;
841 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
->section_entsize
))
842 if ((s
->sh_type
== grub_host_to_target32 (SHT_REL
)) ||
843 (s
->sh_type
== grub_host_to_target32 (SHT_RELA
)))
846 Elf_Word rtab_size
, r_size
, num_rs
;
848 Elf_Word target_section_index
;
849 Elf_Addr target_section_addr
;
850 Elf_Shdr
*target_section
;
853 if (!SUFFIX (is_kept_section
) (s
, image_target
) &&
854 !SUFFIX (is_kept_reloc_section
) (s
, image_target
, smd
))
856 grub_util_info ("not translating relocations for omitted section %s",
857 smd
->strtab
+ grub_le_to_cpu32 (s
->sh_name
));
861 target_section_index
= grub_target_to_host32 (s
->sh_info
);
862 target_section_addr
= smd
->addrs
[target_section_index
];
863 target_section
= (Elf_Shdr
*) ((char *) smd
->sections
864 + (target_section_index
865 * smd
->section_entsize
));
867 grub_util_info ("dealing with the relocation section %s for %s",
868 smd
->strtab
+ grub_target_to_host32 (s
->sh_name
),
869 smd
->strtab
+ grub_target_to_host32 (target_section
->sh_name
));
871 rtab_size
= grub_target_to_host (s
->sh_size
);
872 r_size
= grub_target_to_host (s
->sh_entsize
);
873 rtab_offset
= grub_target_to_host (s
->sh_offset
);
874 num_rs
= rtab_size
/ r_size
;
876 for (j
= 0, r
= (Elf_Rela
*) ((char *) e
+ rtab_offset
);
878 j
++, r
= (Elf_Rela
*) ((char *) r
+ r_size
))
886 offset
= grub_target_to_host (r
->r_offset
);
887 target
= SUFFIX (get_target_address
) (e
, target_section
,
888 offset
, image_target
);
889 info
= grub_target_to_host (r
->r_info
);
890 sym_addr
= SUFFIX (get_symbol_address
) (e
, smd
->symtab
,
891 ELF_R_SYM (info
), image_target
);
893 addend
= (s
->sh_type
== grub_target_to_host32 (SHT_RELA
)) ?
894 grub_target_to_host (r
->r_addend
) : 0;
896 switch (image_target
->elf_target
)
899 switch (ELF_R_TYPE (info
))
905 /* This is absolute. */
906 *target
= grub_host_to_target32 (grub_target_to_host32 (*target
)
907 + addend
+ sym_addr
);
908 grub_util_info ("relocating an R_386_32 entry to 0x%"
909 GRUB_HOST_PRIxLONG_LONG
" at the offset 0x%"
910 GRUB_HOST_PRIxLONG_LONG
,
911 (unsigned long long) *target
,
912 (unsigned long long) offset
);
916 /* This is relative. */
917 *target
= grub_host_to_target32 (grub_target_to_host32 (*target
)
919 - target_section_addr
- offset
920 - image_target
->vaddr_offset
);
921 grub_util_info ("relocating an R_386_PC32 entry to 0x%"
922 GRUB_HOST_PRIxLONG_LONG
" at the offset 0x%"
923 GRUB_HOST_PRIxLONG_LONG
,
924 (unsigned long long) *target
,
925 (unsigned long long) offset
);
928 grub_util_error (_("relocation 0x%x is not implemented yet"),
929 (unsigned int) ELF_R_TYPE (info
));
935 switch (ELF_R_TYPE (info
))
942 *target
= grub_host_to_target64 (grub_target_to_host64 (*target
)
943 + addend
+ sym_addr
);
944 grub_util_info ("relocating an R_X86_64_64 entry to 0x%"
945 GRUB_HOST_PRIxLONG_LONG
" at the offset 0x%"
946 GRUB_HOST_PRIxLONG_LONG
,
947 (unsigned long long) *target
,
948 (unsigned long long) offset
);
954 grub_uint32_t
*t32
= (grub_uint32_t
*) target
;
955 *t32
= grub_host_to_target64 (grub_target_to_host32 (*t32
)
957 - target_section_addr
- offset
958 - image_target
->vaddr_offset
);
959 grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%"
960 GRUB_HOST_PRIxLONG_LONG
,
961 *t32
, (unsigned long long) offset
);
967 *target
= grub_host_to_target64 (grub_target_to_host64 (*target
)
969 - target_section_addr
- offset
970 - image_target
->vaddr_offset
);
971 grub_util_info ("relocating an R_X86_64_PC64 entry to 0x%"
972 GRUB_HOST_PRIxLONG_LONG
" at the offset 0x%"
973 GRUB_HOST_PRIxLONG_LONG
,
974 (unsigned long long) *target
,
975 (unsigned long long) offset
);
982 grub_uint32_t
*t32
= (grub_uint32_t
*) target
;
983 *t32
= grub_host_to_target64 (grub_target_to_host32 (*t32
)
984 + addend
+ sym_addr
);
985 grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%"
986 GRUB_HOST_PRIxLONG_LONG
,
987 *t32
, (unsigned long long) offset
);
992 grub_util_error (_("relocation 0x%x is not implemented yet"),
993 (unsigned int) ELF_R_TYPE (info
));
998 switch (ELF_R_TYPE (info
))
1000 case R_IA64_PCREL21B
:
1003 grub_ia64_make_trampoline (tr
, addend
+ sym_addr
);
1004 noff
= ((char *) tr
- (char *) pe_target
1005 - target_section_addr
- (offset
& ~3)) >> 4;
1008 grub_util_error ("trampoline offset too big (%"
1009 GRUB_HOST_PRIxLONG_LONG
")",
1010 (unsigned long long) noff
);
1011 grub_ia64_add_value_to_slot_20b ((grub_addr_t
) target
, noff
);
1015 case R_IA64_LTOFF22X
:
1016 case R_IA64_LTOFF22
:
1020 sym
= (Elf_Sym
*) ((char *) e
1021 + grub_target_to_host (smd
->symtab
->sh_offset
)
1022 + ELF_R_SYM (info
) * grub_target_to_host (smd
->symtab
->sh_entsize
));
1023 if (ELF_ST_TYPE (sym
->st_info
) == STT_FUNC
)
1024 sym_addr
= grub_target_to_host64 (*(grub_uint64_t
*) (pe_target
1026 - image_target
->vaddr_offset
));
1029 case R_IA64_LTOFF_FPTR22
:
1030 *gpptr
= grub_host_to_target64 (addend
+ sym_addr
);
1031 grub_ia64_add_value_to_slot_21 ((grub_addr_t
) target
,
1032 (char *) gpptr
- (char *) pe_target
1033 + image_target
->vaddr_offset
);
1037 case R_IA64_GPREL22
:
1038 grub_ia64_add_value_to_slot_21 ((grub_addr_t
) target
,
1041 case R_IA64_GPREL64I
:
1042 grub_ia64_set_immu64 ((grub_addr_t
) target
,
1045 case R_IA64_PCREL64LSB
:
1046 *target
= grub_host_to_target64 (grub_target_to_host64 (*target
)
1048 - target_section_addr
- offset
1049 - image_target
->vaddr_offset
);
1052 case R_IA64_SEGREL64LSB
:
1053 *target
= grub_host_to_target64 (grub_target_to_host64 (*target
)
1054 + addend
+ sym_addr
- target_section_addr
);
1056 case R_IA64_DIR64LSB
:
1057 case R_IA64_FPTR64LSB
:
1058 *target
= grub_host_to_target64 (grub_target_to_host64 (*target
)
1059 + addend
+ sym_addr
);
1060 grub_util_info ("relocating a direct entry to 0x%"
1061 GRUB_HOST_PRIxLONG_LONG
" at the offset 0x%"
1062 GRUB_HOST_PRIxLONG_LONG
,
1063 (unsigned long long)
1064 grub_target_to_host64 (*target
),
1065 (unsigned long long) offset
);
1068 /* We treat LTOFF22X as LTOFF22, so we can ignore LDXMOV. */
1073 grub_util_error (_("relocation 0x%x is not implemented yet"),
1074 (unsigned int) ELF_R_TYPE (info
));
1081 switch (ELF_R_TYPE (info
))
1083 case R_AARCH64_ABS64
:
1085 *target
= grub_host_to_target64 (grub_target_to_host64 (*target
) + sym_addr
);
1088 case R_AARCH64_PREL32
:
1090 grub_uint32_t
*t32
= (grub_uint32_t
*) target
;
1091 *t32
= grub_host_to_target64 (grub_target_to_host32 (*t32
)
1093 - target_section_addr
- offset
1094 - image_target
->vaddr_offset
);
1095 grub_util_info ("relocating an R_AARCH64_PREL32 entry to 0x%x at the offset 0x%"
1096 GRUB_HOST_PRIxLONG_LONG
,
1097 *t32
, (unsigned long long) offset
);
1100 case R_AARCH64_ADD_ABS_LO12_NC
:
1101 grub_arm64_set_abs_lo12 ((grub_uint32_t
*) target
,
1104 case R_AARCH64_LDST64_ABS_LO12_NC
:
1105 grub_arm64_set_abs_lo12_ldst64 ((grub_uint32_t
*) target
,
1108 case R_AARCH64_JUMP26
:
1109 case R_AARCH64_CALL26
:
1112 sym_addr
-= target_section_addr
+ image_target
->vaddr_offset
;
1113 if (!grub_arm_64_check_xxxx26_offset (sym_addr
))
1114 grub_util_error ("%s", "CALL26 Relocation out of range");
1116 grub_arm64_set_xxxx26_offset((grub_uint32_t
*)target
,
1120 case R_AARCH64_ADR_GOT_PAGE
:
1123 grub_int64_t gpoffset
= (((char *) gpptr
- (char *) pe_target
+ image_target
->vaddr_offset
) & ~0xfffULL
)
1124 - ((offset
+ target_section_addr
+ image_target
->vaddr_offset
) & ~0xfffULL
);
1126 *gpptr
= grub_host_to_target64 (sym_addr
);
1127 unmatched_adr_got_page
++;
1128 if (!grub_arm64_check_hi21_signed (gpoffset
))
1129 grub_util_error ("HI21 out of range");
1130 grub_arm64_set_hi21((grub_uint32_t
*)target
,
1132 for (k
= 0, rel2
= (Elf_Rela
*) ((char *) r
+ r_size
);
1134 k
++, rel2
= (Elf_Rela
*) ((char *) rel2
+ r_size
))
1135 if (ELF_R_SYM (rel2
->r_info
)
1136 == ELF_R_SYM (r
->r_info
)
1137 && r
->r_addend
== rel2
->r_addend
1138 && ELF_R_TYPE (rel2
->r_info
) == R_AARCH64_LD64_GOT_LO12_NC
)
1140 grub_arm64_set_abs_lo12_ldst64 ((grub_uint32_t
*) SUFFIX (get_target_address
) (e
, target_section
,
1141 grub_target_to_host (rel2
->r_offset
), image_target
),
1142 ((char *) gpptr
- (char *) pe_target
+ image_target
->vaddr_offset
));
1146 grub_util_error ("ADR_GOT_PAGE without matching LD64_GOT_LO12_NC");
1150 case R_AARCH64_LD64_GOT_LO12_NC
:
1151 if (unmatched_adr_got_page
== 0)
1152 grub_util_error ("LD64_GOT_LO12_NC without matching ADR_GOT_PAGE");
1153 unmatched_adr_got_page
--;
1155 case R_AARCH64_ADR_PREL_PG_HI21
:
1157 sym_addr
&= ~0xfffULL
;
1158 sym_addr
-= (offset
+ target_section_addr
+ image_target
->vaddr_offset
) & ~0xfffULL
;
1159 if (!grub_arm64_check_hi21_signed (sym_addr
))
1160 grub_util_error ("%s", "CALL26 Relocation out of range");
1162 grub_arm64_set_hi21((grub_uint32_t
*)target
,
1167 grub_util_error (_("relocation 0x%x is not implemented yet"),
1168 (unsigned int) ELF_R_TYPE (info
));
1177 grub_uint32_t
*t32
= (grub_uint32_t
*) target
;
1180 pc
= offset
+ target_section_addr
+ image_target
->vaddr_offset
;
1182 switch (ELF_R_TYPE (info
))
1186 grub_uint64_t
*t64
= (grub_uint64_t
*) target
;
1187 *t64
= grub_host_to_target64 (grub_target_to_host64 (*t64
) + sym_addr
);
1190 case R_LARCH_MARK_LA
:
1192 case R_LARCH_SOP_PUSH_PCREL
:
1193 case R_LARCH_SOP_PUSH_PLT_PCREL
:
1194 grub_loongarch64_sop_push (&stack
, sym_addr
1195 -(target_section_addr
1197 +image_target
->vaddr_offset
));
1203 off
= sym_addr
- pc
;
1205 grub_loongarch64_b26 (t32
, off
);
1208 case R_LARCH_ABS_HI20
:
1209 grub_loongarch64_xxx_hi20 (t32
, sym_addr
);
1211 case R_LARCH_ABS64_LO20
:
1212 grub_loongarch64_abs64_lo20 (t32
, sym_addr
);
1214 case R_LARCH_ABS64_HI12
:
1215 grub_loongarch64_abs64_hi12 (t32
, sym_addr
);
1217 case R_LARCH_PCALA_HI20
:
1221 hi20
= (((sym_addr
+ 0x800) & ~0xfffULL
) - (pc
& ~0xfffULL
));
1223 grub_loongarch64_xxx_hi20 (t32
, hi20
);
1226 case R_LARCH_ABS_LO12
:
1227 case R_LARCH_PCALA_LO12
:
1228 grub_loongarch64_xxx_lo12 (t32
, sym_addr
);
1230 GRUB_LOONGARCH64_RELOCATION (&stack
, target
, sym_addr
)
1232 grub_util_error (_("relocation 0x%x is not implemented yet"),
1233 (unsigned int) ELF_R_TYPE (info
));
1239 #if defined(MKIMAGE_ELF32)
1243 sym_addr
-= image_target
->vaddr_offset
;
1244 switch (ELF_R_TYPE (info
))
1248 grub_util_info (" ABS32:\toffset=%d\t(0x%08x)",
1249 (int) sym_addr
, (int) sym_addr
);
1250 /* Data will be naturally aligned */
1251 if (image_target
->id
== IMAGE_EFI
)
1252 sym_addr
+= GRUB_PE32_SECTION_ALIGNMENT
;
1253 *target
= grub_host_to_target32 (grub_target_to_host32 (*target
) + sym_addr
);
1256 /* Happens when compiled with -march=armv4.
1257 Since currently we need at least armv5, keep bx as-is.
1261 case R_ARM_THM_CALL
:
1262 case R_ARM_THM_JUMP24
:
1263 case R_ARM_THM_JUMP19
:
1267 grub_util_info (" THM_JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)",
1268 (unsigned long) ((char *) target
1271 sym
= (Elf_Sym
*) ((char *) e
1272 + grub_target_to_host (smd
->symtab
->sh_offset
)
1273 + ELF_R_SYM (info
) * grub_target_to_host (smd
->symtab
->sh_entsize
));
1274 if (ELF_ST_TYPE (sym
->st_info
) != STT_FUNC
)
1276 if (!(sym_addr
& 1))
1278 grub_uint32_t tr_addr
;
1279 grub_int32_t new_offset
;
1280 tr_addr
= (char *) tr
- (char *) pe_target
1281 - target_section_addr
;
1282 new_offset
= sym_addr
- tr_addr
- 12;
1284 if (!grub_arm_jump24_check_offset (new_offset
))
1285 return grub_util_error ("jump24 relocation out of range");
1287 tr
[0] = grub_host_to_target32 (0x46c04778); /* bx pc; nop */
1288 tr
[1] = grub_host_to_target32 (((new_offset
>> 2) & 0xffffff) | 0xea000000); /* b new_offset */
1290 sym_addr
= tr_addr
| 1;
1293 /* Thumb instructions can be 16-bit aligned */
1294 if (ELF_R_TYPE (info
) == R_ARM_THM_JUMP19
)
1295 err
= grub_arm_reloc_thm_jump19 ((grub_uint16_t
*) target
, sym_addr
);
1297 err
= grub_arm_reloc_thm_call ((grub_uint16_t
*) target
,
1300 grub_util_error ("%s", grub_errmsg
);
1308 grub_util_info (" JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)", (unsigned long) ((char *) target
- (char *) e
), sym_addr
);
1311 grub_uint32_t tr_addr
;
1312 grub_int32_t new_offset
;
1313 tr_addr
= (char *) tr
- (char *) pe_target
1314 - target_section_addr
;
1315 new_offset
= sym_addr
- tr_addr
- 12;
1317 /* There is no immediate version of bx, only register one... */
1318 tr
[0] = grub_host_to_target32 (0xe59fc004); /* ldr ip, [pc, #4] */
1319 tr
[1] = grub_host_to_target32 (0xe08cc00f); /* add ip, ip, pc */
1320 tr
[2] = grub_host_to_target32 (0xe12fff1c); /* bx ip */
1321 tr
[3] = grub_host_to_target32 (new_offset
| 1);
1326 err
= grub_arm_reloc_jump24 (target
,
1329 grub_util_error ("%s", grub_errmsg
);
1334 grub_util_error (_("relocation 0x%x is not implemented yet"),
1335 (unsigned int) ELF_R_TYPE (info
));
1340 #endif /* MKIMAGE_ELF32 */
1343 grub_uint64_t
*t64
= (grub_uint64_t
*) target
;
1344 grub_uint32_t
*t32
= (grub_uint32_t
*) target
;
1345 grub_uint16_t
*t16
= (grub_uint16_t
*) target
;
1346 grub_uint8_t
*t8
= (grub_uint8_t
*) target
;
1350 * Instructions and instruction encoding are documented in the RISC-V
1351 * specification. This file is based on version 2.2:
1353 * https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-spec-v2.2.pdf
1357 off
= sym_addr
- target_section_addr
- offset
- image_target
->vaddr_offset
;
1359 switch (ELF_R_TYPE (info
))
1362 *t8
= *t8
+ sym_addr
;
1365 *t16
= grub_host_to_target16 (grub_target_to_host16 (*t16
) + sym_addr
);
1369 *t32
= grub_host_to_target32 (grub_target_to_host32 (*t32
) + sym_addr
);
1373 *t64
= grub_host_to_target64 (grub_target_to_host64 (*t64
) + sym_addr
);
1377 *t8
= sym_addr
- *t8
;
1380 *t16
= grub_host_to_target16 (grub_target_to_host16 (*t16
) - sym_addr
);
1383 *t32
= grub_host_to_target32 (grub_target_to_host32 (*t32
) - sym_addr
);
1386 *t64
= grub_host_to_target64 (grub_target_to_host64 (*t64
) - sym_addr
);
1388 case R_RISCV_BRANCH
:
1390 grub_uint32_t imm12
= (off
& 0x1000) << (31 - 12);
1391 grub_uint32_t imm11
= (off
& 0x800) >> (11 - 7);
1392 grub_uint32_t imm10_5
= (off
& 0x7e0) << (30 - 10);
1393 grub_uint32_t imm4_1
= (off
& 0x1e) << (11 - 4);
1394 *t32
= grub_host_to_target32 ((grub_target_to_host32 (*t32
) & 0x1fff07f)
1395 | imm12
| imm11
| imm10_5
| imm4_1
);
1400 grub_uint32_t imm20
= (off
& 0x100000) << (31 - 20);
1401 grub_uint32_t imm19_12
= (off
& 0xff000);
1402 grub_uint32_t imm11
= (off
& 0x800) << (20 - 11);
1403 grub_uint32_t imm10_1
= (off
& 0x7fe) << (30 - 10);
1404 *t32
= grub_host_to_target32 ((grub_target_to_host32 (*t32
) & 0xfff)
1405 | imm20
| imm19_12
| imm11
| imm10_1
);
1409 case R_RISCV_CALL_PLT
:
1411 grub_uint32_t hi20
, lo12
;
1413 if (off
!= (grub_int32_t
)off
)
1414 grub_util_error ("target %lx not reachable from pc=%lx", (long)sym_addr
, (long)((char *)target
- (char *)e
));
1416 hi20
= (off
+ 0x800) & 0xfffff000;
1417 lo12
= (off
- hi20
) & 0xfff;
1418 t32
[0] = grub_host_to_target32 ((grub_target_to_host32 (t32
[0]) & 0xfff) | hi20
);
1419 t32
[1] = grub_host_to_target32 ((grub_target_to_host32 (t32
[1]) & 0xfffff) | (lo12
<< 20));
1422 case R_RISCV_RVC_BRANCH
:
1424 grub_uint16_t imm8
= (off
& 0x100) << (12 - 8);
1425 grub_uint16_t imm7_6
= (off
& 0xc0) >> (6 - 5);
1426 grub_uint16_t imm5
= (off
& 0x20) >> (5 - 2);
1427 grub_uint16_t imm4_3
= (off
& 0x18) << (12 - 5);
1428 grub_uint16_t imm2_1
= (off
& 0x6) << (12 - 10);
1429 *t16
= grub_host_to_target16 ((grub_target_to_host16 (*t16
) & 0xe383)
1430 | imm8
| imm7_6
| imm5
| imm4_3
| imm2_1
);
1433 case R_RISCV_RVC_JUMP
:
1435 grub_uint16_t imm11
= (off
& 0x800) << (12 - 11);
1436 grub_uint16_t imm10
= (off
& 0x400) >> (10 - 8);
1437 grub_uint16_t imm9_8
= (off
& 0x300) << (12 - 11);
1438 grub_uint16_t imm7
= (off
& 0x80) >> (7 - 6);
1439 grub_uint16_t imm6
= (off
& 0x40) << (12 - 11);
1440 grub_uint16_t imm5
= (off
& 0x20) >> (5 - 2);
1441 grub_uint16_t imm4
= (off
& 0x10) << (12 - 5);
1442 grub_uint16_t imm3_1
= (off
& 0xe) << (12 - 10);
1443 *t16
= grub_host_to_target16 ((grub_target_to_host16 (*t16
) & 0xe003)
1444 | imm11
| imm10
| imm9_8
| imm7
| imm6
1445 | imm5
| imm4
| imm3_1
);
1448 case R_RISCV_PCREL_HI20
:
1452 if (off
!= (grub_int32_t
)off
)
1453 grub_util_error ("target %lx not reachable from pc=%lx", (long)sym_addr
, (long)((char *)target
- (char *)e
));
1455 hi20
= (off
+ 0x800) & 0xfffff000;
1456 *t32
= grub_host_to_target32 ((grub_target_to_host32 (*t32
) & 0xfff) | hi20
);
1459 case R_RISCV_PCREL_LO12_I
:
1460 case R_RISCV_PCREL_LO12_S
:
1464 /* Search backwards for matching HI20 reloc. */
1465 for (k
= j
, rel2
= (Elf_Rela
*) ((char *) r
- r_size
);
1467 k
--, rel2
= (Elf_Rela
*) ((char *) rel2
- r_size
))
1470 Elf_Addr rel2_offset
;
1471 Elf_Addr rel2_sym_addr
;
1472 Elf_Addr rel2_addend
;
1474 grub_int64_t rel2_off
;
1476 rel2_offset
= grub_target_to_host (rel2
->r_offset
);
1477 rel2_info
= grub_target_to_host (rel2
->r_info
);
1478 rel2_loc
= target_section_addr
+ rel2_offset
+ image_target
->vaddr_offset
;
1480 if (ELF_R_TYPE (rel2_info
) == R_RISCV_PCREL_HI20
1481 && rel2_loc
== sym_addr
)
1483 rel2_sym_addr
= SUFFIX (get_symbol_address
)
1484 (e
, smd
->symtab
, ELF_R_SYM (rel2_info
),
1486 rel2_addend
= (s
->sh_type
== grub_target_to_host32 (SHT_RELA
)) ?
1487 grub_target_to_host (rel2
->r_addend
) : 0;
1488 rel2_off
= rel2_sym_addr
+ rel2_addend
- rel2_loc
;
1489 off
= rel2_off
- ((rel2_off
+ 0x800) & 0xfffff000);
1491 if (ELF_R_TYPE (info
) == R_RISCV_PCREL_LO12_I
)
1492 *t32
= grub_host_to_target32 ((grub_target_to_host32 (*t32
) & 0xfffff) | (off
& 0xfff) << 20);
1495 grub_uint32_t imm11_5
= (off
& 0xfe0) << (31 - 11);
1496 grub_uint32_t imm4_0
= (off
& 0x1f) << (11 - 4);
1497 *t32
= grub_host_to_target32 ((grub_target_to_host32 (*t32
) & 0x1fff07f) | imm11_5
| imm4_0
);
1503 grub_util_error ("cannot find matching HI20 relocation");
1507 *t32
= grub_host_to_target32 ((grub_target_to_host32 (*t32
) & 0xfff) | (((grub_int32_t
) sym_addr
+ 0x800) & 0xfffff000));
1509 case R_RISCV_LO12_I
:
1511 grub_int32_t lo12
= (grub_int32_t
) sym_addr
- (((grub_int32_t
) sym_addr
+ 0x800) & 0xfffff000);
1512 *t32
= grub_host_to_target32 ((grub_target_to_host32 (*t32
) & 0xfffff) | ((lo12
& 0xfff) << 20));
1515 case R_RISCV_LO12_S
:
1517 grub_int32_t lo12
= (grub_int32_t
) sym_addr
- (((grub_int32_t
) sym_addr
+ 0x800) & 0xfffff000);
1518 grub_uint32_t imm11_5
= (lo12
& 0xfe0) << (31 - 11);
1519 grub_uint32_t imm4_0
= (lo12
& 0x1f) << (11 - 4);
1520 *t32
= grub_host_to_target32 ((grub_target_to_host32 (*t32
) & 0x1fff07f) | imm11_5
| imm4_0
);
1526 grub_util_error (_("relocation 0x%x is not implemented yet"),
1527 (unsigned int) ELF_R_TYPE (info
));
1533 grub_util_error ("unknown architecture type %d",
1534 image_target
->elf_target
);
1540 /* Add a PE32's fixup entry for a relocation. Return the resulting address
1541 after having written to the file OUT. */
1543 add_fixup_entry (struct fixup_block_list
**cblock
, grub_uint16_t type
,
1544 Elf_Addr addr
, int flush
, Elf_Addr current_address
,
1545 const struct grub_install_image_target_desc
*image_target
)
1547 struct grub_pe32_fixup_block
*b
;
1549 b
= &((*cblock
)->b
);
1551 /* First, check if it is necessary to write out the current block. */
1552 if ((*cblock
)->state
)
1554 if (flush
|| addr
< b
->page_rva
|| b
->page_rva
+ 0x1000 <= addr
)
1560 /* Add as much padding as necessary to align the address
1561 with a section boundary. */
1562 Elf_Addr next_address
;
1563 unsigned padding_size
;
1566 next_address
= current_address
+ b
->block_size
;
1567 padding_size
= ((ALIGN_UP (next_address
, image_target
->section_align
)
1570 cur_index
= ((b
->block_size
- sizeof (*b
)) >> 1);
1571 grub_util_info ("adding %d padding fixup entries", padding_size
);
1572 while (padding_size
--)
1574 b
->entries
[cur_index
++] = 0;
1578 else while (b
->block_size
& (8 - 1))
1580 /* If not aligned with a 32-bit boundary, add
1584 grub_util_info ("adding a padding fixup entry");
1585 cur_index
= ((b
->block_size
- sizeof (*b
)) >> 1);
1586 b
->entries
[cur_index
] = 0;
1591 grub_util_info ("writing %d bytes of a fixup block starting at 0x%x",
1592 b
->block_size
, b
->page_rva
);
1593 size
= b
->block_size
;
1594 current_address
+= size
;
1595 b
->page_rva
= grub_host_to_target32 (b
->page_rva
);
1596 b
->block_size
= grub_host_to_target32 (b
->block_size
);
1597 (*cblock
)->next
= xmalloc (sizeof (**cblock
) + 2 * 0x1000);
1598 memset ((*cblock
)->next
, 0, sizeof (**cblock
) + 2 * 0x1000);
1599 *cblock
= (*cblock
)->next
;
1603 b
= &((*cblock
)->b
);
1607 grub_uint16_t entry
;
1610 /* If not allocated yet, allocate a block with enough entries. */
1611 if (! (*cblock
)->state
)
1613 (*cblock
)->state
= 1;
1615 /* The spec does not mention the requirement of a Page RVA.
1616 Here, align the address with a 4K boundary for safety. */
1617 b
->page_rva
= (addr
& ~(0x1000 - 1));
1618 b
->block_size
= sizeof (*b
);
1622 if (b
->block_size
>= sizeof (*b
) + 2 * 0x1000)
1623 grub_util_error ("too many fixup entries");
1625 /* Add a new entry. */
1626 cur_index
= ((b
->block_size
- sizeof (*b
)) >> 1);
1627 entry
= GRUB_PE32_FIXUP_ENTRY (type
, addr
- b
->page_rva
);
1628 b
->entries
[cur_index
] = grub_host_to_target16 (entry
);
1632 return current_address
;
1637 struct raw_reloc
*next
;
1638 grub_uint32_t offset
;
1639 enum raw_reloc_type
{
1640 RAW_RELOC_NONE
= -1,
1646 struct translate_context
1649 struct fixup_block_list
*lst
, *lst0
;
1650 Elf_Addr current_address
;
1653 struct raw_reloc
*raw_relocs
;
1657 translate_reloc_start (struct translate_context
*ctx
,
1658 const struct grub_install_image_target_desc
*image_target
)
1660 grub_memset (ctx
, 0, sizeof (*ctx
));
1661 if (image_target
->id
== IMAGE_EFI
)
1663 ctx
->lst
= ctx
->lst0
= xmalloc (sizeof (*ctx
->lst
) + 2 * 0x1000);
1664 memset (ctx
->lst
, 0, sizeof (*ctx
->lst
) + 2 * 0x1000);
1665 ctx
->current_address
= 0;
1670 translate_relocation_pe (struct translate_context
*ctx
,
1673 const struct grub_install_image_target_desc
*image_target
)
1675 /* Necessary to relocate only absolute addresses. */
1676 switch (image_target
->elf_target
)
1679 if (ELF_R_TYPE (info
) == R_386_32
)
1681 grub_util_info ("adding a relocation entry for 0x%"
1682 GRUB_HOST_PRIxLONG_LONG
,
1683 (unsigned long long) addr
);
1684 ctx
->current_address
1685 = add_fixup_entry (&ctx
->lst
,
1686 GRUB_PE32_REL_BASED_HIGHLOW
,
1687 addr
, 0, ctx
->current_address
,
1692 if ((ELF_R_TYPE (info
) == R_X86_64_32
) ||
1693 (ELF_R_TYPE (info
) == R_X86_64_32S
))
1695 grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)");
1697 else if (ELF_R_TYPE (info
) == R_X86_64_64
)
1699 grub_util_info ("adding a relocation entry for 0x%"
1700 GRUB_HOST_PRIxLONG_LONG
,
1701 (unsigned long long) addr
);
1702 ctx
->current_address
1703 = add_fixup_entry (&ctx
->lst
,
1704 GRUB_PE32_REL_BASED_DIR64
,
1706 0, ctx
->current_address
,
1711 switch (ELF_R_TYPE (info
))
1713 case R_IA64_PCREL64LSB
:
1715 case R_IA64_PCREL21B
:
1716 case R_IA64_LTOFF_FPTR22
:
1717 case R_IA64_LTOFF22X
:
1718 case R_IA64_LTOFF22
:
1719 case R_IA64_GPREL22
:
1720 case R_IA64_GPREL64I
:
1721 case R_IA64_SEGREL64LSB
:
1724 case R_IA64_FPTR64LSB
:
1725 case R_IA64_DIR64LSB
:
1728 grub_util_info ("adding a relocation entry for 0x%"
1729 GRUB_HOST_PRIxLONG_LONG
,
1730 (unsigned long long) addr
);
1731 ctx
->current_address
1732 = add_fixup_entry (&ctx
->lst
,
1733 GRUB_PE32_REL_BASED_DIR64
,
1735 0, ctx
->current_address
,
1741 grub_util_error (_("relocation 0x%x is not implemented yet"),
1742 (unsigned int) ELF_R_TYPE (info
));
1747 #if defined(MKIMAGE_ELF64)
1748 switch (ELF_R_TYPE (info
))
1750 case R_AARCH64_ABS64
:
1752 ctx
->current_address
1753 = add_fixup_entry (&ctx
->lst
,
1754 GRUB_PE32_REL_BASED_DIR64
,
1755 addr
, 0, ctx
->current_address
,
1759 /* Relative relocations do not require fixup entries. */
1760 case R_AARCH64_CALL26
:
1761 case R_AARCH64_JUMP26
:
1762 case R_AARCH64_PREL32
:
1764 /* Page-relative relocations do not require fixup entries. */
1765 case R_AARCH64_ADR_PREL_PG_HI21
:
1766 /* We page-align the whole kernel, so no need
1769 case R_AARCH64_ADD_ABS_LO12_NC
:
1770 case R_AARCH64_LDST64_ABS_LO12_NC
:
1773 /* GOT is relocated separately. */
1774 case R_AARCH64_ADR_GOT_PAGE
:
1775 case R_AARCH64_LD64_GOT_LO12_NC
:
1779 grub_util_error (_("relocation 0x%x is not implemented yet"),
1780 (unsigned int) ELF_R_TYPE (info
));
1783 #endif /* defined(MKIMAGE_ELF64) */
1786 #if defined(MKIMAGE_ELF64)
1787 switch (ELF_R_TYPE (info
))
1791 ctx
->current_address
= add_fixup_entry (&ctx
->lst
,
1792 GRUB_PE32_REL_BASED_DIR64
,
1793 addr
, 0, ctx
->current_address
,
1797 case R_LARCH_MARK_LA
:
1799 ctx
->current_address
= add_fixup_entry (&ctx
->lst
,
1800 GRUB_PE32_REL_BASED_LOONGARCH64_MARK_LA
,
1801 addr
, 0, ctx
->current_address
,
1805 /* Relative relocations do not require fixup entries. */
1807 case R_LARCH_SOP_PUSH_PCREL
:
1808 case R_LARCH_SOP_PUSH_ABSOLUTE
:
1809 case R_LARCH_SOP_PUSH_PLT_PCREL
:
1810 case R_LARCH_SOP_SUB
:
1811 case R_LARCH_SOP_SL
:
1812 case R_LARCH_SOP_SR
:
1813 case R_LARCH_SOP_ADD
:
1814 case R_LARCH_SOP_AND
:
1815 case R_LARCH_SOP_IF_ELSE
:
1816 case R_LARCH_SOP_POP_32_S_10_5
:
1817 case R_LARCH_SOP_POP_32_U_10_12
:
1818 case R_LARCH_SOP_POP_32_S_10_12
:
1819 case R_LARCH_SOP_POP_32_S_10_16
:
1820 case R_LARCH_SOP_POP_32_S_10_16_S2
:
1821 case R_LARCH_SOP_POP_32_S_5_20
:
1822 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2
:
1823 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2
:
1825 case R_LARCH_ABS_HI20
:
1826 case R_LARCH_ABS_LO12
:
1827 case R_LARCH_ABS64_LO20
:
1828 case R_LARCH_ABS64_HI12
:
1829 case R_LARCH_PCALA_HI20
:
1830 case R_LARCH_PCALA_LO12
:
1831 grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x",
1833 (unsigned int) addr
,
1834 (unsigned int) ctx
->current_address
);
1837 grub_util_error (_("relocation 0x%x is not implemented yet"),
1838 (unsigned int) ELF_R_TYPE (info
));
1841 #endif /* defined(MKIMAGE_ELF64) */
1843 #if defined(MKIMAGE_ELF32)
1845 switch (ELF_R_TYPE (info
))
1848 /* Relative relocations do not require fixup entries. */
1850 case R_ARM_THM_CALL
:
1851 case R_ARM_THM_JUMP19
:
1852 case R_ARM_THM_JUMP24
:
1855 grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x", __FUNCTION__
, (unsigned int) addr
, (unsigned int) ctx
->current_address
);
1858 /* Create fixup entry for PE/COFF loader */
1861 ctx
->current_address
1862 = add_fixup_entry (&ctx
->lst
,
1863 GRUB_PE32_REL_BASED_HIGHLOW
,
1864 addr
, 0, ctx
->current_address
,
1869 grub_util_error (_("relocation 0x%x is not implemented yet"),
1870 (unsigned int) ELF_R_TYPE (info
));
1874 #endif /* defined(MKIMAGE_ELF32) */
1876 switch (ELF_R_TYPE (info
))
1880 ctx
->current_address
1881 = add_fixup_entry (&ctx
->lst
,
1882 GRUB_PE32_REL_BASED_HIGHLOW
,
1883 addr
, 0, ctx
->current_address
,
1889 ctx
->current_address
1890 = add_fixup_entry (&ctx
->lst
,
1891 GRUB_PE32_REL_BASED_DIR64
,
1892 addr
, 0, ctx
->current_address
,
1896 /* Relative relocations do not require fixup entries. */
1897 case R_RISCV_BRANCH
:
1900 case R_RISCV_CALL_PLT
:
1901 case R_RISCV_PCREL_HI20
:
1902 case R_RISCV_PCREL_LO12_I
:
1903 case R_RISCV_PCREL_LO12_S
:
1904 case R_RISCV_RVC_BRANCH
:
1905 case R_RISCV_RVC_JUMP
:
1908 grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x", __FUNCTION__
, (unsigned int) addr
, (unsigned int) ctx
->current_address
);
1912 ctx
->current_address
1913 = add_fixup_entry (&ctx
->lst
,
1914 GRUB_PE32_REL_BASED_RISCV_HI20
,
1915 addr
, 0, ctx
->current_address
,
1919 case R_RISCV_LO12_I
:
1921 ctx
->current_address
1922 = add_fixup_entry (&ctx
->lst
,
1923 GRUB_PE32_REL_BASED_RISCV_LOW12I
,
1924 addr
, 0, ctx
->current_address
,
1928 case R_RISCV_LO12_S
:
1930 ctx
->current_address
1931 = add_fixup_entry (&ctx
->lst
,
1932 GRUB_PE32_REL_BASED_RISCV_LOW12S
,
1933 addr
, 0, ctx
->current_address
,
1940 grub_util_error (_("relocation 0x%x is not implemented yet"),
1941 (unsigned int) ELF_R_TYPE (info
));
1946 grub_util_error ("unknown machine type 0x%x", image_target
->elf_target
);
1950 static enum raw_reloc_type
1951 classify_raw_reloc (Elf_Addr info
,
1952 const struct grub_install_image_target_desc
*image_target
)
1954 /* Necessary to relocate only absolute addresses. */
1955 switch (image_target
->elf_target
)
1958 switch (ELF_R_TYPE (info
))
1962 case R_ARM_THM_CALL
:
1963 case R_ARM_THM_JUMP19
:
1964 case R_ARM_THM_JUMP24
:
1966 return RAW_RELOC_NONE
;
1968 return RAW_RELOC_32
;
1970 grub_util_error (_("relocation 0x%x is not implemented yet"),
1971 (unsigned int) ELF_R_TYPE (info
));
1976 grub_util_error ("unknown machine type 0x%x", image_target
->elf_target
);
1981 translate_relocation_raw (struct translate_context
*ctx
,
1984 const struct grub_install_image_target_desc
*image_target
)
1986 enum raw_reloc_type
class = classify_raw_reloc (info
, image_target
);
1987 struct raw_reloc
*rel
;
1988 if (class == RAW_RELOC_NONE
)
1990 rel
= xmalloc (sizeof (*rel
));
1991 rel
->next
= ctx
->raw_relocs
;
1994 ctx
->raw_relocs
= rel
;
1998 translate_relocation (struct translate_context
*ctx
,
2001 const struct grub_install_image_target_desc
*image_target
)
2003 if (image_target
->id
== IMAGE_EFI
)
2004 translate_relocation_pe (ctx
, addr
, info
, image_target
);
2006 translate_relocation_raw (ctx
, addr
, info
, image_target
);
2010 finish_reloc_translation_pe (struct translate_context
*ctx
, struct grub_mkimage_layout
*layout
,
2011 const struct grub_install_image_target_desc
*image_target
)
2013 ctx
->current_address
= add_fixup_entry (&ctx
->lst
, 0, 0, 1, ctx
->current_address
, image_target
);
2017 layout
->reloc_section
= ptr
= xmalloc (ctx
->current_address
);
2018 for (ctx
->lst
= ctx
->lst0
; ctx
->lst
; ctx
->lst
= ctx
->lst
->next
)
2019 if (ctx
->lst
->state
)
2021 memcpy (ptr
, &ctx
->lst
->b
, grub_target_to_host32 (ctx
->lst
->b
.block_size
));
2022 ptr
+= grub_target_to_host32 (ctx
->lst
->b
.block_size
);
2024 assert ((ctx
->current_address
+ (grub_uint8_t
*) layout
->reloc_section
) == ptr
);
2027 for (ctx
->lst
= ctx
->lst0
; ctx
->lst
; )
2029 struct fixup_block_list
*next
;
2030 next
= ctx
->lst
->next
;
2035 layout
->reloc_size
= ctx
->current_address
;
2036 if (image_target
->elf_target
== EM_ARM
&& layout
->reloc_size
> GRUB_KERNEL_ARM_STACK_SIZE
)
2037 grub_util_error ("Reloc section (%d) is bigger than stack size (%d). "
2038 "This breaks assembly assumptions. Please increase stack size",
2039 (int) layout
->reloc_size
,
2040 (int) GRUB_KERNEL_ARM_STACK_SIZE
);
2045 <type 0 relocations>
2047 <type 1 relocations>
2050 <type n relocations>
2052 each relocation starts with 32-bit offset. Rest depends on relocation.
2053 mkimage stops when it sees first unknown type or end marker.
2054 This allows images to be created with mismatched mkimage and
2055 kernel as long as no relocations are present in kernel that mkimage
2056 isn't aware of (in which case mkimage aborts).
2057 This also allows simple assembly to do the relocs.
2060 #define RAW_SEPARATOR 0xfffffffe
2061 #define RAW_END_MARKER 0xffffffff
2064 finish_reloc_translation_raw (struct translate_context
*ctx
, struct grub_mkimage_layout
*layout
,
2065 const struct grub_install_image_target_desc
*image_target
)
2067 size_t count
= 0, sz
;
2068 enum raw_reloc_type highest
= RAW_RELOC_NONE
;
2069 enum raw_reloc_type curtype
;
2070 struct raw_reloc
*cur
;
2072 if (!ctx
->raw_relocs
)
2074 layout
->reloc_section
= p
= xmalloc (sizeof (grub_uint32_t
));
2075 p
[0] = RAW_END_MARKER
;
2076 layout
->reloc_size
= sizeof (grub_uint32_t
);
2079 for (cur
= ctx
->raw_relocs
; cur
; cur
= cur
->next
)
2082 if (cur
->type
> highest
)
2083 highest
= cur
->type
;
2085 /* highest separators, count relocations and one end marker. */
2086 sz
= (highest
+ count
+ 1) * sizeof (grub_uint32_t
);
2087 layout
->reloc_section
= p
= xmalloc (sz
);
2088 for (curtype
= 0; curtype
<= highest
; curtype
++)
2090 /* Support for special cases would go here. */
2091 for (cur
= ctx
->raw_relocs
; cur
; cur
= cur
->next
)
2092 if (cur
->type
== curtype
)
2096 *p
++ = RAW_SEPARATOR
;
2098 *--p
= RAW_END_MARKER
;
2099 layout
->reloc_size
= sz
;
2103 finish_reloc_translation (struct translate_context
*ctx
, struct grub_mkimage_layout
*layout
,
2104 const struct grub_install_image_target_desc
*image_target
)
2106 if (image_target
->id
== IMAGE_EFI
)
2107 finish_reloc_translation_pe (ctx
, layout
, image_target
);
2109 finish_reloc_translation_raw (ctx
, layout
, image_target
);
2114 create_u64_fixups (struct translate_context
*ctx
,
2115 Elf_Addr jumpers
, grub_size_t njumpers
,
2116 const struct grub_install_image_target_desc
*image_target
)
2119 assert (image_target
->id
== IMAGE_EFI
);
2120 for (i
= 0; i
< njumpers
; i
++)
2121 ctx
->current_address
= add_fixup_entry (&ctx
->lst
,
2122 GRUB_PE32_REL_BASED_DIR64
,
2124 0, ctx
->current_address
,
2128 /* Make a .reloc section. */
2130 make_reloc_section (Elf_Ehdr
*e
, struct grub_mkimage_layout
*layout
,
2131 struct section_metadata
*smd
,
2132 const struct grub_install_image_target_desc
*image_target
)
2136 struct translate_context ctx
;
2138 translate_reloc_start (&ctx
, image_target
);
2140 for (i
= 0, s
= smd
->sections
; i
< smd
->num_sections
;
2141 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
->section_entsize
))
2142 if ((grub_target_to_host32 (s
->sh_type
) == SHT_REL
) ||
2143 (grub_target_to_host32 (s
->sh_type
) == SHT_RELA
))
2146 Elf_Word rtab_size
, r_size
, num_rs
;
2147 Elf_Off rtab_offset
;
2148 Elf_Addr section_address
;
2151 if (!SUFFIX (is_kept_reloc_section
) (s
, image_target
, smd
))
2153 grub_util_info ("not translating the skipped relocation section %s",
2154 smd
->strtab
+ grub_le_to_cpu32 (s
->sh_name
));
2158 grub_util_info ("translating the relocation section %s",
2159 smd
->strtab
+ grub_le_to_cpu32 (s
->sh_name
));
2161 rtab_size
= grub_target_to_host (s
->sh_size
);
2162 r_size
= grub_target_to_host (s
->sh_entsize
);
2163 rtab_offset
= grub_target_to_host (s
->sh_offset
);
2164 num_rs
= rtab_size
/ r_size
;
2166 section_address
= smd
->vaddrs
[grub_le_to_cpu32 (s
->sh_info
)];
2168 for (j
= 0, r
= (Elf_Rel
*) ((char *) e
+ rtab_offset
);
2170 j
++, r
= (Elf_Rel
*) ((char *) r
+ r_size
))
2176 offset
= grub_target_to_host (r
->r_offset
);
2177 info
= grub_target_to_host (r
->r_info
);
2179 addr
= section_address
+ offset
;
2181 translate_relocation (&ctx
, addr
, info
, image_target
);
2185 if (image_target
->elf_target
== EM_IA_64
)
2186 create_u64_fixups (&ctx
,
2188 + image_target
->vaddr_offset
,
2189 2 * layout
->ia64jmpnum
,
2191 if (image_target
->elf_target
== EM_IA_64
|| image_target
->elf_target
== EM_AARCH64
)
2192 create_u64_fixups (&ctx
,
2194 + image_target
->vaddr_offset
,
2195 (layout
->got_size
/ 8),
2198 finish_reloc_translation (&ctx
, layout
, image_target
);
2201 /* Determine if this section is a text section. Return false if this
2202 section is not allocated. */
2204 SUFFIX (is_text_section
) (Elf_Shdr
*s
, const struct grub_install_image_target_desc
*image_target
)
2206 if (!is_relocatable (image_target
)
2207 && grub_target_to_host32 (s
->sh_type
) != SHT_PROGBITS
)
2209 return ((grub_target_to_host (s
->sh_flags
) & (SHF_EXECINSTR
| SHF_ALLOC
))
2210 == (SHF_EXECINSTR
| SHF_ALLOC
));
2213 /* Determine if this section is a data section. */
2215 SUFFIX (is_data_section
) (Elf_Shdr
*s
, const struct grub_install_image_target_desc
*image_target
)
2217 if (!is_relocatable (image_target
)
2218 && grub_target_to_host32 (s
->sh_type
) != SHT_PROGBITS
)
2220 return ((grub_target_to_host (s
->sh_flags
) & (SHF_EXECINSTR
| SHF_ALLOC
))
2221 == SHF_ALLOC
) && !(grub_target_to_host32 (s
->sh_type
) == SHT_NOBITS
);
2225 SUFFIX (is_bss_section
) (Elf_Shdr
*s
, const struct grub_install_image_target_desc
*image_target
)
2227 if (!is_relocatable (image_target
))
2229 return ((grub_target_to_host (s
->sh_flags
) & (SHF_EXECINSTR
| SHF_ALLOC
))
2230 == SHF_ALLOC
) && (grub_target_to_host32 (s
->sh_type
) == SHT_NOBITS
);
2233 /* Determine if a section is going to be in the final output */
2235 SUFFIX (is_kept_section
) (Elf_Shdr
*s
, const struct grub_install_image_target_desc
*image_target
)
2237 /* We keep .text and .data */
2238 if (SUFFIX (is_text_section
) (s
, image_target
)
2239 || SUFFIX (is_data_section
) (s
, image_target
))
2243 * And we keep .bss if we're producing PE binaries or the target doesn't
2244 * have a relocating loader. Platforms other than EFI and U-boot shouldn't
2245 * have .bss in their binaries as we build with -Wl,-Ttext.
2247 if (SUFFIX (is_bss_section
) (s
, image_target
)
2248 && (image_target
->id
== IMAGE_EFI
|| !is_relocatable (image_target
)))
2251 /* Otherwise this is not a section we're keeping in the final output. */
2256 SUFFIX (is_kept_reloc_section
) (Elf_Shdr
*s
, const struct grub_install_image_target_desc
*image_target
,
2257 struct section_metadata
*smd
)
2261 const char *name
= smd
->strtab
+ grub_host_to_target32 (s
->sh_name
);
2263 if (!strncmp (name
, ".rela.", 6))
2265 else if (!strncmp (name
, ".rel.", 5))
2270 for (i
= 0, s
= smd
->sections
; i
< smd
->num_sections
;
2271 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
->section_entsize
))
2273 const char *sname
= smd
->strtab
+ grub_host_to_target32 (s
->sh_name
);
2274 if (strcmp (sname
, name
))
2277 return SUFFIX (is_kept_section
) (s
, image_target
);
2283 /* Return if the ELF header is valid. */
2285 SUFFIX (check_elf_header
) (Elf_Ehdr
*e
, size_t size
, const struct grub_install_image_target_desc
*image_target
)
2287 if (size
< sizeof (*e
)
2288 || e
->e_ident
[EI_MAG0
] != ELFMAG0
2289 || e
->e_ident
[EI_MAG1
] != ELFMAG1
2290 || e
->e_ident
[EI_MAG2
] != ELFMAG2
2291 || e
->e_ident
[EI_MAG3
] != ELFMAG3
2292 || e
->e_ident
[EI_VERSION
] != EV_CURRENT
2293 || e
->e_ident
[EI_CLASS
] != ELFCLASSXX
2294 || e
->e_version
!= grub_host_to_target32 (EV_CURRENT
))
2301 SUFFIX (put_section
) (Elf_Shdr
*s
, int i
,
2302 Elf_Addr current_address
,
2303 struct section_metadata
*smd
,
2304 const struct grub_install_image_target_desc
*image_target
)
2306 Elf_Word align
= grub_host_to_target_addr (s
->sh_addralign
);
2307 const char *name
= smd
->strtab
+ grub_host_to_target32 (s
->sh_name
);
2310 current_address
= ALIGN_UP (current_address
+ image_target
->vaddr_offset
,
2312 - image_target
->vaddr_offset
;
2314 grub_util_info ("locating the section %s at 0x%"
2315 GRUB_HOST_PRIxLONG_LONG
,
2316 name
, (unsigned long long) current_address
);
2317 if (!is_relocatable (image_target
))
2318 current_address
= grub_host_to_target_addr (s
->sh_addr
)
2319 - image_target
->link_addr
;
2320 smd
->addrs
[i
] = current_address
;
2321 current_address
+= grub_host_to_target_addr (s
->sh_size
);
2322 return current_address
;
2326 * Locate section addresses by merging code sections and data sections
2327 * into .text and .data, respectively.
2330 SUFFIX (locate_sections
) (Elf_Ehdr
*e
, const char *kernel_path
,
2331 struct section_metadata
*smd
,
2332 struct grub_mkimage_layout
*layout
,
2333 const struct grub_install_image_target_desc
*image_target
)
2339 /* Page-aligning simplifies relocation handling. */
2340 if (image_target
->elf_target
== EM_AARCH64
)
2341 layout
->align
= 4096;
2343 layout
->kernel_size
= 0;
2345 for (i
= 0, s
= smd
->sections
;
2346 i
< smd
->num_sections
;
2347 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
->section_entsize
))
2348 if ((grub_target_to_host (s
->sh_flags
) & SHF_ALLOC
)
2349 && grub_host_to_target32 (s
->sh_addralign
) > layout
->align
)
2350 layout
->align
= grub_host_to_target32 (s
->sh_addralign
);
2353 for (i
= 0, s
= smd
->sections
;
2354 i
< smd
->num_sections
;
2355 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
->section_entsize
))
2356 if (SUFFIX (is_text_section
) (s
, image_target
))
2358 layout
->kernel_size
= SUFFIX (put_section
) (s
, i
, layout
->kernel_size
,
2360 if (!is_relocatable (image_target
) &&
2361 grub_host_to_target_addr (s
->sh_addr
) != image_target
->link_addr
)
2364 = grub_xasprintf (_("`%s' is miscompiled: its start address is 0x%llx"
2365 " instead of 0x%llx: ld.gold bug?"),
2367 (unsigned long long) grub_host_to_target_addr (s
->sh_addr
),
2368 (unsigned long long) image_target
->link_addr
);
2369 grub_util_error ("%s", msg
);
2373 #ifdef MKIMAGE_ELF32
2374 if (image_target
->elf_target
== EM_ARM
)
2378 layout
->kernel_size
= ALIGN_UP (layout
->kernel_size
, 16);
2380 tramp
= arm_get_trampoline_size (e
, smd
->sections
, smd
->section_entsize
,
2381 smd
->num_sections
, image_target
);
2383 layout
->tramp_off
= layout
->kernel_size
;
2384 layout
->kernel_size
+= ALIGN_UP (tramp
, 16);
2388 layout
->kernel_size
= ALIGN_UP (layout
->kernel_size
+ image_target
->vaddr_offset
,
2389 image_target
->section_align
)
2390 - image_target
->vaddr_offset
;
2391 layout
->exec_size
= layout
->kernel_size
;
2394 for (i
= 0, s
= smd
->sections
;
2395 i
< smd
->num_sections
;
2396 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
->section_entsize
))
2397 if (SUFFIX (is_data_section
) (s
, image_target
))
2398 layout
->kernel_size
= SUFFIX (put_section
) (s
, i
, layout
->kernel_size
, smd
,
2401 layout
->bss_start
= layout
->kernel_size
;
2402 layout
->end
= layout
->kernel_size
;
2405 for (i
= 0, s
= smd
->sections
;
2406 i
< smd
->num_sections
;
2407 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
->section_entsize
))
2409 if (SUFFIX (is_bss_section
) (s
, image_target
))
2410 layout
->end
= SUFFIX (put_section
) (s
, i
, layout
->end
, smd
, image_target
);
2413 * This must to be in the last time this function passes through the loop.
2415 smd
->vaddrs
[i
] = smd
->addrs
[i
] + image_target
->vaddr_offset
;
2418 layout
->end
= ALIGN_UP (layout
->end
+ image_target
->vaddr_offset
,
2419 image_target
->section_align
) - image_target
->vaddr_offset
;
2420 /* Explicitly initialize BSS
2421 when producing PE32 to avoid a bug in EFI implementations.
2422 Platforms other than EFI and U-boot shouldn't have .bss in
2423 their binaries as we build with -Wl,-Ttext.
2425 if (image_target
->id
== IMAGE_EFI
|| !is_relocatable (image_target
))
2426 layout
->kernel_size
= layout
->end
;
2430 SUFFIX (grub_mkimage_load_image
) (const char *kernel_path
,
2431 size_t total_module_size
,
2432 struct grub_mkimage_layout
*layout
,
2433 const struct grub_install_image_target_desc
*image_target
)
2435 char *kernel_img
, *out_img
;
2436 struct section_metadata smd
= { 0, 0, 0, 0, 0, 0, 0 };
2440 Elf_Off section_offset
;
2441 grub_size_t kernel_size
;
2443 grub_memset (layout
, 0, sizeof (*layout
));
2445 layout
->start_address
= 0;
2447 kernel_size
= grub_util_get_image_size (kernel_path
);
2448 kernel_img
= xmalloc (kernel_size
);
2449 grub_util_load_image (kernel_path
, kernel_img
);
2451 e
= (Elf_Ehdr
*) kernel_img
;
2452 if (! SUFFIX (check_elf_header
) (e
, kernel_size
, image_target
))
2453 grub_util_error ("invalid ELF header");
2455 section_offset
= grub_target_to_host (e
->e_shoff
);
2456 smd
.section_entsize
= grub_target_to_host16 (e
->e_shentsize
);
2457 smd
.num_sections
= grub_target_to_host16 (e
->e_shnum
);
2459 if (kernel_size
< section_offset
2460 + (grub_uint32_t
) smd
.section_entsize
* smd
.num_sections
)
2461 grub_util_error (_("premature end of file %s"), kernel_path
);
2463 smd
.sections
= (Elf_Shdr
*) (kernel_img
+ section_offset
);
2465 /* Relocate sections then symbols in the virtual address space. */
2466 s
= (Elf_Shdr
*) ((char *) smd
.sections
2467 + grub_host_to_target16 (e
->e_shstrndx
) * smd
.section_entsize
);
2468 smd
.strtab
= (char *) e
+ grub_host_to_target_addr (s
->sh_offset
);
2470 smd
.addrs
= xcalloc (smd
.num_sections
, sizeof (*smd
.addrs
));
2471 smd
.vaddrs
= xcalloc (smd
.num_sections
, sizeof (*smd
.vaddrs
));
2473 SUFFIX (locate_sections
) (e
, kernel_path
, &smd
, layout
, image_target
);
2475 if (!is_relocatable (image_target
))
2477 Elf_Addr current_address
= layout
->kernel_size
;
2478 Elf_Addr bss_start
= layout
->kernel_size
;
2479 bool is_first
= true;
2481 for (i
= 0, s
= smd
.sections
;
2482 i
< smd
.num_sections
;
2483 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
.section_entsize
))
2484 if (grub_target_to_host32 (s
->sh_type
) == SHT_NOBITS
)
2486 Elf_Word sec_align
= grub_host_to_target_addr (s
->sh_addralign
);
2487 const char *name
= smd
.strtab
+ grub_host_to_target32 (s
->sh_name
);
2490 current_address
= ALIGN_UP (current_address
2491 + image_target
->vaddr_offset
,
2493 - image_target
->vaddr_offset
;
2495 grub_util_info ("locating the section %s at 0x%"
2496 GRUB_HOST_PRIxLONG_LONG
,
2497 name
, (unsigned long long) current_address
);
2498 if (!is_relocatable (image_target
))
2499 current_address
= grub_host_to_target_addr (s
->sh_addr
)
2500 - image_target
->link_addr
;
2502 if (is_first
== true)
2504 bss_start
= current_address
;
2508 smd
.vaddrs
[i
] = current_address
2509 + image_target
->vaddr_offset
;
2510 current_address
+= grub_host_to_target_addr (s
->sh_size
);
2512 current_address
= ALIGN_UP (current_address
+ image_target
->vaddr_offset
,
2513 image_target
->section_align
)
2514 - image_target
->vaddr_offset
;
2516 if (image_target
->id
== IMAGE_YEELOONG_FLASH
2517 || image_target
->id
== IMAGE_FULOONG2F_FLASH
2518 || image_target
->id
== IMAGE_LOONGSON_ELF
2519 || image_target
->id
== IMAGE_QEMU_MIPS_FLASH
2520 || image_target
->id
== IMAGE_MIPS_ARC
)
2522 layout
->kernel_size
= bss_start
;
2525 layout
->bss_size
= current_address
- layout
->kernel_size
;
2528 layout
->bss_size
= 0;
2530 if (image_target
->id
== IMAGE_SPARC64_AOUT
2531 || image_target
->id
== IMAGE_SPARC64_RAW
2532 || image_target
->id
== IMAGE_UBOOT
2533 || image_target
->id
== IMAGE_COREBOOT
2534 || image_target
->id
== IMAGE_SPARC64_CDCORE
)
2535 layout
->kernel_size
= ALIGN_UP (layout
->kernel_size
, image_target
->mod_align
);
2537 if (is_relocatable (image_target
))
2540 for (i
= 0, s
= smd
.sections
;
2541 i
< smd
.num_sections
;
2542 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
.section_entsize
))
2543 if (s
->sh_type
== grub_host_to_target32 (SHT_SYMTAB
))
2549 grub_util_error ("%s", _("no symbol table"));
2550 #ifdef MKIMAGE_ELF64
2551 if (image_target
->elf_target
== EM_IA_64
)
2555 layout
->kernel_size
= ALIGN_UP (layout
->kernel_size
, 16);
2557 grub_ia64_dl_get_tramp_got_size (e
, &tramp
, &layout
->got_size
);
2559 layout
->tramp_off
= layout
->kernel_size
;
2560 layout
->kernel_size
+= ALIGN_UP (tramp
, 16);
2562 layout
->ia64jmp_off
= layout
->kernel_size
;
2563 layout
->ia64jmpnum
= SUFFIX (count_funcs
) (e
, smd
.symtab
,
2565 layout
->kernel_size
+= 16 * layout
->ia64jmpnum
;
2567 layout
->got_off
= layout
->kernel_size
;
2568 layout
->kernel_size
+= ALIGN_UP (layout
->got_size
, 16);
2570 if (image_target
->elf_target
== EM_AARCH64
)
2574 layout
->kernel_size
= ALIGN_UP (layout
->kernel_size
, 16);
2576 grub_arm64_dl_get_tramp_got_size (e
, &tramp
, &layout
->got_size
);
2578 layout
->got_off
= layout
->kernel_size
;
2579 layout
->kernel_size
+= ALIGN_UP (layout
->got_size
, 16);
2583 if (image_target
->id
== IMAGE_EFI
)
2584 layout
->kernel_size
= ALIGN_UP (layout
->kernel_size
,
2585 GRUB_PE32_FILE_ALIGNMENT
);
2589 layout
->reloc_size
= 0;
2590 layout
->reloc_section
= NULL
;
2593 out_img
= xmalloc (layout
->kernel_size
+ total_module_size
);
2594 memset (out_img
, 0, layout
->kernel_size
+ total_module_size
);
2596 if (is_relocatable (image_target
))
2598 layout
->start_address
= SUFFIX (relocate_symbols
) (e
, &smd
,
2599 (char *) out_img
+ layout
->ia64jmp_off
,
2600 layout
->ia64jmp_off
+ image_target
->vaddr_offset
,
2601 layout
->bss_start
, layout
->end
, image_target
);
2603 if (layout
->start_address
== (Elf_Addr
) -1)
2604 grub_util_error ("start symbol is not defined");
2606 /* Resolve addrs in the virtual address space. */
2607 SUFFIX (relocate_addrs
) (e
, &smd
, out_img
, layout
->tramp_off
,
2608 layout
->got_off
, image_target
);
2610 make_reloc_section (e
, layout
, &smd
, image_target
);
2611 if (image_target
->id
!= IMAGE_EFI
)
2613 out_img
= xrealloc (out_img
, layout
->kernel_size
+ total_module_size
2614 + ALIGN_UP (layout
->reloc_size
, image_target
->mod_align
));
2615 memcpy (out_img
+ layout
->kernel_size
, layout
->reloc_section
, layout
->reloc_size
);
2616 memset (out_img
+ layout
->kernel_size
+ layout
->reloc_size
, 0,
2617 total_module_size
+ ALIGN_UP (layout
->reloc_size
, image_target
->mod_align
) - layout
->reloc_size
);
2618 layout
->kernel_size
+= ALIGN_UP (layout
->reloc_size
, image_target
->mod_align
);
2622 for (i
= 0, s
= smd
.sections
;
2623 i
< smd
.num_sections
;
2624 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
.section_entsize
))
2625 if (SUFFIX (is_kept_section
) (s
, image_target
))
2627 if (grub_target_to_host32 (s
->sh_type
) == SHT_NOBITS
)
2628 memset (out_img
+ smd
.addrs
[i
], 0,
2629 grub_host_to_target_addr (s
->sh_size
));
2631 memcpy (out_img
+ smd
.addrs
[i
],
2632 kernel_img
+ grub_host_to_target_addr (s
->sh_offset
),
2633 grub_host_to_target_addr (s
->sh_size
));