⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elf_loader.cpp

📁 浙江大学的悟空嵌入式系统模拟器
💻 CPP
字号:
/* -*- C++ -*- */

/**
 *  Copyright (c) 2005 Zhejiang University, P.R.China
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
///==================================================
/**
 * @file        Elf_Loader.cpp
 * @brief       just do a little modification on ARM_ELF_Loader.cpp 
 * @author      lijiecong <lijiecong@yahoo.com.cn>   2004/11/10
                Wei He <hwzd1997@163.com> 
 *
 * $Id: Elf_Loader.cpp,v 1.10 2005/04/06 07:44:05 zhoucf Exp $
 */
///==================================================

#include "stdafx.h"
#include "Core/Global.h"
#include "Core/Datatype.h"
#include "Core/Memory.h"
#include "Core/Processor.h"
#include "Core/Log.h"
#include "Core/System.h"
#include "ELF_Loader.h"
#include <iostream>

namespace ELF_LOADER{

	//! load elf file
	bool ELF_Loader::load_binary(std::string filepath)
	{
		in_elf_file.open( filepath.c_str(),std::ios::binary);
		
		if( in_elf_file.fail())
		{
			WUKONG_ERROR<<"The file you want to debug can't open.Error occur\
				   at ELF_Loader::read_static_elf"<<std::endl;
			throw( std::invalid_argument("file open error!"));
		}

		if (read_exec_elf() == -2)
			return false;

		in_elf_file.close();

		return true;

	}



	//! read executable elf file
	Core::s32 ELF_Loader::read_exec_elf(void)
	{
		//! judge whether this file can execute.
		if ( is_executable_file( ) == NOTEXECUTABLEFILE)
		{
			WUKONG_ERROR<<"The loading file is not executable"<<std::endl;
			return NOTEXECUTABLEFILE;
		}

		return load_static_elf();

	}




	// !can only read static compiled executable file on arm.
	// !and,return the value of entry point.if this function read file failed
	// !it returns a minus digit.
	Core::u32 ELF_Loader::load_static_elf()
	{	
		std::vector<Core::u8> buffer;
		//!read program header  
		in_elf_file.seekg( elf_header.e_phoff,std::ios_base::beg);

		Core::u32 program_header_num = elf_header.e_phnum;
		program_header = new Elf32_Phdr[program_header_num];
		in_elf_file.read((char *)program_header, sizeof(Elf32_Phdr)*program_header_num);
		
		if(elf_header.e_ident[EI_DATA] == BIG_ENDIAN)
		{//it is big end  lijiecong 2005/3/16
			for( int i = 0 ; i<program_header_num; i++)
				program_head_big2small( program_header+i );
		}



		//! additional for test memory
		in_elf_file.seekg( elf_header.e_shoff,std::ios_base::beg);
		Elf32_Shdr *section_header = new Elf32_Shdr[elf_header.e_shnum];
		in_elf_file.read((char *)section_header, sizeof(Elf32_Shdr)* elf_header.e_shnum);
		
		if(elf_header.e_ident[EI_DATA] == BIG_ENDIAN)
		{//it is big end  lijiecong 2005/3/16
		
			for( int i=0; i<elf_header.e_shnum; i++)
				section_head_big2small( section_header+i);
		}

		Core::u32 end ,start;
		start = 0x0fffffff ; end = 0;
		for( Core::u32 snum = 0 ; snum<elf_header.e_shnum; snum++)
		{

			if ( ((section_header[snum].sh_flags)&SHF_WRITE) == SHF_WRITE)
			{

			start = (start > section_header[snum].sh_addr)?section_header[snum].sh_addr:start;
			end = (end<section_header[snum].sh_addr+section_header[snum].sh_size)?\
				section_header[snum].sh_addr+section_header[snum].sh_size:end;
				 
			}
		
		}
	

		delete []section_header;
		
	
		for( Core::u32 i=0; i<program_header_num; i++)
		{
			char *p_segment;
			Core::u32  memsz_after_align;//memory size after alignment
			Core::u32 p_align   = program_header[i].p_align;
			Core::u32 p_filesz  = program_header[i].p_filesz;
			Core::u32 p_memsz   = program_header[i].p_memsz;
			Core::u32 p_offset  = program_header[i].p_offset;
			Core::u32 p_vaddr   = program_header[i].p_vaddr;

			if(program_header[i].p_type == PT_LOAD)
			{
		
				memsz_after_align = ((p_memsz + p_align-1)/p_align)*p_align;
//				p_segment = new char[memsz_after_align];
				buffer.clear();
				buffer.resize(memsz_after_align);
				in_elf_file.seekg(p_offset,std::ios_base::beg);
//				in_elf_file.read( p_segment, p_filesz);
				in_elf_file.read( (char *)&buffer[0], p_filesz);

//				for(  ; p_memsz<memsz_after_align; p_memsz++)
//				{
//
//					p_segment[p_memsz] = 0;
//
//				}
//
				//!copy to the memory,using the p_vaddr
				if (p_vaddr<LOAD_ADDRESS)
				{	
			
					std::string msg = "error:";
					msg += __LINE__;msg += "lines";
					msg += __FILE__;
					WUKONG_ERROR<<msg<<std::endl;
					return LOADADDRESSERROR;

				}

				Core::u32 start_vaddr = p_vaddr-LOAD_ADDRESS;

			
//				buffer.clear();
//				for( Core::u32 bytes=0; bytes<memsz_after_align;bytes++)
//				{
//				
//					buffer.push_back( p_segment[bytes] );
//
//				}
//
                if( memsz_after_align>0 )		
				{
					Core::MMU<Core::u32>& mmu = ((Core::CPU<Core::u32>*)(Core::Wukong_Get_System().get_cpu()))->get_mmu();
					//get memory
				
					mmu.access(Core::Memory<Core::u32>::MEMORY_WRITE,start_vaddr,memsz_after_align, buffer);
				}
			

//				delete [] p_segment;
		
			}


	}

	Core::u32 pc = elf_header.e_entry;
	this->set_pc( (pc - LOAD_ADDRESS) );
	return elf_header.e_entry;

}

	// !if the file you want to load is executable, the function return true ,else	return false
	Core::s32 ELF_Loader::is_executable_file(void)
	{
		in_elf_file.read( (char *)&elf_header, sizeof(Elf32_Ehdr));
	
		//! judge whether or not the file is elf format and executable
		if( elf_header.e_ident[EI_MAG1] != 'E' || elf_header.e_ident [EI_MAG2] != 'L'\
		|| elf_header.e_ident [EI_MAG3]!='F')
		{

			return NOTEXECUTABLEFILE;

		}
		
		if(elf_header.e_ident[EI_DATA] == BIG_ENDIAN)
		{//it is big end lijiecong 2005/3/16
			 elf_head_big2small( );
		}

		if( elf_header.e_entry <= 0 )
		{	

			return NOTEXECUTABLEFILE;

		}

	
		return EXECUTABLEFILE;

	}


	void ELF_Loader::set_pc(Core::u32 pc)
	{
	
		((Core::CPU<Core::u32>*)(Core::Wukong_Get_System().get_cpu()))->set_pc(pc);
	
	}
	
	
	Core::s32 ELF_Loader::big_to_small( Core::s32 temp,Core::s32 size)
 {
	if( size == 2)
	{
		return ((temp>>8) & 0x00ff) | ((temp<<8)&0x00ff00);
	}
	else if(size == 4)
	{
		return ( (temp<<24) | ((temp<<8) & 0x00ff0000)\
			|((temp>>8)&0x0000ff00) | ((temp>>24)&0x000000ff));
	}

	std::cout<<"There is an error in line:"<<__LINE__<<"file: "<<__FILE__<<std::endl;
}

//convert elf header stored in big-endian to little-endian
void  ELF_Loader::elf_head_big2small()
{
	
	elf_header.e_ehsize = big_to_small(elf_header.e_ehsize,sizeof(elf_header.e_ehsize));
	elf_header.e_entry = big_to_small(elf_header.e_entry,sizeof(elf_header.e_entry));
	elf_header.e_flags = big_to_small(elf_header.e_flags,sizeof(elf_header.e_flags));
	elf_header.e_machine = big_to_small(elf_header.e_machine,sizeof(elf_header.e_machine));
	elf_header.e_phentsize = big_to_small(elf_header.e_phentsize,sizeof(elf_header.e_phentsize));
	elf_header.e_phnum = big_to_small(elf_header.e_phnum,sizeof(elf_header.e_phnum));
	elf_header.e_phoff = big_to_small(elf_header.e_phoff,sizeof(elf_header.e_phoff));
	elf_header.e_shentsize = big_to_small(elf_header.e_shentsize,sizeof(elf_header.e_shentsize));
	elf_header.e_shnum = big_to_small(elf_header.e_shnum,sizeof(elf_header.e_shentsize));
	elf_header.e_shoff = big_to_small(elf_header.e_shoff,sizeof(elf_header.e_shoff));
	elf_header.e_shstrndx = big_to_small(elf_header.e_shstrndx,sizeof(elf_header.e_shstrndx));
	elf_header.e_type = big_to_small(elf_header.e_type,sizeof(elf_header.e_type));
	elf_header.e_version = big_to_small(elf_header.e_version,sizeof(elf_header.e_version));


}

//convert ONE program header stored in big-endian to little-endian
void ELF_Loader::program_head_big2small( Elf32_Phdr *program_header )
{
	if( program_header != NULL)
	{
		program_header->p_align = big_to_small(program_header->p_align,sizeof(program_header->p_align));
		program_header->p_filesz = big_to_small(program_header->p_filesz,sizeof(program_header->p_filesz));
		program_header->p_flags = big_to_small(program_header->p_flags,sizeof(program_header->p_flags));
		program_header->p_memsz = big_to_small(program_header->p_memsz,sizeof(program_header->p_memsz));
		program_header->p_offset = big_to_small(program_header->p_offset,sizeof(program_header->p_offset));
		program_header->p_paddr = big_to_small(program_header->p_paddr,sizeof(program_header->p_paddr));
		program_header->p_type = big_to_small(program_header->p_type,sizeof(program_header->p_type));
		program_header->p_vaddr = big_to_small(program_header->p_vaddr,sizeof(program_header->p_vaddr));
	}
}

//convert ONE section header stored in big-endian to little-endian
void ELF_Loader::section_head_big2small(Elf32_Shdr *section_header)
{
	if( section_header != NULL)
	{
		section_header->sh_addr = big_to_small(section_header->sh_addr,sizeof(section_header->sh_addr));
		section_header->sh_addralign = big_to_small(section_header->sh_addralign,sizeof(section_header->sh_addralign));
		section_header->sh_entsize = big_to_small(section_header->sh_entsize,sizeof(section_header->sh_entsize));
		section_header->sh_flags = big_to_small(section_header->sh_flags,sizeof(section_header->sh_flags));
		section_header->sh_info = big_to_small(section_header->sh_info,sizeof(section_header->sh_info));
		section_header->sh_link = big_to_small(section_header->sh_link,sizeof(section_header->sh_link));
		section_header->sh_name = big_to_small(section_header->sh_name,sizeof(section_header->sh_name));
		section_header->sh_offset = big_to_small(section_header->sh_offset,sizeof(section_header->sh_offset));
		section_header->sh_size = big_to_small(section_header->sh_size,sizeof(section_header->sh_size));
		section_header->sh_type = big_to_small(section_header->sh_type,sizeof(section_header->sh_type));
	}

}



}//namespace

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -