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

📄 elf2flt.c

📁 embedded system 檔案格式轉換工具源代碼
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * elf2flt.c: Convert ELF (or any BFD format) to FLAT binary format * * (c) 1999-2002, Greg Ungerer <gerg@snapgear.com> * Created elf2flt from coff2flt (see copyrights below). Added all the * ELF format file handling. Extended relocation support for all of * text and data. * * (c) 2001, arm/arm-pic/arm-big-endian support <davidm@snapgear.com> * (c) 2001, v850 changes, Mile Bader <miles@lsi.nec.co.jp> * (c) 2001, zflat support <davidm@snapgear.com> * (c) 2001, Changes for GOT entries *           (Pale Dale, pauli@lineo.com, David McCullough davidm@lineo.com) * * Now supports PIC with GOT tables.  This works by taking a '.elf' file * and a fully linked elf executable (at address 0) and produces a flat * file that can be loaded with some fixups.  It still supports the old * style fully relocatable elf format files. * * Originally obj-res.c * * (c) 1998, Kenneth Albanowski <kjahds@kjahds.com> * (c) 1998, D. Jeff Dionne * (c) 1998, The Silver Hammer Group Ltd. * (c) 1996, 1997 Dionne & Associates *           jeff@ryeham.ee.ryerson.ca * * This is Free Software, under the GNU Public Licence v2 or greater. * * Relocation added March 1997, Kresten Krab Thorup  * krab@california.daimi.aau.dk */ #include <stdio.h>#include <fcntl.h>#include <stdlib.h>#include <sys/types.h>#include <netinet/in.h>#include <getopt.h>#include <stdarg.h>#include <bfd.h>#include <elf.h>#include "flat.h"#if defined(TARGET_m68k)#define	ARCH	"m68k/coldfire"#elif defined(TARGET_arm)#define	ARCH	"arm"#elif defined(TARGET_sparc)#define	ARCH	"sparc"#elif defined(TARGET_v850)#define	ARCH	"v850"#else#error "Don't know how to support you CPU archiecture??"#endif/* * Define a maximum number of bytes allowed in the offset table. * We'll fail if the table is larger than this. * * This limit may be different for platforms other than m68k, but * 8000 entries is a lot,  trust me :-) (davidm) */#define GOT_LIMIT 32767#ifndef O_BINARY#define O_BINARY 0#endifint verbose = 0;      /* extra output when running */int pic_with_got = 0; /* do elf/got processing with PIC code */int load_to_ram = 0;  /* instruct loader to allocate everything into RAM */int compress = 0;     /* 1 = compress everything, 2 = compress data only */int use_resolved = 0; /* If true, get the value of symbol references from */                      /* the program contents, not from the relocation table. */					  /* In this case, the input ELF file must be already */					  /* fully resolved (using the `-q' flag with recent */                      /* versions of GNU ld will give you a fully resolved */					  /* output file with relocation entries).  */const char *progname, *filename;int lineno;int nerrors = 0;int nwarnings = 0;static char where[200];enum {  /* Use exactly one of these: */  E_NOFILE = 0,         /* "progname: " */  E_FILE = 1,           /* "filename: " */  E_FILELINE = 2,       /* "filename:lineno: " */  E_FILEWHERE = 3,      /* "filename:%s: " -- set %s with ewhere() */            /* Add in any of these with |': */  E_WARNING = 0x10,  E_PERROR = 0x20};                  void ewhere (const char *format, ...);void einfo (int type, const char *format, ...);                  voidewhere (const char *format, ...) {  va_list args;  va_start (args, format);  vsprintf (where, format, args);  va_end (args);}voideinfo (int type, const char *format, ...) {  va_list args;  switch (type & 0x0f) {  case E_NOFILE:    fprintf (stderr, "%s: ", progname);    break;  case E_FILE:    fprintf (stderr, "%s: ", filename);    break;  case E_FILELINE:    ewhere ("%d", lineno);    /* fall-through */  case E_FILEWHERE:    fprintf (stderr, "%s:%s: ", filename, where);    break;  }  if (type & E_WARNING) {    fprintf (stderr, "warning: ");    nwarnings++;  }  else    nerrors++;  va_start (args, format);  vfprintf (stderr, format, args);  va_end (args);  if (type & E_PERROR)    perror ("");  else    fprintf (stderr, "\n");}asymbol**get_symbols (bfd *abfd, long *num){  long storage_needed;  asymbol **symbol_table;  long number_of_symbols;    storage_needed = bfd_get_symtab_upper_bound (abfd);	    if (storage_needed < 0)    abort ();        if (storage_needed == 0) {    return NULL;  }  symbol_table = (asymbol **) malloc (storage_needed);  number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);    if (number_of_symbols < 0)     abort ();  *num = number_of_symbols;  return symbol_table;}intdump_symbols(asymbol **symbol_table, long number_of_symbols){  long i;  printf("SYMBOL TABLE:\n");  for (i=0; i<number_of_symbols; i++) {	printf("  NAME=%s  VALUE=0x%x\n", symbol_table[i]->name,		symbol_table[i]->value);  }  printf("\n");  return(0);}  longget_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols){  long i;  for (i=0; i<number_of_symbols; i++) {    if (symbol_table[i]->section == sec) {      if (!strcmp(symbol_table[i]->name, name)) {	return symbol_table[i]->value;      }    }  }  return -1;}  longadd_com_to_bss(asymbol **symbol_table, long number_of_symbols, long bss_len){  long i, comsize;  long offset;  comsize = 0;  for (i=0; i<number_of_symbols; i++) {    if (strcmp("*COM*", symbol_table[i]->section->name) == 0) {      offset = bss_len + comsize;      comsize += symbol_table[i]->value;      symbol_table[i]->value = offset;    }  }  return comsize;}  unsigned long *output_relocs (  bfd *abs_bfd,  asymbol **symbols,  int number_of_symbols,  unsigned long *n_relocs,  unsigned char *text, int text_len, unsigned char *data, int data_len,  bfd *rel_bfd){  unsigned long		*flat_relocs;  asection		*a, *sym_section, *r;  arelent		**relpp, **p, *q;  const char		*sym_name, *section_name;  unsigned char		*sectionp;  unsigned long		pflags;  char			addstr[16];  long			sym_addr, sym_vma, section_vma;  int			relsize, relcount;  int			flat_reloc_count;  int			sym_reloc_size, rc;  int			got_size = 0;  asymbol		**symb;  long			nsymb;  #if 0  printf("%s(%d): output_relocs(abs_bfd=%d,synbols=%x,number_of_symbols=%d"	"n_relocs=%x,text=%x,text_len=%d,data=%x,data_len=%d)\n",	__FILE__, __LINE__, abs_bfd, symbols, number_of_symbols, n_relocs,	text, text_len, data, data_len);#endif#if 0dump_symbols(symbols, number_of_symbols);#endif  *n_relocs = 0;  flat_relocs = NULL;  flat_reloc_count = 0;  rc = 0;  pflags = 0;  /* Determine how big our offset table is in bytes.   * This isn't too difficult as we've terminated the table with -1.   * Also note that both the relocatable and absolute versions have this   * terminator even though the relocatable one doesn't have the GOT!   */  if (pic_with_got) {    unsigned long *lp = (unsigned long *)data;    /* Should call ntohl(*lp) here but is isn't going to matter */    while (*lp != 0xffffffff) lp++;    got_size = ((unsigned char *)lp) - data;    if (verbose)	    printf("GOT table contains %d entries (%d bytes)\n",			    got_size/sizeof(unsigned long), got_size);    if (got_size > GOT_LIMIT) {	    fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n",			    got_size, GOT_LIMIT);	    exit(1);    }  }  for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) {  	section_vma = bfd_section_vma(abs_bfd, a);	if (verbose)		printf("SECTION: %s [%x]: flags=%x vma=%x\n", a->name, a,			a->flags, section_vma);//	if (bfd_is_abs_section(a))//		continue;	if (bfd_is_und_section(a))		continue;	if (bfd_is_com_section(a))		continue;//	if ((a->flags & SEC_RELOC) == 0)//		continue;	/*	 *	Only relocate things in the data sections if we are PIC/GOT.	 *	otherwise do text as well	 */	if (!pic_with_got && strcmp(".text", a->name) == 0)		sectionp = text;	else if (strcmp(".data", a->name) == 0)		sectionp = data;	else		continue;	/* Now search for the equivalent section in the relocation binary	 * and use that relocation information to build reloc entries	 * for this one.	 */	for (r=rel_bfd->sections; r != NULL; r=r->next)		if (strcmp(a->name, r->name) == 0)			break;	if (r == NULL)	  continue;	if (verbose)	  printf(" RELOCS: %s [%x]: flags=%x vma=%x\n", r->name, r,			r->flags, bfd_section_vma(abs_bfd, r));  	if ((r->flags & SEC_RELOC) == 0)  	  continue;	relsize = bfd_get_reloc_upper_bound(rel_bfd, r);	if (relsize <= 0) {		if (verbose)			printf("%s(%d): no relocation entries section=%x\n",				__FILE__, __LINE__, r->name);		continue;	}	symb = get_symbols(rel_bfd, &nsymb);	relpp = (arelent **) xmalloc(relsize);	relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb);	if (relcount <= 0) {		if (verbose)			printf("%s(%d): no relocation entries section=%s\n",			__FILE__, __LINE__, r->name);		continue;	} else {		for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {			int relocation_needed = 0;#ifdef TARGET_v850			/* Skip this relocation entirely if possible (we			   do this early, before doing any other			   processing on it).  */			switch ((*p)->howto->type) {#ifdef R_V850_9_PCREL			case R_V850_9_PCREL:#endif#ifdef R_V850_22_PCREL			case R_V850_22_PCREL:#endif#ifdef R_V850_SDA_16_16_OFFSET			case R_V850_SDA_16_16_OFFSET:#endif#ifdef R_V850_SDA_15_16_OFFSET			case R_V850_SDA_15_16_OFFSET:#endif#ifdef R_V850_ZDA_15_16_OFFSET			case R_V850_ZDA_15_16_OFFSET:#endif#ifdef R_V850_TDA_6_8_OFFSET			case R_V850_TDA_6_8_OFFSET:#endif#ifdef R_V850_TDA_7_8_OFFSET			case R_V850_TDA_7_8_OFFSET:#endif#ifdef R_V850_TDA_7_7_OFFSET			case R_V850_TDA_7_7_OFFSET:#endif#ifdef R_V850_TDA_16_16_OFFSET			case R_V850_TDA_16_16_OFFSET:#endif#ifdef R_V850_TDA_4_5_OFFSET			case R_V850_TDA_4_5_OFFSET:#endif#ifdef R_V850_TDA_4_4_OFFSET			case R_V850_TDA_4_4_OFFSET:#endif#ifdef R_V850_SDA_16_16_SPLIT_OFFSET			case R_V850_SDA_16_16_SPLIT_OFFSET:#endif#ifdef R_V850_CALLT_6_7_OFFSET			case R_V850_CALLT_6_7_OFFSET:#endif#ifdef R_V850_CALLT_16_16_OFFSET			case R_V850_CALLT_16_16_OFFSET:#endif				/* These are relative relocations, which				   have already been fixed up by the				   linker at this point, so just ignore				   them.  */ 				continue;			}#endif /* USE_V850_RELOCS */			q = *p;			if (q->sym_ptr_ptr && *q->sym_ptr_ptr) {				sym_name = (*(q->sym_ptr_ptr))->name;				sym_section = (*(q->sym_ptr_ptr))->section;				section_name=(*(q->sym_ptr_ptr))->section->name;			} else {				printf("ERROR: undefined relocation entry\n");				rc = -1;				continue;			}			/* Adjust the address to account for the GOT table which wasn't			 * present in the relative file link.			 */			if (pic_with_got)			  q->address += got_size;								/*			 *	Fixup offset in the actual section.			 */			addstr[0] = 0;  			if ((sym_addr = get_symbol_offset((char *) sym_name,			    sym_section, symbols, number_of_symbols)) == -1) {				sym_addr = 0;			}			if (use_resolved) {				/* Use the address of the symbol already in				   the program text.  */				sym_addr = *((unsigned long *)					     (sectionp + q->address));			} else {				/* Calculate the sym address ourselves.  */				sym_reloc_size = bfd_get_reloc_size(q->howto);				if (sym_reloc_size != 4) {					printf("ERROR: bad reloc size=%d for symbol=%s\n",							sym_reloc_size, sym_name);					rc = -1;					continue;				}				switch ((*p)->howto->type) {#if defined(TARGET_m68k)				case R_68K_32:					relocation_needed = 1;					sym_vma = bfd_section_vma(abs_bfd, sym_section);					sym_addr += sym_vma + q->addend;					break;				case R_68K_PC32:					sym_vma = 0;					sym_addr += sym_vma + q->addend;					sym_addr -= q->address;					break;#endif#if defined(TARGET_arm)				case R_ARM_ABS32:					relocation_needed = 1;					if (verbose)						fprintf(stderr,							"%s vma=0x%x, value=0x%x, address=0x%x "							"sym_addr=0x%x rs=0x%x, opcode=0x%x\n",							"ABS32",							sym_vma, (*(q->sym_ptr_ptr))->value,							q->address, sym_addr,							(*p)->howto->rightshift,							*((unsigned long *) (sectionp + q->address)));					sym_vma = bfd_section_vma(abs_bfd, sym_section);					sym_addr += sym_vma + q->addend;					break;				case R_ARM_PLT32:					if (verbose)						fprintf(stderr,							"%s vma=0x%x, value=0x%x, address=0x%x "							"sym_addr=0x%x rs=0x%x, opcode=0x%x\n",							"PLT32",							sym_vma, (*(q->sym_ptr_ptr))->value,							q->address, sym_addr,							(*p)->howto->rightshift,							*((unsigned long *) (sectionp + q->address)));				case R_ARM_PC24:					sym_vma = 0;					sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift;					break;#endif#ifdef TARGET_v850#ifdef R_V850_32				case R_V850_32:#endif					sym_vma = bfd_section_vma(abs_bfd, sym_section);					sym_addr += sym_vma + q->addend;					break;#ifdef R_V850_ZDA_16_16_OFFSET				case R_V850_ZDA_16_16_OFFSET:#endif#ifdef R_V850_ZDA_16_16_SPLIT_OFFSET				case R_V850_ZDA_16_16_SPLIT_OFFSET:#endif					/* Can't support zero-relocations.  */					printf ("ERROR: %s+0x%x: zero relocations not supported\n",							sym_name, q->addend);					continue;#endif /* TARGET_v850 */#ifdef TARGET_sparc				case R_SPARC_32:				case R_SPARC_UA32:					relocation_needed = 1;					sym_vma = bfd_section_vma(abs_bfd, sym_section);					sym_addr += sym_vma + q->addend;					break;

⌨️ 快捷键说明

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