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

📄 elf.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 3 页
字号:
			cp = Malloc(zstat.st_size);
			Read(secfd,cp,zstat.st_size);
			Write(zipfd,cp,zstat.st_size);
			free(cp);
			close(secfd);
			if (remove_zouts)
				unlink(zoutfile);
		}
		else {
			if ((sptr->sh_size) && (sptr->sh_type != SHT_NOBITS)) {
				if (debug)
					fprintf(stderr,"Read %s offset=%d size=%d\n",
						name,sptr->sh_offset,sptr->sh_size);
				Lseek(elfFD,sptr->sh_offset,SEEK_SET);
				cp = Malloc(sptr->sh_size);
				Read(elfFD,cp,sptr->sh_size);
#if USE_OFFSET_DELTA
				sptr_z->sh_offset -= offset_delta;
#else
				sptr_z->sh_offset = tell(zipfd);
#endif
				Write(zipfd,cp,sptr->sh_size);
				free(cp);
			}
		}

		if ((sptr->sh_type != SHT_NOBITS) && (sptr->sh_flags & SHF_ALLOC)) {
			/* I found that the size of the section does not necessarily */
			/* correspond to the point at which the next section starts in */
			/* the file, so this makes sure that offset_delta is properly */
			/* adjusted if that correspondance does not exist... */
			if ((sptr->sh_size + sptr->sh_offset) != (sptr+1)->sh_offset) {
				int delta;
				delta=((sptr+1)->sh_offset-(sptr->sh_size+sptr->sh_offset));
				offset_delta += 
					((sptr+1)->sh_offset - (sptr->sh_size + sptr->sh_offset));
				if (debug)
					fprintf(stderr,"offset_delta compensation = %d\n",delta); 
			}
		}
	}

	/* Now that all sections have been written to the file, insert the
	 * section header table at the end. Note that the header may be
	 * endian-converted,  so compensate for this prior to writing to file...
	 */
	if (1) {
		int	i;
		shoffz = tell(zipfd);
		/* The section header table base must be 4-byte aligned.. */
		if (shoffz & 3) {
			if (debug)
				fprintf(stderr,"Shifting scnhdr %d bytes up\n",
					4-(shoffz&3));
			shoffz = Lseek(zipfd,4-(shoffz&3),SEEK_CUR);
		}
		if(debug)
			fprintf(stderr,"Inserting scnhdr at 0x%x\n",shoffz);
		for(i=0;i<Ehdr.e_shnum;i++) {
			scntbl_z[i].sh_name = otherEnd32(Ecvt,scntbl_z[i].sh_name);
			scntbl_z[i].sh_type = otherEnd32(Ecvt,scntbl_z[i].sh_type);
			scntbl_z[i].sh_flags = otherEnd32(Ecvt,scntbl_z[i].sh_flags);
			scntbl_z[i].sh_addr = otherEnd32(Ecvt,scntbl_z[i].sh_addr);
			scntbl_z[i].sh_offset = otherEnd32(Ecvt,scntbl_z[i].sh_offset);
			scntbl_z[i].sh_size = otherEnd32(Ecvt,scntbl_z[i].sh_size);
			scntbl_z[i].sh_link = otherEnd32(Ecvt,scntbl_z[i].sh_link);
			scntbl_z[i].sh_info = otherEnd32(Ecvt,scntbl_z[i].sh_info);
			scntbl_z[i].sh_addralign =
				otherEnd32(Ecvt,scntbl_z[i].sh_addralign);
			scntbl_z[i].sh_entsize = otherEnd32(Ecvt,scntbl_z[i].sh_entsize);
		}
		Write(zipfd,(char *)scntbl_z,(int)(Ehdr.e_shnum*Ehdr.e_shentsize));
		for(i=0;i<Ehdr.e_shnum;i++) {
			scntbl_z[i].sh_name = otherEnd32(Ecvt,scntbl_z[i].sh_name);
			scntbl_z[i].sh_type = otherEnd32(Ecvt,scntbl_z[i].sh_type);
			scntbl_z[i].sh_flags = otherEnd32(Ecvt,scntbl_z[i].sh_flags);
			scntbl_z[i].sh_addr = otherEnd32(Ecvt,scntbl_z[i].sh_addr);
			scntbl_z[i].sh_offset = otherEnd32(Ecvt,scntbl_z[i].sh_offset);
			scntbl_z[i].sh_size = otherEnd32(Ecvt,scntbl_z[i].sh_size);
			scntbl_z[i].sh_link = otherEnd32(Ecvt,scntbl_z[i].sh_link);
			scntbl_z[i].sh_info = otherEnd32(Ecvt,scntbl_z[i].sh_info);
			scntbl_z[i].sh_addralign =
				otherEnd32(Ecvt,scntbl_z[i].sh_addralign);
			scntbl_z[i].sh_entsize = otherEnd32(Ecvt,scntbl_z[i].sh_entsize);
		}
	}

	if (debug)
		fprintf(stderr,"offset_delta = %d\n",offset_delta);
	/* Adjust the file header to point to the new section header table. */
	Lseek(zipfd,0x20,SEEK_SET);
	shoffz = otherEnd32(Ecvt,shoffz);
	Write(zipfd,(char *)&shoffz,4);
	
	close(zipfd);
}

void
ElfToBinary(char *binto)
{
	int	fd, sidx, firstone;
	struct	stat buf;
	uchar	*tfrom, *dfrom, *cp;
	unsigned long	paddr;
	struct	elf_shdr	*sptr;

	unlink(binto);
	if ((fd = open(binto,O_RDWR|O_BINARY|O_CREAT,0777))==-1)
	{
		perror(binto);
		exit(1);
	}
	fprintf(stderr,"Converting %s into %s\n",
		elfFname,binto);
	firstone = 1;
	for(sptr=ScnTbl,sidx=0;sidx<Ehdr.e_shnum;sidx++,sptr++) {
		char	*name, padbyte;
		int		padtot;
		unsigned long	nextpaddr;
		
		name = GetElfSectionName(ScnTbl[sidx].sh_name);

		if ((sptr->sh_flags & SHF_ALLOC) &&
		    (sptr->sh_type != SHT_NOBITS) &&
		    (sptr->sh_size)) {
			if (!firstone) {	/* Pad if necessary... */
				if (nextpaddr != sptr->sh_addr) {
					if (sptr->sh_addr < nextpaddr) {
						fprintf(stderr,"Unexpected section address\n");
						exit(1);
					}
					padtot = sptr->sh_addr-nextpaddr;
					printf("Pad 0x%x bytes\n",padtot);
					padbyte = PadByte;
					while(padtot) {
						Write(fd,&padbyte,1);
						padtot--;
					}
				}
			}
			printf("Sec %-8s at 0x%-8x 0x%-6x bytes\n",
				name,sptr->sh_addr,sptr->sh_size);
			cp = (uchar *)Malloc(sptr->sh_size);
			Lseek(elfFD,sptr->sh_offset,SEEK_SET);
			read(elfFD,cp,sptr->sh_size);
			Write(fd,cp,sptr->sh_size);
			free(cp);
			nextpaddr = sptr->sh_addr + sptr->sh_size;
			firstone = 0;
		}
		free(name);
	}
	/* If non-zero, then insert the specified number of bytes just prior */
	/* to the end of the binary file.  Starting at a point 4-bytes befor */
	/* the end.  This is needed because of a problem with GNU linker that */
	/* does not allow a 4-byte section  to exist at 0xfffffffc (branch */
	/* instruction location for PPC403GCX). */
	if (insertPAD) {
		int i;
		char branch[4];

		Lseek(fd,-4,SEEK_CUR);
		Read(fd,branch,4);
		Lseek(fd,-4,SEEK_CUR);
		for(i=0;i<insertPAD;i++)
			Write(fd,&PadByte,1);
		Write(fd,branch,4);
	}
	close(fd);
}

/* StripElfFile():
	This is a bit tricky for elf.  We can only strip out certain
	sections, and the sections are not necessarily at the end of 
	the file; hence, chunks of the file are removed and the file
	offsets in the section header table must be adjusted.
*/
void
StripElfFile(char *stripto,char *append)
{
	uchar	*cp;
	FILE	*zout;
	unsigned long	shoffs, offset_delta;
	int		stripfd, sidx, newsectot;
	struct	elf_shdr *sptr, *scntbl_s, *sptr_s;
	struct stat zstat;

	fprintf(stderr,"Stripping %s into %s \n",elfFname,stripto);
fprintf(stderr,"Not working yet\n");
return;

	/* Allocate space for new section header table that may be smaller */
	/* than the current table... */
	scntbl_s = (struct elf_shdr *)Malloc(Ehdr.e_shnum * Ehdr.e_shentsize);

	/* Create the destination file... */
	unlink(stripto);
	if ((stripfd = open(stripto,O_WRONLY|O_BINARY|O_CREAT,0777))==-1) {
		perror(stripto);
		exit(1);
	}

	/* Up to the first section, do a blind copy from original */
	/* file to new compressed file... */
	if (debug)
		fprintf(stderr,"Copying first %ld bytes\n",ScnTbl[1].sh_offset);
	Lseek(elfFD,0,SEEK_SET);
	cp = Malloc(ScnTbl[1].sh_offset);
	Read(elfFD,cp,ScnTbl[1].sh_offset);
	Write(stripfd,cp,ScnTbl[1].sh_offset);
	free(cp);

	scntbl_s[0] = ScnTbl[0];
	newsectot = 0;
	offset_delta = 0;
	sptr_s = scntbl_s+1;

	/* For each section, either copy it or remove it... */
	for(sptr=&ScnTbl[1],sidx=1;sidx<Ehdr.e_shnum;sidx++,sptr++) {
		char	*name;
			
		name = GetElfSectionName(ScnTbl[sidx].sh_name);

		if (!strcmp(name,".comment")) {
			if (verbose)
				fprintf(stderr,"Removing %s (%d bytes)\n",name,sptr->sh_size);
			offset_delta += sptr->sh_size;
		}
		else {

			*sptr_s++ = *sptr;
			newsectot++;
			if ((sptr->sh_size) && (sptr->sh_type != SHT_NOBITS)) {
				if (verbose)
					fprintf(stderr,"Copying %s (%d bytes)\n",
						name,sptr->sh_size);
				Lseek(elfFD,sptr->sh_offset,SEEK_SET);
				cp = Malloc(sptr->sh_size);
				Read(elfFD,cp,sptr->sh_size);
				Write(stripfd,cp,sptr->sh_size);
				sptr_s->sh_offset -= offset_delta;
				free(cp);
			}
		}
		/* Assuming the section header table comes just after the section */
		/* header string table section, insert the modified table... */
		/* Note that the header may be endian-converted,  so compensate for */
		/* this prior to writing to file... */
		if (!strcmp(name,".shstrtab")) {
			int	i;

			sidx++;
			sptr++;
			sptr_s++;

fprintf(stderr,"section headers at section # %d\n",sidx);
			/* Adjust the size of the section header table: */
			scntbl_s[sidx].sh_size = newsectot * Ehdr.e_shentsize;

			/* Store this current file location: */
			shoffs = tell(stripfd);

			if(debug)
				fprintf(stderr,"Inserting scnhdr at 0x%x\n",shoffs);
			for(i=0;i<newsectot;i++) {
				scntbl_s[i].sh_name = otherEnd32(Ecvt,scntbl_s[i].sh_name);
				scntbl_s[i].sh_type = otherEnd32(Ecvt,scntbl_s[i].sh_type);
				scntbl_s[i].sh_flags = otherEnd32(Ecvt,scntbl_s[i].sh_flags);
				scntbl_s[i].sh_addr = otherEnd32(Ecvt,scntbl_s[i].sh_addr);
				scntbl_s[i].sh_offset = otherEnd32(Ecvt,scntbl_s[i].sh_offset);
				scntbl_s[i].sh_size = otherEnd32(Ecvt,scntbl_s[i].sh_size);
				scntbl_s[i].sh_link = otherEnd32(Ecvt,scntbl_s[i].sh_link);
				scntbl_s[i].sh_info = otherEnd32(Ecvt,scntbl_s[i].sh_info);
				scntbl_s[i].sh_addralign =
					otherEnd32(Ecvt,scntbl_s[i].sh_addralign);
				scntbl_s[i].sh_entsize = 
					otherEnd32(Ecvt,scntbl_s[i].sh_entsize);
			}
			Write(stripfd,(char *)scntbl_s,(int)(newsectot*Ehdr.e_shentsize));
			for(i=0;i<newsectot;i++) {
				scntbl_s[i].sh_name = otherEnd32(Ecvt,scntbl_s[i].sh_name);
				scntbl_s[i].sh_type = otherEnd32(Ecvt,scntbl_s[i].sh_type);
				scntbl_s[i].sh_flags = otherEnd32(Ecvt,scntbl_s[i].sh_flags);
				scntbl_s[i].sh_addr = otherEnd32(Ecvt,scntbl_s[i].sh_addr);
				scntbl_s[i].sh_offset = otherEnd32(Ecvt,scntbl_s[i].sh_offset);
				scntbl_s[i].sh_size = otherEnd32(Ecvt,scntbl_s[i].sh_size);
				scntbl_s[i].sh_link = otherEnd32(Ecvt,scntbl_s[i].sh_link);
				scntbl_s[i].sh_info = otherEnd32(Ecvt,scntbl_s[i].sh_info);
				scntbl_s[i].sh_addralign =
					otherEnd32(Ecvt,scntbl_s[i].sh_addralign);
				scntbl_s[i].sh_entsize =
					otherEnd32(Ecvt,scntbl_s[i].sh_entsize);
			}
			offset_delta += (Ehdr.e_shnum - newsectot) * Ehdr.e_shentsize;
		}
	}

	if (debug)
		fprintf(stderr,"offset_delta = %d\n",offset_delta);

	/* Adjust the file header to point to the new section header table. */
	Lseek(stripfd,0x20,SEEK_SET);
	shoffs = otherEnd32(Ecvt,shoffs);
	Write(stripfd,(char *)&shoffs,4);
	
	close(stripfd);
}

#if 0
	if (append) {
		struct	stat buf;
		char	*aspace;
		if ((afd = open(append,O_RDONLY|O_BINARY))==-1)
		{
			perror(append);
			exit(1);
		}
		stat(append,&buf);
		aspace = Malloc(buf.st_size+32);
		read(afd,aspace,buf.st_size);
		Write(sfd,aspace,buf.st_size);
		free(aspace);
		close(afd);
	}
	close(sfd);
#endif

void
ShowElfMap(int fileoffsets)
{
	int	i;
	unsigned long	size;
	struct	elf_shdr	*eshdr;

	if (debug >= 2)
		fprintf(stderr,"ShowElfMap()\n");

	for(i=0;i<Ehdr.e_shnum;i++) {
		eshdr = &ScnTbl[i];
		size = eshdr->sh_size;
		if (size)
			size--;
		if ((eshdr->sh_flags) || (fileoffsets)) {
			printf("%10s: 0x%08x..0x%08x (%ld bytes) %s\n",
				GetElfSectionName(eshdr->sh_name),
				eshdr->sh_addr,eshdr->sh_addr+size,eshdr->sh_size,
				VerboseShflags(eshdr->sh_flags));
			if (fileoffsets) {
				printf("            ELF file offset: 0x%08x\n",
					eshdr->sh_offset);
			}
		}
	}
	printf("Entrypoint: 0x%08x\n",Ehdr.e_entry);
}

char *

⌨️ 快捷键说明

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