xref: /openbmc/linux/arch/powerpc/boot/elf_util.c (revision 549e8152de8039506f69c677a4546e5427aa6ae7)
188e68731SMark A. Greer /*
288e68731SMark A. Greer  * Copyright (C) Paul Mackerras 1997.
388e68731SMark A. Greer  *
488e68731SMark A. Greer  * Updates for PPC64 by Todd Inglett, Dave Engebretsen & Peter Bergner.
588e68731SMark A. Greer  *
688e68731SMark A. Greer  * This program is free software; you can redistribute it and/or
788e68731SMark A. Greer  * modify it under the terms of the GNU General Public License
888e68731SMark A. Greer  * as published by the Free Software Foundation; either version
988e68731SMark A. Greer  * 2 of the License, or (at your option) any later version.
1088e68731SMark A. Greer  */
1188e68731SMark A. Greer #include <stdarg.h>
1288e68731SMark A. Greer #include <stddef.h>
1388e68731SMark A. Greer #include "elf.h"
1488e68731SMark A. Greer #include "page.h"
1588e68731SMark A. Greer #include "string.h"
1688e68731SMark A. Greer #include "stdio.h"
1788e68731SMark A. Greer 
1888e68731SMark A. Greer int parse_elf64(void *hdr, struct elf_info *info)
1988e68731SMark A. Greer {
2088e68731SMark A. Greer 	Elf64_Ehdr *elf64 = hdr;
2188e68731SMark A. Greer 	Elf64_Phdr *elf64ph;
2288e68731SMark A. Greer 	unsigned int i;
2388e68731SMark A. Greer 
2488e68731SMark A. Greer 	if (!(elf64->e_ident[EI_MAG0]  == ELFMAG0	&&
2588e68731SMark A. Greer 	      elf64->e_ident[EI_MAG1]  == ELFMAG1	&&
2688e68731SMark A. Greer 	      elf64->e_ident[EI_MAG2]  == ELFMAG2	&&
2788e68731SMark A. Greer 	      elf64->e_ident[EI_MAG3]  == ELFMAG3	&&
2888e68731SMark A. Greer 	      elf64->e_ident[EI_CLASS] == ELFCLASS64	&&
2988e68731SMark A. Greer 	      elf64->e_ident[EI_DATA]  == ELFDATA2MSB	&&
30*549e8152SPaul Mackerras 	      (elf64->e_type            == ET_EXEC ||
31*549e8152SPaul Mackerras 	       elf64->e_type            == ET_DYN)	&&
3288e68731SMark A. Greer 	      elf64->e_machine         == EM_PPC64))
3388e68731SMark A. Greer 		return 0;
3488e68731SMark A. Greer 
3588e68731SMark A. Greer 	elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
3688e68731SMark A. Greer 				 (unsigned long)elf64->e_phoff);
3788e68731SMark A. Greer 	for (i = 0; i < (unsigned int)elf64->e_phnum; i++, elf64ph++)
3888e68731SMark A. Greer 		if (elf64ph->p_type == PT_LOAD)
3988e68731SMark A. Greer 			break;
4088e68731SMark A. Greer 	if (i >= (unsigned int)elf64->e_phnum)
4188e68731SMark A. Greer 		return 0;
4288e68731SMark A. Greer 
4388e68731SMark A. Greer 	info->loadsize = (unsigned long)elf64ph->p_filesz;
4488e68731SMark A. Greer 	info->memsize = (unsigned long)elf64ph->p_memsz;
4588e68731SMark A. Greer 	info->elfoffset = (unsigned long)elf64ph->p_offset;
4688e68731SMark A. Greer 
4788e68731SMark A. Greer 	return 1;
4888e68731SMark A. Greer }
4988e68731SMark A. Greer 
5088e68731SMark A. Greer int parse_elf32(void *hdr, struct elf_info *info)
5188e68731SMark A. Greer {
5288e68731SMark A. Greer 	Elf32_Ehdr *elf32 = hdr;
5388e68731SMark A. Greer 	Elf32_Phdr *elf32ph;
5488e68731SMark A. Greer 	unsigned int i;
5588e68731SMark A. Greer 
5688e68731SMark A. Greer 	if (!(elf32->e_ident[EI_MAG0]  == ELFMAG0	&&
5788e68731SMark A. Greer 	      elf32->e_ident[EI_MAG1]  == ELFMAG1	&&
5888e68731SMark A. Greer 	      elf32->e_ident[EI_MAG2]  == ELFMAG2	&&
5988e68731SMark A. Greer 	      elf32->e_ident[EI_MAG3]  == ELFMAG3	&&
6088e68731SMark A. Greer 	      elf32->e_ident[EI_CLASS] == ELFCLASS32	&&
6188e68731SMark A. Greer 	      elf32->e_ident[EI_DATA]  == ELFDATA2MSB	&&
62*549e8152SPaul Mackerras 	      (elf32->e_type            == ET_EXEC ||
63*549e8152SPaul Mackerras 	       elf32->e_type            == ET_DYN)      &&
6488e68731SMark A. Greer 	      elf32->e_machine         == EM_PPC))
6588e68731SMark A. Greer 		return 0;
6688e68731SMark A. Greer 
6788e68731SMark A. Greer 	elf32ph = (Elf32_Phdr *) ((unsigned long)elf32 + elf32->e_phoff);
6888e68731SMark A. Greer 	for (i = 0; i < elf32->e_phnum; i++, elf32ph++)
6988e68731SMark A. Greer 		if (elf32ph->p_type == PT_LOAD)
7088e68731SMark A. Greer 			break;
7188e68731SMark A. Greer 	if (i >= elf32->e_phnum)
7288e68731SMark A. Greer 		return 0;
7388e68731SMark A. Greer 
7488e68731SMark A. Greer 	info->loadsize = elf32ph->p_filesz;
7588e68731SMark A. Greer 	info->memsize = elf32ph->p_memsz;
7688e68731SMark A. Greer 	info->elfoffset = elf32ph->p_offset;
7788e68731SMark A. Greer 	return 1;
7888e68731SMark A. Greer }
79