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

📄 coffobj.c

📁 Omap5910 上实现双核通信 DSP GateWay
💻 C
字号:
/* * coffobj.c * * Copyright (C) 2003-2005 Nokia Corporation * * Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com> * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * 2004/07/22:  DSP Gateway version 3.2 */#include <stdio.h>#include <unistd.h>#include <string.h>#include <malloc.h>#include <fcntl.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/mman.h>#include "coff-c55x.h"#include "cofflib.h"#include "section.h"#include "symbol.h"void coff_init(struct coffobj *cobj);void coff_clear(struct coffobj *cobj);char *scnname(struct coff *coff, char *name){	static char nm[9];	if (name[0] == 0) {		u32 idx = COFF_LONG((&name[4]));		return &coff->strtbl[idx];	} else {		strncpy(nm, name, 8);		nm[8] = '\0';		return nm;	}}void scnname_put(struct coff *coff, char *name, char *dst){	u32 len = strlen(name);	memset(dst, 0, 8);	if (len <= 8)		strncpy(dst, name, 8);	else {		u32 strtblsz = COFF_LONG(coff->strtbl);		strcpy(coff->strtbl + strtblsz, name);		COFF_PUT_LONG(strtblsz, (&dst[4]));		strtblsz += len + 1;		COFF_PUT_LONG(strtblsz, coff->strtbl);	}}char *symname(struct coff *coff, COFF_SYMENT *sym){	static char nm[E_SYMNMLEN+1];	if (COFF_LONG(sym->e.e.e_zeroes) == 0) {		u32 idx = COFF_LONG(sym->e.e.e_offset);		return &coff->strtbl[idx];	} else {		strncpy(nm, sym->e.e_name, E_SYMNMLEN);		nm[E_SYMNMLEN] = '\0';		return nm;	}}void symname_put(struct coff *coff, char *name, COFF_SYMENT *dst){	u32 len = strlen(name);	memset(dst->e.e_name, 0, E_SYMNMLEN);	if (len <= E_SYMNMLEN)		strncpy(dst->e.e_name, name, E_SYMNMLEN);	else {		u32 strtblsz = COFF_LONG(coff->strtbl);		strcpy(coff->strtbl + strtblsz, name);		COFF_PUT_LONG(strtblsz, dst->e.e.e_offset);		strtblsz += len + 1;		COFF_PUT_LONG(strtblsz, coff->strtbl);	}}struct coffobj *coff_new(void){	struct coffobj *cobj = malloc(sizeof(struct coffobj));	coff_init(cobj);	return cobj;}void coff_free(struct coffobj *cobj){	coff_clear(cobj);	if (cobj->aouthdr)		free(cobj->aouthdr);	free(cobj);}void coff_init(struct coffobj *cobj){	cobj->aouthdr = NULL;	INIT_LIST_HEAD(&cobj->scnlist);	INIT_LIST_HEAD(&cobj->symlist);}void coff_clear(struct coffobj *cobj){	section_freelist(&cobj->scnlist);	symbol_freelist(&cobj->symlist);}int coff_read(struct coffobj *cobj, char *fn){	struct coff coff;	int fd;	struct stat stat;	size_t size;	u8 *src;	u16 nscns;	u32 symptr;	u32 nsyms;	u16 opthdr;	u32 strtblsz;	if ((fd = open(fn, O_RDONLY)) < 0) {		fprintf(stderr, "Can't open %s\n", fn);		return -1;	}	/* acquiring file size */	if (fstat(fd, &stat) < 0) {		fprintf(stderr, "%s: fstat() faild\n", fn);		return -1;	}	size = stat.st_size;	/* mmap */	if ((src = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0)) < 0) {		fprintf(stderr, "%s: mmap() failed\n", fn);		return -1;	}	/* COFF file header */	coff.coffhdr = (COFF_FILHDR*)&src[0];	cobj->verid = COFF_SHORT(coff.coffhdr->f_verid);	nscns  = COFF_SHORT(coff.coffhdr->f_nscns);	symptr = COFF_LONG(coff.coffhdr->f_symptr);	nsyms  = COFF_LONG(coff.coffhdr->f_nsyms);	opthdr = COFF_SHORT(coff.coffhdr->f_opthdr);	cobj->flags = COFF_SHORT(coff.coffhdr->f_flags);	cobj->tgtid = COFF_SHORT(coff.coffhdr->f_tgtid);	/*	 * some checks are done here.	 */	if (cobj->tgtid != COFF_TGTID_C55X) {		fprintf(stderr,			"%s: Unknown COFF target ID [0x%04x]!\n"			"We are not sure if this file can be executed "			"in this system.\n", fn, cobj->tgtid);	}	/* a.out header */	if (opthdr) {		coff.aouthdr = (COFF_AOUTHDR *)&src[COFF_FILHSZ];		cobj->aouthdr = malloc(COFF_AOUTSZ);		cobj->aouthdr->magic = COFF_SHORT(coff.aouthdr->magic);		cobj->aouthdr->vstamp = COFF_SHORT(coff.aouthdr->vstamp);		cobj->aouthdr->entry = COFF_LONG(coff.aouthdr->entry);		cobj->aouthdr->text_start = COFF_LONG(coff.aouthdr->text_start);		cobj->aouthdr->data_start = COFF_LONG(coff.aouthdr->data_start);	}	/* section header */	coff.scnhdr = (COFF_SCNHDR*)&src[COFF_FILHSZ + opthdr];	/* symbol table */	coff.symtbl = (COFF_SYMENT*)&src[symptr];	/* string table */	coff.strtbl = &src[symptr + COFF_SYMESZ * nsyms];	strtblsz = COFF_LONG(coff.strtbl);	section_createlist(&cobj->scnlist, nscns);	symbol_createlist(&cobj->symlist, nsyms);	section_filllist(&coff, src, cobj, nscns);	symbol_filllist(&coff, src, cobj, nsyms);	munmap(src, size);	close(fd);	return 0;}int coff_write(struct coffobj *cobj, char *fn){	struct coff coff;	int fd;	const char dummy_c = 0;	struct timeval tm;	size_t size;	u8 *dst;	u16 nscns;	u32 scnptr, symptr, strptr;	u32 nsyms;	u16 opthdr;	u32 strtblsz;	unlink(fn);	if ((fd = open(fn, O_RDWR | O_CREAT, 0644)) < 0) {		fprintf(stderr, "Can't open %s for write.\n", fn);		return -1;	}	/* size info */	opthdr = cobj->aouthdr ? COFF_AOUTSZ : 0;	nscns = list_count(&cobj->scnlist);	nsyms = symbol_countlist(&cobj->symlist);	scnptr = COFF_FILHSZ + opthdr;	symptr = scnptr + nscns * COFF_SCNHSZ +		 section_total_datasz(&cobj->scnlist);	strptr = symptr + COFF_SYMESZ * nsyms;	size = strptr + 4 + section_total_strtblsz(&cobj->scnlist) +	       symbol_total_strtblsz(&cobj->symlist);	lseek(fd, size-1, SEEK_SET);	write(fd, &dummy_c, 1);	/* mmap */	if ((dst = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) < 0) {		fprintf(stderr, "%s: mmap() failed\n", fn);		return -1;	}	coff.coffhdr = (COFF_FILHDR*)&dst[0];	if (opthdr)		coff.aouthdr = (COFF_AOUTHDR *)&dst[COFF_FILHSZ];	coff.scnhdr  = (COFF_SCNHDR*)&dst[scnptr];	coff.symtbl  = (COFF_SYMENT*)&dst[symptr];	coff.strtbl  = &dst[strptr];	/* COFF file header */	gettimeofday(&tm, NULL);	COFF_PUT_SHORT(cobj->verid, coff.coffhdr->f_verid);	COFF_PUT_SHORT(nscns,       coff.coffhdr->f_nscns);	COFF_PUT_LONG(tm.tv_sec,   coff.coffhdr->f_timdat);	COFF_PUT_LONG(symptr,       coff.coffhdr->f_symptr);	COFF_PUT_LONG(nsyms,        coff.coffhdr->f_nsyms);	COFF_PUT_SHORT(opthdr,      coff.coffhdr->f_opthdr);	COFF_PUT_SHORT(cobj->flags, coff.coffhdr->f_flags);	COFF_PUT_SHORT(cobj->tgtid, coff.coffhdr->f_tgtid);	/* a.out header */	if (cobj->aouthdr) {		u32 tsize;		u32 dsize;		u32 bsize;		struct section *scn;				scn = section_find_by_name(&cobj->scnlist, ".text");		tsize = scn ? scn->size : 0;		scn = section_find_by_name(&cobj->scnlist, ".data");		dsize = scn ? scn->size : 0;		scn = section_find_by_name(&cobj->scnlist, ".bss");		bsize = scn ? scn->size : 0;		COFF_PUT_SHORT(cobj->aouthdr->magic,     coff.aouthdr->magic);		COFF_PUT_SHORT(cobj->aouthdr->vstamp,    coff.aouthdr->vstamp);		COFF_PUT_LONG(tsize,                     coff.aouthdr->tsize);		COFF_PUT_LONG(dsize,                     coff.aouthdr->dsize);		COFF_PUT_LONG(bsize,                     coff.aouthdr->bsize);		COFF_PUT_LONG(cobj->aouthdr->entry,      coff.aouthdr->entry);		COFF_PUT_LONG(cobj->aouthdr->text_start, coff.aouthdr->text_start);		COFF_PUT_LONG(cobj->aouthdr->data_start, coff.aouthdr->data_start);	}	/* string table init */	strtblsz = 4;	COFF_PUT_LONG(strtblsz, coff.strtbl);	section_putlist(&coff, dst, cobj, nscns);	symbol_putlist(&coff, cobj);	munmap(dst, size);	close(fd);	return 0;}

⌨️ 快捷键说明

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