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

📄 oasys.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 3 页
字号:
/* BFD back-end for oasys objects.   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999   Free Software Foundation, Inc.   Written by Steve Chamberlain of Cygnus Support, <sac@cygnus.com>.This file is part of BFD, the Binary File Descriptor library.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */#define UNDERSCORE_HACK 1#include "bfd.h"#include "sysdep.h"#include <ctype.h>#include "libbfd.h"#include "oasys.h"#include "liboasys.h"/* XXX - FIXME.  offsetof belongs in the system-specific files in   ../include/sys. *//* Define offsetof for those systems which lack it */#ifndef offsetof#define offsetof(type, identifier) (size_t) &(((type *) 0)->identifier)#endifstatic boolean oasys_read_record PARAMS ((bfd *,					  oasys_record_union_type *));static boolean oasys_write_sections PARAMS ((bfd *));static boolean oasys_write_record PARAMS ((bfd *,					   oasys_record_enum_type,					   oasys_record_union_type *,					   size_t));static boolean oasys_write_syms PARAMS ((bfd *));static boolean oasys_write_header PARAMS ((bfd *));static boolean oasys_write_end PARAMS ((bfd *));static boolean oasys_write_data PARAMS ((bfd *));/* Read in all the section data and relocation stuff too */PROTO (static boolean, oasys_slurp_section_data, (bfd * CONST abfd));static booleanoasys_read_record (abfd, record)     bfd *abfd;     oasys_record_union_type *record;{  if (bfd_read ((PTR) record, 1, sizeof (record->header), abfd)      != sizeof (record->header))    return false;  if ((size_t) record->header.length <= (size_t) sizeof (record->header))    return true;  if (bfd_read ((PTR) (((char *) record) + sizeof (record->header)),		1, record->header.length - sizeof (record->header),		abfd)      != record->header.length - sizeof (record->header))    return false;  return true;}static size_toasys_string_length (record)     oasys_record_union_type *record;{  return record->header.length    - ((char *) record->symbol.name - (char *) record);}/*****************************************************************************//*Slurp the symbol table by reading in all the records at the start filetill we get to the first section record.We'll sort the symbolss into  two lists, defined and undefined. Theundefined symbols will be placed into the table according to theirrefno.We do this by placing all undefined symbols at the front of the tablemoving in, and the defined symbols at the end of the table moving back.*/static booleanoasys_slurp_symbol_table (abfd)     bfd *CONST abfd;{  oasys_record_union_type record;  oasys_data_type *data = OASYS_DATA (abfd);  boolean loop = true;  asymbol *dest_defined;  asymbol *dest;  char *string_ptr;  if (data->symbols != (asymbol *) NULL)    {      return true;    }  /* Buy enough memory for all the symbols and all the names */  data->symbols =    (asymbol *) bfd_alloc (abfd, sizeof (asymbol) * abfd->symcount);#ifdef UNDERSCORE_HACK  /* buy 1 more char for each symbol to keep the underscore in*/  data->strings = bfd_alloc (abfd, data->symbol_string_length +			     abfd->symcount);#else  data->strings = bfd_alloc (abfd, data->symbol_string_length);#endif  if (!data->symbols || !data->strings)    return false;  dest_defined = data->symbols + abfd->symcount - 1;  string_ptr = data->strings;  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)    return false;  while (loop)    {      if (! oasys_read_record (abfd, &record))	return false;      switch (record.header.type)	{	case oasys_record_is_header_enum:	  break;	case oasys_record_is_local_enum:	case oasys_record_is_symbol_enum:	  {	    int flag = record.header.type == (int) oasys_record_is_local_enum ?	    (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);	    size_t length = oasys_string_length (&record);	    switch (record.symbol.relb & RELOCATION_TYPE_BITS)	      {	      case RELOCATION_TYPE_ABS:		dest = dest_defined--;		dest->section = bfd_abs_section_ptr;		dest->flags = 0;		break;	      case RELOCATION_TYPE_REL:		dest = dest_defined--;		dest->section =		  OASYS_DATA (abfd)->sections[record.symbol.relb &					      RELOCATION_SECT_BITS];		if (record.header.type == (int) oasys_record_is_local_enum)		  {		    dest->flags = BSF_LOCAL;		    if (dest->section == (asection *) (~0))		      {			/* It seems that sometimes internal symbols are tied up, but		       still get output, even though there is no		       section */			dest->section = 0;		      }		  }		else		  {		    dest->flags = flag;		  }		break;	      case RELOCATION_TYPE_UND:		dest = data->symbols + bfd_h_get_16 (abfd, record.symbol.refno);		dest->section = bfd_und_section_ptr;		break;	      case RELOCATION_TYPE_COM:		dest = dest_defined--;		dest->name = string_ptr;		dest->the_bfd = abfd;		dest->section = bfd_com_section_ptr;		break;	      default:		dest = dest_defined--;		BFD_ASSERT (0);		break;	      }	    dest->name = string_ptr;	    dest->the_bfd = abfd;	    dest->udata.p = (PTR) NULL;	    dest->value = bfd_h_get_32 (abfd, record.symbol.value);#ifdef UNDERSCORE_HACK	    if (record.symbol.name[0] != '_')	      {		string_ptr[0] = '_';		string_ptr++;	      }#endif	    memcpy (string_ptr, record.symbol.name, length);	    string_ptr[length] = 0;	    string_ptr += length + 1;	  }	  break;	default:	  loop = false;	}    }  return true;}static longoasys_get_symtab_upper_bound (abfd)     bfd *CONST abfd;{  if (! oasys_slurp_symbol_table (abfd))    return -1;  return (abfd->symcount + 1) * (sizeof (oasys_symbol_type *));}/**/extern const bfd_target oasys_vec;longoasys_get_symtab (abfd, location)     bfd *abfd;     asymbol **location;{  asymbol *symbase;  unsigned int counter;  if (oasys_slurp_symbol_table (abfd) == false)    {      return -1;    }  symbase = OASYS_DATA (abfd)->symbols;  for (counter = 0; counter < abfd->symcount; counter++)    {      *(location++) = symbase++;    }  *location = 0;  return abfd->symcount;}/************************************************************************  archive stuff*/static const bfd_target *oasys_archive_p (abfd)     bfd *abfd;{  oasys_archive_header_type header;  oasys_extarchive_header_type header_ext;  unsigned int i;  file_ptr filepos;  if (bfd_seek (abfd, (file_ptr) 0, false) != 0      || (bfd_read ((PTR) & header_ext, 1, sizeof (header_ext), abfd)	  != sizeof (header_ext)))    {      if (bfd_get_error () != bfd_error_system_call)	bfd_set_error (bfd_error_wrong_format);      return NULL;    }  header.version = bfd_h_get_32 (abfd, header_ext.version);  header.mod_count = bfd_h_get_32 (abfd, header_ext.mod_count);  header.mod_tbl_offset = bfd_h_get_32 (abfd, header_ext.mod_tbl_offset);  header.sym_tbl_size = bfd_h_get_32 (abfd, header_ext.sym_tbl_size);  header.sym_count = bfd_h_get_32 (abfd, header_ext.sym_count);  header.sym_tbl_offset = bfd_h_get_32 (abfd, header_ext.sym_tbl_offset);  header.xref_count = bfd_h_get_32 (abfd, header_ext.xref_count);  header.xref_lst_offset = bfd_h_get_32 (abfd, header_ext.xref_lst_offset);  /*    There isn't a magic number in an Oasys archive, so the best we    can do to verify reasnableness is to make sure that the values in    the header are too weird    */  if (header.version > 10000 ||      header.mod_count > 10000 ||      header.sym_count > 100000 ||      header.xref_count > 100000)    return (const bfd_target *) NULL;  /*    That all worked, let's buy the space for the header and read in    the headers.    */  {    oasys_ar_data_type *ar =    (oasys_ar_data_type *) bfd_alloc (abfd, sizeof (oasys_ar_data_type));    oasys_module_info_type *module =    (oasys_module_info_type *)    bfd_alloc (abfd, sizeof (oasys_module_info_type) * header.mod_count);    oasys_module_table_type record;    if (!ar || !module)      return NULL;    abfd->tdata.oasys_ar_data = ar;    ar->module = module;    ar->module_count = header.mod_count;    filepos = header.mod_tbl_offset;    for (i = 0; i < header.mod_count; i++)      {	if (bfd_seek (abfd, filepos, SEEK_SET) != 0)	  return NULL;	/* There are two ways of specifying the archive header */	if (0)	  {	    oasys_extmodule_table_type_a_type record_ext;	    if (bfd_read ((PTR) & record_ext, 1, sizeof (record_ext), abfd)		!= sizeof (record_ext))	      return NULL;	    record.mod_size = bfd_h_get_32 (abfd, record_ext.mod_size);	    record.file_offset = bfd_h_get_32 (abfd, record_ext.file_offset);	    record.dep_count = bfd_h_get_32 (abfd, record_ext.dep_count);	    record.depee_count = bfd_h_get_32 (abfd, record_ext.depee_count);	    record.sect_count = bfd_h_get_32 (abfd, record_ext.sect_count);	    module[i].name = bfd_alloc (abfd, 33);	    if (!module[i].name)	      return NULL;	    memcpy (module[i].name, record_ext.mod_name, 33);	    filepos +=	      sizeof (record_ext) +	      record.dep_count * 4 +	      record.depee_count * 4 +	      record.sect_count * 8 + 187;	  }	else	  {	    oasys_extmodule_table_type_b_type record_ext;	    if (bfd_read ((PTR) & record_ext, 1, sizeof (record_ext), abfd)		!= sizeof (record_ext))	      return NULL;	    record.mod_size = bfd_h_get_32 (abfd, record_ext.mod_size);	    record.file_offset = bfd_h_get_32 (abfd, record_ext.file_offset);	    record.dep_count = bfd_h_get_32 (abfd, record_ext.dep_count);	    record.depee_count = bfd_h_get_32 (abfd, record_ext.depee_count);	    record.sect_count = bfd_h_get_32 (abfd, record_ext.sect_count);	    record.module_name_size = bfd_h_get_32 (abfd, record_ext.mod_name_length);	    module[i].name = bfd_alloc (abfd, record.module_name_size + 1);	    if (!module[i].name)	      return NULL;	    if (bfd_read ((PTR) module[i].name, 1, record.module_name_size,			  abfd)		!= record.module_name_size)	      return NULL;	    module[i].name[record.module_name_size] = 0;	    filepos +=	      sizeof (record_ext) +	      record.dep_count * 4 +	      record.module_name_size + 1;	  }	module[i].size = record.mod_size;	module[i].pos = record.file_offset;	module[i].abfd = 0;      }  }  return abfd->xvec;}static booleanoasys_mkobject (abfd)     bfd *abfd;{  abfd->tdata.oasys_obj_data = (oasys_data_type *) bfd_alloc (abfd, sizeof (oasys_data_type));  return abfd->tdata.oasys_obj_data ? true : false;}#define MAX_SECS 16static const bfd_target *oasys_object_p (abfd)     bfd *abfd;{  oasys_data_type *oasys;  oasys_data_type *save = OASYS_DATA (abfd);  boolean loop = true;  boolean had_usefull = false;  abfd->tdata.oasys_obj_data = 0;  oasys_mkobject (abfd);  oasys = OASYS_DATA (abfd);  memset ((PTR) oasys->sections, 0xff, sizeof (oasys->sections));  /* Point to the start of the file */  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)    goto fail;  oasys->symbol_string_length = 0;  /* Inspect the records, but only keep the section info -     remember the size of the symbols     */  oasys->first_data_record = 0;  while (loop)    {      oasys_record_union_type record;      if (! oasys_read_record (abfd, &record))	goto fail;      if ((size_t) record.header.length < (size_t) sizeof (record.header))	goto fail;      switch ((oasys_record_enum_type) (record.header.type))	{	case oasys_record_is_header_enum:	  had_usefull = true;	  break;	case oasys_record_is_symbol_enum:	case oasys_record_is_local_enum:	  /* Count symbols and remember their size for a future malloc   */	  abfd->symcount++;	  oasys->symbol_string_length += 1 + oasys_string_length (&record);	  had_usefull = true;	  break;	case oasys_record_is_section_enum:	  {	    asection *s;	    char *buffer;	    unsigned int section_number;	    if (record.section.header.length != sizeof (record.section))	      {		goto fail;	      }	    buffer = bfd_alloc (abfd, 3);	    if (!buffer)	      goto fail;	    section_number = record.section.relb & RELOCATION_SECT_BITS;	    sprintf (buffer, "%u", section_number);	    s = bfd_make_section (abfd, buffer);	    oasys->sections[section_number] = s;	    switch (record.section.relb & RELOCATION_TYPE_BITS)	      {	      case RELOCATION_TYPE_ABS:	      case RELOCATION_TYPE_REL:		break;	      case RELOCATION_TYPE_UND:	      case RELOCATION_TYPE_COM:		BFD_FAIL ();	      }	    s->_raw_size = bfd_h_get_32 (abfd, record.section.value);	    s->vma = bfd_h_get_32 (abfd, record.section.vma);	    s->flags = 0;	    had_usefull = true;	  }	  break;	case oasys_record_is_data_enum:	  oasys->first_data_record = bfd_tell (abfd) - record.header.length;	case oasys_record_is_debug_enum:	case oasys_record_is_module_enum:	case oasys_record_is_named_section_enum:	case oasys_record_is_end_enum:	  if (had_usefull == false)	    goto fail;	  loop = false;	  break;	default:	  goto fail;	}    }  oasys->symbols = (asymbol *) NULL;  /*    Oasys support several architectures, but I can't see a simple way    to discover which one is in a particular file - we'll guess    */  bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);  if (abfd->symcount != 0)    {      abfd->flags |= HAS_SYMS;    }  /*    We don't know if a section has data until we've read it..    */  oasys_slurp_section_data (abfd);  return abfd->xvec;fail:  (void) bfd_release (abfd, oasys);  abfd->tdata.oasys_obj_data = save;  return (const bfd_target *) NULL;}

⌨️ 快捷键说明

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