#include <grub/cache.h>
#include <grub/i18n.h>
+#ifdef GRUB_MACHINE_EFI
+#include <grub/efi/memory.h>
+#endif
+
/* Platforms where modules are in a readonly area of memory. */
#if defined(GRUB_MACHINE_QEMU)
#define GRUB_MODULES_MACHINE_READONLY
#endif
-\f
+#ifdef GRUB_MACHINE_EFI
+#define DL_ALIGN GRUB_EFI_PAGE_SIZE
+#else
+#define DL_ALIGN 1
+#endif
#pragma GCC diagnostic ignored "-Wcast-align"
{
unsigned i;
const Elf_Shdr *s;
- grub_size_t tsize = 0, talign = 1;
+ grub_size_t tsize = 0, talign = 1, arch_addralign = 1;
#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \
!defined (__loongarch__)
grub_size_t tramp;
+ grub_size_t tramp_align;
grub_size_t got;
+ grub_size_t got_align;
grub_err_t err;
#endif
char *ptr;
+ arch_addralign = DL_ALIGN;
+
for (i = 0, s = (const Elf_Shdr *)((const char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (const Elf_Shdr *)((const char *) s + e->e_shentsize))
{
+ grub_size_t sh_addralign;
+ grub_size_t sh_size;
+
if (s->sh_size == 0 || !(s->sh_flags & SHF_ALLOC))
continue;
- tsize = ALIGN_UP (tsize, s->sh_addralign) + s->sh_size;
- if (talign < s->sh_addralign)
- talign = s->sh_addralign;
+ sh_addralign = ALIGN_UP (s->sh_addralign, arch_addralign);
+ sh_size = ALIGN_UP (s->sh_size, sh_addralign);
+
+ tsize = ALIGN_UP (tsize, sh_addralign) + sh_size;
+ talign = grub_max (talign, sh_addralign);
}
#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \
err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got);
if (err)
return err;
- tsize += ALIGN_UP (tramp, GRUB_ARCH_DL_TRAMP_ALIGN);
- if (talign < GRUB_ARCH_DL_TRAMP_ALIGN)
- talign = GRUB_ARCH_DL_TRAMP_ALIGN;
- tsize += ALIGN_UP (got, GRUB_ARCH_DL_GOT_ALIGN);
- if (talign < GRUB_ARCH_DL_GOT_ALIGN)
- talign = GRUB_ARCH_DL_GOT_ALIGN;
+ tramp_align = grub_max (GRUB_ARCH_DL_TRAMP_ALIGN, arch_addralign);
+ tsize += ALIGN_UP (tramp, tramp_align);
+ talign = grub_max (talign, tramp_align);
+ got_align = grub_max (GRUB_ARCH_DL_GOT_ALIGN, arch_addralign);
+ tsize += ALIGN_UP (got, got_align);
+ talign = grub_max (talign, got_align);
#endif
#ifdef GRUB_MACHINE_EMU
i < e->e_shnum;
i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
{
+ grub_size_t sh_addralign = ALIGN_UP (s->sh_addralign, arch_addralign);
+ grub_size_t sh_size = ALIGN_UP (s->sh_size, sh_addralign);
+
if (s->sh_flags & SHF_ALLOC)
{
grub_dl_segment_t seg;
{
void *addr;
- ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, s->sh_addralign);
+ ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, sh_addralign);
addr = ptr;
- ptr += s->sh_size;
+ ptr += sh_size;
switch (s->sh_type)
{
case SHT_PROGBITS:
grub_memcpy (addr, (char *) e + s->sh_offset, s->sh_size);
+ grub_memset ((char *) addr + s->sh_size, 0, sh_size - s->sh_size);
break;
case SHT_NOBITS:
- grub_memset (addr, 0, s->sh_size);
+ grub_memset (addr, 0, sh_size);
break;
}
else
seg->addr = 0;
- seg->size = s->sh_size;
+ seg->size = sh_size;
seg->section = i;
seg->next = mod->segment;
mod->segment = seg;
}
#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \
!defined (__loongarch__)
- ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN);
+ ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, tramp_align);
mod->tramp = ptr;
mod->trampptr = ptr;
ptr += tramp;
- ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_GOT_ALIGN);
+ ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, got_align);
mod->got = ptr;
mod->gotptr = ptr;
ptr += got;