/* Calculate the amount of memory spanned by the segments. */ grub_size_t grub_elf32_size (grub_elf_t elf, Elf32_Addr *base, grub_uint32_t *max_align) { Elf32_Addr segments_start = (Elf32_Addr) -1; Elf32_Addr segments_end = 0; int nr_phdrs = 0; grub_uint32_t curr_align = 1; /* Run through the program headers to calculate the total memory size we * should claim. */ auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf32_Phdr *phdr, void *_arg); int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)), Elf32_Phdr *phdr, void *_arg __attribute__ ((unused))) { /* Only consider loadable segments. */ if (phdr->p_type != PT_LOAD) return 0; nr_phdrs++; if (phdr->p_paddr < segments_start) segments_start = phdr->p_paddr; if (phdr->p_paddr + phdr->p_memsz > segments_end) segments_end = phdr->p_paddr + phdr->p_memsz; if (curr_align < phdr->p_align) curr_align = phdr->p_align; return 0; } grub_elf32_phdr_iterate (elf, calcsize, 0); if (base) *base = 0; if (nr_phdrs == 0) { grub_error (GRUB_ERR_BAD_OS, "no program headers present"); return 0; } if (segments_end < segments_start) { /* Very bad addresses. */ grub_error (GRUB_ERR_BAD_OS, "bad program header load addresses"); return 0; } if (base) *base = segments_start; if (max_align) *max_align = curr_align; return segments_end - segments_start; }
"couldn't read segment from file: " "wanted 0x%lx bytes; read 0x%lx bytes", phdr->p_filesz, read); } } if (phdr->p_filesz < phdr->p_memsz) grub_memset ((void *) (long) (load_addr + phdr->p_filesz), 0, phdr->p_memsz - phdr->p_filesz); load_size += phdr->p_memsz; return 0; } err = grub_elf32_phdr_iterate (_elf, grub_elf32_load_segment, _load_hook); if (base) *base = load_base; if (size) *size = load_size; return err; } /* 64-bit */ int grub_elf_is_elf64 (grub_elf_t elf)