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 #pragma GCC diagnostic ignored "-Wcast-align"
53 #define GRUB_MKIMAGEXX
54 #if !defined(MKIMAGE_ELF32) && !defined(MKIMAGE_ELF64)
55 #if __SIZEOF_POINTER__ == 8
56 #include "grub-mkimage64.c"
58 #include "grub-mkimage32.c"
62 /* These structures are defined according to the CHRP binding to IEEE1275,
63 "Client Program Format" section. */
65 struct grub_ieee1275_note_desc
67 grub_uint32_t real_mode;
68 grub_uint32_t real_base;
69 grub_uint32_t real_size;
70 grub_uint32_t virt_base;
71 grub_uint32_t virt_size;
72 grub_uint32_t load_base;
75 #define GRUB_IEEE1275_NOTE_NAME "PowerPC"
76 #define GRUB_IEEE1275_NOTE_TYPE 0x1275
78 struct grub_ieee1275_note
81 char name[ALIGN_UP(sizeof (GRUB_IEEE1275_NOTE_NAME), 4)];
82 struct grub_ieee1275_note_desc descriptor;
85 #define GRUB_XEN_NOTE_NAME "Xen"
87 struct fixup_block_list
89 struct fixup_block_list *next;
91 struct grub_pe32_fixup_block b;
94 #define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof))
96 struct section_metadata
98 Elf_Half num_sections;
102 Elf_Half section_entsize;
108 is_relocatable (const struct grub_install_image_target_desc *image_target)
110 return image_target->id == IMAGE_EFI || image_target->id == IMAGE_UBOOT
111 || (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_ARM);
117 * R_ARM_THM_CALL/THM_JUMP24
119 * Relocate Thumb (T32) instruction set relative branches:
123 grub_arm_reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr)
127 offset = grub_arm_thm_call_get_offset (target);
129 grub_dprintf ("dl", " sym_addr = 0x%08x", sym_addr);
133 grub_dprintf("dl", " BL*: target=%p, sym_addr=0x%08x, offset=%d\n",
134 target, sym_addr, offset);
136 /* Keep traditional (pre-Thumb2) limits on blx. In any case if the kernel
137 is bigger than 2M (currently under 150K) then we probably have a problem
139 if (offset < -0x200000 || offset >= 0x200000)
140 return grub_error (GRUB_ERR_BAD_MODULE,
141 "THM_CALL Relocation out of range.");
143 grub_dprintf ("dl", " relative destination = %p",
144 (char *) target + offset);
146 return grub_arm_thm_call_set_offset (target, offset);
152 * Relocate conditional Thumb (T32) B<c>.W
155 grub_arm_reloc_thm_jump19 (grub_uint16_t *target, Elf32_Addr sym_addr)
160 return grub_error (GRUB_ERR_BAD_MODULE,
161 "Relocation targeting wrong execution state");
163 offset = grub_arm_thm_jump19_get_offset (target);
165 /* Adjust and re-truncate offset */
168 if (!grub_arm_thm_jump19_check_offset (offset))
169 return grub_error (GRUB_ERR_BAD_MODULE,
170 "THM_JUMP19 Relocation out of range.");
172 grub_arm_thm_jump19_set_offset (target, offset);
174 return GRUB_ERR_NONE;
180 * Relocate ARM (A32) B
183 grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr)
188 return grub_error (GRUB_ERR_BAD_MODULE,
189 "Relocation targeting wrong execution state");
191 offset = grub_arm_jump24_get_offset (target);
194 if (!grub_arm_jump24_check_offset (offset))
195 return grub_error (GRUB_ERR_BAD_MODULE,
196 "JUMP24 Relocation out of range.");
199 grub_arm_jump24_set_offset (target, offset);
201 return GRUB_ERR_NONE;
207 SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc *image_target,
208 int note, char **core_img, size_t *core_size,
209 Elf_Addr target_addr,
210 struct grub_mkimage_layout *layout)
217 int header_size, footer_size = 0;
220 int string_size = sizeof (".text") + sizeof ("mods") + 1;
222 if (image_target->id != IMAGE_LOONGSON_ELF)
228 footer_size += sizeof (struct grub_ieee1275_note);
230 if (image_target->id == IMAGE_XEN)
234 string_size += sizeof (".xen");
235 footer_size += XEN_NOTE_SIZE;
237 header_size = ALIGN_UP (sizeof (*ehdr) + phnum * sizeof (*phdr)
238 + shnum * sizeof (*shdr) + string_size, layout->align);
240 program_size = ALIGN_ADDR (*core_size);
242 elf_img = xmalloc (program_size + header_size + footer_size);
243 memset (elf_img, 0, program_size + header_size + footer_size);
244 memcpy (elf_img + header_size, *core_img, *core_size);
245 ehdr = (void *) elf_img;
246 phdr = (void *) (elf_img + sizeof (*ehdr));
247 shdr = (void *) (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr));
248 memcpy (ehdr->e_ident, ELFMAG, SELFMAG);
249 ehdr->e_ident[EI_CLASS] = ELFCLASSXX;
250 if (!image_target->bigendian)
251 ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
253 ehdr->e_ident[EI_DATA] = ELFDATA2MSB;
254 ehdr->e_ident[EI_VERSION] = EV_CURRENT;
255 ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE;
256 ehdr->e_type = grub_host_to_target16 (ET_EXEC);
257 ehdr->e_machine = grub_host_to_target16 (image_target->elf_target);
258 ehdr->e_version = grub_host_to_target32 (EV_CURRENT);
260 ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr);
261 ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr));
262 ehdr->e_phnum = grub_host_to_target16 (phnum);
264 ehdr->e_shoff = grub_host_to_target32 ((grub_uint8_t *) shdr
265 - (grub_uint8_t *) ehdr);
266 if (image_target->id == IMAGE_LOONGSON_ELF)
267 ehdr->e_shentsize = grub_host_to_target16 (0);
269 ehdr->e_shentsize = grub_host_to_target16 (sizeof (Elf_Shdr));
270 ehdr->e_shnum = grub_host_to_target16 (shnum);
271 ehdr->e_shstrndx = grub_host_to_target16 (1);
273 ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr));
275 phdr->p_type = grub_host_to_target32 (PT_LOAD);
276 phdr->p_offset = grub_host_to_target32 (header_size);
277 phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X);
279 ehdr->e_entry = grub_host_to_target32 (target_addr);
280 phdr->p_vaddr = grub_host_to_target32 (target_addr);
281 phdr->p_paddr = grub_host_to_target32 (target_addr);
282 phdr->p_align = grub_host_to_target32 (layout->align > image_target->link_align ?
283 layout->align : image_target->link_align);
284 if (image_target->id == IMAGE_LOONGSON_ELF)
285 ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER
286 | EF_MIPS_PIC | EF_MIPS_CPIC);
289 if (image_target->id == IMAGE_LOONGSON_ELF)
291 phdr->p_filesz = grub_host_to_target32 (*core_size);
292 phdr->p_memsz = grub_host_to_target32 (*core_size);
296 grub_uint32_t target_addr_mods;
297 phdr->p_filesz = grub_host_to_target32 (layout->kernel_size);
298 if (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_ARM)
299 phdr->p_memsz = grub_host_to_target32 (layout->kernel_size);
301 phdr->p_memsz = grub_host_to_target32 (layout->kernel_size + layout->bss_size);
304 phdr->p_type = grub_host_to_target32 (PT_GNU_STACK);
305 phdr->p_offset = grub_host_to_target32 (header_size + layout->kernel_size);
306 phdr->p_paddr = phdr->p_vaddr = phdr->p_filesz = phdr->p_memsz = 0;
307 phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X);
308 phdr->p_align = grub_host_to_target32 (image_target->link_align);
311 phdr->p_type = grub_host_to_target32 (PT_LOAD);
312 phdr->p_offset = grub_host_to_target32 (header_size + layout->kernel_size);
313 phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X);
314 phdr->p_filesz = phdr->p_memsz
315 = grub_host_to_target32 (*core_size - layout->kernel_size);
317 if (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_386)
318 target_addr_mods = GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR;
319 else if (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_ARM)
320 target_addr_mods = ALIGN_UP (target_addr + layout->end
321 + image_target->mod_gap,
322 image_target->mod_align);
324 target_addr_mods = ALIGN_UP (target_addr + layout->kernel_size + layout->bss_size
325 + image_target->mod_gap,
326 image_target->mod_align);
327 phdr->p_vaddr = grub_host_to_target_addr (target_addr_mods);
328 phdr->p_paddr = grub_host_to_target_addr (target_addr_mods);
329 phdr->p_align = grub_host_to_target32 (image_target->link_align);
332 if (image_target->id == IMAGE_XEN)
334 char *note_start = (elf_img + program_size + header_size);
336 char *ptr = (char *) note_start;
338 grub_util_info ("adding XEN NOTE segment");
341 note_ptr = (Elf_Nhdr *) ptr;
342 note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
343 note_ptr->n_descsz = grub_host_to_target32 (sizeof (PACKAGE_NAME));
344 note_ptr->n_type = grub_host_to_target32 (6);
345 ptr += sizeof (Elf_Nhdr);
346 memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
347 ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
348 memcpy (ptr, PACKAGE_NAME, sizeof (PACKAGE_NAME));
349 ptr += ALIGN_UP (sizeof (PACKAGE_NAME), 4);
352 note_ptr = (Elf_Nhdr *) ptr;
353 note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
354 note_ptr->n_descsz = grub_host_to_target32 (sizeof ("generic"));
355 note_ptr->n_type = grub_host_to_target32 (8);
356 ptr += sizeof (Elf_Nhdr);
357 memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
358 ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
359 memcpy (ptr, "generic", sizeof ("generic"));
360 ptr += ALIGN_UP (sizeof ("generic"), 4);
363 note_ptr = (Elf_Nhdr *) ptr;
364 note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
365 note_ptr->n_descsz = grub_host_to_target32 (sizeof ("xen-3.0"));
366 note_ptr->n_type = grub_host_to_target32 (5);
367 ptr += sizeof (Elf_Nhdr);
368 memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
369 ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
370 memcpy (ptr, "xen-3.0", sizeof ("xen-3.0"));
371 ptr += ALIGN_UP (sizeof ("xen-3.0"), 4);
374 note_ptr = (Elf_Nhdr *) ptr;
375 note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
376 note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof);
377 note_ptr->n_type = grub_host_to_target32 (1);
378 ptr += sizeof (Elf_Nhdr);
379 memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
380 ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
381 memset (ptr, 0, image_target->voidp_sizeof);
382 ptr += image_target->voidp_sizeof;
385 note_ptr = (Elf_Nhdr *) ptr;
386 note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
387 note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof);
388 note_ptr->n_type = grub_host_to_target32 (3);
389 ptr += sizeof (Elf_Nhdr);
390 memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
391 ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
392 memset (ptr, 0, image_target->voidp_sizeof);
393 ptr += image_target->voidp_sizeof;
396 if (image_target->elf_target == EM_386)
398 note_ptr = (Elf_Nhdr *) ptr;
399 note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME));
400 note_ptr->n_descsz = grub_host_to_target32 (sizeof ("yes,bimodal"));
401 note_ptr->n_type = grub_host_to_target32 (9);
402 ptr += sizeof (Elf_Nhdr);
403 memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME));
404 ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4);
405 memcpy (ptr, "yes", sizeof ("yes"));
406 ptr += ALIGN_UP (sizeof ("yes"), 4);
409 assert (XEN_NOTE_SIZE == (ptr - note_start));
412 phdr->p_type = grub_host_to_target32 (PT_NOTE);
413 phdr->p_flags = grub_host_to_target32 (PF_R);
414 phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof);
417 phdr->p_filesz = grub_host_to_target32 (XEN_NOTE_SIZE);
419 phdr->p_offset = grub_host_to_target32 (header_size + program_size);
424 int note_size = sizeof (struct grub_ieee1275_note);
425 struct grub_ieee1275_note *note_ptr = (struct grub_ieee1275_note *)
426 (elf_img + program_size + header_size);
428 grub_util_info ("adding CHRP NOTE segment");
430 note_ptr->header.n_namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME));
431 note_ptr->header.n_descsz = grub_host_to_target32 (note_size);
432 note_ptr->header.n_type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE);
433 strcpy (note_ptr->name, GRUB_IEEE1275_NOTE_NAME);
434 note_ptr->descriptor.real_mode = grub_host_to_target32 (0xffffffff);
435 note_ptr->descriptor.real_base = grub_host_to_target32 (0x00c00000);
436 note_ptr->descriptor.real_size = grub_host_to_target32 (0xffffffff);
437 note_ptr->descriptor.virt_base = grub_host_to_target32 (0xffffffff);
438 note_ptr->descriptor.virt_size = grub_host_to_target32 (0xffffffff);
439 note_ptr->descriptor.load_base = grub_host_to_target32 (0x00004000);
442 phdr->p_type = grub_host_to_target32 (PT_NOTE);
443 phdr->p_flags = grub_host_to_target32 (PF_R);
444 phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof);
447 phdr->p_filesz = grub_host_to_target32 (note_size);
449 phdr->p_offset = grub_host_to_target32 (header_size + program_size);
453 char *str_start = (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr)
454 + shnum * sizeof (*shdr));
455 char *ptr = str_start + 1;
459 shdr->sh_name = grub_host_to_target32 (0);
460 shdr->sh_type = grub_host_to_target32 (SHT_STRTAB);
461 shdr->sh_addr = grub_host_to_target_addr (0);
462 shdr->sh_offset = grub_host_to_target_addr (str_start - elf_img);
463 shdr->sh_size = grub_host_to_target32 (string_size);
464 shdr->sh_link = grub_host_to_target32 (0);
465 shdr->sh_info = grub_host_to_target32 (0);
466 shdr->sh_addralign = grub_host_to_target32 (layout->align);
467 shdr->sh_entsize = grub_host_to_target32 (0);
470 memcpy (ptr, ".text", sizeof (".text"));
472 shdr->sh_name = grub_host_to_target32 (ptr - str_start);
473 ptr += sizeof (".text");
474 shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS);
475 shdr->sh_addr = grub_host_to_target_addr (target_addr);
476 shdr->sh_offset = grub_host_to_target_addr (header_size);
477 shdr->sh_size = grub_host_to_target32 (layout->kernel_size);
478 shdr->sh_link = grub_host_to_target32 (0);
479 shdr->sh_info = grub_host_to_target32 (0);
480 shdr->sh_addralign = grub_host_to_target32 (layout->align);
481 shdr->sh_entsize = grub_host_to_target32 (0);
484 memcpy (ptr, "mods", sizeof ("mods"));
485 shdr->sh_name = grub_host_to_target32 (ptr - str_start);
486 ptr += sizeof ("mods");
487 shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS);
488 shdr->sh_addr = grub_host_to_target_addr (target_addr + layout->kernel_size);
489 shdr->sh_offset = grub_host_to_target_addr (header_size + layout->kernel_size);
490 shdr->sh_size = grub_host_to_target32 (*core_size - layout->kernel_size);
491 shdr->sh_link = grub_host_to_target32 (0);
492 shdr->sh_info = grub_host_to_target32 (0);
493 shdr->sh_addralign = grub_host_to_target32 (image_target->voidp_sizeof);
494 shdr->sh_entsize = grub_host_to_target32 (0);
497 if (image_target->id == IMAGE_XEN)
499 memcpy (ptr, ".xen", sizeof (".xen"));
500 shdr->sh_name = grub_host_to_target32 (ptr - str_start);
501 ptr += sizeof (".xen");
502 shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS);
503 shdr->sh_addr = grub_host_to_target_addr (target_addr + layout->kernel_size);
504 shdr->sh_offset = grub_host_to_target_addr (program_size + header_size);
505 shdr->sh_size = grub_host_to_target32 (XEN_NOTE_SIZE);
506 shdr->sh_link = grub_host_to_target32 (0);
507 shdr->sh_info = grub_host_to_target32 (0);
508 shdr->sh_addralign = grub_host_to_target32 (image_target->voidp_sizeof);
509 shdr->sh_entsize = grub_host_to_target32 (0);
516 *core_size = program_size + header_size + footer_size;
519 /* Relocate symbols; note that this function overwrites the symbol table.
520 Return the address of a start symbol. */
522 SUFFIX (relocate_symbols) (Elf_Ehdr *e, struct section_metadata *smd,
523 void *jumpers, Elf_Addr jumpers_addr,
524 Elf_Addr bss_start, Elf_Addr end,
525 const struct grub_install_image_target_desc *image_target)
527 Elf_Word symtab_size, sym_size, num_syms;
528 Elf_Off symtab_offset;
529 Elf_Addr start_address = (Elf_Addr) -1;
532 Elf_Shdr *symtab_section;
534 grub_uint64_t *jptr = jumpers;
536 symtab_section = (Elf_Shdr *) ((char *) smd->sections
537 + grub_target_to_host32 (smd->symtab->sh_link)
538 * smd->section_entsize);
539 symtab = (char *) e + grub_target_to_host (symtab_section->sh_offset);
541 symtab_size = grub_target_to_host (smd->symtab->sh_size);
542 sym_size = grub_target_to_host (smd->symtab->sh_entsize);
543 symtab_offset = grub_target_to_host (smd->symtab->sh_offset);
544 num_syms = symtab_size / sym_size;
546 for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset);
548 i++, sym = (Elf_Sym *) ((char *) sym + sym_size))
550 Elf_Section cur_index;
553 name = symtab + grub_target_to_host32 (sym->st_name);
555 cur_index = grub_target_to_host16 (sym->st_shndx);
556 if (cur_index == STN_ABS)
560 else if (cur_index == STN_UNDEF)
562 if (sym->st_name && grub_strcmp (name, "__bss_start") == 0)
563 sym->st_value = bss_start;
564 else if (sym->st_name && grub_strcmp (name, "_end") == 0)
566 else if (sym->st_name)
567 grub_util_error ("undefined symbol %s", name);
571 else if (cur_index >= smd->num_sections)
572 grub_util_error ("section %d does not exist", cur_index);
575 sym->st_value = (grub_target_to_host (sym->st_value)
576 + smd->vaddrs[cur_index]);
579 if (image_target->elf_target == EM_IA_64 && ELF_ST_TYPE (sym->st_info)
582 *jptr = grub_host_to_target64 (sym->st_value);
583 sym->st_value = (char *) jptr - (char *) jumpers + jumpers_addr;
588 grub_util_info ("locating %s at 0x%" GRUB_HOST_PRIxLONG_LONG
589 " (0x%" GRUB_HOST_PRIxLONG_LONG ")", name,
590 (unsigned long long) sym->st_value,
591 (unsigned long long) smd->vaddrs[cur_index]);
593 if (start_address == (Elf_Addr)-1)
594 if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0)
595 start_address = sym->st_value;
598 return start_address;
601 /* Return the address of a symbol at the index I in the section S. */
603 SUFFIX (get_symbol_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i,
604 const struct grub_install_image_target_desc *image_target)
608 sym = (Elf_Sym *) ((char *) e
609 + grub_target_to_host (s->sh_offset)
610 + i * grub_target_to_host (s->sh_entsize));
611 return sym->st_value;
614 /* Return the address of a modified value. */
616 SUFFIX (get_target_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset,
617 const struct grub_install_image_target_desc *image_target)
619 return (Elf_Addr *) ((char *) e + grub_target_to_host (s->sh_offset) + offset);
624 SUFFIX (count_funcs) (Elf_Ehdr *e, Elf_Shdr *symtab_section,
625 const struct grub_install_image_target_desc *image_target)
627 Elf_Word symtab_size, sym_size, num_syms;
628 Elf_Off symtab_offset;
633 symtab_size = grub_target_to_host (symtab_section->sh_size);
634 sym_size = grub_target_to_host (symtab_section->sh_entsize);
635 symtab_offset = grub_target_to_host (symtab_section->sh_offset);
636 num_syms = symtab_size / sym_size;
638 for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset);
640 i++, sym = (Elf_Sym *) ((char *) sym + sym_size))
641 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC)
649 /* Deal with relocation information. This function relocates addresses
650 within the virtual address space starting from 0. So only relative
651 addresses can be fully resolved. Absolute addresses must be relocated
652 again by a PE32 relocator when loaded. */
654 arm_get_trampoline_size (Elf_Ehdr *e,
656 Elf_Half section_entsize,
657 Elf_Half num_sections,
658 const struct grub_install_image_target_desc *image_target)
664 for (i = 0, s = sections;
666 i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
667 if ((s->sh_type == grub_host_to_target32 (SHT_REL)) ||
668 (s->sh_type == grub_host_to_target32 (SHT_RELA)))
671 Elf_Word rtab_size, r_size, num_rs;
673 Elf_Shdr *symtab_section;
676 symtab_section = (Elf_Shdr *) ((char *) sections
677 + (grub_target_to_host32 (s->sh_link)
680 rtab_size = grub_target_to_host (s->sh_size);
681 r_size = grub_target_to_host (s->sh_entsize);
682 rtab_offset = grub_target_to_host (s->sh_offset);
683 num_rs = rtab_size / r_size;
685 for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset);
687 j++, r = (Elf_Rela *) ((char *) r + r_size))
692 info = grub_target_to_host (r->r_info);
693 sym_addr = SUFFIX (get_symbol_address) (e, symtab_section,
694 ELF_R_SYM (info), image_target);
696 sym_addr += (s->sh_type == grub_target_to_host32 (SHT_RELA)) ?
697 grub_target_to_host (r->r_addend) : 0;
699 switch (ELF_R_TYPE (info))
705 case R_ARM_THM_JUMP24:
706 case R_ARM_THM_JUMP19:
718 grub_util_error (_("relocation 0x%x is not implemented yet"),
719 (unsigned int) ELF_R_TYPE (info));
729 SUFFIX (is_kept_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target);
731 SUFFIX (is_kept_reloc_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target,
732 struct section_metadata *smd);
734 /* Deal with relocation information. This function relocates addresses
735 within the virtual address space starting from 0. So only relative
736 addresses can be fully resolved. Absolute addresses must be relocated
737 again by a PE32 relocator when loaded. */
739 SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd,
740 char *pe_target, Elf_Addr tramp_off, Elf_Addr got_off,
741 const struct grub_install_image_target_desc *image_target)
746 struct grub_ia64_trampoline *tr = (void *) (pe_target + tramp_off);
747 grub_uint64_t *gpptr = (void *) (pe_target + got_off);
748 unsigned unmatched_adr_got_page = 0;
749 #define MASK19 ((1 << 19) - 1)
751 grub_uint32_t *tr = (void *) (pe_target + tramp_off);
754 for (i = 0, s = smd->sections;
755 i < smd->num_sections;
756 i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
757 if ((s->sh_type == grub_host_to_target32 (SHT_REL)) ||
758 (s->sh_type == grub_host_to_target32 (SHT_RELA)))
761 Elf_Word rtab_size, r_size, num_rs;
763 Elf_Word target_section_index;
764 Elf_Addr target_section_addr;
765 Elf_Shdr *target_section;
768 if (!SUFFIX (is_kept_section) (s, image_target) &&
769 !SUFFIX (is_kept_reloc_section) (s, image_target, smd))
771 grub_util_info ("not translating relocations for omitted section %s",
772 smd->strtab + grub_le_to_cpu32 (s->sh_name));
776 target_section_index = grub_target_to_host32 (s->sh_info);
777 target_section_addr = smd->addrs[target_section_index];
778 target_section = (Elf_Shdr *) ((char *) smd->sections
779 + (target_section_index
780 * smd->section_entsize));
782 grub_util_info ("dealing with the relocation section %s for %s",
783 smd->strtab + grub_target_to_host32 (s->sh_name),
784 smd->strtab + grub_target_to_host32 (target_section->sh_name));
786 rtab_size = grub_target_to_host (s->sh_size);
787 r_size = grub_target_to_host (s->sh_entsize);
788 rtab_offset = grub_target_to_host (s->sh_offset);
789 num_rs = rtab_size / r_size;
791 for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset);
793 j++, r = (Elf_Rela *) ((char *) r + r_size))
801 offset = grub_target_to_host (r->r_offset);
802 target = SUFFIX (get_target_address) (e, target_section,
803 offset, image_target);
804 info = grub_target_to_host (r->r_info);
805 sym_addr = SUFFIX (get_symbol_address) (e, smd->symtab,
806 ELF_R_SYM (info), image_target);
808 addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ?
809 grub_target_to_host (r->r_addend) : 0;
811 switch (image_target->elf_target)
814 switch (ELF_R_TYPE (info))
820 /* This is absolute. */
821 *target = grub_host_to_target32 (grub_target_to_host32 (*target)
822 + addend + sym_addr);
823 grub_util_info ("relocating an R_386_32 entry to 0x%"
824 GRUB_HOST_PRIxLONG_LONG " at the offset 0x%"
825 GRUB_HOST_PRIxLONG_LONG,
826 (unsigned long long) *target,
827 (unsigned long long) offset);
831 /* This is relative. */
832 *target = grub_host_to_target32 (grub_target_to_host32 (*target)
834 - target_section_addr - offset
835 - image_target->vaddr_offset);
836 grub_util_info ("relocating an R_386_PC32 entry to 0x%"
837 GRUB_HOST_PRIxLONG_LONG " at the offset 0x%"
838 GRUB_HOST_PRIxLONG_LONG,
839 (unsigned long long) *target,
840 (unsigned long long) offset);
843 grub_util_error (_("relocation 0x%x is not implemented yet"),
844 (unsigned int) ELF_R_TYPE (info));
850 switch (ELF_R_TYPE (info))
857 *target = grub_host_to_target64 (grub_target_to_host64 (*target)
858 + addend + sym_addr);
859 grub_util_info ("relocating an R_X86_64_64 entry to 0x%"
860 GRUB_HOST_PRIxLONG_LONG " at the offset 0x%"
861 GRUB_HOST_PRIxLONG_LONG,
862 (unsigned long long) *target,
863 (unsigned long long) offset);
869 grub_uint32_t *t32 = (grub_uint32_t *) target;
870 *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32)
872 - target_section_addr - offset
873 - image_target->vaddr_offset);
874 grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%"
875 GRUB_HOST_PRIxLONG_LONG,
876 *t32, (unsigned long long) offset);
882 *target = grub_host_to_target64 (grub_target_to_host64 (*target)
884 - target_section_addr - offset
885 - image_target->vaddr_offset);
886 grub_util_info ("relocating an R_X86_64_PC64 entry to 0x%"
887 GRUB_HOST_PRIxLONG_LONG " at the offset 0x%"
888 GRUB_HOST_PRIxLONG_LONG,
889 (unsigned long long) *target,
890 (unsigned long long) offset);
897 grub_uint32_t *t32 = (grub_uint32_t *) target;
898 *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32)
899 + addend + sym_addr);
900 grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%"
901 GRUB_HOST_PRIxLONG_LONG,
902 *t32, (unsigned long long) offset);
907 grub_util_error (_("relocation 0x%x is not implemented yet"),
908 (unsigned int) ELF_R_TYPE (info));
913 switch (ELF_R_TYPE (info))
915 case R_IA64_PCREL21B:
918 grub_ia64_make_trampoline (tr, addend + sym_addr);
919 noff = ((char *) tr - (char *) pe_target
920 - target_section_addr - (offset & ~3)) >> 4;
923 grub_util_error ("trampoline offset too big (%"
924 GRUB_HOST_PRIxLONG_LONG ")",
925 (unsigned long long) noff);
926 grub_ia64_add_value_to_slot_20b ((grub_addr_t) target, noff);
930 case R_IA64_LTOFF22X:
935 sym = (Elf_Sym *) ((char *) e
936 + grub_target_to_host (smd->symtab->sh_offset)
937 + ELF_R_SYM (info) * grub_target_to_host (smd->symtab->sh_entsize));
938 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC)
939 sym_addr = grub_target_to_host64 (*(grub_uint64_t *) (pe_target
941 - image_target->vaddr_offset));
944 case R_IA64_LTOFF_FPTR22:
945 *gpptr = grub_host_to_target64 (addend + sym_addr);
946 grub_ia64_add_value_to_slot_21 ((grub_addr_t) target,
947 (char *) gpptr - (char *) pe_target
948 + image_target->vaddr_offset);
953 grub_ia64_add_value_to_slot_21 ((grub_addr_t) target,
956 case R_IA64_GPREL64I:
957 grub_ia64_set_immu64 ((grub_addr_t) target,
960 case R_IA64_PCREL64LSB:
961 *target = grub_host_to_target64 (grub_target_to_host64 (*target)
963 - target_section_addr - offset
964 - image_target->vaddr_offset);
967 case R_IA64_SEGREL64LSB:
968 *target = grub_host_to_target64 (grub_target_to_host64 (*target)
969 + addend + sym_addr - target_section_addr);
971 case R_IA64_DIR64LSB:
972 case R_IA64_FPTR64LSB:
973 *target = grub_host_to_target64 (grub_target_to_host64 (*target)
974 + addend + sym_addr);
975 grub_util_info ("relocating a direct entry to 0x%"
976 GRUB_HOST_PRIxLONG_LONG " at the offset 0x%"
977 GRUB_HOST_PRIxLONG_LONG,
979 grub_target_to_host64 (*target),
980 (unsigned long long) offset);
983 /* We treat LTOFF22X as LTOFF22, so we can ignore LDXMOV. */
988 grub_util_error (_("relocation 0x%x is not implemented yet"),
989 (unsigned int) ELF_R_TYPE (info));
996 switch (ELF_R_TYPE (info))
998 case R_AARCH64_ABS64:
1000 *target = grub_host_to_target64 (grub_target_to_host64 (*target) + sym_addr);
1003 case R_AARCH64_PREL32:
1005 grub_uint32_t *t32 = (grub_uint32_t *) target;
1006 *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32)
1008 - target_section_addr - offset
1009 - image_target->vaddr_offset);
1010 grub_util_info ("relocating an R_AARCH64_PREL32 entry to 0x%x at the offset 0x%"
1011 GRUB_HOST_PRIxLONG_LONG,
1012 *t32, (unsigned long long) offset);
1015 case R_AARCH64_ADD_ABS_LO12_NC:
1016 grub_arm64_set_abs_lo12 ((grub_uint32_t *) target,
1019 case R_AARCH64_LDST64_ABS_LO12_NC:
1020 grub_arm64_set_abs_lo12_ldst64 ((grub_uint32_t *) target,
1023 case R_AARCH64_JUMP26:
1024 case R_AARCH64_CALL26:
1027 sym_addr -= target_section_addr + image_target->vaddr_offset;
1028 if (!grub_arm_64_check_xxxx26_offset (sym_addr))
1029 grub_util_error ("%s", "CALL26 Relocation out of range");
1031 grub_arm64_set_xxxx26_offset((grub_uint32_t *)target,
1035 case R_AARCH64_ADR_GOT_PAGE:
1038 grub_int64_t gpoffset = (((char *) gpptr - (char *) pe_target + image_target->vaddr_offset) & ~0xfffULL)
1039 - ((offset + target_section_addr + image_target->vaddr_offset) & ~0xfffULL);
1041 *gpptr = grub_host_to_target64 (sym_addr);
1042 unmatched_adr_got_page++;
1043 if (!grub_arm64_check_hi21_signed (gpoffset))
1044 grub_util_error ("HI21 out of range");
1045 grub_arm64_set_hi21((grub_uint32_t *)target,
1047 for (k = 0, rel2 = (Elf_Rela *) ((char *) r + r_size);
1049 k++, rel2 = (Elf_Rela *) ((char *) rel2 + r_size))
1050 if (ELF_R_SYM (rel2->r_info)
1051 == ELF_R_SYM (r->r_info)
1052 && r->r_addend == rel2->r_addend
1053 && ELF_R_TYPE (rel2->r_info) == R_AARCH64_LD64_GOT_LO12_NC)
1055 grub_arm64_set_abs_lo12_ldst64 ((grub_uint32_t *) SUFFIX (get_target_address) (e, target_section,
1056 grub_target_to_host (rel2->r_offset), image_target),
1057 ((char *) gpptr - (char *) pe_target + image_target->vaddr_offset));
1061 grub_util_error ("ADR_GOT_PAGE without matching LD64_GOT_LO12_NC");
1065 case R_AARCH64_LD64_GOT_LO12_NC:
1066 if (unmatched_adr_got_page == 0)
1067 grub_util_error ("LD64_GOT_LO12_NC without matching ADR_GOT_PAGE");
1068 unmatched_adr_got_page--;
1070 case R_AARCH64_ADR_PREL_PG_HI21:
1072 sym_addr &= ~0xfffULL;
1073 sym_addr -= (offset + target_section_addr + image_target->vaddr_offset) & ~0xfffULL;
1074 if (!grub_arm64_check_hi21_signed (sym_addr))
1075 grub_util_error ("%s", "CALL26 Relocation out of range");
1077 grub_arm64_set_hi21((grub_uint32_t *)target,
1082 grub_util_error (_("relocation 0x%x is not implemented yet"),
1083 (unsigned int) ELF_R_TYPE (info));
1089 #if defined(MKIMAGE_ELF32)
1093 sym_addr -= image_target->vaddr_offset;
1094 switch (ELF_R_TYPE (info))
1098 grub_util_info (" ABS32:\toffset=%d\t(0x%08x)",
1099 (int) sym_addr, (int) sym_addr);
1100 /* Data will be naturally aligned */
1101 if (image_target->id == IMAGE_EFI)
1103 *target = grub_host_to_target32 (grub_target_to_host32 (*target) + sym_addr);
1106 /* Happens when compiled with -march=armv4.
1107 Since currently we need at least armv5, keep bx as-is.
1111 case R_ARM_THM_CALL:
1112 case R_ARM_THM_JUMP24:
1113 case R_ARM_THM_JUMP19:
1117 grub_util_info (" THM_JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)",
1118 (unsigned long) ((char *) target
1121 sym = (Elf_Sym *) ((char *) e
1122 + grub_target_to_host (smd->symtab->sh_offset)
1123 + ELF_R_SYM (info) * grub_target_to_host (smd->symtab->sh_entsize));
1124 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
1126 if (!(sym_addr & 1))
1128 grub_uint32_t tr_addr;
1129 grub_int32_t new_offset;
1130 tr_addr = (char *) tr - (char *) pe_target
1131 - target_section_addr;
1132 new_offset = sym_addr - tr_addr - 12;
1134 if (!grub_arm_jump24_check_offset (new_offset))
1135 return grub_util_error ("jump24 relocation out of range");
1137 tr[0] = grub_host_to_target32 (0x46c04778); /* bx pc; nop */
1138 tr[1] = grub_host_to_target32 (((new_offset >> 2) & 0xffffff) | 0xea000000); /* b new_offset */
1140 sym_addr = tr_addr | 1;
1143 /* Thumb instructions can be 16-bit aligned */
1144 if (ELF_R_TYPE (info) == R_ARM_THM_JUMP19)
1145 err = grub_arm_reloc_thm_jump19 ((grub_uint16_t *) target, sym_addr);
1147 err = grub_arm_reloc_thm_call ((grub_uint16_t *) target,
1150 grub_util_error ("%s", grub_errmsg);
1158 grub_util_info (" JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)", (unsigned long) ((char *) target - (char *) e), sym_addr);
1161 grub_uint32_t tr_addr;
1162 grub_int32_t new_offset;
1163 tr_addr = (char *) tr - (char *) pe_target
1164 - target_section_addr;
1165 new_offset = sym_addr - tr_addr - 12;
1167 /* There is no immediate version of bx, only register one... */
1168 tr[0] = grub_host_to_target32 (0xe59fc004); /* ldr ip, [pc, #4] */
1169 tr[1] = grub_host_to_target32 (0xe08cc00f); /* add ip, ip, pc */
1170 tr[2] = grub_host_to_target32 (0xe12fff1c); /* bx ip */
1171 tr[3] = grub_host_to_target32 (new_offset | 1);
1176 err = grub_arm_reloc_jump24 (target,
1179 grub_util_error ("%s", grub_errmsg);
1184 grub_util_error (_("relocation 0x%x is not implemented yet"),
1185 (unsigned int) ELF_R_TYPE (info));
1190 #endif /* MKIMAGE_ELF32 */
1192 grub_util_error ("unknown architecture type %d",
1193 image_target->elf_target);
1199 /* Add a PE32's fixup entry for a relocation. Return the resulting address
1200 after having written to the file OUT. */
1202 add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type,
1203 Elf_Addr addr, int flush, Elf_Addr current_address,
1204 const struct grub_install_image_target_desc *image_target)
1206 struct grub_pe32_fixup_block *b;
1208 b = &((*cblock)->b);
1210 /* First, check if it is necessary to write out the current block. */
1211 if ((*cblock)->state)
1213 if (flush || addr < b->page_rva || b->page_rva + 0x1000 <= addr)
1219 /* Add as much padding as necessary to align the address
1220 with a section boundary. */
1221 Elf_Addr next_address;
1222 unsigned padding_size;
1225 next_address = current_address + b->block_size;
1226 padding_size = ((ALIGN_UP (next_address, image_target->section_align)
1229 cur_index = ((b->block_size - sizeof (*b)) >> 1);
1230 grub_util_info ("adding %d padding fixup entries", padding_size);
1231 while (padding_size--)
1233 b->entries[cur_index++] = 0;
1237 else while (b->block_size & (8 - 1))
1239 /* If not aligned with a 32-bit boundary, add
1243 grub_util_info ("adding a padding fixup entry");
1244 cur_index = ((b->block_size - sizeof (*b)) >> 1);
1245 b->entries[cur_index] = 0;
1250 grub_util_info ("writing %d bytes of a fixup block starting at 0x%x",
1251 b->block_size, b->page_rva);
1252 size = b->block_size;
1253 current_address += size;
1254 b->page_rva = grub_host_to_target32 (b->page_rva);
1255 b->block_size = grub_host_to_target32 (b->block_size);
1256 (*cblock)->next = xmalloc (sizeof (**cblock) + 2 * 0x1000);
1257 memset ((*cblock)->next, 0, sizeof (**cblock) + 2 * 0x1000);
1258 *cblock = (*cblock)->next;
1262 b = &((*cblock)->b);
1266 grub_uint16_t entry;
1269 /* If not allocated yet, allocate a block with enough entries. */
1270 if (! (*cblock)->state)
1272 (*cblock)->state = 1;
1274 /* The spec does not mention the requirement of a Page RVA.
1275 Here, align the address with a 4K boundary for safety. */
1276 b->page_rva = (addr & ~(0x1000 - 1));
1277 b->block_size = sizeof (*b);
1281 if (b->block_size >= sizeof (*b) + 2 * 0x1000)
1282 grub_util_error ("too many fixup entries");
1284 /* Add a new entry. */
1285 cur_index = ((b->block_size - sizeof (*b)) >> 1);
1286 entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva);
1287 b->entries[cur_index] = grub_host_to_target16 (entry);
1291 return current_address;
1296 struct raw_reloc *next;
1297 grub_uint32_t offset;
1298 enum raw_reloc_type {
1299 RAW_RELOC_NONE = -1,
1305 struct translate_context
1308 struct fixup_block_list *lst, *lst0;
1309 Elf_Addr current_address;
1312 struct raw_reloc *raw_relocs;
1316 translate_reloc_start (struct translate_context *ctx,
1317 const struct grub_install_image_target_desc *image_target)
1319 grub_memset (ctx, 0, sizeof (*ctx));
1320 if (image_target->id == IMAGE_EFI)
1322 ctx->lst = ctx->lst0 = xmalloc (sizeof (*ctx->lst) + 2 * 0x1000);
1323 memset (ctx->lst, 0, sizeof (*ctx->lst) + 2 * 0x1000);
1324 ctx->current_address = 0;
1329 translate_relocation_pe (struct translate_context *ctx,
1332 const struct grub_install_image_target_desc *image_target)
1334 /* Necessary to relocate only absolute addresses. */
1335 switch (image_target->elf_target)
1338 if (ELF_R_TYPE (info) == R_386_32)
1340 grub_util_info ("adding a relocation entry for 0x%"
1341 GRUB_HOST_PRIxLONG_LONG,
1342 (unsigned long long) addr);
1343 ctx->current_address
1344 = add_fixup_entry (&ctx->lst,
1345 GRUB_PE32_REL_BASED_HIGHLOW,
1346 addr, 0, ctx->current_address,
1351 if ((ELF_R_TYPE (info) == R_X86_64_32) ||
1352 (ELF_R_TYPE (info) == R_X86_64_32S))
1354 grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)");
1356 else if (ELF_R_TYPE (info) == R_X86_64_64)
1358 grub_util_info ("adding a relocation entry for 0x%"
1359 GRUB_HOST_PRIxLONG_LONG,
1360 (unsigned long long) addr);
1361 ctx->current_address
1362 = add_fixup_entry (&ctx->lst,
1363 GRUB_PE32_REL_BASED_DIR64,
1365 0, ctx->current_address,
1370 switch (ELF_R_TYPE (info))
1372 case R_IA64_PCREL64LSB:
1374 case R_IA64_PCREL21B:
1375 case R_IA64_LTOFF_FPTR22:
1376 case R_IA64_LTOFF22X:
1377 case R_IA64_LTOFF22:
1378 case R_IA64_GPREL22:
1379 case R_IA64_GPREL64I:
1380 case R_IA64_SEGREL64LSB:
1383 case R_IA64_FPTR64LSB:
1384 case R_IA64_DIR64LSB:
1387 grub_util_info ("adding a relocation entry for 0x%"
1388 GRUB_HOST_PRIxLONG_LONG,
1389 (unsigned long long) addr);
1390 ctx->current_address
1391 = add_fixup_entry (&ctx->lst,
1392 GRUB_PE32_REL_BASED_DIR64,
1394 0, ctx->current_address,
1400 grub_util_error (_("relocation 0x%x is not implemented yet"),
1401 (unsigned int) ELF_R_TYPE (info));
1406 switch (ELF_R_TYPE (info))
1408 case R_AARCH64_ABS64:
1410 ctx->current_address
1411 = add_fixup_entry (&ctx->lst,
1412 GRUB_PE32_REL_BASED_DIR64,
1413 addr, 0, ctx->current_address,
1417 /* Relative relocations do not require fixup entries. */
1418 case R_AARCH64_CALL26:
1419 case R_AARCH64_JUMP26:
1420 case R_AARCH64_PREL32:
1422 /* Page-relative relocations do not require fixup entries. */
1423 case R_AARCH64_ADR_PREL_PG_HI21:
1424 /* We page-align the whole kernel, so no need
1427 case R_AARCH64_ADD_ABS_LO12_NC:
1428 case R_AARCH64_LDST64_ABS_LO12_NC:
1431 /* GOT is relocated separately. */
1432 case R_AARCH64_ADR_GOT_PAGE:
1433 case R_AARCH64_LD64_GOT_LO12_NC:
1437 grub_util_error (_("relocation 0x%x is not implemented yet"),
1438 (unsigned int) ELF_R_TYPE (info));
1443 #if defined(MKIMAGE_ELF32)
1445 switch (ELF_R_TYPE (info))
1448 /* Relative relocations do not require fixup entries. */
1450 case R_ARM_THM_CALL:
1451 case R_ARM_THM_JUMP19:
1452 case R_ARM_THM_JUMP24:
1455 grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x", __FUNCTION__, (unsigned int) addr, (unsigned int) ctx->current_address);
1458 /* Create fixup entry for PE/COFF loader */
1461 ctx->current_address
1462 = add_fixup_entry (&ctx->lst,
1463 GRUB_PE32_REL_BASED_HIGHLOW,
1464 addr, 0, ctx->current_address,
1469 grub_util_error (_("relocation 0x%x is not implemented yet"),
1470 (unsigned int) ELF_R_TYPE (info));
1474 #endif /* defined(MKIMAGE_ELF32) */
1476 grub_util_error ("unknown machine type 0x%x", image_target->elf_target);
1480 static enum raw_reloc_type
1481 classify_raw_reloc (Elf_Addr info,
1482 const struct grub_install_image_target_desc *image_target)
1484 /* Necessary to relocate only absolute addresses. */
1485 switch (image_target->elf_target)
1488 switch (ELF_R_TYPE (info))
1492 case R_ARM_THM_CALL:
1493 case R_ARM_THM_JUMP19:
1494 case R_ARM_THM_JUMP24:
1496 return RAW_RELOC_NONE;
1498 return RAW_RELOC_32;
1500 grub_util_error (_("relocation 0x%x is not implemented yet"),
1501 (unsigned int) ELF_R_TYPE (info));
1506 grub_util_error ("unknown machine type 0x%x", image_target->elf_target);
1511 translate_relocation_raw (struct translate_context *ctx,
1514 const struct grub_install_image_target_desc *image_target)
1516 enum raw_reloc_type class = classify_raw_reloc (info, image_target);
1517 struct raw_reloc *rel;
1518 if (class == RAW_RELOC_NONE)
1520 rel = xmalloc (sizeof (*rel));
1521 rel->next = ctx->raw_relocs;
1524 ctx->raw_relocs = rel;
1528 translate_relocation (struct translate_context *ctx,
1531 const struct grub_install_image_target_desc *image_target)
1533 if (image_target->id == IMAGE_EFI)
1534 translate_relocation_pe (ctx, addr, info, image_target);
1536 translate_relocation_raw (ctx, addr, info, image_target);
1540 finish_reloc_translation_pe (struct translate_context *ctx, struct grub_mkimage_layout *layout,
1541 const struct grub_install_image_target_desc *image_target)
1543 ctx->current_address = add_fixup_entry (&ctx->lst, 0, 0, 1, ctx->current_address, image_target);
1547 layout->reloc_section = ptr = xmalloc (ctx->current_address);
1548 for (ctx->lst = ctx->lst0; ctx->lst; ctx->lst = ctx->lst->next)
1549 if (ctx->lst->state)
1551 memcpy (ptr, &ctx->lst->b, grub_target_to_host32 (ctx->lst->b.block_size));
1552 ptr += grub_target_to_host32 (ctx->lst->b.block_size);
1554 assert ((ctx->current_address + (grub_uint8_t *) layout->reloc_section) == ptr);
1557 for (ctx->lst = ctx->lst0; ctx->lst; )
1559 struct fixup_block_list *next;
1560 next = ctx->lst->next;
1565 layout->reloc_size = ctx->current_address;
1566 if (image_target->elf_target == EM_ARM && layout->reloc_size > GRUB_KERNEL_ARM_STACK_SIZE)
1567 grub_util_error ("Reloc section (%d) is bigger than stack size (%d). "
1568 "This breaks assembly assumptions. Please increase stack size",
1569 (int) layout->reloc_size,
1570 (int) GRUB_KERNEL_ARM_STACK_SIZE);
1575 <type 0 relocations>
1577 <type 1 relocations>
1580 <type n relocations>
1582 each relocation starts with 32-bit offset. Rest depends on relocation.
1583 mkimage stops when it sees first unknown type or end marker.
1584 This allows images to be created with mismatched mkimage and
1585 kernel as long as no relocations are present in kernel that mkimage
1586 isn't aware of (in which case mkimage aborts).
1587 This also allows simple assembly to do the relocs.
1590 #define RAW_SEPARATOR 0xfffffffe
1591 #define RAW_END_MARKER 0xffffffff
1594 finish_reloc_translation_raw (struct translate_context *ctx, struct grub_mkimage_layout *layout,
1595 const struct grub_install_image_target_desc *image_target)
1597 size_t count = 0, sz;
1598 enum raw_reloc_type highest = RAW_RELOC_NONE;
1599 enum raw_reloc_type curtype;
1600 struct raw_reloc *cur;
1602 if (!ctx->raw_relocs)
1604 layout->reloc_section = p = xmalloc (sizeof (grub_uint32_t));
1605 p[0] = RAW_END_MARKER;
1606 layout->reloc_size = sizeof (grub_uint32_t);
1609 for (cur = ctx->raw_relocs; cur; cur = cur->next)
1612 if (cur->type > highest)
1613 highest = cur->type;
1615 /* highest separators, count relocations and one end marker. */
1616 sz = (highest + count + 1) * sizeof (grub_uint32_t);
1617 layout->reloc_section = p = xmalloc (sz);
1618 for (curtype = 0; curtype <= highest; curtype++)
1620 /* Support for special cases would go here. */
1621 for (cur = ctx->raw_relocs; cur; cur = cur->next)
1622 if (cur->type == curtype)
1626 *p++ = RAW_SEPARATOR;
1628 *--p = RAW_END_MARKER;
1629 layout->reloc_size = sz;
1633 finish_reloc_translation (struct translate_context *ctx, struct grub_mkimage_layout *layout,
1634 const struct grub_install_image_target_desc *image_target)
1636 if (image_target->id == IMAGE_EFI)
1637 finish_reloc_translation_pe (ctx, layout, image_target);
1639 finish_reloc_translation_raw (ctx, layout, image_target);
1644 create_u64_fixups (struct translate_context *ctx,
1645 Elf_Addr jumpers, grub_size_t njumpers,
1646 const struct grub_install_image_target_desc *image_target)
1649 assert (image_target->id == IMAGE_EFI);
1650 for (i = 0; i < njumpers; i++)
1651 ctx->current_address = add_fixup_entry (&ctx->lst,
1652 GRUB_PE32_REL_BASED_DIR64,
1654 0, ctx->current_address,
1658 /* Make a .reloc section. */
1660 make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout,
1661 struct section_metadata *smd,
1662 const struct grub_install_image_target_desc *image_target)
1666 struct translate_context ctx;
1668 translate_reloc_start (&ctx, image_target);
1670 for (i = 0, s = smd->sections; i < smd->num_sections;
1671 i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
1672 if ((grub_target_to_host32 (s->sh_type) == SHT_REL) ||
1673 (grub_target_to_host32 (s->sh_type) == SHT_RELA))
1676 Elf_Word rtab_size, r_size, num_rs;
1677 Elf_Off rtab_offset;
1678 Elf_Addr section_address;
1681 if (!SUFFIX (is_kept_reloc_section) (s, image_target, smd))
1683 grub_util_info ("not translating the skipped relocation section %s",
1684 smd->strtab + grub_le_to_cpu32 (s->sh_name));
1688 grub_util_info ("translating the relocation section %s",
1689 smd->strtab + grub_le_to_cpu32 (s->sh_name));
1691 rtab_size = grub_target_to_host (s->sh_size);
1692 r_size = grub_target_to_host (s->sh_entsize);
1693 rtab_offset = grub_target_to_host (s->sh_offset);
1694 num_rs = rtab_size / r_size;
1696 section_address = smd->vaddrs[grub_le_to_cpu32 (s->sh_info)];
1698 for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset);
1700 j++, r = (Elf_Rel *) ((char *) r + r_size))
1706 offset = grub_target_to_host (r->r_offset);
1707 info = grub_target_to_host (r->r_info);
1709 addr = section_address + offset;
1711 translate_relocation (&ctx, addr, info, image_target);
1715 if (image_target->elf_target == EM_IA_64)
1716 create_u64_fixups (&ctx,
1718 + image_target->vaddr_offset,
1719 2 * layout->ia64jmpnum,
1721 if (image_target->elf_target == EM_IA_64 || image_target->elf_target == EM_AARCH64)
1722 create_u64_fixups (&ctx,
1724 + image_target->vaddr_offset,
1725 (layout->got_size / 8),
1728 finish_reloc_translation (&ctx, layout, image_target);
1731 /* Determine if this section is a text section. Return false if this
1732 section is not allocated. */
1734 SUFFIX (is_text_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target)
1736 if (!is_relocatable (image_target)
1737 && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS)
1739 return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC))
1740 == (SHF_EXECINSTR | SHF_ALLOC));
1743 /* Determine if this section is a data section. */
1745 SUFFIX (is_data_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target)
1747 if (!is_relocatable (image_target)
1748 && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS)
1750 return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC))
1751 == SHF_ALLOC) && !(grub_target_to_host32 (s->sh_type) == SHT_NOBITS);
1755 SUFFIX (is_bss_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target)
1757 if (!is_relocatable (image_target))
1759 return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC))
1760 == SHF_ALLOC) && (grub_target_to_host32 (s->sh_type) == SHT_NOBITS);
1763 /* Determine if a section is going to be in the final output */
1765 SUFFIX (is_kept_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target)
1767 /* We keep .text and .data */
1768 if (SUFFIX (is_text_section) (s, image_target)
1769 || SUFFIX (is_data_section) (s, image_target))
1773 * And we keep .bss if we're producing PE binaries or the target doesn't
1774 * have a relocating loader. Platforms other than EFI and U-boot shouldn't
1775 * have .bss in their binaries as we build with -Wl,-Ttext.
1777 if (SUFFIX (is_bss_section) (s, image_target)
1778 && (image_target->id == IMAGE_EFI || !is_relocatable (image_target)))
1781 /* Otherwise this is not a section we're keeping in the final output. */
1786 SUFFIX (is_kept_reloc_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target,
1787 struct section_metadata *smd)
1791 const char *name = smd->strtab + grub_host_to_target32 (s->sh_name);
1793 if (!strncmp (name, ".rela.", 6))
1795 else if (!strncmp (name, ".rel.", 5))
1800 for (i = 0, s = smd->sections; i < smd->num_sections;
1801 i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
1803 const char *sname = smd->strtab + grub_host_to_target32 (s->sh_name);
1804 if (strcmp (sname, name))
1807 return SUFFIX (is_kept_section) (s, image_target);
1813 /* Return if the ELF header is valid. */
1815 SUFFIX (check_elf_header) (Elf_Ehdr *e, size_t size, const struct grub_install_image_target_desc *image_target)
1817 if (size < sizeof (*e)
1818 || e->e_ident[EI_MAG0] != ELFMAG0
1819 || e->e_ident[EI_MAG1] != ELFMAG1
1820 || e->e_ident[EI_MAG2] != ELFMAG2
1821 || e->e_ident[EI_MAG3] != ELFMAG3
1822 || e->e_ident[EI_VERSION] != EV_CURRENT
1823 || e->e_ident[EI_CLASS] != ELFCLASSXX
1824 || e->e_version != grub_host_to_target32 (EV_CURRENT))
1831 SUFFIX (put_section) (Elf_Shdr *s, int i,
1832 Elf_Addr current_address,
1833 struct section_metadata *smd,
1834 const struct grub_install_image_target_desc *image_target)
1836 Elf_Word align = grub_host_to_target_addr (s->sh_addralign);
1837 const char *name = smd->strtab + grub_host_to_target32 (s->sh_name);
1840 current_address = ALIGN_UP (current_address + image_target->vaddr_offset,
1842 - image_target->vaddr_offset;
1844 grub_util_info ("locating the section %s at 0x%"
1845 GRUB_HOST_PRIxLONG_LONG,
1846 name, (unsigned long long) current_address);
1847 if (!is_relocatable (image_target))
1848 current_address = grub_host_to_target_addr (s->sh_addr)
1849 - image_target->link_addr;
1850 smd->addrs[i] = current_address;
1851 current_address += grub_host_to_target_addr (s->sh_size);
1852 return current_address;
1856 * Locate section addresses by merging code sections and data sections
1857 * into .text and .data, respectively.
1860 SUFFIX (locate_sections) (Elf_Ehdr *e, const char *kernel_path,
1861 struct section_metadata *smd,
1862 struct grub_mkimage_layout *layout,
1863 const struct grub_install_image_target_desc *image_target)
1869 /* Page-aligning simplifies relocation handling. */
1870 if (image_target->elf_target == EM_AARCH64)
1871 layout->align = 4096;
1873 layout->kernel_size = 0;
1875 for (i = 0, s = smd->sections;
1876 i < smd->num_sections;
1877 i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
1878 if ((grub_target_to_host (s->sh_flags) & SHF_ALLOC)
1879 && grub_host_to_target32 (s->sh_addralign) > layout->align)
1880 layout->align = grub_host_to_target32 (s->sh_addralign);
1883 for (i = 0, s = smd->sections;
1884 i < smd->num_sections;
1885 i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
1886 if (SUFFIX (is_text_section) (s, image_target))
1888 layout->kernel_size = SUFFIX (put_section) (s, i, layout->kernel_size,
1890 if (!is_relocatable (image_target) &&
1891 grub_host_to_target_addr (s->sh_addr) != image_target->link_addr)
1894 = grub_xasprintf (_("`%s' is miscompiled: its start address is 0x%llx"
1895 " instead of 0x%llx: ld.gold bug?"),
1897 (unsigned long long) grub_host_to_target_addr (s->sh_addr),
1898 (unsigned long long) image_target->link_addr);
1899 grub_util_error ("%s", msg);
1903 layout->kernel_size = ALIGN_UP (layout->kernel_size + image_target->vaddr_offset,
1904 image_target->section_align)
1905 - image_target->vaddr_offset;
1906 layout->exec_size = layout->kernel_size;
1909 for (i = 0, s = smd->sections;
1910 i < smd->num_sections;
1911 i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
1912 if (SUFFIX (is_data_section) (s, image_target))
1913 layout->kernel_size = SUFFIX (put_section) (s, i, layout->kernel_size, smd,
1916 #ifdef MKIMAGE_ELF32
1917 if (image_target->elf_target == EM_ARM)
1920 layout->kernel_size = ALIGN_UP (layout->kernel_size + image_target->vaddr_offset,
1921 image_target->section_align) - image_target->vaddr_offset;
1923 layout->kernel_size = ALIGN_UP (layout->kernel_size, 16);
1925 tramp = arm_get_trampoline_size (e, smd->sections, smd->section_entsize,
1926 smd->num_sections, image_target);
1928 layout->tramp_off = layout->kernel_size;
1929 layout->kernel_size += ALIGN_UP (tramp, 16);
1933 layout->bss_start = layout->kernel_size;
1934 layout->end = layout->kernel_size;
1937 for (i = 0, s = smd->sections;
1938 i < smd->num_sections;
1939 i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
1941 if (SUFFIX (is_bss_section) (s, image_target))
1942 layout->end = SUFFIX (put_section) (s, i, layout->end, smd, image_target);
1945 * This must to be in the last time this function passes through the loop.
1947 smd->vaddrs[i] = smd->addrs[i] + image_target->vaddr_offset;
1950 layout->end = ALIGN_UP (layout->end + image_target->vaddr_offset,
1951 image_target->section_align) - image_target->vaddr_offset;
1952 /* Explicitly initialize BSS
1953 when producing PE32 to avoid a bug in EFI implementations.
1954 Platforms other than EFI and U-boot shouldn't have .bss in
1955 their binaries as we build with -Wl,-Ttext.
1957 if (image_target->id == IMAGE_EFI || !is_relocatable (image_target))
1958 layout->kernel_size = layout->end;
1962 SUFFIX (grub_mkimage_load_image) (const char *kernel_path,
1963 size_t total_module_size,
1964 struct grub_mkimage_layout *layout,
1965 const struct grub_install_image_target_desc *image_target)
1967 char *kernel_img, *out_img;
1968 struct section_metadata smd = { 0, };
1972 Elf_Off section_offset;
1973 grub_size_t kernel_size;
1975 grub_memset (layout, 0, sizeof (*layout));
1977 layout->start_address = 0;
1979 kernel_size = grub_util_get_image_size (kernel_path);
1980 kernel_img = xmalloc (kernel_size);
1981 grub_util_load_image (kernel_path, kernel_img);
1983 e = (Elf_Ehdr *) kernel_img;
1984 if (! SUFFIX (check_elf_header) (e, kernel_size, image_target))
1985 grub_util_error ("invalid ELF header");
1987 section_offset = grub_target_to_host (e->e_shoff);
1988 smd.section_entsize = grub_target_to_host16 (e->e_shentsize);
1989 smd.num_sections = grub_target_to_host16 (e->e_shnum);
1991 if (kernel_size < section_offset
1992 + (grub_uint32_t) smd.section_entsize * smd.num_sections)
1993 grub_util_error (_("premature end of file %s"), kernel_path);
1995 smd.sections = (Elf_Shdr *) (kernel_img + section_offset);
1997 /* Relocate sections then symbols in the virtual address space. */
1998 s = (Elf_Shdr *) ((char *) smd.sections
1999 + grub_host_to_target16 (e->e_shstrndx) * smd.section_entsize);
2000 smd.strtab = (char *) e + grub_host_to_target_addr (s->sh_offset);
2002 smd.addrs = xmalloc (sizeof (*smd.addrs) * smd.num_sections);
2003 memset (smd.addrs, 0, sizeof (*smd.addrs) * smd.num_sections);
2004 smd.vaddrs = xmalloc (sizeof (*smd.vaddrs) * smd.num_sections);
2005 memset (smd.vaddrs, 0, sizeof (*smd.vaddrs) * smd.num_sections);
2007 SUFFIX (locate_sections) (e, kernel_path, &smd, layout, image_target);
2009 if (!is_relocatable (image_target))
2011 Elf_Addr current_address = layout->kernel_size;
2013 for (i = 0, s = smd.sections;
2014 i < smd.num_sections;
2015 i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize))
2016 if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS)
2018 Elf_Word sec_align = grub_host_to_target_addr (s->sh_addralign);
2019 const char *name = smd.strtab + grub_host_to_target32 (s->sh_name);
2022 current_address = ALIGN_UP (current_address
2023 + image_target->vaddr_offset,
2025 - image_target->vaddr_offset;
2027 grub_util_info ("locating the section %s at 0x%"
2028 GRUB_HOST_PRIxLONG_LONG,
2029 name, (unsigned long long) current_address);
2030 if (!is_relocatable (image_target))
2031 current_address = grub_host_to_target_addr (s->sh_addr)
2032 - image_target->link_addr;
2034 smd.vaddrs[i] = current_address
2035 + image_target->vaddr_offset;
2036 current_address += grub_host_to_target_addr (s->sh_size);
2038 current_address = ALIGN_UP (current_address + image_target->vaddr_offset,
2039 image_target->section_align)
2040 - image_target->vaddr_offset;
2041 layout->bss_size = current_address - layout->kernel_size;
2044 layout->bss_size = 0;
2046 if (image_target->id == IMAGE_SPARC64_AOUT
2047 || image_target->id == IMAGE_SPARC64_RAW
2048 || image_target->id == IMAGE_UBOOT
2049 || image_target->id == IMAGE_COREBOOT
2050 || image_target->id == IMAGE_SPARC64_CDCORE)
2051 layout->kernel_size = ALIGN_UP (layout->kernel_size, image_target->mod_align);
2053 if (is_relocatable (image_target))
2056 for (i = 0, s = smd.sections;
2057 i < smd.num_sections;
2058 i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize))
2059 if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB))
2065 grub_util_error ("%s", _("no symbol table"));
2066 #ifdef MKIMAGE_ELF64
2067 if (image_target->elf_target == EM_IA_64)
2071 layout->kernel_size = ALIGN_UP (layout->kernel_size, 16);
2073 grub_ia64_dl_get_tramp_got_size (e, &tramp, &layout->got_size);
2075 layout->tramp_off = layout->kernel_size;
2076 layout->kernel_size += ALIGN_UP (tramp, 16);
2078 layout->ia64jmp_off = layout->kernel_size;
2079 layout->ia64jmpnum = SUFFIX (count_funcs) (e, smd.symtab,
2081 layout->kernel_size += 16 * layout->ia64jmpnum;
2083 layout->got_off = layout->kernel_size;
2084 layout->kernel_size += ALIGN_UP (layout->got_size, 16);
2086 if (image_target->elf_target == EM_AARCH64)
2090 layout->kernel_size = ALIGN_UP (layout->kernel_size, 16);
2092 grub_arm64_dl_get_tramp_got_size (e, &tramp, &layout->got_size);
2094 layout->got_off = layout->kernel_size;
2095 layout->kernel_size += ALIGN_UP (layout->got_size, 16);
2101 layout->reloc_size = 0;
2102 layout->reloc_section = NULL;
2105 out_img = xmalloc (layout->kernel_size + total_module_size);
2106 memset (out_img, 0, layout->kernel_size + total_module_size);
2108 if (is_relocatable (image_target))
2110 layout->start_address = SUFFIX (relocate_symbols) (e, &smd,
2111 (char *) out_img + layout->ia64jmp_off,
2112 layout->ia64jmp_off + image_target->vaddr_offset,
2113 layout->bss_start, layout->end, image_target);
2115 if (layout->start_address == (Elf_Addr) -1)
2116 grub_util_error ("start symbol is not defined");
2118 /* Resolve addrs in the virtual address space. */
2119 SUFFIX (relocate_addrs) (e, &smd, out_img, layout->tramp_off,
2120 layout->got_off, image_target);
2122 make_reloc_section (e, layout, &smd, image_target);
2123 if (image_target->id != IMAGE_EFI)
2125 out_img = xrealloc (out_img, layout->kernel_size + total_module_size
2126 + ALIGN_UP (layout->reloc_size, image_target->mod_align));
2127 memcpy (out_img + layout->kernel_size, layout->reloc_section, layout->reloc_size);
2128 memset (out_img + layout->kernel_size + layout->reloc_size, 0,
2129 total_module_size + ALIGN_UP (layout->reloc_size, image_target->mod_align) - layout->reloc_size);
2130 layout->kernel_size += ALIGN_UP (layout->reloc_size, image_target->mod_align);
2134 for (i = 0, s = smd.sections;
2135 i < smd.num_sections;
2136 i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize))
2137 if (SUFFIX (is_kept_section) (s, image_target))
2139 if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS)
2140 memset (out_img + smd.addrs[i], 0,
2141 grub_host_to_target_addr (s->sh_size));
2143 memcpy (out_img + smd.addrs[i],
2144 kernel_img + grub_host_to_target_addr (s->sh_offset),
2145 grub_host_to_target_addr (s->sh_size));