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

📄 oasys.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* BFD back-end for oasys objects.   Copyright 1990, 1991, 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */#define UNDERSCORE_HACK 1#include "bfd.h"#include "sysdep.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) #endif/* Read in all the section data and relocation stuff too */PROTO(static boolean,oasys_slurp_section_data,(bfd *CONST abfd));static void DEFUN(oasys_read_record,(abfd, record),      bfd *CONST abfd AND       oasys_record_union_type *record){  bfd_read((PTR)record, 1, sizeof(record->header), abfd);  if ((size_t) record->header.length <= (size_t) sizeof (record->header))    return;  bfd_read((PTR)(((char *)record )+ sizeof(record->header)),	   1, record->header.length - sizeof(record->header),	   abfd);}static size_tDEFUN(oasys_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 booleanDEFUN(oasys_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  dest_defined = data->symbols + abfd->symcount -1;  string_ptr = data->strings;  bfd_seek(abfd, (file_ptr)0, SEEK_SET);  while (loop) {    oasys_read_record(abfd, &record);    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;	    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, (bfd_byte *)&record.symbol.refno[0]);	    dest->section = &bfd_und_section;	    break;	  case RELOCATION_TYPE_COM:	    dest = dest_defined--;	    dest->name = string_ptr;	    dest->the_bfd = abfd;	    dest->section = &bfd_com_section;	    break;	  default:	    dest = dest_defined--;	    BFD_ASSERT(0);	    break;	  }	  dest->name = string_ptr;	  dest->the_bfd = abfd;	  dest->udata = (PTR)NULL;	  dest->value = bfd_h_get_32(abfd, (bfd_byte *)&record.symbol.value[0]);#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 unsigned intDEFUN(oasys_get_symtab_upper_bound,(abfd),     bfd *CONST abfd){  oasys_slurp_symbol_table (abfd);  return    (abfd->symcount+1) * (sizeof (oasys_symbol_type *));}/* */extern bfd_target oasys_vec;unsigned intDEFUN(oasys_get_symtab,(abfd, location),      bfd *abfd AND      asymbol **location){  asymbol *symbase ;  unsigned int counter ;  if (oasys_slurp_symbol_table(abfd) == false) {    return 0;  }  symbase = OASYS_DATA(abfd)->symbols;  for (counter = 0; counter < abfd->symcount; counter++) {    *(location++) = symbase++;  }  *location = 0;  return abfd->symcount;}/************************************************************************  archive stuff */static bfd_target *DEFUN(oasys_archive_p,(abfd),      bfd *abfd){  oasys_archive_header_type header;  oasys_extarchive_header_type header_ext;  unsigned int i;  file_ptr filepos;    bfd_seek(abfd, (file_ptr) 0, false);    bfd_read((PTR)&header_ext, 1, sizeof(header_ext), abfd);  header.version = bfd_h_get_32(abfd, (bfd_byte *)header_ext.version);  header.mod_count = bfd_h_get_32(abfd, (bfd_byte *)header_ext.mod_count);  header.mod_tbl_offset = bfd_h_get_32(abfd, (bfd_byte *)header_ext.mod_tbl_offset);  header.sym_tbl_size = bfd_h_get_32(abfd, (bfd_byte *)header_ext.sym_tbl_size);  header.sym_count = bfd_h_get_32(abfd, (bfd_byte *)header_ext.sym_count);  header.sym_tbl_offset = bfd_h_get_32(abfd, (bfd_byte *)header_ext.sym_tbl_offset);  header.xref_count = bfd_h_get_32(abfd, (bfd_byte *)header_ext.xref_count);  header.xref_lst_offset = bfd_h_get_32(abfd, (bfd_byte *)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 (bfd_target *)NULL;  /*    That all worked, lets 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;      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++) {        bfd_seek(abfd, filepos, SEEK_SET);	/* There are two ways of specifying the archive header */	if (0) {	  oasys_extmodule_table_type_a_type record_ext;	  bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);		  record.mod_size = bfd_h_get_32(abfd, (bfd_byte *)record_ext.mod_size);	  record.file_offset = bfd_h_get_32(abfd,					 (bfd_byte *)   record_ext.file_offset);	  record.dep_count = bfd_h_get_32(abfd, (bfd_byte *)record_ext.dep_count);	  record.depee_count = bfd_h_get_32(abfd,(bfd_byte *) record_ext.depee_count);	  record.sect_count = bfd_h_get_32(abfd, (bfd_byte *) record_ext.sect_count);	  module[i].name = bfd_alloc(abfd,33);	  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;	  bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);		  record.mod_size = bfd_h_get_32(abfd, (bfd_byte *) record_ext.mod_size);	  record.file_offset = bfd_h_get_32(abfd,					    (bfd_byte *)record_ext.file_offset);	  record.dep_count = bfd_h_get_32(abfd, (bfd_byte *) record_ext.dep_count);	  record.depee_count = bfd_h_get_32(abfd, (bfd_byte *) record_ext.depee_count);	  record.sect_count = bfd_h_get_32(abfd, (bfd_byte *) record_ext.sect_count);	  record.module_name_size = bfd_h_get_32(abfd, (bfd_byte *) record_ext.mod_name_length);	  module[i].name = bfd_alloc(abfd,record.module_name_size + 1);	  bfd_read((PTR)module[i].name, 1, record.module_name_size, abfd);	  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 booleanDEFUN(oasys_mkobject,(abfd),      bfd *abfd){  abfd->tdata.oasys_obj_data =    (oasys_data_type*)bfd_alloc(abfd, sizeof(oasys_data_type));  return true;}#define MAX_SECS 16static bfd_target *DEFUN(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 */  bfd_seek(abfd, (file_ptr)0, SEEK_SET);  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;    oasys_read_record(abfd, &record);    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);	  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, (bfd_byte *) & record.section.value[0]) ;	  s->vma = bfd_h_get_32(abfd, (bfd_byte *)&record.section.vma[0]);	  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);

⌨️ 快捷键说明

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