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

📄 elf.c

📁 qnx powerpc MPC8245的 BSP源文件
💻 C
字号:
/* * $QNXLicenseC:  * Copyright 2007, QNX Software Systems.   *   * Licensed under the Apache License, Version 2.0 (the "License"). You   * may not reproduce, modify or distribute this software except in   * compliance with the License. You may obtain a copy of the License   * at: http://www.apache.org/licenses/LICENSE-2.0   *   * Unless required by applicable law or agreed to in writing, software   * distributed under the License is distributed on an "AS IS" basis,   * WITHOUT WARRANTIES OF ANY KIND, either express or implied.  *  * This file may contain contributions from others, either as   * contributors under the License or as licensors under other terms.    * Please review this entire file for other proprietary rights or license   * notices, as well as the QNX Development Suite License Guide at   * http://licensing.qnx.com/license-guide/ for other information.  * $  */#include "startup.h"#include <sys/elf_nto.h>Elf32_Phdr *is_elf(Elf32_Ehdr *hdr, paddr32_t addr) {	Elf32_Ehdr	*p;	p = startup_memory_map(sizeof(*hdr), addr, PROT_READ);	*hdr = *p;	startup_memory_unmap(p);	if (memcmp(hdr->e_ident, ELFMAG, SELFMAG)		|| hdr->e_ident [EI_DATA] != ELFDATANATIVE		|| hdr->e_machine != EM_NATIVE		|| hdr->e_phnum == 0		|| hdr->e_phentsize != sizeof(Elf32_Phdr))		return(NULL);	return startup_memory_map(hdr->e_phnum * sizeof(Elf32_Phdr),				addr + hdr->e_phoff, PROT_READ|PROT_WRITE);}#define PAGEBITS 	(__PAGESIZE-1)static voidload_elf32mmu(paddr32_t addr, Elf32_Ehdr *hdr, Elf32_Phdr *phdr) {	int			i;	for(i = 0; i < hdr->e_phnum; ++i, ++phdr) {		switch(phdr->p_type) {		case PT_LOAD:			{				size_t memsz  = phdr->p_memsz + (phdr->p_vaddr & PAGEBITS);				size_t filesz = phdr->p_filesz + (phdr->p_vaddr & PAGEBITS);				uintptr_t vaddr  = phdr->p_vaddr & ~PAGEBITS;				paddr32_t paddr  = phdr->p_paddr & ~PAGEBITS;				paddr32_t daddr;								if((phdr->p_flags & PF_W) == 0 && memsz == filesz) {					filesz = memsz = ROUNDPG(filesz);				}				if(phdr->p_paddr != 0) {					elf_map(vaddr, paddr, filesz & ~PAGEBITS, phdr->p_flags);					memsz = ROUNDPG(memsz - (filesz & ~PAGEBITS));					if(memsz) {						daddr = calloc_ram(memsz, __PAGESIZE);						copy_memory(daddr, (paddr + (filesz & ~PAGEBITS)), filesz & PAGEBITS);						elf_map(vaddr + (filesz & ~PAGEBITS), daddr, memsz, phdr->p_flags);					}				} else {#ifndef BOOTSTRAPS_RUN_ONE_TO_ONE	/*	 * We need to do different things depending on whether the bootstrap	 * executables a run in a physical <-> virtual one to one mapping	 * area (MIPS, SH, PPC) or if they use the normal virtual address	 * mapping gear (X86, ARM). Basically, is startup or procnto	 * enabling the MMU on the CPU.	 */	#error BOOTSTRAPS_RUN_ONE_TO_ONE must be defined#endif#if BOOTSTRAPS_RUN_ONE_TO_ONE					daddr = alloc_ram(vaddr - shdr->paddr_bias, ROUNDPG(memsz), __PAGESIZE);					if(daddr != vaddr - shdr->paddr_bias) {						crash("Error: can not allocate RAM for proc in XIP.\n");					}					memmove((void *)phdr->p_vaddr,							MAKE_1TO1_PTR(addr + phdr->p_offset),							phdr->p_filesz);					memset((void *)(phdr->p_vaddr + phdr->p_filesz), 0,								(phdr->p_memsz - phdr->p_filesz));#else					daddr = calloc_ram(ROUNDPG(memsz), __PAGESIZE);					copy_memory(daddr, (addr + phdr->p_offset) - (phdr->p_vaddr & PAGEBITS), filesz);					elf_map(vaddr, daddr, memsz, phdr->p_flags);#endif				}			}			break;		}	}}uintptr_tload_elf32(paddr32_t addr) {	Elf32_Ehdr	hdr;	Elf32_Phdr	*phdr;	Elf32_Phdr	*phdr_start;	int			i;		if((phdr_start = is_elf(&hdr, addr)) == NULL) {		return(~0L);	}	if(!(shdr->flags1 & STARTUP_HDR_FLAGS1_VIRTUAL)) {		phdr = phdr_start;		for(i = 0; i < hdr.e_phnum; ++i, ++phdr) {			switch(phdr->p_type) {			case PT_LOAD:				if(MAKE_1TO1_PTR(phdr->p_paddr) != (void *)phdr->p_vaddr) {					alloc_ram(phdr->p_vaddr - shdr->paddr_bias, phdr->p_memsz, 1);					memmove((void *)phdr->p_vaddr,						MAKE_1TO1_PTR(addr + phdr->p_offset),						phdr->p_filesz);					memset((void *)(phdr->p_vaddr+phdr->p_filesz), 0,								phdr->p_memsz - phdr->p_filesz);				}				break;			}		}#ifdef __X86__	} else if(load_elf32mmu_4m(addr, &hdr, phdr_start)) {		// Nothing to do#endif	} else {		load_elf32mmu(addr, &hdr, phdr_start);	}	startup_memory_unmap(phdr_start);	return hdr.e_entry;}

⌨️ 快捷键说明

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