162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) Paul Mackerras 1997.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Updates for PPC64 by Todd Inglett, Dave Engebretsen & Peter Bergner.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci#include <stdarg.h>
862306a36Sopenharmony_ci#include <stddef.h>
962306a36Sopenharmony_ci#include "elf.h"
1062306a36Sopenharmony_ci#include "page.h"
1162306a36Sopenharmony_ci#include "string.h"
1262306a36Sopenharmony_ci#include "stdio.h"
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ciint parse_elf64(void *hdr, struct elf_info *info)
1562306a36Sopenharmony_ci{
1662306a36Sopenharmony_ci	Elf64_Ehdr *elf64 = hdr;
1762306a36Sopenharmony_ci	Elf64_Phdr *elf64ph;
1862306a36Sopenharmony_ci	unsigned int i;
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci	if (!(elf64->e_ident[EI_MAG0]  == ELFMAG0	&&
2162306a36Sopenharmony_ci	      elf64->e_ident[EI_MAG1]  == ELFMAG1	&&
2262306a36Sopenharmony_ci	      elf64->e_ident[EI_MAG2]  == ELFMAG2	&&
2362306a36Sopenharmony_ci	      elf64->e_ident[EI_MAG3]  == ELFMAG3	&&
2462306a36Sopenharmony_ci	      elf64->e_ident[EI_CLASS] == ELFCLASS64	&&
2562306a36Sopenharmony_ci#ifdef __LITTLE_ENDIAN__
2662306a36Sopenharmony_ci	      elf64->e_ident[EI_DATA]  == ELFDATA2LSB	&&
2762306a36Sopenharmony_ci#else
2862306a36Sopenharmony_ci	      elf64->e_ident[EI_DATA]  == ELFDATA2MSB	&&
2962306a36Sopenharmony_ci#endif
3062306a36Sopenharmony_ci	      (elf64->e_type            == ET_EXEC ||
3162306a36Sopenharmony_ci	       elf64->e_type            == ET_DYN)	&&
3262306a36Sopenharmony_ci	      elf64->e_machine         == EM_PPC64))
3362306a36Sopenharmony_ci		return 0;
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
3662306a36Sopenharmony_ci				 (unsigned long)elf64->e_phoff);
3762306a36Sopenharmony_ci	for (i = 0; i < (unsigned int)elf64->e_phnum; i++, elf64ph++)
3862306a36Sopenharmony_ci		if (elf64ph->p_type == PT_LOAD)
3962306a36Sopenharmony_ci			break;
4062306a36Sopenharmony_ci	if (i >= (unsigned int)elf64->e_phnum)
4162306a36Sopenharmony_ci		return 0;
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	info->loadsize = (unsigned long)elf64ph->p_filesz;
4462306a36Sopenharmony_ci	info->memsize = (unsigned long)elf64ph->p_memsz;
4562306a36Sopenharmony_ci	info->elfoffset = (unsigned long)elf64ph->p_offset;
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	return 1;
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ciint parse_elf32(void *hdr, struct elf_info *info)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci	Elf32_Ehdr *elf32 = hdr;
5362306a36Sopenharmony_ci	Elf32_Phdr *elf32ph;
5462306a36Sopenharmony_ci	unsigned int i;
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	if (!(elf32->e_ident[EI_MAG0]  == ELFMAG0	&&
5762306a36Sopenharmony_ci	      elf32->e_ident[EI_MAG1]  == ELFMAG1	&&
5862306a36Sopenharmony_ci	      elf32->e_ident[EI_MAG2]  == ELFMAG2	&&
5962306a36Sopenharmony_ci	      elf32->e_ident[EI_MAG3]  == ELFMAG3	&&
6062306a36Sopenharmony_ci	      elf32->e_ident[EI_CLASS] == ELFCLASS32	&&
6162306a36Sopenharmony_ci	      elf32->e_ident[EI_DATA]  == ELFDATA2MSB	&&
6262306a36Sopenharmony_ci	      (elf32->e_type            == ET_EXEC ||
6362306a36Sopenharmony_ci	       elf32->e_type            == ET_DYN)      &&
6462306a36Sopenharmony_ci	      elf32->e_machine         == EM_PPC))
6562306a36Sopenharmony_ci		return 0;
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	elf32ph = (Elf32_Phdr *) ((unsigned long)elf32 + elf32->e_phoff);
6862306a36Sopenharmony_ci	for (i = 0; i < elf32->e_phnum; i++, elf32ph++)
6962306a36Sopenharmony_ci		if (elf32ph->p_type == PT_LOAD)
7062306a36Sopenharmony_ci			break;
7162306a36Sopenharmony_ci	if (i >= elf32->e_phnum)
7262306a36Sopenharmony_ci		return 0;
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	info->loadsize = elf32ph->p_filesz;
7562306a36Sopenharmony_ci	info->memsize = elf32ph->p_memsz;
7662306a36Sopenharmony_ci	info->elfoffset = elf32ph->p_offset;
7762306a36Sopenharmony_ci	return 1;
7862306a36Sopenharmony_ci}
79