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

📄 coff.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* coff.c:
	Perform some dumps/conversions of a coff file.

	General notice:
	This code is part of a boot-monitor package developed as a generic base
	platform for embedded system designs.  As such, it is likely to be
	distributed to various projects beyond the control of the original
	author.  Please notify the author of any enhancements made or bugs found
	so that all may benefit from the changes.  In addition, notification back
	to the author will allow the new user to pick up changes that may have
	been made by other users after this version of the code was distributed.

	Author:	Ed Sutter
	email:	esutter@lucent.com		(home: lesutter@worldnet.att.net)
	phone:	908-582-2351			(home: 908-889-5161)
*/
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef BUILD_WITH_VCC
#include <io.h>
#endif
#include "coff.h"
#include "../zlib/zlib.h"
#include "utils.h"
#include "version.h"

#ifndef O_BINARY
#define O_BINARY 0
#endif

int 	coffFD = 0, noPad;
char	*coffFname = (char *)0;

struct	filehdr	CoffFhdr;
struct	aouthdr	OptAhdr;
struct	scnhdr	*ScnTbl;

/* open verbosity: */
#define SHOWHDR			0x0001
#define SHOWSECTIONS	0x0002
#define SHOWMAP			0x0004
#define SHOWMAPOFFSET	0x0008
#define SHOWAPPEND		0x0010

struct	filehdr *GetCoffFileHdr();
int		Ecvt, verbose, debug;


void
ShowAppend(void)
{
	int	i;
	char	c;
	long	maxsize, maxoff;

	maxoff = 0;
	for(i=0;i<CoffFhdr.f_nscns;i++) {
		if (ScnTbl[i].s_scnptr > maxoff) {
			maxoff = ScnTbl[i].s_scnptr;
			maxsize = ScnTbl[i].s_size;
		}
	}
	Lseek(coffFD,maxoff+maxsize,SEEK_SET);
	while(1) {
		if (read(coffFD,&c,1) != 1)
			break;
		putchar(c);
	}

}

void
ShowCoffSections(void)
{
	int	i;

	printf("\n\t\tCOFF FILE SECTION HEADERS\n");
	for(i=0;i<CoffFhdr.f_nscns;i++) {
		printf("Section: %s...\n",ScnTbl[i].s_name);
		printf("  s_paddr:   0x%x\n",ScnTbl[i].s_paddr);
		printf("  s_vaddr:   0x%x\n",ScnTbl[i].s_vaddr);
		printf("  s_size:    %d\n",ScnTbl[i].s_size);
		printf("  s_scnptr:  0x%x\n",ScnTbl[i].s_scnptr);
		printf("  s_relptr:  0x%x\n",ScnTbl[i].s_relptr);
		printf("  s_lnnoptr: 0x%x\n",ScnTbl[i].s_lnnoptr);
		printf("  s_nreloc:  %d\n",ScnTbl[i].s_nreloc);
		printf("  s_nlnno:   %d\n",ScnTbl[i].s_nlnno);
		printf("  s_flags:   0x%x\n\n",ScnTbl[i].s_flags);
	}
}

void
ShowCoffHdr(void)
{
	printf("\n\t\tCOFF FILE HEADER\n");

	printf("Magic:				0x%x\n",CoffFhdr.f_magic);
	if (CoffFhdr.f_opthdr) {
		printf("Text size:			0x%x (%d)\n",
			OptAhdr.tsize,OptAhdr.tsize);
		printf("Data size:			0x%x (%d)\n",
			OptAhdr.dsize,OptAhdr.dsize);
		printf("Bss size:			0x%x (%d)\n",
			OptAhdr.bsize,OptAhdr.bsize);
		printf("Entrypoint:			0x%x\n",OptAhdr.entry);
	}
	printf("Number of sections:		%d\n",CoffFhdr.f_nscns);
	printf("Number of symbols:		%d\n",CoffFhdr.f_nsyms);
}

void
ShowCoffMap(void)
{
	int	i, size;

	printf("\n\t\tCOFF FILE MEMORY MAP\n\n");
	for(i=0;i<CoffFhdr.f_nscns;i++) {
		char name[9];
		memcpy(name,ScnTbl[i].s_name,8);
		name[8] = 0;
		
		size = ScnTbl[i].s_size;
		printf("%8s: 0x%08x .. 0x%08x, 0x%x (%d) bytes.\n",
			name,ScnTbl[i].s_paddr,ScnTbl[i].s_paddr+size,size,size);
	}
}

void
ShowCoffOffsets(void)
{
	int	i, start;

	start = sizeof(struct filehdr) + CoffFhdr.f_opthdr;
	printf("\n\t\tCOFF FILE SECTION FILE OFFSETS\n");

	for(i=0;i<CoffFhdr.f_nscns;i++) {
		printf("%8s: 0x%08x .. 0x%08x (%d bytes)\n",
			ScnTbl[i].s_name,ScnTbl[i].s_scnptr,
			ScnTbl[i].s_scnptr+ScnTbl[i].s_size,
			ScnTbl[i].s_size);
		start += ScnTbl[i].s_size;
	}
}

/* GetCoffFileHdr():
   Retrieve the header from the file and do a BE-to-LE conversion
   on each of its members.
*/
struct filehdr *
GetCoffFileHdr(void)
{
	if (verbose)
		fprintf(stderr,"GetCoffFileHdr()\n");

	/* Read in the coff file header. */
	Lseek(coffFD,0,SEEK_SET);
	Read(coffFD,(char *)&CoffFhdr,(unsigned)sizeof(struct filehdr));
	CoffFhdr.f_magic = otherEnd16(Ecvt,CoffFhdr.f_magic);
	CoffFhdr.f_nscns = otherEnd16(Ecvt,CoffFhdr.f_nscns);
	CoffFhdr.f_timdat = otherEnd32(Ecvt,CoffFhdr.f_timdat);
	CoffFhdr.f_symptr = otherEnd32(Ecvt,CoffFhdr.f_symptr);
	CoffFhdr.f_nsyms = otherEnd32(Ecvt,CoffFhdr.f_nsyms);
	CoffFhdr.f_opthdr = otherEnd16(Ecvt,CoffFhdr.f_opthdr);
	CoffFhdr.f_flags = otherEnd16(Ecvt,CoffFhdr.f_flags);

	if (CoffFhdr.f_opthdr) {
		Read(coffFD,(char *)&OptAhdr,(unsigned)sizeof(struct aouthdr));
		OptAhdr.magic = otherEnd16(Ecvt,OptAhdr.magic);
		OptAhdr.vstamp = otherEnd16(Ecvt,OptAhdr.vstamp);
		OptAhdr.tsize = otherEnd32(Ecvt,OptAhdr.tsize);
		OptAhdr.dsize = otherEnd32(Ecvt,OptAhdr.dsize);
		OptAhdr.bsize = otherEnd32(Ecvt,OptAhdr.bsize);
		OptAhdr.entry = otherEnd32(Ecvt,OptAhdr.entry);
		OptAhdr.text_start = otherEnd32(Ecvt,OptAhdr.text_start);
		OptAhdr.data_start = otherEnd32(Ecvt,OptAhdr.data_start);
	}
	return(&CoffFhdr);
}

GetCoffSectionHdrs(void)
{
	int	i;

	ScnTbl = (struct scnhdr *)Malloc(CoffFhdr.f_nscns * sizeof(struct scnhdr));

	/* Read in the coff section headers. */
	Lseek(coffFD,sizeof(struct filehdr)+CoffFhdr.f_opthdr,SEEK_SET);
	Read(coffFD,(char *)ScnTbl,
		(unsigned)(CoffFhdr.f_nscns * sizeof(struct scnhdr)));

	for(i=0;i<CoffFhdr.f_nscns;i++) {
		ScnTbl[i].s_paddr = otherEnd32(Ecvt,ScnTbl[i].s_paddr);
		ScnTbl[i].s_vaddr = otherEnd32(Ecvt,ScnTbl[i].s_vaddr);
		ScnTbl[i].s_size = otherEnd32(Ecvt,ScnTbl[i].s_size);
		ScnTbl[i].s_scnptr = otherEnd32(Ecvt,ScnTbl[i].s_scnptr);
		ScnTbl[i].s_relptr = otherEnd32(Ecvt,ScnTbl[i].s_relptr);
		ScnTbl[i].s_lnnoptr = otherEnd32(Ecvt,ScnTbl[i].s_lnnoptr);
		ScnTbl[i].s_nreloc = otherEnd16(Ecvt,ScnTbl[i].s_nreloc);
		ScnTbl[i].s_nlnno = otherEnd16(Ecvt,ScnTbl[i].s_nlnno);
		ScnTbl[i].s_flags = otherEnd32(Ecvt,ScnTbl[i].s_flags);
	}

	return(CoffFhdr.f_nscns);
}

void
CoffToBinary(char *binto)
{
	int	fd, sidx, firstone;
	uchar	*cp;
	struct	scnhdr	*sptr;

	unlink(binto);
	if ((fd = open(binto,O_WRONLY|O_BINARY|O_CREAT,0777))==-1)
	{
		perror(binto);
		exit(1);
	}
	fprintf(stderr,"Converting %s into %s\n",
		coffFname,binto);
	firstone = 1;
	for(sptr=ScnTbl,sidx=0;sidx<CoffFhdr.f_nscns;sidx++,sptr++) {
		char	name[9], padbyte;
		int		padtot;
		long	nextpaddr;
		
		memcpy(name,sptr->s_name,8);
		name[8] = 0;

		if ((sptr->s_flags != STYP_BSS) &&
		    (sptr->s_flags != STYP_INFO) &&
		    (sptr->s_size)) {
			if (!firstone) {	/* Pad if necessary... */
				if ((!noPad) && (nextpaddr != sptr->s_paddr)) {
					if (sptr->s_paddr < nextpaddr) {
						fprintf(stderr,"Unexpected section address\n");
						exit(1);
					}
					padtot = sptr->s_paddr-nextpaddr;
					printf("Pad 0x%x bytes\n",padtot);
					padbyte = 0;
					while(padtot) {
						write(fd,&padbyte,1);
						padtot--;
					}
				}
			}
			printf("Sec %-8s at 0x%-8x 0x%-6x bytes\n",
				name,sptr->s_paddr,sptr->s_size);
			cp = (uchar *)Malloc(sptr->s_size);
			Lseek(coffFD,sptr->s_scnptr,SEEK_SET);
			read(coffFD,cp,sptr->s_size);
			write(fd,cp,sptr->s_size);
			free(cp);
			nextpaddr = sptr->s_paddr + sptr->s_size;
			firstone = 0;
		}
	}
	close(fd);
}	

void
PackCoffSections(char *packto)
{
	char	*ibuf,*obuf, *sdata, *obase, *ibase;
	int		i, pfd, sno, savings;
	struct	stat finfo;
	struct  filehdr *coffp;
	struct	scnhdr *sp;

	unlink(packto);
	if ((pfd = open(packto,O_WRONLY|O_BINARY|O_CREAT,0777))==-1)
	{
		perror(packto);
		exit(1);
	}
	fprintf(stderr,"Packing %s into %s...\n",
		coffFname,packto);

	/* First copy the entire COFF file into the input buffer: */
	fstat(coffFD,&finfo);
	Lseek(coffFD,0,SEEK_SET);
	ibuf = Malloc(finfo.st_size+32);
	ibase = ibuf;
	obuf = Malloc(finfo.st_size+32);
	obase = obuf;
	coffp = (struct filehdr *)obase;
	Read(coffFD,ibuf,finfo.st_size);

	/* Now copy the file header and optional header to the out buffer: */
	for(i=0;i<sizeof(struct filehdr)+CoffFhdr.f_opthdr;i++)
		*obuf++ = *ibuf++;

	/* Since the output file will be stripped, modify the new header: */
	coffp->f_symptr = 0;
	coffp->f_nsyms = 0;

	/* At this point ibuf & obuf are at the base of the table of section */
	/* headers.  The section headers must be adjusted because the size */
	/* of the sections will be changing, so for each section, compress */
	/* the data and adjust the header information... */
	sp = (struct scnhdr *)obuf;

	/* Set sdata to point into the new buffer at the point immediately */
	/* after the headers. This pointer will be used to write the new */
	/* compressed sections. */
	sdata = obase + sizeof(struct filehdr) + CoffFhdr.f_opthdr +
		(CoffFhdr.f_nscns * sizeof(struct scnhdr));

	/* For each section, if the section is loadable, the compress the */
	/* data associated with that section... */
	savings = 0;
	for (sno=0;sno<CoffFhdr.f_nscns;sno++) {
		int	psize;

		/* If the section has data, compress it and adjust the */
		/* section header information. */
		if (ScnTbl[sno].s_scnptr) {
			/* Compress the section: */
			printf("Section %s: ",ScnTbl[sno].s_name);
			psize = packdata(ibase+ScnTbl[sno].s_scnptr,sdata,
				ScnTbl[sno].s_size,1);

			/* Keep track of total space saved: */
			savings += (ScnTbl[sno].s_size - psize);

			/* Adjust the affected section header members: */
			ScnTbl[sno].s_size = psize;
			ScnTbl[sno].s_scnptr = (unsigned long)(sdata - obase);
			sdata += psize;
		}

		memcpy(sp->s_name,ScnTbl[sno].s_name,8);
		sp->s_paddr = otherEnd32(Ecvt,ScnTbl[sno].s_paddr);
		sp->s_vaddr = otherEnd32(Ecvt,ScnTbl[sno].s_vaddr);
		sp->s_size = otherEnd32(Ecvt,ScnTbl[sno].s_size);
		sp->s_scnptr = otherEnd32(Ecvt,ScnTbl[sno].s_scnptr);
		sp->s_relptr = otherEnd32(Ecvt,ScnTbl[sno].s_relptr);
		sp->s_lnnoptr = otherEnd32(Ecvt,ScnTbl[sno].s_lnnoptr);
		sp->s_nreloc = otherEnd16(Ecvt,ScnTbl[sno].s_nreloc);
		sp->s_nlnno = otherEnd16(Ecvt,ScnTbl[sno].s_nlnno);
		sp->s_flags = otherEnd32(Ecvt,ScnTbl[sno].s_flags);

⌨️ 快捷键说明

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