mkimage: refactor a bunch of section data into a struct.
This basically moves a bunch of the section information we pass around a lot into a struct, and passes a pointer to a single one of those instead. This shouldn't change the binary file output or the "grub-mkimage -v" output in any way. Signed-off-by: Peter Jones <pjones@redhat.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
parent
e30de94926
commit
7542af695f
1 changed files with 115 additions and 146 deletions
|
@ -93,6 +93,17 @@ struct fixup_block_list
|
||||||
|
|
||||||
#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof))
|
#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof))
|
||||||
|
|
||||||
|
struct section_metadata
|
||||||
|
{
|
||||||
|
Elf_Half num_sections;
|
||||||
|
Elf_Shdr *sections;
|
||||||
|
Elf_Addr *addrs;
|
||||||
|
Elf_Addr *vaddrs;
|
||||||
|
Elf_Half section_entsize;
|
||||||
|
Elf_Shdr *symtab;
|
||||||
|
const char *strtab;
|
||||||
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
is_relocatable (const struct grub_install_image_target_desc *image_target)
|
is_relocatable (const struct grub_install_image_target_desc *image_target)
|
||||||
{
|
{
|
||||||
|
@ -508,9 +519,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
|
||||||
/* Relocate symbols; note that this function overwrites the symbol table.
|
/* Relocate symbols; note that this function overwrites the symbol table.
|
||||||
Return the address of a start symbol. */
|
Return the address of a start symbol. */
|
||||||
static Elf_Addr
|
static Elf_Addr
|
||||||
SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections,
|
SUFFIX (relocate_symbols) (Elf_Ehdr *e, struct section_metadata *smd,
|
||||||
Elf_Shdr *symtab_section, Elf_Addr *section_vaddresses,
|
|
||||||
Elf_Half section_entsize, Elf_Half num_sections,
|
|
||||||
void *jumpers, Elf_Addr jumpers_addr,
|
void *jumpers, Elf_Addr jumpers_addr,
|
||||||
Elf_Addr bss_start, Elf_Addr end,
|
Elf_Addr bss_start, Elf_Addr end,
|
||||||
const struct grub_install_image_target_desc *image_target)
|
const struct grub_install_image_target_desc *image_target)
|
||||||
|
@ -520,19 +529,18 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections,
|
||||||
Elf_Addr start_address = (Elf_Addr) -1;
|
Elf_Addr start_address = (Elf_Addr) -1;
|
||||||
Elf_Sym *sym;
|
Elf_Sym *sym;
|
||||||
Elf_Word i;
|
Elf_Word i;
|
||||||
Elf_Shdr *symtab_link_section;
|
Elf_Shdr *symtab_section;
|
||||||
const char *symtab;
|
const char *symtab;
|
||||||
grub_uint64_t *jptr = jumpers;
|
grub_uint64_t *jptr = jumpers;
|
||||||
|
|
||||||
symtab_link_section
|
symtab_section = (Elf_Shdr *) ((char *) smd->sections
|
||||||
= (Elf_Shdr *) ((char *) sections
|
+ grub_target_to_host32 (smd->symtab->sh_link)
|
||||||
+ (grub_target_to_host32 (symtab_section->sh_link)
|
* smd->section_entsize);
|
||||||
* section_entsize));
|
symtab = (char *) e + grub_target_to_host (symtab_section->sh_offset);
|
||||||
symtab = (char *) e + grub_target_to_host (symtab_link_section->sh_offset);
|
|
||||||
|
|
||||||
symtab_size = grub_target_to_host (symtab_section->sh_size);
|
symtab_size = grub_target_to_host (smd->symtab->sh_size);
|
||||||
sym_size = grub_target_to_host (symtab_section->sh_entsize);
|
sym_size = grub_target_to_host (smd->symtab->sh_entsize);
|
||||||
symtab_offset = grub_target_to_host (symtab_section->sh_offset);
|
symtab_offset = grub_target_to_host (smd->symtab->sh_offset);
|
||||||
num_syms = symtab_size / sym_size;
|
num_syms = symtab_size / sym_size;
|
||||||
|
|
||||||
for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset);
|
for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset);
|
||||||
|
@ -560,12 +568,12 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections,
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (cur_index >= num_sections)
|
else if (cur_index >= smd->num_sections)
|
||||||
grub_util_error ("section %d does not exist", cur_index);
|
grub_util_error ("section %d does not exist", cur_index);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sym->st_value = (grub_target_to_host (sym->st_value)
|
sym->st_value = (grub_target_to_host (sym->st_value)
|
||||||
+ section_vaddresses[cur_index]);
|
+ smd->vaddrs[cur_index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image_target->elf_target == EM_IA_64 && ELF_ST_TYPE (sym->st_info)
|
if (image_target->elf_target == EM_IA_64 && ELF_ST_TYPE (sym->st_info)
|
||||||
|
@ -580,7 +588,7 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections,
|
||||||
grub_util_info ("locating %s at 0x%" GRUB_HOST_PRIxLONG_LONG
|
grub_util_info ("locating %s at 0x%" GRUB_HOST_PRIxLONG_LONG
|
||||||
" (0x%" GRUB_HOST_PRIxLONG_LONG ")", name,
|
" (0x%" GRUB_HOST_PRIxLONG_LONG ")", name,
|
||||||
(unsigned long long) sym->st_value,
|
(unsigned long long) sym->st_value,
|
||||||
(unsigned long long) section_vaddresses[cur_index]);
|
(unsigned long long) smd->vaddrs[cur_index]);
|
||||||
|
|
||||||
if (start_address == (Elf_Addr)-1)
|
if (start_address == (Elf_Addr)-1)
|
||||||
if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0)
|
if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0)
|
||||||
|
@ -722,12 +730,8 @@ arm_get_trampoline_size (Elf_Ehdr *e,
|
||||||
addresses can be fully resolved. Absolute addresses must be relocated
|
addresses can be fully resolved. Absolute addresses must be relocated
|
||||||
again by a PE32 relocator when loaded. */
|
again by a PE32 relocator when loaded. */
|
||||||
static void
|
static void
|
||||||
SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections,
|
SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd,
|
||||||
Elf_Addr *section_addresses,
|
char *pe_target, Elf_Addr tramp_off, Elf_Addr got_off,
|
||||||
Elf_Half section_entsize, Elf_Half num_sections,
|
|
||||||
const char *strtab,
|
|
||||||
char *pe_target, Elf_Addr tramp_off,
|
|
||||||
Elf_Addr got_off,
|
|
||||||
const struct grub_install_image_target_desc *image_target)
|
const struct grub_install_image_target_desc *image_target)
|
||||||
{
|
{
|
||||||
Elf_Half i;
|
Elf_Half i;
|
||||||
|
@ -741,33 +745,29 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections,
|
||||||
grub_uint32_t *tr = (void *) (pe_target + tramp_off);
|
grub_uint32_t *tr = (void *) (pe_target + tramp_off);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0, s = sections;
|
for (i = 0, s = smd->sections;
|
||||||
i < num_sections;
|
i < smd->num_sections;
|
||||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
|
||||||
if ((s->sh_type == grub_host_to_target32 (SHT_REL)) ||
|
if ((s->sh_type == grub_host_to_target32 (SHT_REL)) ||
|
||||||
(s->sh_type == grub_host_to_target32 (SHT_RELA)))
|
(s->sh_type == grub_host_to_target32 (SHT_RELA)))
|
||||||
{
|
{
|
||||||
Elf_Rela *r;
|
Elf_Rela *r;
|
||||||
Elf_Word rtab_size, r_size, num_rs;
|
Elf_Word rtab_size, r_size, num_rs;
|
||||||
Elf_Off rtab_offset;
|
Elf_Off rtab_offset;
|
||||||
Elf_Shdr *symtab_section;
|
|
||||||
Elf_Word target_section_index;
|
Elf_Word target_section_index;
|
||||||
Elf_Addr target_section_addr;
|
Elf_Addr target_section_addr;
|
||||||
Elf_Shdr *target_section;
|
Elf_Shdr *target_section;
|
||||||
Elf_Word j;
|
Elf_Word j;
|
||||||
|
|
||||||
symtab_section = (Elf_Shdr *) ((char *) sections
|
|
||||||
+ (grub_target_to_host32 (s->sh_link)
|
|
||||||
* section_entsize));
|
|
||||||
target_section_index = grub_target_to_host32 (s->sh_info);
|
target_section_index = grub_target_to_host32 (s->sh_info);
|
||||||
target_section_addr = section_addresses[target_section_index];
|
target_section_addr = smd->addrs[target_section_index];
|
||||||
target_section = (Elf_Shdr *) ((char *) sections
|
target_section = (Elf_Shdr *) ((char *) smd->sections
|
||||||
+ (target_section_index
|
+ (target_section_index
|
||||||
* section_entsize));
|
* smd->section_entsize));
|
||||||
|
|
||||||
grub_util_info ("dealing with the relocation section %s for %s",
|
grub_util_info ("dealing with the relocation section %s for %s",
|
||||||
strtab + grub_target_to_host32 (s->sh_name),
|
smd->strtab + grub_target_to_host32 (s->sh_name),
|
||||||
strtab + grub_target_to_host32 (target_section->sh_name));
|
smd->strtab + grub_target_to_host32 (target_section->sh_name));
|
||||||
|
|
||||||
rtab_size = grub_target_to_host (s->sh_size);
|
rtab_size = grub_target_to_host (s->sh_size);
|
||||||
r_size = grub_target_to_host (s->sh_entsize);
|
r_size = grub_target_to_host (s->sh_entsize);
|
||||||
|
@ -788,7 +788,7 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections,
|
||||||
target = SUFFIX (get_target_address) (e, target_section,
|
target = SUFFIX (get_target_address) (e, target_section,
|
||||||
offset, image_target);
|
offset, image_target);
|
||||||
info = grub_target_to_host (r->r_info);
|
info = grub_target_to_host (r->r_info);
|
||||||
sym_addr = SUFFIX (get_symbol_address) (e, symtab_section,
|
sym_addr = SUFFIX (get_symbol_address) (e, smd->symtab,
|
||||||
ELF_R_SYM (info), image_target);
|
ELF_R_SYM (info), image_target);
|
||||||
|
|
||||||
addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ?
|
addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ?
|
||||||
|
@ -919,8 +919,8 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections,
|
||||||
Elf_Sym *sym;
|
Elf_Sym *sym;
|
||||||
|
|
||||||
sym = (Elf_Sym *) ((char *) e
|
sym = (Elf_Sym *) ((char *) e
|
||||||
+ grub_target_to_host (symtab_section->sh_offset)
|
+ grub_target_to_host (smd->symtab->sh_offset)
|
||||||
+ ELF_R_SYM (info) * grub_target_to_host (symtab_section->sh_entsize));
|
+ ELF_R_SYM (info) * grub_target_to_host (smd->symtab->sh_entsize));
|
||||||
if (ELF_ST_TYPE (sym->st_info) == STT_FUNC)
|
if (ELF_ST_TYPE (sym->st_info) == STT_FUNC)
|
||||||
sym_addr = grub_target_to_host64 (*(grub_uint64_t *) (pe_target
|
sym_addr = grub_target_to_host64 (*(grub_uint64_t *) (pe_target
|
||||||
+ sym->st_value
|
+ sym->st_value
|
||||||
|
@ -1105,8 +1105,8 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections,
|
||||||
- (char *) e),
|
- (char *) e),
|
||||||
sym_addr);
|
sym_addr);
|
||||||
sym = (Elf_Sym *) ((char *) e
|
sym = (Elf_Sym *) ((char *) e
|
||||||
+ grub_target_to_host (symtab_section->sh_offset)
|
+ grub_target_to_host (smd->symtab->sh_offset)
|
||||||
+ ELF_R_SYM (info) * grub_target_to_host (symtab_section->sh_entsize));
|
+ ELF_R_SYM (info) * grub_target_to_host (smd->symtab->sh_entsize));
|
||||||
if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
|
if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
|
||||||
sym_addr |= 1;
|
sym_addr |= 1;
|
||||||
if (!(sym_addr & 1))
|
if (!(sym_addr & 1))
|
||||||
|
@ -1644,9 +1644,7 @@ create_u64_fixups (struct translate_context *ctx,
|
||||||
/* Make a .reloc section. */
|
/* Make a .reloc section. */
|
||||||
static void
|
static void
|
||||||
make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout,
|
make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout,
|
||||||
Elf_Addr *section_vaddresses, Elf_Shdr *sections,
|
struct section_metadata *smd,
|
||||||
Elf_Half section_entsize, Elf_Half num_sections,
|
|
||||||
const char *strtab,
|
|
||||||
const struct grub_install_image_target_desc *image_target)
|
const struct grub_install_image_target_desc *image_target)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
@ -1655,8 +1653,8 @@ make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout,
|
||||||
|
|
||||||
translate_reloc_start (&ctx, image_target);
|
translate_reloc_start (&ctx, image_target);
|
||||||
|
|
||||||
for (i = 0, s = sections; i < num_sections;
|
for (i = 0, s = smd->sections; i < smd->num_sections;
|
||||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
|
||||||
if ((grub_target_to_host32 (s->sh_type) == SHT_REL) ||
|
if ((grub_target_to_host32 (s->sh_type) == SHT_REL) ||
|
||||||
(grub_target_to_host32 (s->sh_type) == SHT_RELA))
|
(grub_target_to_host32 (s->sh_type) == SHT_RELA))
|
||||||
{
|
{
|
||||||
|
@ -1667,14 +1665,14 @@ make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout,
|
||||||
Elf_Word j;
|
Elf_Word j;
|
||||||
|
|
||||||
grub_util_info ("translating the relocation section %s",
|
grub_util_info ("translating the relocation section %s",
|
||||||
strtab + grub_le_to_cpu32 (s->sh_name));
|
smd->strtab + grub_le_to_cpu32 (s->sh_name));
|
||||||
|
|
||||||
rtab_size = grub_target_to_host (s->sh_size);
|
rtab_size = grub_target_to_host (s->sh_size);
|
||||||
r_size = grub_target_to_host (s->sh_entsize);
|
r_size = grub_target_to_host (s->sh_entsize);
|
||||||
rtab_offset = grub_target_to_host (s->sh_offset);
|
rtab_offset = grub_target_to_host (s->sh_offset);
|
||||||
num_rs = rtab_size / r_size;
|
num_rs = rtab_size / r_size;
|
||||||
|
|
||||||
section_address = section_vaddresses[grub_le_to_cpu32 (s->sh_info)];
|
section_address = smd->vaddrs[grub_le_to_cpu32 (s->sh_info)];
|
||||||
|
|
||||||
for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset);
|
for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset);
|
||||||
j < num_rs;
|
j < num_rs;
|
||||||
|
@ -1761,12 +1759,11 @@ SUFFIX (check_elf_header) (Elf_Ehdr *e, size_t size, const struct grub_install_i
|
||||||
static Elf_Addr
|
static Elf_Addr
|
||||||
SUFFIX (put_section) (Elf_Shdr *s, int i,
|
SUFFIX (put_section) (Elf_Shdr *s, int i,
|
||||||
Elf_Addr current_address,
|
Elf_Addr current_address,
|
||||||
Elf_Addr *section_addresses,
|
struct section_metadata *smd,
|
||||||
const char *strtab,
|
|
||||||
const struct grub_install_image_target_desc *image_target)
|
const struct grub_install_image_target_desc *image_target)
|
||||||
{
|
{
|
||||||
Elf_Word align = grub_host_to_target_addr (s->sh_addralign);
|
Elf_Word align = grub_host_to_target_addr (s->sh_addralign);
|
||||||
const char *name = strtab + grub_host_to_target32 (s->sh_name);
|
const char *name = smd->strtab + grub_host_to_target32 (s->sh_name);
|
||||||
|
|
||||||
if (align)
|
if (align)
|
||||||
current_address = ALIGN_UP (current_address + image_target->vaddr_offset,
|
current_address = ALIGN_UP (current_address + image_target->vaddr_offset,
|
||||||
|
@ -1778,8 +1775,8 @@ SUFFIX (put_section) (Elf_Shdr *s, int i,
|
||||||
name, (unsigned long long) current_address);
|
name, (unsigned long long) current_address);
|
||||||
if (!is_relocatable (image_target))
|
if (!is_relocatable (image_target))
|
||||||
current_address = grub_host_to_target_addr (s->sh_addr)
|
current_address = grub_host_to_target_addr (s->sh_addr)
|
||||||
- image_target->link_addr;
|
- image_target->link_addr;
|
||||||
section_addresses[i] = current_address;
|
smd->addrs[i] = current_address;
|
||||||
current_address += grub_host_to_target_addr (s->sh_size);
|
current_address += grub_host_to_target_addr (s->sh_size);
|
||||||
return current_address;
|
return current_address;
|
||||||
}
|
}
|
||||||
|
@ -1790,9 +1787,7 @@ SUFFIX (put_section) (Elf_Shdr *s, int i,
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
SUFFIX (locate_sections) (Elf_Ehdr *e, const char *kernel_path,
|
SUFFIX (locate_sections) (Elf_Ehdr *e, const char *kernel_path,
|
||||||
Elf_Shdr *sections, Elf_Half section_entsize,
|
struct section_metadata *smd,
|
||||||
Elf_Half num_sections, Elf_Addr *section_addresses,
|
|
||||||
Elf_Addr *section_vaddresses, const char *strtab,
|
|
||||||
struct grub_mkimage_layout *layout,
|
struct grub_mkimage_layout *layout,
|
||||||
const struct grub_install_image_target_desc *image_target)
|
const struct grub_install_image_target_desc *image_target)
|
||||||
{
|
{
|
||||||
|
@ -1804,28 +1799,23 @@ SUFFIX (locate_sections) (Elf_Ehdr *e, const char *kernel_path,
|
||||||
if (image_target->elf_target == EM_AARCH64)
|
if (image_target->elf_target == EM_AARCH64)
|
||||||
layout->align = 4096;
|
layout->align = 4096;
|
||||||
|
|
||||||
|
|
||||||
layout->kernel_size = 0;
|
layout->kernel_size = 0;
|
||||||
|
|
||||||
for (i = 0, s = sections;
|
for (i = 0, s = smd->sections;
|
||||||
i < num_sections;
|
i < smd->num_sections;
|
||||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
|
||||||
if ((grub_target_to_host (s->sh_flags) & SHF_ALLOC)
|
if ((grub_target_to_host (s->sh_flags) & SHF_ALLOC)
|
||||||
&& grub_host_to_target32 (s->sh_addralign) > layout->align)
|
&& grub_host_to_target32 (s->sh_addralign) > layout->align)
|
||||||
layout->align = grub_host_to_target32 (s->sh_addralign);
|
layout->align = grub_host_to_target32 (s->sh_addralign);
|
||||||
|
|
||||||
|
|
||||||
/* .text */
|
/* .text */
|
||||||
for (i = 0, s = sections;
|
for (i = 0, s = smd->sections;
|
||||||
i < num_sections;
|
i < smd->num_sections;
|
||||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
|
||||||
if (SUFFIX (is_text_section) (s, image_target))
|
if (SUFFIX (is_text_section) (s, image_target))
|
||||||
{
|
{
|
||||||
layout->kernel_size = SUFFIX (put_section) (s, i,
|
layout->kernel_size = SUFFIX (put_section) (s, i, layout->kernel_size,
|
||||||
layout->kernel_size,
|
smd, image_target);
|
||||||
section_addresses,
|
|
||||||
strtab,
|
|
||||||
image_target);
|
|
||||||
if (!is_relocatable (image_target) &&
|
if (!is_relocatable (image_target) &&
|
||||||
grub_host_to_target_addr (s->sh_addr) != image_target->link_addr)
|
grub_host_to_target_addr (s->sh_addr) != image_target->link_addr)
|
||||||
{
|
{
|
||||||
|
@ -1845,15 +1835,12 @@ SUFFIX (locate_sections) (Elf_Ehdr *e, const char *kernel_path,
|
||||||
layout->exec_size = layout->kernel_size;
|
layout->exec_size = layout->kernel_size;
|
||||||
|
|
||||||
/* .data */
|
/* .data */
|
||||||
for (i = 0, s = sections;
|
for (i = 0, s = smd->sections;
|
||||||
i < num_sections;
|
i < smd->num_sections;
|
||||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
|
||||||
if (SUFFIX (is_data_section) (s, image_target))
|
if (SUFFIX (is_data_section) (s, image_target))
|
||||||
layout->kernel_size = SUFFIX (put_section) (s, i,
|
layout->kernel_size = SUFFIX (put_section) (s, i, layout->kernel_size, smd,
|
||||||
layout->kernel_size,
|
image_target);
|
||||||
section_addresses,
|
|
||||||
strtab,
|
|
||||||
image_target);
|
|
||||||
|
|
||||||
#ifdef MKIMAGE_ELF32
|
#ifdef MKIMAGE_ELF32
|
||||||
if (image_target->elf_target == EM_ARM)
|
if (image_target->elf_target == EM_ARM)
|
||||||
|
@ -1864,8 +1851,8 @@ SUFFIX (locate_sections) (Elf_Ehdr *e, const char *kernel_path,
|
||||||
|
|
||||||
layout->kernel_size = ALIGN_UP (layout->kernel_size, 16);
|
layout->kernel_size = ALIGN_UP (layout->kernel_size, 16);
|
||||||
|
|
||||||
tramp = arm_get_trampoline_size (e, sections, section_entsize,
|
tramp = arm_get_trampoline_size (e, smd->sections, smd->section_entsize,
|
||||||
num_sections, image_target);
|
smd->num_sections, image_target);
|
||||||
|
|
||||||
layout->tramp_off = layout->kernel_size;
|
layout->tramp_off = layout->kernel_size;
|
||||||
layout->kernel_size += ALIGN_UP (tramp, 16);
|
layout->kernel_size += ALIGN_UP (tramp, 16);
|
||||||
|
@ -1876,18 +1863,17 @@ SUFFIX (locate_sections) (Elf_Ehdr *e, const char *kernel_path,
|
||||||
layout->end = layout->kernel_size;
|
layout->end = layout->kernel_size;
|
||||||
|
|
||||||
/* .bss */
|
/* .bss */
|
||||||
for (i = 0, s = sections;
|
for (i = 0, s = smd->sections;
|
||||||
i < num_sections;
|
i < smd->num_sections;
|
||||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize))
|
||||||
{
|
{
|
||||||
if (SUFFIX (is_bss_section) (s, image_target))
|
if (SUFFIX (is_bss_section) (s, image_target))
|
||||||
layout->end = SUFFIX (put_section) (s, i, layout->end,
|
layout->end = SUFFIX (put_section) (s, i, layout->end, smd, image_target);
|
||||||
section_addresses, strtab,
|
|
||||||
image_target);
|
|
||||||
/*
|
/*
|
||||||
* This must to be in the last time this function passes through the loop.
|
* This must to be in the last time this function passes through the loop.
|
||||||
*/
|
*/
|
||||||
section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset;
|
smd->vaddrs[i] = smd->addrs[i] + image_target->vaddr_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
layout->end = ALIGN_UP (layout->end + image_target->vaddr_offset,
|
layout->end = ALIGN_UP (layout->end + image_target->vaddr_offset,
|
||||||
|
@ -1908,18 +1894,12 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path,
|
||||||
const struct grub_install_image_target_desc *image_target)
|
const struct grub_install_image_target_desc *image_target)
|
||||||
{
|
{
|
||||||
char *kernel_img, *out_img;
|
char *kernel_img, *out_img;
|
||||||
const char *strtab;
|
struct section_metadata smd = { 0, };
|
||||||
Elf_Ehdr *e;
|
Elf_Ehdr *e;
|
||||||
Elf_Shdr *sections;
|
|
||||||
Elf_Addr *section_addresses;
|
|
||||||
Elf_Addr *section_vaddresses;
|
|
||||||
int i;
|
int i;
|
||||||
Elf_Shdr *s;
|
Elf_Shdr *s;
|
||||||
Elf_Half num_sections;
|
|
||||||
Elf_Off section_offset;
|
Elf_Off section_offset;
|
||||||
Elf_Half section_entsize;
|
|
||||||
grub_size_t kernel_size;
|
grub_size_t kernel_size;
|
||||||
Elf_Shdr *symtab_section = 0;
|
|
||||||
|
|
||||||
grub_memset (layout, 0, sizeof (*layout));
|
grub_memset (layout, 0, sizeof (*layout));
|
||||||
|
|
||||||
|
@ -1934,46 +1914,45 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path,
|
||||||
grub_util_error ("invalid ELF header");
|
grub_util_error ("invalid ELF header");
|
||||||
|
|
||||||
section_offset = grub_target_to_host (e->e_shoff);
|
section_offset = grub_target_to_host (e->e_shoff);
|
||||||
section_entsize = grub_target_to_host16 (e->e_shentsize);
|
smd.section_entsize = grub_target_to_host16 (e->e_shentsize);
|
||||||
num_sections = grub_target_to_host16 (e->e_shnum);
|
smd.num_sections = grub_target_to_host16 (e->e_shnum);
|
||||||
|
|
||||||
if (kernel_size < section_offset + (grub_uint32_t) section_entsize * num_sections)
|
if (kernel_size < section_offset
|
||||||
|
+ (grub_uint32_t) smd.section_entsize * smd.num_sections)
|
||||||
grub_util_error (_("premature end of file %s"), kernel_path);
|
grub_util_error (_("premature end of file %s"), kernel_path);
|
||||||
|
|
||||||
sections = (Elf_Shdr *) (kernel_img + section_offset);
|
smd.sections = (Elf_Shdr *) (kernel_img + section_offset);
|
||||||
|
|
||||||
/* Relocate sections then symbols in the virtual address space. */
|
/* Relocate sections then symbols in the virtual address space. */
|
||||||
s = (Elf_Shdr *) ((char *) sections
|
s = (Elf_Shdr *) ((char *) smd.sections
|
||||||
+ grub_host_to_target16 (e->e_shstrndx) * section_entsize);
|
+ grub_host_to_target16 (e->e_shstrndx) * smd.section_entsize);
|
||||||
strtab = (char *) e + grub_host_to_target_addr (s->sh_offset);
|
smd.strtab = (char *) e + grub_host_to_target_addr (s->sh_offset);
|
||||||
|
|
||||||
section_addresses = xmalloc (sizeof (*section_addresses) * num_sections);
|
smd.addrs = xmalloc (sizeof (*smd.addrs) * smd.num_sections);
|
||||||
memset (section_addresses, 0, sizeof (*section_addresses) * num_sections);
|
memset (smd.addrs, 0, sizeof (*smd.addrs) * smd.num_sections);
|
||||||
section_vaddresses = xmalloc (sizeof (*section_vaddresses) * num_sections);
|
smd.vaddrs = xmalloc (sizeof (*smd.vaddrs) * smd.num_sections);
|
||||||
memset (section_vaddresses, 0, sizeof (*section_vaddresses) * num_sections);
|
memset (smd.vaddrs, 0, sizeof (*smd.vaddrs) * smd.num_sections);
|
||||||
|
|
||||||
SUFFIX (locate_sections) (e, kernel_path, sections, section_entsize, num_sections,
|
SUFFIX (locate_sections) (e, kernel_path, &smd, layout, image_target);
|
||||||
section_addresses, section_vaddresses, strtab, layout,
|
|
||||||
image_target);
|
|
||||||
|
|
||||||
if (!is_relocatable (image_target))
|
if (!is_relocatable (image_target))
|
||||||
{
|
{
|
||||||
Elf_Addr current_address = layout->kernel_size;
|
Elf_Addr current_address = layout->kernel_size;
|
||||||
|
|
||||||
for (i = 0, s = sections;
|
for (i = 0, s = smd.sections;
|
||||||
i < num_sections;
|
i < smd.num_sections;
|
||||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize))
|
||||||
if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS)
|
if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS)
|
||||||
{
|
{
|
||||||
Elf_Word sec_align = grub_host_to_target_addr (s->sh_addralign);
|
Elf_Word sec_align = grub_host_to_target_addr (s->sh_addralign);
|
||||||
const char *name = strtab + grub_host_to_target32 (s->sh_name);
|
const char *name = smd.strtab + grub_host_to_target32 (s->sh_name);
|
||||||
|
|
||||||
if (sec_align)
|
if (sec_align)
|
||||||
current_address = ALIGN_UP (current_address
|
current_address = ALIGN_UP (current_address
|
||||||
+ image_target->vaddr_offset,
|
+ image_target->vaddr_offset,
|
||||||
sec_align)
|
sec_align)
|
||||||
- image_target->vaddr_offset;
|
- image_target->vaddr_offset;
|
||||||
|
|
||||||
grub_util_info ("locating the section %s at 0x%"
|
grub_util_info ("locating the section %s at 0x%"
|
||||||
GRUB_HOST_PRIxLONG_LONG,
|
GRUB_HOST_PRIxLONG_LONG,
|
||||||
name, (unsigned long long) current_address);
|
name, (unsigned long long) current_address);
|
||||||
|
@ -1981,7 +1960,7 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path,
|
||||||
current_address = grub_host_to_target_addr (s->sh_addr)
|
current_address = grub_host_to_target_addr (s->sh_addr)
|
||||||
- image_target->link_addr;
|
- image_target->link_addr;
|
||||||
|
|
||||||
section_vaddresses[i] = current_address
|
smd.vaddrs[i] = current_address
|
||||||
+ image_target->vaddr_offset;
|
+ image_target->vaddr_offset;
|
||||||
current_address += grub_host_to_target_addr (s->sh_size);
|
current_address += grub_host_to_target_addr (s->sh_size);
|
||||||
}
|
}
|
||||||
|
@ -2002,16 +1981,16 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path,
|
||||||
|
|
||||||
if (is_relocatable (image_target))
|
if (is_relocatable (image_target))
|
||||||
{
|
{
|
||||||
symtab_section = NULL;
|
smd.symtab = NULL;
|
||||||
for (i = 0, s = sections;
|
for (i = 0, s = smd.sections;
|
||||||
i < num_sections;
|
i < smd.num_sections;
|
||||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize))
|
||||||
if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB))
|
if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB))
|
||||||
{
|
{
|
||||||
symtab_section = s;
|
smd.symtab = s;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (! symtab_section)
|
if (! smd.symtab)
|
||||||
grub_util_error ("%s", _("no symbol table"));
|
grub_util_error ("%s", _("no symbol table"));
|
||||||
#ifdef MKIMAGE_ELF64
|
#ifdef MKIMAGE_ELF64
|
||||||
if (image_target->elf_target == EM_IA_64)
|
if (image_target->elf_target == EM_IA_64)
|
||||||
|
@ -2026,7 +2005,7 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path,
|
||||||
layout->kernel_size += ALIGN_UP (tramp, 16);
|
layout->kernel_size += ALIGN_UP (tramp, 16);
|
||||||
|
|
||||||
layout->ia64jmp_off = layout->kernel_size;
|
layout->ia64jmp_off = layout->kernel_size;
|
||||||
layout->ia64jmpnum = SUFFIX (count_funcs) (e, symtab_section,
|
layout->ia64jmpnum = SUFFIX (count_funcs) (e, smd.symtab,
|
||||||
image_target);
|
image_target);
|
||||||
layout->kernel_size += 16 * layout->ia64jmpnum;
|
layout->kernel_size += 16 * layout->ia64jmpnum;
|
||||||
|
|
||||||
|
@ -2057,31 +2036,19 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path,
|
||||||
|
|
||||||
if (is_relocatable (image_target))
|
if (is_relocatable (image_target))
|
||||||
{
|
{
|
||||||
layout->start_address = SUFFIX (relocate_symbols) (e, sections, symtab_section,
|
layout->start_address = SUFFIX (relocate_symbols) (e, &smd,
|
||||||
section_vaddresses, section_entsize,
|
(char *) out_img + layout->ia64jmp_off,
|
||||||
num_sections,
|
layout->ia64jmp_off + image_target->vaddr_offset,
|
||||||
(char *) out_img + layout->ia64jmp_off,
|
layout->bss_start, layout->end, image_target);
|
||||||
layout->ia64jmp_off
|
|
||||||
+ image_target->vaddr_offset,
|
|
||||||
layout->bss_start,
|
|
||||||
layout->end,
|
|
||||||
image_target);
|
|
||||||
if (layout->start_address == (Elf_Addr) -1)
|
if (layout->start_address == (Elf_Addr) -1)
|
||||||
grub_util_error ("start symbol is not defined");
|
grub_util_error ("start symbol is not defined");
|
||||||
|
|
||||||
/* Resolve addresses in the virtual address space. */
|
/* Resolve addrs in the virtual address space. */
|
||||||
SUFFIX (relocate_addresses) (e, sections, section_addresses,
|
SUFFIX (relocate_addrs) (e, &smd, out_img, layout->tramp_off,
|
||||||
section_entsize,
|
layout->got_off, image_target);
|
||||||
num_sections, strtab,
|
|
||||||
out_img, layout->tramp_off,
|
|
||||||
layout->got_off,
|
|
||||||
image_target);
|
|
||||||
|
|
||||||
make_reloc_section (e, layout,
|
make_reloc_section (e, layout, &smd, image_target);
|
||||||
section_vaddresses, sections,
|
|
||||||
section_entsize, num_sections,
|
|
||||||
strtab,
|
|
||||||
image_target);
|
|
||||||
if (image_target->id != IMAGE_EFI)
|
if (image_target->id != IMAGE_EFI)
|
||||||
{
|
{
|
||||||
out_img = xrealloc (out_img, layout->kernel_size + total_module_size
|
out_img = xrealloc (out_img, layout->kernel_size + total_module_size
|
||||||
|
@ -2093,9 +2060,9 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0, s = sections;
|
for (i = 0, s = smd.sections;
|
||||||
i < num_sections;
|
i < smd.num_sections;
|
||||||
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
|
i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize))
|
||||||
if (SUFFIX (is_data_section) (s, image_target)
|
if (SUFFIX (is_data_section) (s, image_target)
|
||||||
/* Explicitly initialize BSS
|
/* Explicitly initialize BSS
|
||||||
when producing PE32 to avoid a bug in EFI implementations.
|
when producing PE32 to avoid a bug in EFI implementations.
|
||||||
|
@ -2106,17 +2073,19 @@ SUFFIX (grub_mkimage_load_image) (const char *kernel_path,
|
||||||
|| SUFFIX (is_text_section) (s, image_target))
|
|| SUFFIX (is_text_section) (s, image_target))
|
||||||
{
|
{
|
||||||
if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS)
|
if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS)
|
||||||
memset (out_img + section_addresses[i], 0,
|
memset (out_img + smd.addrs[i], 0,
|
||||||
grub_host_to_target_addr (s->sh_size));
|
grub_host_to_target_addr (s->sh_size));
|
||||||
else
|
else
|
||||||
memcpy (out_img + section_addresses[i],
|
memcpy (out_img + smd.addrs[i],
|
||||||
kernel_img + grub_host_to_target_addr (s->sh_offset),
|
kernel_img + grub_host_to_target_addr (s->sh_offset),
|
||||||
grub_host_to_target_addr (s->sh_size));
|
grub_host_to_target_addr (s->sh_size));
|
||||||
}
|
}
|
||||||
free (kernel_img);
|
free (kernel_img);
|
||||||
|
|
||||||
free (section_vaddresses);
|
free (smd.vaddrs);
|
||||||
free (section_addresses);
|
smd.vaddrs = NULL;
|
||||||
|
free (smd.addrs);
|
||||||
|
smd.addrs = NULL;
|
||||||
|
|
||||||
return out_img;
|
return out_img;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue