18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) Paul Mackerras 1997.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Updates for PPC64 by Todd Inglett, Dave Engebretsen & Peter Bergner.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci#include <stdarg.h>
88c2ecf20Sopenharmony_ci#include <stddef.h>
98c2ecf20Sopenharmony_ci#include "elf.h"
108c2ecf20Sopenharmony_ci#include "page.h"
118c2ecf20Sopenharmony_ci#include "string.h"
128c2ecf20Sopenharmony_ci#include "stdio.h"
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ciint parse_elf64(void *hdr, struct elf_info *info)
158c2ecf20Sopenharmony_ci{
168c2ecf20Sopenharmony_ci	Elf64_Ehdr *elf64 = hdr;
178c2ecf20Sopenharmony_ci	Elf64_Phdr *elf64ph;
188c2ecf20Sopenharmony_ci	unsigned int i;
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci	if (!(elf64->e_ident[EI_MAG0]  == ELFMAG0	&&
218c2ecf20Sopenharmony_ci	      elf64->e_ident[EI_MAG1]  == ELFMAG1	&&
228c2ecf20Sopenharmony_ci	      elf64->e_ident[EI_MAG2]  == ELFMAG2	&&
238c2ecf20Sopenharmony_ci	      elf64->e_ident[EI_MAG3]  == ELFMAG3	&&
248c2ecf20Sopenharmony_ci	      elf64->e_ident[EI_CLASS] == ELFCLASS64	&&
258c2ecf20Sopenharmony_ci#ifdef __LITTLE_ENDIAN__
268c2ecf20Sopenharmony_ci	      elf64->e_ident[EI_DATA]  == ELFDATA2LSB	&&
278c2ecf20Sopenharmony_ci#else
288c2ecf20Sopenharmony_ci	      elf64->e_ident[EI_DATA]  == ELFDATA2MSB	&&
298c2ecf20Sopenharmony_ci#endif
308c2ecf20Sopenharmony_ci	      (elf64->e_type            == ET_EXEC ||
318c2ecf20Sopenharmony_ci	       elf64->e_type            == ET_DYN)	&&
328c2ecf20Sopenharmony_ci	      elf64->e_machine         == EM_PPC64))
338c2ecf20Sopenharmony_ci		return 0;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
368c2ecf20Sopenharmony_ci				 (unsigned long)elf64->e_phoff);
378c2ecf20Sopenharmony_ci	for (i = 0; i < (unsigned int)elf64->e_phnum; i++, elf64ph++)
388c2ecf20Sopenharmony_ci		if (elf64ph->p_type == PT_LOAD)
398c2ecf20Sopenharmony_ci			break;
408c2ecf20Sopenharmony_ci	if (i >= (unsigned int)elf64->e_phnum)
418c2ecf20Sopenharmony_ci		return 0;
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	info->loadsize = (unsigned long)elf64ph->p_filesz;
448c2ecf20Sopenharmony_ci	info->memsize = (unsigned long)elf64ph->p_memsz;
458c2ecf20Sopenharmony_ci	info->elfoffset = (unsigned long)elf64ph->p_offset;
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	return 1;
488c2ecf20Sopenharmony_ci}
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ciint parse_elf32(void *hdr, struct elf_info *info)
518c2ecf20Sopenharmony_ci{
528c2ecf20Sopenharmony_ci	Elf32_Ehdr *elf32 = hdr;
538c2ecf20Sopenharmony_ci	Elf32_Phdr *elf32ph;
548c2ecf20Sopenharmony_ci	unsigned int i;
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	if (!(elf32->e_ident[EI_MAG0]  == ELFMAG0	&&
578c2ecf20Sopenharmony_ci	      elf32->e_ident[EI_MAG1]  == ELFMAG1	&&
588c2ecf20Sopenharmony_ci	      elf32->e_ident[EI_MAG2]  == ELFMAG2	&&
598c2ecf20Sopenharmony_ci	      elf32->e_ident[EI_MAG3]  == ELFMAG3	&&
608c2ecf20Sopenharmony_ci	      elf32->e_ident[EI_CLASS] == ELFCLASS32	&&
618c2ecf20Sopenharmony_ci	      elf32->e_ident[EI_DATA]  == ELFDATA2MSB	&&
628c2ecf20Sopenharmony_ci	      (elf32->e_type            == ET_EXEC ||
638c2ecf20Sopenharmony_ci	       elf32->e_type            == ET_DYN)      &&
648c2ecf20Sopenharmony_ci	      elf32->e_machine         == EM_PPC))
658c2ecf20Sopenharmony_ci		return 0;
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	elf32ph = (Elf32_Phdr *) ((unsigned long)elf32 + elf32->e_phoff);
688c2ecf20Sopenharmony_ci	for (i = 0; i < elf32->e_phnum; i++, elf32ph++)
698c2ecf20Sopenharmony_ci		if (elf32ph->p_type == PT_LOAD)
708c2ecf20Sopenharmony_ci			break;
718c2ecf20Sopenharmony_ci	if (i >= elf32->e_phnum)
728c2ecf20Sopenharmony_ci		return 0;
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	info->loadsize = elf32ph->p_filesz;
758c2ecf20Sopenharmony_ci	info->memsize = elf32ph->p_memsz;
768c2ecf20Sopenharmony_ci	info->elfoffset = elf32ph->p_offset;
778c2ecf20Sopenharmony_ci	return 1;
788c2ecf20Sopenharmony_ci}
79