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/osdep/hostfile.h>
48 #include <grub/util/install.h>
49 #include <grub/util/mkimage.h>
51 #include <xen/elfnote.h>
53 #pragma GCC diagnostic ignored "-Wcast-align"
55 #define GRUB_MKIMAGEXX
56 #if !defined(MKIMAGE_ELF32) && !defined(MKIMAGE_ELF64)
57 #if __SIZEOF_POINTER__ == 8
58 #include "grub-mkimage64.c"
60 #include "grub-mkimage32.c"
64 /* These structures are defined according to the CHRP binding to IEEE1275,
65 "Client Program Format" section. */
67 struct grub_ieee1275_note_desc
69 grub_uint32_t real_mode
;
70 grub_uint32_t real_base
;
71 grub_uint32_t real_size
;
72 grub_uint32_t virt_base
;
73 grub_uint32_t virt_size
;
74 grub_uint32_t load_base
;
77 #define GRUB_IEEE1275_NOTE_NAME "PowerPC"
78 #define GRUB_IEEE1275_NOTE_TYPE 0x1275
80 struct grub_ieee1275_note
83 char name
[ALIGN_UP(sizeof (GRUB_IEEE1275_NOTE_NAME
), 4)];
84 struct grub_ieee1275_note_desc descriptor
;
87 #define GRUB_XEN_NOTE_NAME "Xen"
89 struct fixup_block_list
91 struct fixup_block_list
*next
;
93 struct grub_pe32_fixup_block b
;
96 #define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof))
98 struct section_metadata
100 Elf_Half num_sections
;
104 Elf_Half section_entsize
;
110 is_relocatable (const struct grub_install_image_target_desc
*image_target
)
112 return image_target
->id
== IMAGE_EFI
|| image_target
->id
== IMAGE_UBOOT
113 || (image_target
->id
== IMAGE_COREBOOT
&& image_target
->elf_target
== EM_ARM
);
119 * R_ARM_THM_CALL/THM_JUMP24
121 * Relocate Thumb (T32) instruction set relative branches:
125 grub_arm_reloc_thm_call (grub_uint16_t
*target
, Elf32_Addr sym_addr
)
129 offset
= grub_arm_thm_call_get_offset (target
);
131 grub_dprintf ("dl", " sym_addr = 0x%08x", sym_addr
);
135 grub_dprintf("dl", " BL*: target=%p, sym_addr=0x%08x, offset=%d\n",
136 target
, sym_addr
, offset
);
138 /* Keep traditional (pre-Thumb2) limits on blx. In any case if the kernel
139 is bigger than 2M (currently under 150K) then we probably have a problem
141 if (offset
< -0x200000 || offset
>= 0x200000)
142 return grub_error (GRUB_ERR_BAD_MODULE
,
143 "THM_CALL Relocation out of range.");
145 grub_dprintf ("dl", " relative destination = %p",
146 (char *) target
+ offset
);
148 return grub_arm_thm_call_set_offset (target
, offset
);
154 * Relocate conditional Thumb (T32) B<c>.W
157 grub_arm_reloc_thm_jump19 (grub_uint16_t
*target
, Elf32_Addr sym_addr
)
162 return grub_error (GRUB_ERR_BAD_MODULE
,
163 "Relocation targeting wrong execution state");
165 offset
= grub_arm_thm_jump19_get_offset (target
);
167 /* Adjust and re-truncate offset */
170 if (!grub_arm_thm_jump19_check_offset (offset
))
171 return grub_error (GRUB_ERR_BAD_MODULE
,
172 "THM_JUMP19 Relocation out of range.");
174 grub_arm_thm_jump19_set_offset (target
, offset
);
176 return GRUB_ERR_NONE
;
182 * Relocate ARM (A32) B
185 grub_arm_reloc_jump24 (grub_uint32_t
*target
, Elf32_Addr sym_addr
)
190 return grub_error (GRUB_ERR_BAD_MODULE
,
191 "Relocation targeting wrong execution state");
193 offset
= grub_arm_jump24_get_offset (target
);
196 if (!grub_arm_jump24_check_offset (offset
))
197 return grub_error (GRUB_ERR_BAD_MODULE
,
198 "JUMP24 Relocation out of range.");
201 grub_arm_jump24_set_offset (target
, offset
);
203 return GRUB_ERR_NONE
;
209 SUFFIX (grub_mkimage_generate_elf
) (const struct grub_install_image_target_desc
*image_target
,
210 int note
, char **core_img
, size_t *core_size
,
211 Elf_Addr target_addr
,
212 struct grub_mkimage_layout
*layout
)
219 int header_size
, footer_size
= 0;
222 int string_size
= sizeof (".text") + sizeof ("mods") + 1;
224 if (image_target
->id
!= IMAGE_LOONGSON_ELF
)
230 footer_size
+= sizeof (struct grub_ieee1275_note
);
232 if (image_target
->id
== IMAGE_XEN
|| image_target
->id
== IMAGE_XEN_PVH
)
236 string_size
+= sizeof (".xen");
237 footer_size
+= (image_target
->id
== IMAGE_XEN
) ? XEN_NOTE_SIZE
: XEN_PVH_NOTE_SIZE
;
239 header_size
= ALIGN_UP (sizeof (*ehdr
) + phnum
* sizeof (*phdr
)
240 + shnum
* sizeof (*shdr
) + string_size
, layout
->align
);
242 program_size
= ALIGN_ADDR (*core_size
);
244 elf_img
= xmalloc (program_size
+ header_size
+ footer_size
);
245 memset (elf_img
, 0, program_size
+ header_size
+ footer_size
);
246 memcpy (elf_img
+ header_size
, *core_img
, *core_size
);
247 ehdr
= (void *) elf_img
;
248 phdr
= (void *) (elf_img
+ sizeof (*ehdr
));
249 shdr
= (void *) (elf_img
+ sizeof (*ehdr
) + phnum
* sizeof (*phdr
));
250 memcpy (ehdr
->e_ident
, ELFMAG
, SELFMAG
);
251 ehdr
->e_ident
[EI_CLASS
] = ELFCLASSXX
;
252 if (!image_target
->bigendian
)
253 ehdr
->e_ident
[EI_DATA
] = ELFDATA2LSB
;
255 ehdr
->e_ident
[EI_DATA
] = ELFDATA2MSB
;
256 ehdr
->e_ident
[EI_VERSION
] = EV_CURRENT
;
257 ehdr
->e_ident
[EI_OSABI
] = ELFOSABI_NONE
;
258 ehdr
->e_type
= grub_host_to_target16 (ET_EXEC
);
259 ehdr
->e_machine
= grub_host_to_target16 (image_target
->elf_target
);
260 ehdr
->e_version
= grub_host_to_target32 (EV_CURRENT
);
262 ehdr
->e_phoff
= grub_host_to_target32 ((char *) phdr
- (char *) ehdr
);
263 ehdr
->e_phentsize
= grub_host_to_target16 (sizeof (*phdr
));
264 ehdr
->e_phnum
= grub_host_to_target16 (phnum
);
266 ehdr
->e_shoff
= grub_host_to_target32 ((grub_uint8_t
*) shdr
267 - (grub_uint8_t
*) ehdr
);
268 if (image_target
->id
== IMAGE_LOONGSON_ELF
)
269 ehdr
->e_shentsize
= grub_host_to_target16 (0);
271 ehdr
->e_shentsize
= grub_host_to_target16 (sizeof (Elf_Shdr
));
272 ehdr
->e_shnum
= grub_host_to_target16 (shnum
);
273 ehdr
->e_shstrndx
= grub_host_to_target16 (1);
275 ehdr
->e_ehsize
= grub_host_to_target16 (sizeof (*ehdr
));
277 phdr
->p_type
= grub_host_to_target32 (PT_LOAD
);
278 phdr
->p_offset
= grub_host_to_target32 (header_size
);
279 phdr
->p_flags
= grub_host_to_target32 (PF_R
| PF_W
| PF_X
);
281 ehdr
->e_entry
= grub_host_to_target32 (target_addr
);
282 phdr
->p_vaddr
= grub_host_to_target32 (target_addr
);
283 phdr
->p_paddr
= grub_host_to_target32 (target_addr
);
284 phdr
->p_align
= grub_host_to_target32 (layout
->align
> image_target
->link_align
?
285 layout
->align
: image_target
->link_align
);
286 if (image_target
->id
== IMAGE_LOONGSON_ELF
)
287 ehdr
->e_flags
= grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER
288 | EF_MIPS_PIC
| EF_MIPS_CPIC
);
291 if (image_target
->id
== IMAGE_LOONGSON_ELF
)
293 phdr
->p_filesz
= grub_host_to_target32 (*core_size
);
294 phdr
->p_memsz
= grub_host_to_target32 (*core_size
);
298 grub_uint32_t target_addr_mods
;
299 phdr
->p_filesz
= grub_host_to_target32 (layout
->kernel_size
);
300 if (image_target
->id
== IMAGE_COREBOOT
&& image_target
->elf_target
== EM_ARM
)
301 phdr
->p_memsz
= grub_host_to_target32 (layout
->kernel_size
);
303 phdr
->p_memsz
= grub_host_to_target32 (layout
->kernel_size
+ layout
->bss_size
);
306 phdr
->p_type
= grub_host_to_target32 (PT_GNU_STACK
);
307 phdr
->p_offset
= grub_host_to_target32 (header_size
+ layout
->kernel_size
);
308 phdr
->p_paddr
= phdr
->p_vaddr
= phdr
->p_filesz
= phdr
->p_memsz
= 0;
309 phdr
->p_flags
= grub_host_to_target32 (PF_R
| PF_W
| PF_X
);
310 phdr
->p_align
= grub_host_to_target32 (image_target
->link_align
);
313 phdr
->p_type
= grub_host_to_target32 (PT_LOAD
);
314 phdr
->p_offset
= grub_host_to_target32 (header_size
+ layout
->kernel_size
);
315 phdr
->p_flags
= grub_host_to_target32 (PF_R
| PF_W
| PF_X
);
316 phdr
->p_filesz
= phdr
->p_memsz
317 = grub_host_to_target32 (*core_size
- layout
->kernel_size
);
319 if (image_target
->id
== IMAGE_COREBOOT
&& image_target
->elf_target
== EM_386
)
320 target_addr_mods
= GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR
;
321 else if (image_target
->id
== IMAGE_COREBOOT
&& image_target
->elf_target
== EM_ARM
)
322 target_addr_mods
= ALIGN_UP (target_addr
+ layout
->end
323 + image_target
->mod_gap
,
324 image_target
->mod_align
);
326 target_addr_mods
= ALIGN_UP (target_addr
+ layout
->kernel_size
+ layout
->bss_size
327 + image_target
->mod_gap
,
328 image_target
->mod_align
);
329 phdr
->p_vaddr
= grub_host_to_target_addr (target_addr_mods
);
330 phdr
->p_paddr
= grub_host_to_target_addr (target_addr_mods
);
331 phdr
->p_align
= grub_host_to_target32 (image_target
->link_align
);
334 if (image_target
->id
== IMAGE_XEN
)
336 char *note_start
= (elf_img
+ program_size
+ header_size
);
338 char *ptr
= (char *) note_start
;
340 grub_util_info ("adding XEN NOTE segment");
343 note_ptr
= (Elf_Nhdr
*) ptr
;
344 note_ptr
->n_namesz
= grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME
));
345 note_ptr
->n_descsz
= grub_host_to_target32 (sizeof (PACKAGE_NAME
));
346 note_ptr
->n_type
= grub_host_to_target32 (XEN_ELFNOTE_GUEST_OS
);
347 ptr
+= sizeof (Elf_Nhdr
);
348 memcpy (ptr
, GRUB_XEN_NOTE_NAME
, sizeof (GRUB_XEN_NOTE_NAME
));
349 ptr
+= ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME
), 4);
350 memcpy (ptr
, PACKAGE_NAME
, sizeof (PACKAGE_NAME
));
351 ptr
+= ALIGN_UP (sizeof (PACKAGE_NAME
), 4);
354 note_ptr
= (Elf_Nhdr
*) ptr
;
355 note_ptr
->n_namesz
= grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME
));
356 note_ptr
->n_descsz
= grub_host_to_target32 (sizeof ("generic"));
357 note_ptr
->n_type
= grub_host_to_target32 (XEN_ELFNOTE_LOADER
);
358 ptr
+= sizeof (Elf_Nhdr
);
359 memcpy (ptr
, GRUB_XEN_NOTE_NAME
, sizeof (GRUB_XEN_NOTE_NAME
));
360 ptr
+= ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME
), 4);
361 memcpy (ptr
, "generic", sizeof ("generic"));
362 ptr
+= ALIGN_UP (sizeof ("generic"), 4);
365 note_ptr
= (Elf_Nhdr
*) ptr
;
366 note_ptr
->n_namesz
= grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME
));
367 note_ptr
->n_descsz
= grub_host_to_target32 (sizeof ("xen-3.0"));
368 note_ptr
->n_type
= grub_host_to_target32 (XEN_ELFNOTE_XEN_VERSION
);
369 ptr
+= sizeof (Elf_Nhdr
);
370 memcpy (ptr
, GRUB_XEN_NOTE_NAME
, sizeof (GRUB_XEN_NOTE_NAME
));
371 ptr
+= ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME
), 4);
372 memcpy (ptr
, "xen-3.0", sizeof ("xen-3.0"));
373 ptr
+= ALIGN_UP (sizeof ("xen-3.0"), 4);
376 note_ptr
= (Elf_Nhdr
*) ptr
;
377 note_ptr
->n_namesz
= grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME
));
378 note_ptr
->n_descsz
= grub_host_to_target32 (image_target
->voidp_sizeof
);
379 note_ptr
->n_type
= grub_host_to_target32 (XEN_ELFNOTE_ENTRY
);
380 ptr
+= sizeof (Elf_Nhdr
);
381 memcpy (ptr
, GRUB_XEN_NOTE_NAME
, sizeof (GRUB_XEN_NOTE_NAME
));
382 ptr
+= ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME
), 4);
383 memset (ptr
, 0, image_target
->voidp_sizeof
);
384 ptr
+= image_target
->voidp_sizeof
;
387 note_ptr
= (Elf_Nhdr
*) ptr
;
388 note_ptr
->n_namesz
= grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME
));
389 note_ptr
->n_descsz
= grub_host_to_target32 (image_target
->voidp_sizeof
);
390 note_ptr
->n_type
= grub_host_to_target32 (XEN_ELFNOTE_VIRT_BASE
);
391 ptr
+= sizeof (Elf_Nhdr
);
392 memcpy (ptr
, GRUB_XEN_NOTE_NAME
, sizeof (GRUB_XEN_NOTE_NAME
));
393 ptr
+= ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME
), 4);
394 memset (ptr
, 0, image_target
->voidp_sizeof
);
395 ptr
+= image_target
->voidp_sizeof
;
398 if (image_target
->elf_target
== EM_386
)
400 note_ptr
= (Elf_Nhdr
*) ptr
;
401 note_ptr
->n_namesz
= grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME
));
402 note_ptr
->n_descsz
= grub_host_to_target32 (sizeof ("yes,bimodal"));
403 note_ptr
->n_type
= grub_host_to_target32 (XEN_ELFNOTE_PAE_MODE
);
404 ptr
+= sizeof (Elf_Nhdr
);
405 memcpy (ptr
, GRUB_XEN_NOTE_NAME
, sizeof (GRUB_XEN_NOTE_NAME
));
406 ptr
+= ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME
), 4);
407 memcpy (ptr
, "yes", sizeof ("yes"));
408 ptr
+= ALIGN_UP (sizeof ("yes"), 4);
411 assert (XEN_NOTE_SIZE
== (ptr
- note_start
));
414 phdr
->p_type
= grub_host_to_target32 (PT_NOTE
);
415 phdr
->p_flags
= grub_host_to_target32 (PF_R
);
416 phdr
->p_align
= grub_host_to_target32 (image_target
->voidp_sizeof
);
419 phdr
->p_filesz
= grub_host_to_target32 (XEN_NOTE_SIZE
);
421 phdr
->p_offset
= grub_host_to_target32 (header_size
+ program_size
);
424 if (image_target
->id
== IMAGE_XEN_PVH
)
426 char *note_start
= (elf_img
+ program_size
+ header_size
);
428 char *ptr
= (char *) note_start
;
430 grub_util_info ("adding XEN NOTE segment");
433 note_ptr
= (Elf_Nhdr
*) ptr
;
434 note_ptr
->n_namesz
= grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME
));
435 note_ptr
->n_descsz
= grub_host_to_target32 (image_target
->voidp_sizeof
);
436 note_ptr
->n_type
= grub_host_to_target32 (XEN_ELFNOTE_PHYS32_ENTRY
);
437 ptr
+= sizeof (Elf_Nhdr
);
438 memcpy (ptr
, GRUB_XEN_NOTE_NAME
, sizeof (GRUB_XEN_NOTE_NAME
));
439 ptr
+= ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME
), 4);
440 memset (ptr
, 0, image_target
->voidp_sizeof
);
441 *(grub_uint32_t
*) ptr
= GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR
;
442 ptr
+= image_target
->voidp_sizeof
;
444 assert (XEN_PVH_NOTE_SIZE
== (ptr
- note_start
));
447 phdr
->p_type
= grub_host_to_target32 (PT_NOTE
);
448 phdr
->p_flags
= grub_host_to_target32 (PF_R
);
449 phdr
->p_align
= grub_host_to_target32 (image_target
->voidp_sizeof
);
452 phdr
->p_filesz
= grub_host_to_target32 (XEN_PVH_NOTE_SIZE
);
454 phdr
->p_offset
= grub_host_to_target32 (header_size
+ program_size
);
459 int note_size
= sizeof (struct grub_ieee1275_note
);
460 struct grub_ieee1275_note
*note_ptr
= (struct grub_ieee1275_note
*)
461 (elf_img
+ program_size
+ header_size
);
463 grub_util_info ("adding CHRP NOTE segment");
465 note_ptr
->header
.n_namesz
= grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME
));
466 note_ptr
->header
.n_descsz
= grub_host_to_target32 (note_size
);
467 note_ptr
->header
.n_type
= grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE
);
468 strcpy (note_ptr
->name
, GRUB_IEEE1275_NOTE_NAME
);
469 note_ptr
->descriptor
.real_mode
= grub_host_to_target32 (0xffffffff);
470 note_ptr
->descriptor
.real_base
= grub_host_to_target32 (0x00c00000);
471 note_ptr
->descriptor
.real_size
= grub_host_to_target32 (0xffffffff);
472 note_ptr
->descriptor
.virt_base
= grub_host_to_target32 (0xffffffff);
473 note_ptr
->descriptor
.virt_size
= grub_host_to_target32 (0xffffffff);
474 note_ptr
->descriptor
.load_base
= grub_host_to_target32 (0x00004000);
477 phdr
->p_type
= grub_host_to_target32 (PT_NOTE
);
478 phdr
->p_flags
= grub_host_to_target32 (PF_R
);
479 phdr
->p_align
= grub_host_to_target32 (image_target
->voidp_sizeof
);
482 phdr
->p_filesz
= grub_host_to_target32 (note_size
);
484 phdr
->p_offset
= grub_host_to_target32 (header_size
+ program_size
);
488 char *str_start
= (elf_img
+ sizeof (*ehdr
) + phnum
* sizeof (*phdr
)
489 + shnum
* sizeof (*shdr
));
490 char *ptr
= str_start
+ 1;
494 shdr
->sh_name
= grub_host_to_target32 (0);
495 shdr
->sh_type
= grub_host_to_target32 (SHT_STRTAB
);
496 shdr
->sh_addr
= grub_host_to_target_addr (0);
497 shdr
->sh_offset
= grub_host_to_target_addr (str_start
- elf_img
);
498 shdr
->sh_size
= grub_host_to_target32 (string_size
);
499 shdr
->sh_link
= grub_host_to_target32 (0);
500 shdr
->sh_info
= grub_host_to_target32 (0);
501 shdr
->sh_addralign
= grub_host_to_target32 (layout
->align
);
502 shdr
->sh_entsize
= grub_host_to_target32 (0);
505 memcpy (ptr
, ".text", sizeof (".text"));
507 shdr
->sh_name
= grub_host_to_target32 (ptr
- str_start
);
508 ptr
+= sizeof (".text");
509 shdr
->sh_type
= grub_host_to_target32 (SHT_PROGBITS
);
510 shdr
->sh_addr
= grub_host_to_target_addr (target_addr
);
511 shdr
->sh_offset
= grub_host_to_target_addr (header_size
);
512 shdr
->sh_size
= grub_host_to_target32 (layout
->kernel_size
);
513 shdr
->sh_link
= grub_host_to_target32 (0);
514 shdr
->sh_info
= grub_host_to_target32 (0);
515 shdr
->sh_addralign
= grub_host_to_target32 (layout
->align
);
516 shdr
->sh_entsize
= grub_host_to_target32 (0);
519 memcpy (ptr
, "mods", sizeof ("mods"));
520 shdr
->sh_name
= grub_host_to_target32 (ptr
- str_start
);
521 ptr
+= sizeof ("mods");
522 shdr
->sh_type
= grub_host_to_target32 (SHT_PROGBITS
);
523 shdr
->sh_addr
= grub_host_to_target_addr (target_addr
+ layout
->kernel_size
);
524 shdr
->sh_offset
= grub_host_to_target_addr (header_size
+ layout
->kernel_size
);
525 shdr
->sh_size
= grub_host_to_target32 (*core_size
- layout
->kernel_size
);
526 shdr
->sh_link
= grub_host_to_target32 (0);
527 shdr
->sh_info
= grub_host_to_target32 (0);
528 shdr
->sh_addralign
= grub_host_to_target32 (image_target
->voidp_sizeof
);
529 shdr
->sh_entsize
= grub_host_to_target32 (0);
532 if (image_target
->id
== IMAGE_XEN
|| image_target
->id
== IMAGE_XEN_PVH
)
534 memcpy (ptr
, ".xen", sizeof (".xen"));
535 shdr
->sh_name
= grub_host_to_target32 (ptr
- str_start
);
536 ptr
+= sizeof (".xen");
537 shdr
->sh_type
= grub_host_to_target32 (SHT_PROGBITS
);
538 shdr
->sh_addr
= grub_host_to_target_addr (target_addr
+ layout
->kernel_size
);
539 shdr
->sh_offset
= grub_host_to_target_addr (program_size
+ header_size
);
540 if (image_target
->id
== IMAGE_XEN
)
541 shdr
->sh_size
= grub_host_to_target32 (XEN_NOTE_SIZE
);
543 shdr
->sh_size
= grub_host_to_target32 (XEN_PVH_NOTE_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 (image_target
->voidp_sizeof
);
547 shdr
->sh_entsize
= grub_host_to_target32 (0);
554 *core_size
= program_size
+ header_size
+ footer_size
;
557 /* Relocate symbols; note that this function overwrites the symbol table.
558 Return the address of a start symbol. */
560 SUFFIX (relocate_symbols
) (Elf_Ehdr
*e
, struct section_metadata
*smd
,
561 void *jumpers
, Elf_Addr jumpers_addr
,
562 Elf_Addr bss_start
, Elf_Addr end
,
563 const struct grub_install_image_target_desc
*image_target
)
565 Elf_Word symtab_size
, sym_size
, num_syms
;
566 Elf_Off symtab_offset
;
567 Elf_Addr start_address
= (Elf_Addr
) -1;
570 Elf_Shdr
*symtab_section
;
572 grub_uint64_t
*jptr
= jumpers
;
574 symtab_section
= (Elf_Shdr
*) ((char *) smd
->sections
575 + grub_target_to_host32 (smd
->symtab
->sh_link
)
576 * smd
->section_entsize
);
577 symtab
= (char *) e
+ grub_target_to_host (symtab_section
->sh_offset
);
579 symtab_size
= grub_target_to_host (smd
->symtab
->sh_size
);
580 sym_size
= grub_target_to_host (smd
->symtab
->sh_entsize
);
581 symtab_offset
= grub_target_to_host (smd
->symtab
->sh_offset
);
582 num_syms
= symtab_size
/ sym_size
;
584 for (i
= 0, sym
= (Elf_Sym
*) ((char *) e
+ symtab_offset
);
586 i
++, sym
= (Elf_Sym
*) ((char *) sym
+ sym_size
))
588 Elf_Section cur_index
;
591 name
= symtab
+ grub_target_to_host32 (sym
->st_name
);
593 cur_index
= grub_target_to_host16 (sym
->st_shndx
);
594 if (cur_index
== STN_ABS
)
598 else if (cur_index
== STN_UNDEF
)
600 if (sym
->st_name
&& grub_strcmp (name
, "__bss_start") == 0)
601 sym
->st_value
= bss_start
;
602 else if (sym
->st_name
&& grub_strcmp (name
, "_end") == 0)
604 else if (sym
->st_name
)
605 grub_util_error ("undefined symbol %s", name
);
609 else if (cur_index
>= smd
->num_sections
)
610 grub_util_error ("section %d does not exist", cur_index
);
613 sym
->st_value
= (grub_target_to_host (sym
->st_value
)
614 + smd
->vaddrs
[cur_index
]);
617 if (image_target
->elf_target
== EM_IA_64
&& ELF_ST_TYPE (sym
->st_info
)
620 *jptr
= grub_host_to_target64 (sym
->st_value
);
621 sym
->st_value
= (char *) jptr
- (char *) jumpers
+ jumpers_addr
;
626 grub_util_info ("locating %s at 0x%" GRUB_HOST_PRIxLONG_LONG
627 " (0x%" GRUB_HOST_PRIxLONG_LONG
")", name
,
628 (unsigned long long) sym
->st_value
,
629 (unsigned long long) smd
->vaddrs
[cur_index
]);
631 if (start_address
== (Elf_Addr
)-1)
632 if (strcmp (name
, "_start") == 0 || strcmp (name
, "start") == 0)
633 start_address
= sym
->st_value
;
636 return start_address
;
639 /* Return the address of a symbol at the index I in the section S. */
641 SUFFIX (get_symbol_address
) (Elf_Ehdr
*e
, Elf_Shdr
*s
, Elf_Word i
,
642 const struct grub_install_image_target_desc
*image_target
)
646 sym
= (Elf_Sym
*) ((char *) e
647 + grub_target_to_host (s
->sh_offset
)
648 + i
* grub_target_to_host (s
->sh_entsize
));
649 return sym
->st_value
;
652 /* Return the address of a modified value. */
654 SUFFIX (get_target_address
) (Elf_Ehdr
*e
, Elf_Shdr
*s
, Elf_Addr offset
,
655 const struct grub_install_image_target_desc
*image_target
)
657 return (Elf_Addr
*) ((char *) e
+ grub_target_to_host (s
->sh_offset
) + offset
);
662 SUFFIX (count_funcs
) (Elf_Ehdr
*e
, Elf_Shdr
*symtab_section
,
663 const struct grub_install_image_target_desc
*image_target
)
665 Elf_Word symtab_size
, sym_size
, num_syms
;
666 Elf_Off symtab_offset
;
671 symtab_size
= grub_target_to_host (symtab_section
->sh_size
);
672 sym_size
= grub_target_to_host (symtab_section
->sh_entsize
);
673 symtab_offset
= grub_target_to_host (symtab_section
->sh_offset
);
674 num_syms
= symtab_size
/ sym_size
;
676 for (i
= 0, sym
= (Elf_Sym
*) ((char *) e
+ symtab_offset
);
678 i
++, sym
= (Elf_Sym
*) ((char *) sym
+ sym_size
))
679 if (ELF_ST_TYPE (sym
->st_info
) == STT_FUNC
)
687 /* Deal with relocation information. This function relocates addresses
688 within the virtual address space starting from 0. So only relative
689 addresses can be fully resolved. Absolute addresses must be relocated
690 again by a PE32 relocator when loaded. */
692 arm_get_trampoline_size (Elf_Ehdr
*e
,
694 Elf_Half section_entsize
,
695 Elf_Half num_sections
,
696 const struct grub_install_image_target_desc
*image_target
)
702 for (i
= 0, s
= sections
;
704 i
++, s
= (Elf_Shdr
*) ((char *) s
+ section_entsize
))
705 if ((s
->sh_type
== grub_host_to_target32 (SHT_REL
)) ||
706 (s
->sh_type
== grub_host_to_target32 (SHT_RELA
)))
709 Elf_Word rtab_size
, r_size
, num_rs
;
711 Elf_Shdr
*symtab_section
;
714 symtab_section
= (Elf_Shdr
*) ((char *) sections
715 + (grub_target_to_host32 (s
->sh_link
)
718 rtab_size
= grub_target_to_host (s
->sh_size
);
719 r_size
= grub_target_to_host (s
->sh_entsize
);
720 rtab_offset
= grub_target_to_host (s
->sh_offset
);
721 num_rs
= rtab_size
/ r_size
;
723 for (j
= 0, r
= (Elf_Rela
*) ((char *) e
+ rtab_offset
);
725 j
++, r
= (Elf_Rela
*) ((char *) r
+ r_size
))
730 info
= grub_target_to_host (r
->r_info
);
731 sym_addr
= SUFFIX (get_symbol_address
) (e
, symtab_section
,
732 ELF_R_SYM (info
), image_target
);
734 sym_addr
+= (s
->sh_type
== grub_target_to_host32 (SHT_RELA
)) ?
735 grub_target_to_host (r
->r_addend
) : 0;
737 switch (ELF_R_TYPE (info
))
743 case R_ARM_THM_JUMP24
:
744 case R_ARM_THM_JUMP19
:
756 grub_util_error (_("relocation 0x%x is not implemented yet"),
757 (unsigned int) ELF_R_TYPE (info
));
767 SUFFIX (is_kept_section
) (Elf_Shdr
*s
, const struct grub_install_image_target_desc
*image_target
);
769 SUFFIX (is_kept_reloc_section
) (Elf_Shdr
*s
, const struct grub_install_image_target_desc
*image_target
,
770 struct section_metadata
*smd
);
772 /* Deal with relocation information. This function relocates addresses
773 within the virtual address space starting from 0. So only relative
774 addresses can be fully resolved. Absolute addresses must be relocated
775 again by a PE32 relocator when loaded. */
777 SUFFIX (relocate_addrs
) (Elf_Ehdr
*e
, struct section_metadata
*smd
,
778 char *pe_target
, Elf_Addr tramp_off
, Elf_Addr got_off
,
779 const struct grub_install_image_target_desc
*image_target
)
784 struct grub_ia64_trampoline
*tr
= (void *) (pe_target
+ tramp_off
);
785 grub_uint64_t
*gpptr
= (void *) (pe_target
+ got_off
);
786 unsigned unmatched_adr_got_page
= 0;
787 #define MASK19 ((1 << 19) - 1)
789 grub_uint32_t
*tr
= (void *) (pe_target
+ tramp_off
);
792 for (i
= 0, s
= smd
->sections
;
793 i
< smd
->num_sections
;
794 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
->section_entsize
))
795 if ((s
->sh_type
== grub_host_to_target32 (SHT_REL
)) ||
796 (s
->sh_type
== grub_host_to_target32 (SHT_RELA
)))
799 Elf_Word rtab_size
, r_size
, num_rs
;
801 Elf_Word target_section_index
;
802 Elf_Addr target_section_addr
;
803 Elf_Shdr
*target_section
;
806 if (!SUFFIX (is_kept_section
) (s
, image_target
) &&
807 !SUFFIX (is_kept_reloc_section
) (s
, image_target
, smd
))
809 grub_util_info ("not translating relocations for omitted section %s",
810 smd
->strtab
+ grub_le_to_cpu32 (s
->sh_name
));
814 target_section_index
= grub_target_to_host32 (s
->sh_info
);
815 target_section_addr
= smd
->addrs
[target_section_index
];
816 target_section
= (Elf_Shdr
*) ((char *) smd
->sections
817 + (target_section_index
818 * smd
->section_entsize
));
820 grub_util_info ("dealing with the relocation section %s for %s",
821 smd
->strtab
+ grub_target_to_host32 (s
->sh_name
),
822 smd
->strtab
+ grub_target_to_host32 (target_section
->sh_name
));
824 rtab_size
= grub_target_to_host (s
->sh_size
);
825 r_size
= grub_target_to_host (s
->sh_entsize
);
826 rtab_offset
= grub_target_to_host (s
->sh_offset
);
827 num_rs
= rtab_size
/ r_size
;
829 for (j
= 0, r
= (Elf_Rela
*) ((char *) e
+ rtab_offset
);
831 j
++, r
= (Elf_Rela
*) ((char *) r
+ r_size
))
839 offset
= grub_target_to_host (r
->r_offset
);
840 target
= SUFFIX (get_target_address
) (e
, target_section
,
841 offset
, image_target
);
842 if (image_target
->elf_target
== EM_MIPS
&& image_target
->voidp_sizeof
== 8)
843 info
= ((grub_uint64_t
) r
->r_info
<< 32) |
844 (grub_uint32_t
) grub_be_to_cpu64 (r
->r_info
);
846 info
= grub_target_to_host (r
->r_info
);
847 sym_addr
= SUFFIX (get_symbol_address
) (e
, smd
->symtab
,
848 ELF_R_SYM (info
), image_target
);
850 addend
= (s
->sh_type
== grub_target_to_host32 (SHT_RELA
)) ?
851 grub_target_to_host (r
->r_addend
) : 0;
853 switch (image_target
->elf_target
)
856 switch (ELF_R_TYPE (info
))
862 /* This is absolute. */
863 *target
= grub_host_to_target32 (grub_target_to_host32 (*target
)
864 + addend
+ sym_addr
);
865 grub_util_info ("relocating an R_386_32 entry to 0x%"
866 GRUB_HOST_PRIxLONG_LONG
" at the offset 0x%"
867 GRUB_HOST_PRIxLONG_LONG
,
868 (unsigned long long) *target
,
869 (unsigned long long) offset
);
873 /* This is relative. */
874 *target
= grub_host_to_target32 (grub_target_to_host32 (*target
)
876 - target_section_addr
- offset
877 - image_target
->vaddr_offset
);
878 grub_util_info ("relocating an R_386_PC32 entry to 0x%"
879 GRUB_HOST_PRIxLONG_LONG
" at the offset 0x%"
880 GRUB_HOST_PRIxLONG_LONG
,
881 (unsigned long long) *target
,
882 (unsigned long long) offset
);
885 grub_util_error (_("relocation 0x%x is not implemented yet"),
886 (unsigned int) ELF_R_TYPE (info
));
892 switch (ELF_R_TYPE (info
))
899 *target
= grub_host_to_target64 (grub_target_to_host64 (*target
)
900 + addend
+ sym_addr
);
901 grub_util_info ("relocating an R_X86_64_64 entry to 0x%"
902 GRUB_HOST_PRIxLONG_LONG
" at the offset 0x%"
903 GRUB_HOST_PRIxLONG_LONG
,
904 (unsigned long long) *target
,
905 (unsigned long long) offset
);
911 grub_uint32_t
*t32
= (grub_uint32_t
*) target
;
912 *t32
= grub_host_to_target64 (grub_target_to_host32 (*t32
)
914 - target_section_addr
- offset
915 - image_target
->vaddr_offset
);
916 grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%"
917 GRUB_HOST_PRIxLONG_LONG
,
918 *t32
, (unsigned long long) offset
);
924 *target
= grub_host_to_target64 (grub_target_to_host64 (*target
)
926 - target_section_addr
- offset
927 - image_target
->vaddr_offset
);
928 grub_util_info ("relocating an R_X86_64_PC64 entry to 0x%"
929 GRUB_HOST_PRIxLONG_LONG
" at the offset 0x%"
930 GRUB_HOST_PRIxLONG_LONG
,
931 (unsigned long long) *target
,
932 (unsigned long long) offset
);
939 grub_uint32_t
*t32
= (grub_uint32_t
*) target
;
940 *t32
= grub_host_to_target64 (grub_target_to_host32 (*t32
)
941 + addend
+ sym_addr
);
942 grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%"
943 GRUB_HOST_PRIxLONG_LONG
,
944 *t32
, (unsigned long long) offset
);
949 grub_util_error (_("relocation 0x%x is not implemented yet"),
950 (unsigned int) ELF_R_TYPE (info
));
955 switch (ELF_R_TYPE (info
))
957 case R_IA64_PCREL21B
:
960 grub_ia64_make_trampoline (tr
, addend
+ sym_addr
);
961 noff
= ((char *) tr
- (char *) pe_target
962 - target_section_addr
- (offset
& ~3)) >> 4;
965 grub_util_error ("trampoline offset too big (%"
966 GRUB_HOST_PRIxLONG_LONG
")",
967 (unsigned long long) noff
);
968 grub_ia64_add_value_to_slot_20b ((grub_addr_t
) target
, noff
);
972 case R_IA64_LTOFF22X
:
977 sym
= (Elf_Sym
*) ((char *) e
978 + grub_target_to_host (smd
->symtab
->sh_offset
)
979 + ELF_R_SYM (info
) * grub_target_to_host (smd
->symtab
->sh_entsize
));
980 if (ELF_ST_TYPE (sym
->st_info
) == STT_FUNC
)
981 sym_addr
= grub_target_to_host64 (*(grub_uint64_t
*) (pe_target
983 - image_target
->vaddr_offset
));
986 case R_IA64_LTOFF_FPTR22
:
987 *gpptr
= grub_host_to_target64 (addend
+ sym_addr
);
988 grub_ia64_add_value_to_slot_21 ((grub_addr_t
) target
,
989 (char *) gpptr
- (char *) pe_target
990 + image_target
->vaddr_offset
);
995 grub_ia64_add_value_to_slot_21 ((grub_addr_t
) target
,
998 case R_IA64_GPREL64I
:
999 grub_ia64_set_immu64 ((grub_addr_t
) target
,
1002 case R_IA64_PCREL64LSB
:
1003 *target
= grub_host_to_target64 (grub_target_to_host64 (*target
)
1005 - target_section_addr
- offset
1006 - image_target
->vaddr_offset
);
1009 case R_IA64_SEGREL64LSB
:
1010 *target
= grub_host_to_target64 (grub_target_to_host64 (*target
)
1011 + addend
+ sym_addr
- target_section_addr
);
1013 case R_IA64_DIR64LSB
:
1014 case R_IA64_FPTR64LSB
:
1015 *target
= grub_host_to_target64 (grub_target_to_host64 (*target
)
1016 + addend
+ sym_addr
);
1017 grub_util_info ("relocating a direct entry to 0x%"
1018 GRUB_HOST_PRIxLONG_LONG
" at the offset 0x%"
1019 GRUB_HOST_PRIxLONG_LONG
,
1020 (unsigned long long)
1021 grub_target_to_host64 (*target
),
1022 (unsigned long long) offset
);
1025 /* We treat LTOFF22X as LTOFF22, so we can ignore LDXMOV. */
1030 grub_util_error (_("relocation 0x%x is not implemented yet"),
1031 (unsigned int) ELF_R_TYPE (info
));
1038 switch (ELF_R_TYPE (info
))
1040 case R_AARCH64_ABS64
:
1042 *target
= grub_host_to_target64 (grub_target_to_host64 (*target
) + sym_addr
);
1045 case R_AARCH64_PREL32
:
1047 grub_uint32_t
*t32
= (grub_uint32_t
*) target
;
1048 *t32
= grub_host_to_target64 (grub_target_to_host32 (*t32
)
1050 - target_section_addr
- offset
1051 - image_target
->vaddr_offset
);
1052 grub_util_info ("relocating an R_AARCH64_PREL32 entry to 0x%x at the offset 0x%"
1053 GRUB_HOST_PRIxLONG_LONG
,
1054 *t32
, (unsigned long long) offset
);
1057 case R_AARCH64_ADD_ABS_LO12_NC
:
1058 grub_arm64_set_abs_lo12 ((grub_uint32_t
*) target
,
1061 case R_AARCH64_LDST64_ABS_LO12_NC
:
1062 grub_arm64_set_abs_lo12_ldst64 ((grub_uint32_t
*) target
,
1065 case R_AARCH64_JUMP26
:
1066 case R_AARCH64_CALL26
:
1069 sym_addr
-= target_section_addr
+ image_target
->vaddr_offset
;
1070 if (!grub_arm_64_check_xxxx26_offset (sym_addr
))
1071 grub_util_error ("%s", "CALL26 Relocation out of range");
1073 grub_arm64_set_xxxx26_offset((grub_uint32_t
*)target
,
1077 case R_AARCH64_ADR_GOT_PAGE
:
1080 grub_int64_t gpoffset
= (((char *) gpptr
- (char *) pe_target
+ image_target
->vaddr_offset
) & ~0xfffULL
)
1081 - ((offset
+ target_section_addr
+ image_target
->vaddr_offset
) & ~0xfffULL
);
1083 *gpptr
= grub_host_to_target64 (sym_addr
);
1084 unmatched_adr_got_page
++;
1085 if (!grub_arm64_check_hi21_signed (gpoffset
))
1086 grub_util_error ("HI21 out of range");
1087 grub_arm64_set_hi21((grub_uint32_t
*)target
,
1089 for (k
= 0, rel2
= (Elf_Rela
*) ((char *) r
+ r_size
);
1091 k
++, rel2
= (Elf_Rela
*) ((char *) rel2
+ r_size
))
1092 if (ELF_R_SYM (rel2
->r_info
)
1093 == ELF_R_SYM (r
->r_info
)
1094 && r
->r_addend
== rel2
->r_addend
1095 && ELF_R_TYPE (rel2
->r_info
) == R_AARCH64_LD64_GOT_LO12_NC
)
1097 grub_arm64_set_abs_lo12_ldst64 ((grub_uint32_t
*) SUFFIX (get_target_address
) (e
, target_section
,
1098 grub_target_to_host (rel2
->r_offset
), image_target
),
1099 ((char *) gpptr
- (char *) pe_target
+ image_target
->vaddr_offset
));
1103 grub_util_error ("ADR_GOT_PAGE without matching LD64_GOT_LO12_NC");
1107 case R_AARCH64_LD64_GOT_LO12_NC
:
1108 if (unmatched_adr_got_page
== 0)
1109 grub_util_error ("LD64_GOT_LO12_NC without matching ADR_GOT_PAGE");
1110 unmatched_adr_got_page
--;
1112 case R_AARCH64_ADR_PREL_PG_HI21
:
1114 sym_addr
&= ~0xfffULL
;
1115 sym_addr
-= (offset
+ target_section_addr
+ image_target
->vaddr_offset
) & ~0xfffULL
;
1116 if (!grub_arm64_check_hi21_signed (sym_addr
))
1117 grub_util_error ("%s", "CALL26 Relocation out of range");
1119 grub_arm64_set_hi21((grub_uint32_t
*)target
,
1124 grub_util_error (_("relocation 0x%x is not implemented yet"),
1125 (unsigned int) ELF_R_TYPE (info
));
1133 switch (ELF_R_TYPE (info
))
1139 *target
= grub_host_to_target64 (grub_target_to_host64 (*target
) + sym_addr
);
1144 grub_uint32_t
*t32
= (grub_uint32_t
*) target
;
1145 *t32
= grub_host_to_target64 (grub_target_to_host32 (*t32
) + sym_addr
);
1150 grub_uint32_t
*t32
= (grub_uint32_t
*) target
;
1151 grub_addr_t addr
= grub_host_to_target64 (sym_addr
);
1152 *t32
= ((*t32
) & 0xfc000000U
) | ((addr
>> 2) & 0x3ffffffUL
);
1157 grub_int16_t
*t16
= (grub_int16_t
*) target
;
1158 grub_addr_t addr
= grub_host_to_target64 (sym_addr
);
1159 *t16
= (grub_int16_t
) addr
;
1164 grub_int16_t
*t16
= (grub_int16_t
*) target
;
1165 grub_addr_t addr
= grub_host_to_target64 (sym_addr
);
1166 *t16
= (grub_int16_t
) ((addr
+ 0x8000UL
) >> 16);
1171 grub_int16_t
*t16
= (grub_int16_t
*) target
;
1172 grub_addr_t addr
= grub_host_to_target64 (sym_addr
);
1173 *t16
= (grub_int16_t
) ((addr
+ 0x80008000UL
) >> 32);
1176 case R_MIPS_HIGHEST
:
1178 grub_uint16_t
*t16
= (grub_uint16_t
*) target
;
1179 grub_addr_t addr
= grub_host_to_target64 (sym_addr
);
1180 *t16
= (grub_uint16_t
) ((addr
+ 0x800080008000UL
) >> 48);
1184 grub_util_error (_("relocation 0x%x is not implemented yet"),
1185 (unsigned int) ELF_R_TYPE (info
));
1191 #if defined(MKIMAGE_ELF32)
1195 sym_addr
-= image_target
->vaddr_offset
;
1196 switch (ELF_R_TYPE (info
))
1200 grub_util_info (" ABS32:\toffset=%d\t(0x%08x)",
1201 (int) sym_addr
, (int) sym_addr
);
1202 /* Data will be naturally aligned */
1203 if (image_target
->id
== IMAGE_EFI
)
1204 sym_addr
+= GRUB_PE32_SECTION_ALIGNMENT
;
1205 *target
= grub_host_to_target32 (grub_target_to_host32 (*target
) + sym_addr
);
1208 /* Happens when compiled with -march=armv4.
1209 Since currently we need at least armv5, keep bx as-is.
1213 case R_ARM_THM_CALL
:
1214 case R_ARM_THM_JUMP24
:
1215 case R_ARM_THM_JUMP19
:
1219 grub_util_info (" THM_JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)",
1220 (unsigned long) ((char *) target
1223 sym
= (Elf_Sym
*) ((char *) e
1224 + grub_target_to_host (smd
->symtab
->sh_offset
)
1225 + ELF_R_SYM (info
) * grub_target_to_host (smd
->symtab
->sh_entsize
));
1226 if (ELF_ST_TYPE (sym
->st_info
) != STT_FUNC
)
1228 if (!(sym_addr
& 1))
1230 grub_uint32_t tr_addr
;
1231 grub_int32_t new_offset
;
1232 tr_addr
= (char *) tr
- (char *) pe_target
1233 - target_section_addr
;
1234 new_offset
= sym_addr
- tr_addr
- 12;
1236 if (!grub_arm_jump24_check_offset (new_offset
))
1237 return grub_util_error ("jump24 relocation out of range");
1239 tr
[0] = grub_host_to_target32 (0x46c04778); /* bx pc; nop */
1240 tr
[1] = grub_host_to_target32 (((new_offset
>> 2) & 0xffffff) | 0xea000000); /* b new_offset */
1242 sym_addr
= tr_addr
| 1;
1245 /* Thumb instructions can be 16-bit aligned */
1246 if (ELF_R_TYPE (info
) == R_ARM_THM_JUMP19
)
1247 err
= grub_arm_reloc_thm_jump19 ((grub_uint16_t
*) target
, sym_addr
);
1249 err
= grub_arm_reloc_thm_call ((grub_uint16_t
*) target
,
1252 grub_util_error ("%s", grub_errmsg
);
1260 grub_util_info (" JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)", (unsigned long) ((char *) target
- (char *) e
), sym_addr
);
1263 grub_uint32_t tr_addr
;
1264 grub_int32_t new_offset
;
1265 tr_addr
= (char *) tr
- (char *) pe_target
1266 - target_section_addr
;
1267 new_offset
= sym_addr
- tr_addr
- 12;
1269 /* There is no immediate version of bx, only register one... */
1270 tr
[0] = grub_host_to_target32 (0xe59fc004); /* ldr ip, [pc, #4] */
1271 tr
[1] = grub_host_to_target32 (0xe08cc00f); /* add ip, ip, pc */
1272 tr
[2] = grub_host_to_target32 (0xe12fff1c); /* bx ip */
1273 tr
[3] = grub_host_to_target32 (new_offset
| 1);
1278 err
= grub_arm_reloc_jump24 (target
,
1281 grub_util_error ("%s", grub_errmsg
);
1286 grub_util_error (_("relocation 0x%x is not implemented yet"),
1287 (unsigned int) ELF_R_TYPE (info
));
1292 #endif /* MKIMAGE_ELF32 */
1295 grub_uint64_t
*t64
= (grub_uint64_t
*) target
;
1296 grub_uint32_t
*t32
= (grub_uint32_t
*) target
;
1297 grub_uint16_t
*t16
= (grub_uint16_t
*) target
;
1298 grub_uint8_t
*t8
= (grub_uint8_t
*) target
;
1299 grub_int64_t off
= (long)sym_addr
- target_section_addr
- offset
1300 - image_target
->vaddr_offset
;
1303 * Instructions and instruction encoding are documented in the RISC-V
1304 * specification. This file is based on version 2.2:
1306 * https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-spec-v2.2.pdf
1311 switch (ELF_R_TYPE (info
))
1314 *t8
= *t8
+ sym_addr
;
1317 *t16
= grub_host_to_target16 (grub_target_to_host16 (*t16
) + sym_addr
);
1321 *t32
= grub_host_to_target32 (grub_target_to_host32 (*t32
) + sym_addr
);
1325 *t64
= grub_host_to_target64 (grub_target_to_host64 (*t64
) + sym_addr
);
1329 *t8
= sym_addr
- *t8
;
1332 *t16
= grub_host_to_target16 (grub_target_to_host16 (*t16
) - sym_addr
);
1335 *t32
= grub_host_to_target32 (grub_target_to_host32 (*t32
) - sym_addr
);
1338 *t64
= grub_host_to_target64 (grub_target_to_host64 (*t64
) - sym_addr
);
1340 case R_RISCV_BRANCH
:
1342 grub_uint32_t imm12
= (off
& 0x1000) << (31 - 12);
1343 grub_uint32_t imm11
= (off
& 0x800) >> (11 - 7);
1344 grub_uint32_t imm10_5
= (off
& 0x7e0) << (30 - 10);
1345 grub_uint32_t imm4_1
= (off
& 0x1e) << (11 - 4);
1346 *t32
= grub_host_to_target32 ((grub_target_to_host32 (*t32
) & 0x1fff07f)
1347 | imm12
| imm11
| imm10_5
| imm4_1
);
1352 grub_uint32_t imm20
= (off
& 0x100000) << (31 - 20);
1353 grub_uint32_t imm19_12
= (off
& 0xff000);
1354 grub_uint32_t imm11
= (off
& 0x800) << (20 - 11);
1355 grub_uint32_t imm10_1
= (off
& 0x7fe) << (30 - 10);
1356 *t32
= grub_host_to_target32 ((grub_target_to_host32 (*t32
) & 0xfff)
1357 | imm20
| imm19_12
| imm11
| imm10_1
);
1362 grub_uint32_t hi20
, lo12
;
1364 if (off
!= (grub_int32_t
)off
)
1365 grub_util_error ("target %lx not reachable from pc=%lx", (long)sym_addr
, (long)((char *)target
- (char *)e
));
1367 hi20
= (off
+ 0x800) & 0xfffff000;
1368 lo12
= (off
- hi20
) & 0xfff;
1369 t32
[0] = grub_host_to_target32 ((grub_target_to_host32 (t32
[0]) & 0xfff) | hi20
);
1370 t32
[1] = grub_host_to_target32 ((grub_target_to_host32 (t32
[1]) & 0xfffff) | (lo12
<< 20));
1373 case R_RISCV_RVC_BRANCH
:
1375 grub_uint16_t imm8
= (off
& 0x100) << (12 - 8);
1376 grub_uint16_t imm7_6
= (off
& 0xc0) >> (6 - 5);
1377 grub_uint16_t imm5
= (off
& 0x20) >> (5 - 2);
1378 grub_uint16_t imm4_3
= (off
& 0x18) << (12 - 5);
1379 grub_uint16_t imm2_1
= (off
& 0x6) << (12 - 10);
1380 *t16
= grub_host_to_target16 ((grub_target_to_host16 (*t16
) & 0xe383)
1381 | imm8
| imm7_6
| imm5
| imm4_3
| imm2_1
);
1384 case R_RISCV_RVC_JUMP
:
1386 grub_uint16_t imm11
= (off
& 0x800) << (12 - 11);
1387 grub_uint16_t imm10
= (off
& 0x400) >> (10 - 8);
1388 grub_uint16_t imm9_8
= (off
& 0x300) << (12 - 11);
1389 grub_uint16_t imm7
= (off
& 0x80) >> (7 - 6);
1390 grub_uint16_t imm6
= (off
& 0x40) << (12 - 11);
1391 grub_uint16_t imm5
= (off
& 0x20) >> (5 - 2);
1392 grub_uint16_t imm4
= (off
& 0x10) << (12 - 5);
1393 grub_uint16_t imm3_1
= (off
& 0xe) << (12 - 10);
1394 *t16
= grub_host_to_target16 ((grub_target_to_host16 (*t16
) & 0xe003)
1395 | imm11
| imm10
| imm9_8
| imm7
| imm6
1396 | imm5
| imm4
| imm3_1
);
1399 case R_RISCV_PCREL_HI20
:
1403 if (off
!= (grub_int32_t
)off
)
1404 grub_util_error ("target %lx not reachable from pc=%lx", (long)sym_addr
, (long)((char *)target
- (char *)e
));
1406 hi20
= (off
+ 0x800) & 0xfffff000;
1407 *t32
= grub_host_to_target32 ((grub_target_to_host32 (*t32
) & 0xfff) | hi20
);
1410 case R_RISCV_PCREL_LO12_I
:
1411 case R_RISCV_PCREL_LO12_S
:
1415 /* Search backwards for matching HI20 reloc. */
1416 for (k
= j
, rel2
= (Elf_Rela
*) ((char *) r
- r_size
);
1418 k
--, rel2
= (Elf_Rela
*) ((char *) rel2
- r_size
))
1421 Elf_Addr rel2_offset
;
1422 Elf_Addr rel2_sym_addr
;
1423 Elf_Addr rel2_addend
;
1425 grub_int64_t rel2_off
;
1427 rel2_offset
= grub_target_to_host (rel2
->r_offset
);
1428 rel2_info
= grub_target_to_host (rel2
->r_info
);
1429 rel2_loc
= target_section_addr
+ rel2_offset
+ image_target
->vaddr_offset
;
1431 if (ELF_R_TYPE (rel2_info
) == R_RISCV_PCREL_HI20
1432 && rel2_loc
== sym_addr
)
1434 rel2_sym_addr
= SUFFIX (get_symbol_address
)
1435 (e
, smd
->symtab
, ELF_R_SYM (rel2_info
),
1437 rel2_addend
= (s
->sh_type
== grub_target_to_host32 (SHT_RELA
)) ?
1438 grub_target_to_host (rel2
->r_addend
) : 0;
1439 rel2_off
= rel2_sym_addr
+ rel2_addend
- rel2_loc
;
1440 off
= rel2_off
- ((rel2_off
+ 0x800) & 0xfffff000);
1442 if (ELF_R_TYPE (info
) == R_RISCV_PCREL_LO12_I
)
1443 *t32
= grub_host_to_target32 ((grub_target_to_host32 (*t32
) & 0xfffff) | (off
& 0xfff) << 20);
1446 grub_uint32_t imm11_5
= (off
& 0xfe0) << (31 - 11);
1447 grub_uint32_t imm4_0
= (off
& 0x1f) << (11 - 4);
1448 *t32
= grub_host_to_target32 ((grub_target_to_host32 (*t32
) & 0x1fff07f) | imm11_5
| imm4_0
);
1454 grub_util_error ("cannot find matching HI20 relocation");
1458 *t32
= grub_host_to_target32 ((grub_target_to_host32 (*t32
) & 0xfff) | (((grub_int32_t
) sym_addr
+ 0x800) & 0xfffff000));
1460 case R_RISCV_LO12_I
:
1462 grub_int32_t lo12
= (grub_int32_t
) sym_addr
- (((grub_int32_t
) sym_addr
+ 0x800) & 0xfffff000);
1463 *t32
= grub_host_to_target32 ((grub_target_to_host32 (*t32
) & 0xfffff) | ((lo12
& 0xfff) << 20));
1466 case R_RISCV_LO12_S
:
1468 grub_int32_t lo12
= (grub_int32_t
) sym_addr
- (((grub_int32_t
) sym_addr
+ 0x800) & 0xfffff000);
1469 grub_uint32_t imm11_5
= (lo12
& 0xfe0) << (31 - 11);
1470 grub_uint32_t imm4_0
= (lo12
& 0x1f) << (11 - 4);
1471 *t32
= grub_host_to_target32 ((grub_target_to_host32 (*t32
) & 0x1fff07f) | imm11_5
| imm4_0
);
1477 grub_util_error (_("relocation 0x%x is not implemented yet"),
1478 (unsigned int) ELF_R_TYPE (info
));
1484 grub_util_error ("unknown architecture type %d",
1485 image_target
->elf_target
);
1491 /* Add a PE32's fixup entry for a relocation. Return the resulting address
1492 after having written to the file OUT. */
1494 add_fixup_entry (struct fixup_block_list
**cblock
, grub_uint16_t type
,
1495 Elf_Addr addr
, int flush
, Elf_Addr current_address
,
1496 const struct grub_install_image_target_desc
*image_target
)
1498 struct grub_pe32_fixup_block
*b
;
1500 b
= &((*cblock
)->b
);
1502 /* First, check if it is necessary to write out the current block. */
1503 if ((*cblock
)->state
)
1505 if (flush
|| (type
&& (addr
< b
->page_rva
|| b
->page_rva
+ 0x1000 <= addr
)))
1511 /* Add as much padding as necessary to align the address
1512 with a section boundary. */
1513 Elf_Addr next_address
;
1514 unsigned padding_size
;
1517 next_address
= current_address
+ b
->block_size
;
1518 padding_size
= ((ALIGN_UP (next_address
, image_target
->section_align
)
1521 cur_index
= ((b
->block_size
- sizeof (*b
)) >> 1);
1522 grub_util_info ("adding %d padding fixup entries", padding_size
);
1523 while (padding_size
--)
1525 b
->entries
[cur_index
++] = 0;
1529 else while (b
->block_size
& (8 - 1))
1531 /* If not aligned with a 32-bit boundary, add
1535 grub_util_info ("adding a padding fixup entry");
1536 cur_index
= ((b
->block_size
- sizeof (*b
)) >> 1);
1537 b
->entries
[cur_index
] = 0;
1542 grub_util_info ("writing %d bytes of a fixup block starting at 0x%x",
1543 b
->block_size
, b
->page_rva
);
1544 size
= b
->block_size
;
1545 current_address
+= size
;
1546 b
->page_rva
= grub_host_to_target32 (b
->page_rva
);
1547 b
->block_size
= grub_host_to_target32 (b
->block_size
);
1548 (*cblock
)->next
= xmalloc (sizeof (**cblock
) + 2 * 0x1000);
1549 memset ((*cblock
)->next
, 0, sizeof (**cblock
) + 2 * 0x1000);
1550 *cblock
= (*cblock
)->next
;
1554 b
= &((*cblock
)->b
);
1558 grub_uint16_t entry
;
1561 /* If not allocated yet, allocate a block with enough entries. */
1562 if (! (*cblock
)->state
)
1564 (*cblock
)->state
= 1;
1566 /* The spec does not mention the requirement of a Page RVA.
1567 Here, align the address with a 4K boundary for safety. */
1569 b
->page_rva
= (addr
& ~(0x1000 - 1));
1570 b
->block_size
= sizeof (*b
);
1574 if (b
->block_size
>= sizeof (*b
) + 2 * 0x1000)
1575 grub_util_error ("too many fixup entries");
1577 /* Add a new entry. */
1578 cur_index
= ((b
->block_size
- sizeof (*b
)) >> 1);
1579 entry
= GRUB_PE32_FIXUP_ENTRY (type
, type
? (addr
- b
->page_rva
) : addr
);
1580 b
->entries
[cur_index
] = grub_host_to_target16 (entry
);
1584 return current_address
;
1589 struct raw_reloc
*next
;
1590 grub_uint32_t offset
;
1591 enum raw_reloc_type
{
1592 RAW_RELOC_NONE
= -1,
1598 struct translate_context
1601 struct fixup_block_list
*lst
, *lst0
;
1602 Elf_Addr current_address
;
1605 struct raw_reloc
*raw_relocs
;
1609 translate_reloc_start (struct translate_context
*ctx
,
1610 const struct grub_install_image_target_desc
*image_target
)
1612 grub_memset (ctx
, 0, sizeof (*ctx
));
1613 if (image_target
->id
== IMAGE_EFI
)
1615 ctx
->lst
= ctx
->lst0
= xmalloc (sizeof (*ctx
->lst
) + 2 * 0x1000);
1616 memset (ctx
->lst
, 0, sizeof (*ctx
->lst
) + 2 * 0x1000);
1617 ctx
->current_address
= 0;
1622 translate_relocation_pe (struct translate_context
*ctx
,
1627 const struct grub_install_image_target_desc
*image_target
)
1629 /* Necessary to relocate only absolute addresses. */
1630 switch (image_target
->elf_target
)
1633 if (ELF_R_TYPE (info
) == R_386_32
)
1635 grub_util_info ("adding a relocation entry for 0x%"
1636 GRUB_HOST_PRIxLONG_LONG
,
1637 (unsigned long long) addr
);
1638 ctx
->current_address
1639 = add_fixup_entry (&ctx
->lst
,
1640 GRUB_PE32_REL_BASED_HIGHLOW
,
1641 addr
, 0, ctx
->current_address
,
1646 if ((ELF_R_TYPE (info
) == R_X86_64_32
) ||
1647 (ELF_R_TYPE (info
) == R_X86_64_32S
))
1649 grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)");
1651 else if (ELF_R_TYPE (info
) == R_X86_64_64
)
1653 grub_util_info ("adding a relocation entry for 0x%"
1654 GRUB_HOST_PRIxLONG_LONG
,
1655 (unsigned long long) addr
);
1656 ctx
->current_address
1657 = add_fixup_entry (&ctx
->lst
,
1658 GRUB_PE32_REL_BASED_DIR64
,
1660 0, ctx
->current_address
,
1665 switch (ELF_R_TYPE (info
))
1667 case R_IA64_PCREL64LSB
:
1669 case R_IA64_PCREL21B
:
1670 case R_IA64_LTOFF_FPTR22
:
1671 case R_IA64_LTOFF22X
:
1672 case R_IA64_LTOFF22
:
1673 case R_IA64_GPREL22
:
1674 case R_IA64_GPREL64I
:
1675 case R_IA64_SEGREL64LSB
:
1678 case R_IA64_FPTR64LSB
:
1679 case R_IA64_DIR64LSB
:
1682 grub_util_info ("adding a relocation entry for 0x%"
1683 GRUB_HOST_PRIxLONG_LONG
,
1684 (unsigned long long) addr
);
1685 ctx
->current_address
1686 = add_fixup_entry (&ctx
->lst
,
1687 GRUB_PE32_REL_BASED_DIR64
,
1689 0, ctx
->current_address
,
1695 grub_util_error (_("relocation 0x%x is not implemented yet"),
1696 (unsigned int) ELF_R_TYPE (info
));
1701 switch (ELF_R_TYPE (info
))
1703 case R_AARCH64_ABS64
:
1705 ctx
->current_address
1706 = add_fixup_entry (&ctx
->lst
,
1707 GRUB_PE32_REL_BASED_DIR64
,
1708 addr
, 0, ctx
->current_address
,
1712 /* Relative relocations do not require fixup entries. */
1713 case R_AARCH64_CALL26
:
1714 case R_AARCH64_JUMP26
:
1715 case R_AARCH64_PREL32
:
1717 /* Page-relative relocations do not require fixup entries. */
1718 case R_AARCH64_ADR_PREL_PG_HI21
:
1719 /* We page-align the whole kernel, so no need
1722 case R_AARCH64_ADD_ABS_LO12_NC
:
1723 case R_AARCH64_LDST64_ABS_LO12_NC
:
1726 /* GOT is relocated separately. */
1727 case R_AARCH64_ADR_GOT_PAGE
:
1728 case R_AARCH64_LD64_GOT_LO12_NC
:
1732 grub_util_error (_("relocation 0x%x is not implemented yet"),
1733 (unsigned int) ELF_R_TYPE (info
));
1737 #if defined(MKIMAGE_ELF64)
1739 switch (ELF_R_TYPE (info
))
1743 ctx
->current_address
1744 = add_fixup_entry (&ctx
->lst
,
1745 GRUB_PE32_REL_BASED_DIR64
,
1746 addr
, 0, ctx
->current_address
,
1753 ctx
->current_address
1754 = add_fixup_entry (&ctx
->lst
,
1755 GRUB_PE32_REL_BASED_HIGHLOW
,
1756 addr
, 0, ctx
->current_address
,
1763 ctx
->current_address
1764 = add_fixup_entry (&ctx
->lst
,
1765 GRUB_PE32_REL_BASED_MIPS_JMPADDR
,
1766 addr
, 0, ctx
->current_address
,
1772 Elf_Addr target
= sym_addr
+ addend
;
1774 ctx
->current_address
1775 = add_fixup_entry (&ctx
->lst
,
1776 GRUB_PE32_REL_BASED_MIPS_LOW
,
1777 addr
, 0, ctx
->current_address
,
1780 ctx
->current_address
1781 = add_fixup_entry (&ctx
->lst
, 0,
1782 (grub_int16_t
) ((target
& 0x8000UL
) >> 16),
1783 0, ctx
->current_address
,
1786 ctx
->current_address
1787 = add_fixup_entry (&ctx
->lst
, 0,
1788 (grub_int16_t
) ((target
& 0x80008000UL
) >> 32),
1789 0, ctx
->current_address
,
1792 ctx
->current_address
1793 = add_fixup_entry (&ctx
->lst
, 0,
1794 (grub_uint16_t
) ((target
& 0x800080008000UL
) >> 48),
1795 0, ctx
->current_address
,
1801 Elf_Addr target
= sym_addr
+ addend
;
1803 ctx
->current_address
1804 = add_fixup_entry (&ctx
->lst
,
1805 GRUB_PE32_REL_BASED_MIPS_HIGH
,
1806 addr
, 0, ctx
->current_address
,
1809 ctx
->current_address
1810 = add_fixup_entry (&ctx
->lst
, 0,
1811 (grub_int16_t
) target
,
1812 0, ctx
->current_address
,
1815 ctx
->current_address
1816 = add_fixup_entry (&ctx
->lst
, 0,
1817 (grub_int16_t
) ((target
& 0x80008000UL
) >> 32),
1818 0, ctx
->current_address
,
1821 ctx
->current_address
1822 = add_fixup_entry (&ctx
->lst
, 0,
1823 (grub_uint16_t
) ((target
& 0x800080008000UL
) >> 48),
1824 0, ctx
->current_address
,
1830 Elf_Addr target
= sym_addr
+ addend
;
1832 ctx
->current_address
1833 = add_fixup_entry (&ctx
->lst
,
1834 GRUB_PE32_REL_BASED_MIPS_HIGHER
,
1835 addr
, 0, ctx
->current_address
,
1838 ctx
->current_address
1839 = add_fixup_entry (&ctx
->lst
, 0,
1840 (grub_int16_t
) target
,
1841 0, ctx
->current_address
,
1844 ctx
->current_address
1845 = add_fixup_entry (&ctx
->lst
, 0,
1846 (grub_int16_t
) ((target
& 0x8000UL
) >> 16),
1847 0, ctx
->current_address
,
1850 ctx
->current_address
1851 = add_fixup_entry (&ctx
->lst
, 0,
1852 (grub_uint16_t
) ((target
& 0x800080008000UL
) >> 48),
1853 0, ctx
->current_address
,
1857 case R_MIPS_HIGHEST
:
1859 Elf_Addr target
= sym_addr
+ addend
;
1861 ctx
->current_address
1862 = add_fixup_entry (&ctx
->lst
,
1863 GRUB_PE32_REL_BASED_MIPS_HIGHEST
,
1864 addr
, 0, ctx
->current_address
,
1867 ctx
->current_address
1868 = add_fixup_entry (&ctx
->lst
, 0,
1869 (grub_int16_t
) target
,
1870 0, ctx
->current_address
,
1873 ctx
->current_address
1874 = add_fixup_entry (&ctx
->lst
, 0,
1875 (grub_int16_t
) ((target
& 0x8000UL
) >> 16),
1876 0, ctx
->current_address
,
1879 ctx
->current_address
1880 = add_fixup_entry (&ctx
->lst
, 0,
1881 (grub_int16_t
) ((target
& 0x80008000UL
) >> 32),
1882 0, ctx
->current_address
,
1887 grub_util_error (_("relocation 0x%x is not implemented yet"),
1888 (unsigned int) ELF_R_TYPE (info
));
1893 #if defined(MKIMAGE_ELF32)
1895 switch (ELF_R_TYPE (info
))
1898 /* Relative relocations do not require fixup entries. */
1900 case R_ARM_THM_CALL
:
1901 case R_ARM_THM_JUMP19
:
1902 case R_ARM_THM_JUMP24
:
1905 grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x", __FUNCTION__
, (unsigned int) addr
, (unsigned int) ctx
->current_address
);
1908 /* Create fixup entry for PE/COFF loader */
1911 ctx
->current_address
1912 = add_fixup_entry (&ctx
->lst
,
1913 GRUB_PE32_REL_BASED_HIGHLOW
,
1914 addr
, 0, ctx
->current_address
,
1919 grub_util_error (_("relocation 0x%x is not implemented yet"),
1920 (unsigned int) ELF_R_TYPE (info
));
1924 #endif /* defined(MKIMAGE_ELF32) */
1926 switch (ELF_R_TYPE (info
))
1930 ctx
->current_address
1931 = add_fixup_entry (&ctx
->lst
,
1932 GRUB_PE32_REL_BASED_HIGHLOW
,
1933 addr
, 0, ctx
->current_address
,
1939 ctx
->current_address
1940 = add_fixup_entry (&ctx
->lst
,
1941 GRUB_PE32_REL_BASED_DIR64
,
1942 addr
, 0, ctx
->current_address
,
1946 /* Relative relocations do not require fixup entries. */
1947 case R_RISCV_BRANCH
:
1950 case R_RISCV_PCREL_HI20
:
1951 case R_RISCV_PCREL_LO12_I
:
1952 case R_RISCV_PCREL_LO12_S
:
1953 case R_RISCV_RVC_BRANCH
:
1954 case R_RISCV_RVC_JUMP
:
1957 grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x", __FUNCTION__
, (unsigned int) addr
, (unsigned int) ctx
->current_address
);
1961 ctx
->current_address
1962 = add_fixup_entry (&ctx
->lst
,
1963 GRUB_PE32_REL_BASED_RISCV_HI20
,
1964 addr
, 0, ctx
->current_address
,
1968 case R_RISCV_LO12_I
:
1970 ctx
->current_address
1971 = add_fixup_entry (&ctx
->lst
,
1972 GRUB_PE32_REL_BASED_RISCV_LOW12I
,
1973 addr
, 0, ctx
->current_address
,
1977 case R_RISCV_LO12_S
:
1979 ctx
->current_address
1980 = add_fixup_entry (&ctx
->lst
,
1981 GRUB_PE32_REL_BASED_RISCV_LOW12S
,
1982 addr
, 0, ctx
->current_address
,
1989 grub_util_error (_("relocation 0x%x is not implemented yet"),
1990 (unsigned int) ELF_R_TYPE (info
));
1995 grub_util_error ("unknown machine type 0x%x", image_target
->elf_target
);
1999 static enum raw_reloc_type
2000 classify_raw_reloc (Elf_Addr info
,
2001 const struct grub_install_image_target_desc
*image_target
)
2003 /* Necessary to relocate only absolute addresses. */
2004 switch (image_target
->elf_target
)
2007 switch (ELF_R_TYPE (info
))
2011 case R_ARM_THM_CALL
:
2012 case R_ARM_THM_JUMP19
:
2013 case R_ARM_THM_JUMP24
:
2015 return RAW_RELOC_NONE
;
2017 return RAW_RELOC_32
;
2019 grub_util_error (_("relocation 0x%x is not implemented yet"),
2020 (unsigned int) ELF_R_TYPE (info
));
2025 grub_util_error ("unknown machine type 0x%x", image_target
->elf_target
);
2030 translate_relocation_raw (struct translate_context
*ctx
,
2033 const struct grub_install_image_target_desc
*image_target
)
2035 enum raw_reloc_type
class = classify_raw_reloc (info
, image_target
);
2036 struct raw_reloc
*rel
;
2037 if (class == RAW_RELOC_NONE
)
2039 rel
= xmalloc (sizeof (*rel
));
2040 rel
->next
= ctx
->raw_relocs
;
2043 ctx
->raw_relocs
= rel
;
2047 translate_relocation (struct translate_context
*ctx
,
2052 const struct grub_install_image_target_desc
*image_target
)
2054 if (image_target
->id
== IMAGE_EFI
)
2055 translate_relocation_pe (ctx
, addr
, info
, sym_addr
, addend
, image_target
);
2057 translate_relocation_raw (ctx
, addr
, info
, image_target
);
2061 finish_reloc_translation_pe (struct translate_context
*ctx
, struct grub_mkimage_layout
*layout
,
2062 const struct grub_install_image_target_desc
*image_target
)
2064 ctx
->current_address
= add_fixup_entry (&ctx
->lst
, 0, 0, 1, ctx
->current_address
, image_target
);
2068 layout
->reloc_section
= ptr
= xmalloc (ctx
->current_address
);
2069 for (ctx
->lst
= ctx
->lst0
; ctx
->lst
; ctx
->lst
= ctx
->lst
->next
)
2070 if (ctx
->lst
->state
)
2072 memcpy (ptr
, &ctx
->lst
->b
, grub_target_to_host32 (ctx
->lst
->b
.block_size
));
2073 ptr
+= grub_target_to_host32 (ctx
->lst
->b
.block_size
);
2075 assert ((ctx
->current_address
+ (grub_uint8_t
*) layout
->reloc_section
) == ptr
);
2078 for (ctx
->lst
= ctx
->lst0
; ctx
->lst
; )
2080 struct fixup_block_list
*next
;
2081 next
= ctx
->lst
->next
;
2086 layout
->reloc_size
= ctx
->current_address
;
2087 if (image_target
->elf_target
== EM_ARM
&& layout
->reloc_size
> GRUB_KERNEL_ARM_STACK_SIZE
)
2088 grub_util_error ("Reloc section (%d) is bigger than stack size (%d). "
2089 "This breaks assembly assumptions. Please increase stack size",
2090 (int) layout
->reloc_size
,
2091 (int) GRUB_KERNEL_ARM_STACK_SIZE
);
2096 <type 0 relocations>
2098 <type 1 relocations>
2101 <type n relocations>
2103 each relocation starts with 32-bit offset. Rest depends on relocation.
2104 mkimage stops when it sees first unknown type or end marker.
2105 This allows images to be created with mismatched mkimage and
2106 kernel as long as no relocations are present in kernel that mkimage
2107 isn't aware of (in which case mkimage aborts).
2108 This also allows simple assembly to do the relocs.
2111 #define RAW_SEPARATOR 0xfffffffe
2112 #define RAW_END_MARKER 0xffffffff
2115 finish_reloc_translation_raw (struct translate_context
*ctx
, struct grub_mkimage_layout
*layout
,
2116 const struct grub_install_image_target_desc
*image_target
)
2118 size_t count
= 0, sz
;
2119 enum raw_reloc_type highest
= RAW_RELOC_NONE
;
2120 enum raw_reloc_type curtype
;
2121 struct raw_reloc
*cur
;
2123 if (!ctx
->raw_relocs
)
2125 layout
->reloc_section
= p
= xmalloc (sizeof (grub_uint32_t
));
2126 p
[0] = RAW_END_MARKER
;
2127 layout
->reloc_size
= sizeof (grub_uint32_t
);
2130 for (cur
= ctx
->raw_relocs
; cur
; cur
= cur
->next
)
2133 if (cur
->type
> highest
)
2134 highest
= cur
->type
;
2136 /* highest separators, count relocations and one end marker. */
2137 sz
= (highest
+ count
+ 1) * sizeof (grub_uint32_t
);
2138 layout
->reloc_section
= p
= xmalloc (sz
);
2139 for (curtype
= 0; curtype
<= highest
; curtype
++)
2141 /* Support for special cases would go here. */
2142 for (cur
= ctx
->raw_relocs
; cur
; cur
= cur
->next
)
2143 if (cur
->type
== curtype
)
2147 *p
++ = RAW_SEPARATOR
;
2149 *--p
= RAW_END_MARKER
;
2150 layout
->reloc_size
= sz
;
2154 finish_reloc_translation (struct translate_context
*ctx
, struct grub_mkimage_layout
*layout
,
2155 const struct grub_install_image_target_desc
*image_target
)
2157 if (image_target
->id
== IMAGE_EFI
)
2158 finish_reloc_translation_pe (ctx
, layout
, image_target
);
2160 finish_reloc_translation_raw (ctx
, layout
, image_target
);
2165 create_u64_fixups (struct translate_context
*ctx
,
2166 Elf_Addr jumpers
, grub_size_t njumpers
,
2167 const struct grub_install_image_target_desc
*image_target
)
2170 assert (image_target
->id
== IMAGE_EFI
);
2171 for (i
= 0; i
< njumpers
; i
++)
2172 ctx
->current_address
= add_fixup_entry (&ctx
->lst
,
2173 GRUB_PE32_REL_BASED_DIR64
,
2175 0, ctx
->current_address
,
2179 /* Make a .reloc section. */
2181 make_reloc_section (Elf_Ehdr
*e
, struct grub_mkimage_layout
*layout
,
2182 struct section_metadata
*smd
,
2183 const struct grub_install_image_target_desc
*image_target
)
2187 struct translate_context ctx
;
2189 translate_reloc_start (&ctx
, image_target
);
2191 for (i
= 0, s
= smd
->sections
; i
< smd
->num_sections
;
2192 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
->section_entsize
))
2193 if ((grub_target_to_host32 (s
->sh_type
) == SHT_REL
) ||
2194 (grub_target_to_host32 (s
->sh_type
) == SHT_RELA
))
2197 Elf_Word rtab_size
, r_size
, num_rs
;
2198 Elf_Off rtab_offset
;
2199 Elf_Shdr
*symtab_section
;
2200 Elf_Addr section_address
;
2203 if (!SUFFIX (is_kept_reloc_section
) (s
, image_target
, smd
))
2205 grub_util_info ("not translating the skipped relocation section %s",
2206 smd
->strtab
+ grub_le_to_cpu32 (s
->sh_name
));
2210 symtab_section
= (Elf_Shdr
*) ((char *) smd
->sections
2211 + (grub_target_to_host32 (s
->sh_link
)
2212 * smd
->section_entsize
));
2214 grub_util_info ("translating the relocation section %s",
2215 smd
->strtab
+ grub_le_to_cpu32 (s
->sh_name
));
2217 rtab_size
= grub_target_to_host (s
->sh_size
);
2218 r_size
= grub_target_to_host (s
->sh_entsize
);
2219 rtab_offset
= grub_target_to_host (s
->sh_offset
);
2220 num_rs
= rtab_size
/ r_size
;
2222 section_address
= smd
->vaddrs
[grub_le_to_cpu32 (s
->sh_info
)];
2224 for (j
= 0, r
= (Elf_Rela
*) ((char *) e
+ rtab_offset
);
2226 j
++, r
= (Elf_Rela
*) ((char *) r
+ r_size
))
2234 offset
= grub_target_to_host (r
->r_offset
);
2235 if (image_target
->elf_target
== EM_MIPS
&& image_target
->voidp_sizeof
== 8)
2236 info
= ((grub_uint64_t
) r
->r_info
<< 32) |
2237 (grub_uint32_t
) grub_be_to_cpu64 (r
->r_info
);
2239 info
= grub_target_to_host (r
->r_info
);
2241 sym_addr
= SUFFIX (get_symbol_address
) (e
, symtab_section
,
2242 ELF_R_SYM (info
), image_target
);
2243 addend
= (s
->sh_type
== grub_target_to_host32 (SHT_RELA
)) ?
2244 grub_target_to_host (r
->r_addend
) : 0;
2245 addr
= section_address
+ offset
;
2247 translate_relocation (&ctx
, addr
, info
, sym_addr
, addend
, image_target
);
2251 if (image_target
->elf_target
== EM_IA_64
)
2252 create_u64_fixups (&ctx
,
2254 + image_target
->vaddr_offset
,
2255 2 * layout
->ia64jmpnum
,
2257 if (image_target
->elf_target
== EM_IA_64
|| image_target
->elf_target
== EM_AARCH64
)
2258 create_u64_fixups (&ctx
,
2260 + image_target
->vaddr_offset
,
2261 (layout
->got_size
/ 8),
2264 finish_reloc_translation (&ctx
, layout
, image_target
);
2267 /* Determine if this section is a text section. Return false if this
2268 section is not allocated. */
2270 SUFFIX (is_text_section
) (Elf_Shdr
*s
, const struct grub_install_image_target_desc
*image_target
)
2272 if (!is_relocatable (image_target
)
2273 && grub_target_to_host32 (s
->sh_type
) != SHT_PROGBITS
)
2275 return ((grub_target_to_host (s
->sh_flags
) & (SHF_EXECINSTR
| SHF_ALLOC
))
2276 == (SHF_EXECINSTR
| SHF_ALLOC
));
2279 /* Determine if this section is a data section. */
2281 SUFFIX (is_data_section
) (Elf_Shdr
*s
, const struct grub_install_image_target_desc
*image_target
)
2283 if (!is_relocatable (image_target
)
2284 && grub_target_to_host32 (s
->sh_type
) != SHT_PROGBITS
)
2286 return ((grub_target_to_host (s
->sh_flags
) & (SHF_EXECINSTR
| SHF_ALLOC
))
2287 == SHF_ALLOC
) && !(grub_target_to_host32 (s
->sh_type
) == SHT_NOBITS
);
2291 SUFFIX (is_bss_section
) (Elf_Shdr
*s
, const struct grub_install_image_target_desc
*image_target
)
2293 if (!is_relocatable (image_target
))
2295 return ((grub_target_to_host (s
->sh_flags
) & (SHF_EXECINSTR
| SHF_ALLOC
))
2296 == SHF_ALLOC
) && (grub_target_to_host32 (s
->sh_type
) == SHT_NOBITS
);
2299 /* Determine if a section is going to be in the final output */
2301 SUFFIX (is_kept_section
) (Elf_Shdr
*s
, const struct grub_install_image_target_desc
*image_target
)
2303 /* We keep .text and .data */
2304 if (SUFFIX (is_text_section
) (s
, image_target
)
2305 || SUFFIX (is_data_section
) (s
, image_target
))
2309 * And we keep .bss if we're producing PE binaries or the target doesn't
2310 * have a relocating loader. Platforms other than EFI and U-boot shouldn't
2311 * have .bss in their binaries as we build with -Wl,-Ttext.
2313 if (SUFFIX (is_bss_section
) (s
, image_target
)
2314 && (image_target
->id
== IMAGE_EFI
|| !is_relocatable (image_target
)))
2317 /* Otherwise this is not a section we're keeping in the final output. */
2322 SUFFIX (is_kept_reloc_section
) (Elf_Shdr
*s
, const struct grub_install_image_target_desc
*image_target
,
2323 struct section_metadata
*smd
)
2327 const char *name
= smd
->strtab
+ grub_host_to_target32 (s
->sh_name
);
2329 if (!strncmp (name
, ".rela.", 6))
2331 else if (!strncmp (name
, ".rel.", 5))
2336 for (i
= 0, s
= smd
->sections
; i
< smd
->num_sections
;
2337 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
->section_entsize
))
2339 const char *sname
= smd
->strtab
+ grub_host_to_target32 (s
->sh_name
);
2340 if (strcmp (sname
, name
))
2343 return SUFFIX (is_kept_section
) (s
, image_target
);
2349 /* Return if the ELF header is valid. */
2351 SUFFIX (check_elf_header
) (Elf_Ehdr
*e
, size_t size
, const struct grub_install_image_target_desc
*image_target
)
2353 if (size
< sizeof (*e
)
2354 || e
->e_ident
[EI_MAG0
] != ELFMAG0
2355 || e
->e_ident
[EI_MAG1
] != ELFMAG1
2356 || e
->e_ident
[EI_MAG2
] != ELFMAG2
2357 || e
->e_ident
[EI_MAG3
] != ELFMAG3
2358 || e
->e_ident
[EI_VERSION
] != EV_CURRENT
2359 || e
->e_ident
[EI_CLASS
] != ELFCLASSXX
2360 || e
->e_version
!= grub_host_to_target32 (EV_CURRENT
))
2367 SUFFIX (put_section
) (Elf_Shdr
*s
, int i
,
2368 Elf_Addr current_address
,
2369 struct section_metadata
*smd
,
2370 const struct grub_install_image_target_desc
*image_target
)
2372 Elf_Word align
= grub_host_to_target_addr (s
->sh_addralign
);
2373 const char *name
= smd
->strtab
+ grub_host_to_target32 (s
->sh_name
);
2376 current_address
= ALIGN_UP (current_address
+ image_target
->vaddr_offset
,
2378 - image_target
->vaddr_offset
;
2380 grub_util_info ("locating the section %s at 0x%"
2381 GRUB_HOST_PRIxLONG_LONG
,
2382 name
, (unsigned long long) current_address
);
2383 if (!is_relocatable (image_target
))
2384 current_address
= grub_host_to_target_addr (s
->sh_addr
)
2385 - image_target
->link_addr
;
2386 smd
->addrs
[i
] = current_address
;
2387 current_address
+= grub_host_to_target_addr (s
->sh_size
);
2388 return current_address
;
2392 * Locate section addresses by merging code sections and data sections
2393 * into .text and .data, respectively.
2396 SUFFIX (locate_sections
) (Elf_Ehdr
*e
, const char *kernel_path
,
2397 struct section_metadata
*smd
,
2398 struct grub_mkimage_layout
*layout
,
2399 const struct grub_install_image_target_desc
*image_target
)
2405 /* Page-aligning simplifies relocation handling. */
2406 if (image_target
->elf_target
== EM_AARCH64
)
2407 layout
->align
= 4096;
2409 layout
->kernel_size
= 0;
2411 for (i
= 0, s
= smd
->sections
;
2412 i
< smd
->num_sections
;
2413 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
->section_entsize
))
2414 if ((grub_target_to_host (s
->sh_flags
) & SHF_ALLOC
)
2415 && grub_host_to_target32 (s
->sh_addralign
) > layout
->align
)
2416 layout
->align
= grub_host_to_target32 (s
->sh_addralign
);
2419 for (i
= 0, s
= smd
->sections
;
2420 i
< smd
->num_sections
;
2421 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
->section_entsize
))
2422 if (SUFFIX (is_text_section
) (s
, image_target
))
2424 layout
->kernel_size
= SUFFIX (put_section
) (s
, i
, layout
->kernel_size
,
2426 if (!is_relocatable (image_target
) &&
2427 grub_host_to_target_addr (s
->sh_addr
) != image_target
->link_addr
)
2430 = grub_xasprintf (_("`%s' is miscompiled: its start address is 0x%llx"
2431 " instead of 0x%llx: ld.gold bug?"),
2433 (unsigned long long) grub_host_to_target_addr (s
->sh_addr
),
2434 (unsigned long long) image_target
->link_addr
);
2435 grub_util_error ("%s", msg
);
2439 #ifdef MKIMAGE_ELF32
2440 if (image_target
->elf_target
== EM_ARM
)
2444 layout
->kernel_size
= ALIGN_UP (layout
->kernel_size
, 16);
2446 tramp
= arm_get_trampoline_size (e
, smd
->sections
, smd
->section_entsize
,
2447 smd
->num_sections
, image_target
);
2449 layout
->tramp_off
= layout
->kernel_size
;
2450 layout
->kernel_size
+= ALIGN_UP (tramp
, 16);
2454 layout
->kernel_size
= ALIGN_UP (layout
->kernel_size
+ image_target
->vaddr_offset
,
2455 image_target
->section_align
)
2456 - image_target
->vaddr_offset
;
2457 layout
->exec_size
= layout
->kernel_size
;
2460 for (i
= 0, s
= smd
->sections
;
2461 i
< smd
->num_sections
;
2462 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
->section_entsize
))
2463 if (SUFFIX (is_data_section
) (s
, image_target
))
2464 layout
->kernel_size
= SUFFIX (put_section
) (s
, i
, layout
->kernel_size
, smd
,
2467 layout
->bss_start
= layout
->kernel_size
;
2468 layout
->end
= layout
->kernel_size
;
2471 for (i
= 0, s
= smd
->sections
;
2472 i
< smd
->num_sections
;
2473 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
->section_entsize
))
2475 if (SUFFIX (is_bss_section
) (s
, image_target
))
2476 layout
->end
= SUFFIX (put_section
) (s
, i
, layout
->end
, smd
, image_target
);
2479 * This must to be in the last time this function passes through the loop.
2481 smd
->vaddrs
[i
] = smd
->addrs
[i
] + image_target
->vaddr_offset
;
2484 layout
->end
= ALIGN_UP (layout
->end
+ image_target
->vaddr_offset
,
2485 image_target
->section_align
) - image_target
->vaddr_offset
;
2486 /* Explicitly initialize BSS
2487 when producing PE32 to avoid a bug in EFI implementations.
2488 Platforms other than EFI and U-boot shouldn't have .bss in
2489 their binaries as we build with -Wl,-Ttext.
2491 if (image_target
->id
== IMAGE_EFI
|| !is_relocatable (image_target
))
2492 layout
->kernel_size
= layout
->end
;
2496 SUFFIX (grub_mkimage_load_image
) (const char *kernel_path
,
2497 size_t total_module_size
,
2498 struct grub_mkimage_layout
*layout
,
2499 const struct grub_install_image_target_desc
*image_target
)
2501 char *kernel_img
, *out_img
;
2502 struct section_metadata smd
= { 0, 0, 0, 0, 0, 0, 0 };
2506 Elf_Off section_offset
;
2507 grub_size_t kernel_size
;
2509 grub_memset (layout
, 0, sizeof (*layout
));
2511 layout
->start_address
= 0;
2513 kernel_size
= grub_util_get_image_size (kernel_path
);
2514 kernel_img
= xmalloc (kernel_size
);
2515 grub_util_load_image (kernel_path
, kernel_img
);
2517 e
= (Elf_Ehdr
*) kernel_img
;
2518 if (! SUFFIX (check_elf_header
) (e
, kernel_size
, image_target
))
2519 grub_util_error ("invalid ELF header");
2521 section_offset
= grub_target_to_host (e
->e_shoff
);
2522 smd
.section_entsize
= grub_target_to_host16 (e
->e_shentsize
);
2523 smd
.num_sections
= grub_target_to_host16 (e
->e_shnum
);
2525 if (kernel_size
< section_offset
2526 + (grub_uint32_t
) smd
.section_entsize
* smd
.num_sections
)
2527 grub_util_error (_("premature end of file %s"), kernel_path
);
2529 smd
.sections
= (Elf_Shdr
*) (kernel_img
+ section_offset
);
2531 /* Relocate sections then symbols in the virtual address space. */
2532 s
= (Elf_Shdr
*) ((char *) smd
.sections
2533 + grub_host_to_target16 (e
->e_shstrndx
) * smd
.section_entsize
);
2534 smd
.strtab
= (char *) e
+ grub_host_to_target_addr (s
->sh_offset
);
2536 smd
.addrs
= xmalloc (sizeof (*smd
.addrs
) * smd
.num_sections
);
2537 memset (smd
.addrs
, 0, sizeof (*smd
.addrs
) * smd
.num_sections
);
2538 smd
.vaddrs
= xmalloc (sizeof (*smd
.vaddrs
) * smd
.num_sections
);
2539 memset (smd
.vaddrs
, 0, sizeof (*smd
.vaddrs
) * smd
.num_sections
);
2541 SUFFIX (locate_sections
) (e
, kernel_path
, &smd
, layout
, image_target
);
2543 if (!is_relocatable (image_target
))
2545 Elf_Addr current_address
= layout
->kernel_size
;
2547 for (i
= 0, s
= smd
.sections
;
2548 i
< smd
.num_sections
;
2549 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
.section_entsize
))
2550 if (grub_target_to_host32 (s
->sh_type
) == SHT_NOBITS
)
2552 Elf_Word sec_align
= grub_host_to_target_addr (s
->sh_addralign
);
2553 const char *name
= smd
.strtab
+ grub_host_to_target32 (s
->sh_name
);
2556 current_address
= ALIGN_UP (current_address
2557 + image_target
->vaddr_offset
,
2559 - image_target
->vaddr_offset
;
2561 grub_util_info ("locating the section %s at 0x%"
2562 GRUB_HOST_PRIxLONG_LONG
,
2563 name
, (unsigned long long) current_address
);
2564 if (!is_relocatable (image_target
))
2565 current_address
= grub_host_to_target_addr (s
->sh_addr
)
2566 - image_target
->link_addr
;
2568 smd
.vaddrs
[i
] = current_address
2569 + image_target
->vaddr_offset
;
2570 current_address
+= grub_host_to_target_addr (s
->sh_size
);
2572 current_address
= ALIGN_UP (current_address
+ image_target
->vaddr_offset
,
2573 image_target
->section_align
)
2574 - image_target
->vaddr_offset
;
2575 layout
->bss_size
= current_address
- layout
->kernel_size
;
2578 layout
->bss_size
= 0;
2580 if (image_target
->id
== IMAGE_SPARC64_AOUT
2581 || image_target
->id
== IMAGE_SPARC64_RAW
2582 || image_target
->id
== IMAGE_UBOOT
2583 || image_target
->id
== IMAGE_COREBOOT
2584 || image_target
->id
== IMAGE_SPARC64_CDCORE
)
2585 layout
->kernel_size
= ALIGN_UP (layout
->kernel_size
, image_target
->mod_align
);
2587 if (is_relocatable (image_target
))
2590 for (i
= 0, s
= smd
.sections
;
2591 i
< smd
.num_sections
;
2592 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
.section_entsize
))
2593 if (s
->sh_type
== grub_host_to_target32 (SHT_SYMTAB
))
2599 grub_util_error ("%s", _("no symbol table"));
2600 #ifdef MKIMAGE_ELF64
2601 if (image_target
->elf_target
== EM_IA_64
)
2605 layout
->kernel_size
= ALIGN_UP (layout
->kernel_size
, 16);
2607 grub_ia64_dl_get_tramp_got_size (e
, &tramp
, &layout
->got_size
);
2609 layout
->tramp_off
= layout
->kernel_size
;
2610 layout
->kernel_size
+= ALIGN_UP (tramp
, 16);
2612 layout
->ia64jmp_off
= layout
->kernel_size
;
2613 layout
->ia64jmpnum
= SUFFIX (count_funcs
) (e
, smd
.symtab
,
2615 layout
->kernel_size
+= 16 * layout
->ia64jmpnum
;
2617 layout
->got_off
= layout
->kernel_size
;
2618 layout
->kernel_size
+= ALIGN_UP (layout
->got_size
, 16);
2620 if (image_target
->elf_target
== EM_AARCH64
)
2624 layout
->kernel_size
= ALIGN_UP (layout
->kernel_size
, 16);
2626 grub_arm64_dl_get_tramp_got_size (e
, &tramp
, &layout
->got_size
);
2628 layout
->got_off
= layout
->kernel_size
;
2629 layout
->kernel_size
+= ALIGN_UP (layout
->got_size
, 16);
2635 layout
->reloc_size
= 0;
2636 layout
->reloc_section
= NULL
;
2639 out_img
= xmalloc (layout
->kernel_size
+ total_module_size
);
2640 memset (out_img
, 0, layout
->kernel_size
+ total_module_size
);
2642 if (is_relocatable (image_target
))
2644 layout
->start_address
= SUFFIX (relocate_symbols
) (e
, &smd
,
2645 (char *) out_img
+ layout
->ia64jmp_off
,
2646 layout
->ia64jmp_off
+ image_target
->vaddr_offset
,
2647 layout
->bss_start
, layout
->end
, image_target
);
2649 if (layout
->start_address
== (Elf_Addr
) -1)
2650 grub_util_error ("start symbol is not defined");
2652 /* Resolve addrs in the virtual address space. */
2653 SUFFIX (relocate_addrs
) (e
, &smd
, out_img
, layout
->tramp_off
,
2654 layout
->got_off
, image_target
);
2656 make_reloc_section (e
, layout
, &smd
, image_target
);
2657 if (image_target
->id
!= IMAGE_EFI
)
2659 out_img
= xrealloc (out_img
, layout
->kernel_size
+ total_module_size
2660 + ALIGN_UP (layout
->reloc_size
, image_target
->mod_align
));
2661 memcpy (out_img
+ layout
->kernel_size
, layout
->reloc_section
, layout
->reloc_size
);
2662 memset (out_img
+ layout
->kernel_size
+ layout
->reloc_size
, 0,
2663 total_module_size
+ ALIGN_UP (layout
->reloc_size
, image_target
->mod_align
) - layout
->reloc_size
);
2664 layout
->kernel_size
+= ALIGN_UP (layout
->reloc_size
, image_target
->mod_align
);
2668 for (i
= 0, s
= smd
.sections
;
2669 i
< smd
.num_sections
;
2670 i
++, s
= (Elf_Shdr
*) ((char *) s
+ smd
.section_entsize
))
2671 if (SUFFIX (is_kept_section
) (s
, image_target
))
2673 if (grub_target_to_host32 (s
->sh_type
) == SHT_NOBITS
)
2674 memset (out_img
+ smd
.addrs
[i
], 0,
2675 grub_host_to_target_addr (s
->sh_size
));
2677 memcpy (out_img
+ smd
.addrs
[i
],
2678 kernel_img
+ grub_host_to_target_addr (s
->sh_offset
),
2679 grub_host_to_target_addr (s
->sh_size
));