[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 6/7] mkimage: support images which require full relocation at
From: |
Leif Lindholm |
Subject: |
Re: [PATCH 6/7] mkimage: support images which require full relocation at mkimage time. |
Date: |
Sun, 29 Dec 2013 22:53:00 +0000 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
On Sun, Dec 29, 2013 at 06:47:35PM +0000, Ian Campbell wrote:
> To do so support the specification of a "target_address" (which must be 0 for
> image types which do not have this flag) and a new image flag to signal the
> need for absolute relocation. If this flag is present then image->link_addr is
> the default target.
>
> Account for the target address when relocating.
>
> Fabricate correct addresses for absolute symbols relating to the bss
> ("__bss_start" and "_end").
>
> This functionality is not yet used by any image type and is connected only to
> grub-mkimage ("-T option) and not yet to grub-install.
>
> Signed-off-by: Ian Campbell <address@hidden>
> ---
> include/grub/util/install.h | 2 +-
> util/grub-install-common.c | 4 +--
> util/grub-mkimage.c | 7 +++++
> util/grub-mkimagexx.c | 74
> +++++++++++++++++++++++++++++++--------------
> util/mkimage.c | 24 ++++++++++++---
> 5 files changed, 81 insertions(+), 30 deletions(-)
>
> diff --git a/include/grub/util/install.h b/include/grub/util/install.h
> index bc987aa..b7ecf27 100644
> --- a/include/grub/util/install.h
> +++ b/include/grub/util/install.h
> @@ -167,7 +167,7 @@ struct grub_install_image_target_desc;
>
> void
> grub_install_generate_image (const char *dir, const char *prefix,
> - FILE *out,
> + FILE *out, grub_uint64_t target_address,
> const char *outname, char *mods[],
> char *memdisk_path, char **pubkey_paths,
> size_t npubkeys,
> diff --git a/util/grub-install-common.c b/util/grub-install-common.c
> index ae26875..82a44f2 100644
> --- a/util/grub-install-common.c
> +++ b/util/grub-install-common.c
> @@ -495,8 +495,8 @@ grub_install_make_image_wrap_file (const char *dir, const
> char *prefix,
> if (!tgt)
> grub_util_error (_("unknown target format %s\n"), mkimage_target);
>
> - grub_install_generate_image (dir, prefix, fp, outname,
> - modules.entries, memdisk_path,
> + grub_install_generate_image (dir, prefix, fp, 0,
> + outname, modules.entries, memdisk_path,
> pubkeys, npubkeys, config_path, tgt,
> note, compression);
> while (dc--)
> diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
> index a2bd4c1..267beaa 100644
> --- a/util/grub-mkimage.c
> +++ b/util/grub-mkimage.c
> @@ -65,6 +65,7 @@ static struct argp_option options[] = {
> /* TRANSLATORS: platform here isn't identifier. It can be translated. */
> N_("use images and modules under DIR [default=%s/<platform>]"), 0},
> {"prefix", 'p', N_("DIR"), 0, N_("set prefix directory [default=%s]"), 0},
> + {"target-address", 'T', N_("ADDR"), 0, N_("set kernel target address
> [default=%d]"), 0},
For this to actually print a default value, you need to also update
the help_filter function. Also, you probably want a %p here.
---
--- a/util/grub-mkimage.c
+++ b/util/grub-mkimage.c
@@ -65,7 +65,7 @@ static struct argp_option options[] = {
/* TRANSLATORS: platform here isn't identifier. It can be translated. */
N_("use images and modules under DIR [default=%s/<platform>]"), 0},
{"prefix", 'p', N_("DIR"), 0, N_("set prefix directory [default=%s]"), 0},
- {"target-address", 'T', N_("ADDR"), 0, N_("set kernel target address
[default=%d]"), 0},
+ {"target-address", 'T', N_("ADDR"), 0, N_("set kernel target address
[default=%p]"), 0},
{"memdisk", 'm', N_("FILE"), 0,
/* TRANSLATORS: "memdisk" here isn't an identifier, it can be translated.
"embed" is a verb (command description). "*/
@@ -104,6 +104,8 @@ help_filter (int key, const char *text, void *input
__attribute__ ((unused)))
free (formats);
return ret;
}
+ case 'T':
+ return xasprintf (text, GRUB_KERNEL_ARM_UBOOT_DEFAULT_LINK_ADDR);
default:
return (char *) text;
}
---
(Of course, you probably want to abstract away the ARM_UBOOT bit...)
> {"memdisk", 'm', N_("FILE"), 0,
> /* TRANSLATORS: "memdisk" here isn't an identifier, it can be translated.
> "embed" is a verb (command description). "*/
> @@ -126,6 +127,7 @@ struct arguments
> int note;
> const struct grub_install_image_target_desc *image_target;
> grub_compression_t comp;
> + grub_uint64_t target_address;
> };
>
> static error_t
> @@ -217,6 +219,10 @@ argp_parser (int key, char *arg, struct argp_state
> *state)
> arguments->prefix = xstrdup (arg);
> break;
>
> + case 'T':
> + arguments->target_address = strtoull (arg, NULL, 0);
> + break;
> +
> case 'v':
> verbosity++;
> break;
> @@ -289,6 +295,7 @@ main (int argc, char *argv[])
>
> grub_install_generate_image (arguments.dir,
> arguments.prefix ? : DEFAULT_DIRECTORY, fp,
> + arguments.target_address,
> arguments.output, arguments.modules,
> arguments.memdisk, arguments.pubkeys,
> arguments.npubkeys, arguments.config,
> diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
> index b4216ff..186d259 100644
> --- a/util/grub-mkimagexx.c
> +++ b/util/grub-mkimagexx.c
> @@ -378,6 +378,7 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr
> *sections,
> Elf_Shdr *symtab_section, Elf_Addr
> *section_addresses,
> Elf_Half section_entsize, Elf_Half num_sections,
> void *jumpers, Elf_Addr jumpers_addr,
> + Elf_Addr bss_addr, size_t bss_size,
> const struct grub_install_image_target_desc
> *image_target)
> {
> Elf_Word symtab_size, sym_size, num_syms;
> @@ -416,10 +417,14 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr
> *sections,
> }
> else if (cur_index == STN_UNDEF)
> {
> - if (sym->st_name)
> + if (strcmp (name, "__bss_start") == 0 && bss_addr)
> + sym->st_value = bss_addr;
> + else if (strcmp (name, "_end") == 0 && bss_addr)
> + sym->st_value = bss_addr + bss_size;
> + else if (sym->st_name)
> grub_util_error ("undefined symbol %s", name);
> - else
> - continue;
> +
> + continue;
> }
> else if (cur_index >= num_sections)
> grub_util_error ("section %d does not exist", cur_index);
> @@ -584,7 +589,7 @@ static void
> SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections,
> Elf_Addr *section_addresses,
> Elf_Half section_entsize, Elf_Half num_sections,
> - const char *strtab,
> + const char *strtab, grub_uint64_t target_address,
> char *pe_target, Elf_Addr tramp_off,
> Elf_Addr got_off,
> const struct grub_install_image_target_desc
> *image_target)
> @@ -867,6 +872,7 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr
> *sections,
> {
> case R_ARM_ABS32:
> {
> + sym_addr += target_address;
> grub_util_info ("
> ABS32:\ttarget=0x%08lx\toffset=(0x%08x)",
> (unsigned long) ((char *) target
> - (char *) e),
> @@ -928,7 +934,7 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr
> *sections,
> grub_uint32_t tr_addr;
> grub_int32_t new_offset;
> tr_addr = (char *) tr - (char *) pe_target
> - - target_section_addr;
> + - (target_address - target_section_addr);
> new_offset = sym_addr - tr_addr - 12;
>
> /* There is no immediate version of bx, only
> register one... */
> @@ -1337,6 +1343,7 @@ static Elf_Addr *
> SUFFIX (locate_sections) (const char *kernel_path,
> Elf_Shdr *sections, Elf_Half section_entsize,
> Elf_Half num_sections, const char *strtab,
> + grub_uint64_t target_address,
> size_t *exec_size, size_t *kernel_sz,
> size_t *all_align,
> const struct grub_install_image_target_desc
> *image_target)
> @@ -1351,7 +1358,7 @@ SUFFIX (locate_sections) (const char *kernel_path,
> section_addresses = xmalloc (sizeof (*section_addresses) * num_sections);
> memset (section_addresses, 0, sizeof (*section_addresses) * num_sections);
>
> - current_address = 0;
> + current_address = target_address;
>
> for (i = 0, s = sections;
> i < num_sections;
> @@ -1391,6 +1398,15 @@ SUFFIX (locate_sections) (const char *kernel_path,
> grub_util_error ("%s", msg);
> }
> }
> + else if (!grub_image_needs_abs_reloc(image_target))
> + {
> + if (grub_host_to_target_addr (s->sh_addr))
> + grub_util_error (_("`%s' is miscompiled: its start address is
> 0x%llx"
> + " but this platform uses late relocation"),
> + kernel_path,
> + (unsigned long long) grub_host_to_target_addr
> (s->sh_addr));
> + }
> +
> section_addresses[i] = current_address;
> current_address += grub_host_to_target_addr (s->sh_size);
> }
> @@ -1398,7 +1414,7 @@ SUFFIX (locate_sections) (const char *kernel_path,
> current_address = ALIGN_UP (current_address + image_target->vaddr_offset,
> image_target->section_align)
> - image_target->vaddr_offset;
> - *exec_size = current_address;
> + *exec_size = current_address - target_address;
>
> /* .data */
> for (i = 0, s = sections;
> @@ -1426,14 +1442,15 @@ SUFFIX (locate_sections) (const char *kernel_path,
>
> current_address = ALIGN_UP (current_address + image_target->vaddr_offset,
> image_target->section_align) -
> image_target->vaddr_offset;
> - *kernel_sz = current_address;
> + *kernel_sz = current_address - target_address;
> return section_addresses;
> }
>
> static char *
> SUFFIX (load_image) (const char *kernel_path, size_t *exec_size,
> size_t *kernel_sz, size_t *bss_size,
> - size_t total_module_size, grub_uint64_t *start,
> + size_t total_module_size, grub_uint64_t target_address,
> + grub_uint64_t *start,
> void **reloc_section, size_t *reloc_size,
> size_t *align,
> const struct grub_install_image_target_desc *image_target)
> @@ -1444,6 +1461,7 @@ SUFFIX (load_image) (const char *kernel_path, size_t
> *exec_size,
> Elf_Shdr *sections;
> Elf_Addr *section_addresses;
> Elf_Addr *section_vaddresses;
> + Elf_Addr bss_addr = 0;
> int i;
> Elf_Shdr *s;
> Elf_Half num_sections;
> @@ -1455,6 +1473,9 @@ SUFFIX (load_image) (const char *kernel_path, size_t
> *exec_size,
> Elf_Shdr *symtab_section = 0;
> grub_size_t got = 0;
>
> + if (target_address && !grub_image_needs_abs_reloc(image_target))
> + grub_util_error("cannot perform absolute relocation for this image
> type");
> +
> *start = 0;
>
> kernel_size = grub_util_get_image_size (kernel_path);
> @@ -1481,7 +1502,7 @@ SUFFIX (load_image) (const char *kernel_path, size_t
> *exec_size,
>
> section_addresses = SUFFIX (locate_sections) (kernel_path,
> sections, section_entsize,
> - num_sections, strtab,
> + num_sections, strtab,
> target_address,
> exec_size, kernel_sz, align,
> image_target);
>
> @@ -1530,9 +1551,9 @@ SUFFIX (load_image) (const char *kernel_path, size_t
> *exec_size,
> for (i = 0; i < num_sections; i++)
> section_vaddresses[i] = section_addresses[i] +
> image_target->vaddr_offset;
>
> - if (!grub_image_needs_reloc(image_target))
> + if (!grub_image_needs_reloc(image_target) ||
> grub_image_needs_abs_reloc(image_target))
> {
> - Elf_Addr current_address = *kernel_sz;
> + Elf_Addr current_address = target_address + *kernel_sz;
>
> for (i = 0, s = sections;
> i < num_sections;
> @@ -1558,11 +1579,16 @@ SUFFIX (load_image) (const char *kernel_path, size_t
> *exec_size,
> section_vaddresses[i] = current_address
> + image_target->vaddr_offset;
> current_address += grub_host_to_target_addr (s->sh_size);
> +
> + if (!bss_addr)
> + bss_addr = section_vaddresses[i];
> }
> current_address = ALIGN_UP (current_address +
> image_target->vaddr_offset,
> image_target->section_align)
> - image_target->vaddr_offset;
> - *bss_size = current_address - *kernel_sz;
> + *bss_size = current_address - *kernel_sz - target_address;
> + grub_util_info ("locating bss at 0x%x-0x%x (0x%x bytes)",
> + (int)bss_addr, (int)(bss_addr + *bss_size),
> (int)*bss_size);
> }
> else
> *bss_size = 0;
> @@ -1603,6 +1629,7 @@ SUFFIX (load_image) (const char *kernel_path, size_t
> *exec_size,
> (char *) out_img + ia64jmp_off,
> ia64jmp_off
> + image_target->vaddr_offset,
> + bss_addr, *bss_size,
> image_target);
> if (*start == INVALID_START_ADDR)
> grub_util_error ("start symbol is not defined");
> @@ -1612,17 +1639,18 @@ SUFFIX (load_image) (const char *kernel_path, size_t
> *exec_size,
> /* Resolve addresses in the virtual address space. */
> SUFFIX (relocate_addresses) (e, sections, section_addresses,
> section_entsize,
> - num_sections, strtab,
> + num_sections, strtab, target_address,
> out_img, tramp_off, ia64_got_off,
> image_target);
>
> - *reloc_size = SUFFIX (make_reloc_section) (e, reloc_section,
> - section_vaddresses, sections,
> - section_entsize, num_sections,
> - strtab, ia64jmp_off
> - + image_target->vaddr_offset,
> - 2 * ia64jmpnum + (got / 8),
> - image_target);
> + if (!grub_image_needs_abs_reloc(image_target))
> + *reloc_size = SUFFIX (make_reloc_section) (e, reloc_section,
> + section_vaddresses,
> sections,
> + section_entsize,
> num_sections,
> + strtab, ia64jmp_off
> + +
> image_target->vaddr_offset,
> + 2 * ia64jmpnum + (got / 8),
> + image_target);
The above is only indentation changes?
> }
>
> for (i = 0, s = sections;
> @@ -1632,10 +1660,10 @@ SUFFIX (load_image) (const char *kernel_path, size_t
> *exec_size,
> || SUFFIX (is_text_section) (s, image_target))
> {
> if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS)
> - memset (out_img + section_addresses[i], 0,
> + memset (out_img + section_addresses[i] - target_address, 0,
> grub_host_to_target_addr (s->sh_size));
> else
> - memcpy (out_img + section_addresses[i],
> + memcpy (out_img + section_addresses[i] - target_address,
> kernel_img + grub_host_to_target_addr (s->sh_offset),
> grub_host_to_target_addr (s->sh_size));
> }
> diff --git a/util/mkimage.c b/util/mkimage.c
> index 645e296..7b29acf 100644
> --- a/util/mkimage.c
> +++ b/util/mkimage.c
> @@ -74,6 +74,7 @@ struct grub_install_image_target_desc
> PLATFORM_FLAGS_NONE = 0,
> PLATFORM_FLAGS_DECOMPRESSORS = 2,
> PLATFORM_FLAGS_MODULES_BEFORE_KERNEL = 4,
> + PLATFORM_FLAGS_ABS_RELOC = 8,
> } flags;
> unsigned total_module_size;
> unsigned decompressor_compressed_size;
> @@ -922,11 +923,16 @@ grub_arm_reloc_jump24 (grub_uint32_t *target,
> Elf32_Addr sym_addr)
> return GRUB_ERR_NONE;
> }
>
> +static int grub_image_needs_abs_reloc(const struct
> grub_install_image_target_desc *target)
> +{
> + return target->flags & PLATFORM_FLAGS_ABS_RELOC;
> +}
> +
> static int grub_image_needs_reloc(const struct
> grub_install_image_target_desc *target)
> {
> if (target->id == IMAGE_EFI)
> return 1;
> - return 0;
> + return grub_image_needs_abs_reloc(target);
> }
>
> #pragma GCC diagnostic ignored "-Wcast-align"
> @@ -987,7 +993,8 @@ grub_install_get_image_targets_string (void)
>
> void
> grub_install_generate_image (const char *dir, const char *prefix,
> - FILE *out, const char *outname, char *mods[],
> + FILE *out, grub_uint64_t target_address,
> + const char *outname, char *mods[],
> char *memdisk_path, char **pubkey_paths,
> size_t npubkeys, char *config_path,
> const struct grub_install_image_target_desc
> *image_target,
> @@ -1024,6 +1031,13 @@ grub_install_generate_image (const char *dir, const
> char *prefix,
> else
> total_module_size = sizeof (struct grub_module_info32);
>
> + if (!target_address && grub_image_needs_abs_reloc(image_target))
> + {
> + grub_util_info ("Using default target address 0x%llx",
> + (unsigned long long)image_target->link_addr);
> + target_address = image_target->link_addr;
> + }
> +
> {
> size_t i;
> for (i = 0; i < npubkeys; i++)
> @@ -1069,11 +1083,13 @@ grub_install_generate_image (const char *dir, const
> char *prefix,
>
> if (image_target->voidp_sizeof == 4)
> kernel_img = load_image32 (kernel_path, &exec_size, &kernel_size,
> &bss_size,
> - total_module_size, &start_address, &rel_section,
> + total_module_size, target_address,
> + &start_address, &rel_section,
> &reloc_size, &align, image_target);
> else
> kernel_img = load_image64 (kernel_path, &exec_size, &kernel_size,
> &bss_size,
> - total_module_size, &start_address, &rel_section,
> + total_module_size, target_address,
> + &start_address, &rel_section,
> &reloc_size, &align, image_target);
> if (image_target->id == IMAGE_XEN && align < 4096)
> align = 4096;
> --
> 1.8.4.rc3
>
- [PATCH 0/7] arm-uboot: support for different RAM bases, Ian Campbell, 2013/12/29
- [PATCH 2/7] mkimage: Replace hardcoded 0x400 in R_ARM_ABS32 relocation, Ian Campbell, 2013/12/29
- [PATCH 1/7] mkimage: Refactor IMAGE_EFI checks into a function grub_image_needs_reloc., Ian Campbell, 2013/12/29
- [PATCH 3/7] mkimage: account for space for trampolines earlier, Ian Campbell, 2013/12/29
- [PATCH 4/7] mkimage: make R_ARM_ABS32 debug output more consistent, Ian Campbell, 2013/12/29
- [PATCH 5/7] mkimage: allow linking at address 0, Ian Campbell, 2013/12/29
- [PATCH 6/7] mkimage: support images which require full relocation at mkimage time., Ian Campbell, 2013/12/29
- [PATCH 7/7] arm-uboot: support relocation at installation time, Ian Campbell, 2013/12/29
- Re: [PATCH 0/7] arm-uboot: support for different RAM bases, Ian Campbell, 2013/12/29
- Re: [PATCH 0/7] arm-uboot: support for different RAM bases, Leif Lindholm, 2013/12/29
- Re: [PATCH 0/7] arm-uboot: support for different RAM bases, Vladimir 'φ-coder/phcoder' Serbinenko, 2013/12/29