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

📄 oasys.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
  return abfd->xvec; fail:  (void)  bfd_release(abfd, oasys);  abfd->tdata.oasys_obj_data = save;  return (bfd_target *)NULL;}static void DEFUN(oasys_print_symbol,(ignore_abfd, afile, symbol, how),      bfd *ignore_abfd AND      PTR afile AND      asymbol *symbol AND      bfd_print_symbol_type how){  FILE *file = (FILE *)afile;  switch (how) {  case bfd_print_symbol_name:  case bfd_print_symbol_more:    fprintf(file,"%s", symbol->name);    break;  case bfd_print_symbol_all:  case bfd_print_symbol_nm:    {      CONST char *section_name = symbol->section == (asection *)NULL ?	(CONST char *) "*abs" : symbol->section->name;      bfd_print_symbol_vandf((PTR)file,symbol);      fprintf(file," %-5s %s",	      section_name,	      symbol->name);    }    break;  }}/* The howto table is build using the top two bits of a reloc byte to index into it. The bits are PCREL,WORD/LONG*/static reloc_howto_type howto_table[]= {HOWTO(  0, 0,  1,   16, false,0,   true,true,0,"abs16",true,0x0000ffff, 0x0000ffff,false),HOWTO(  0, 0,  2,   32, false,0,   true,true,0,"abs32",true,0xffffffff, 0xffffffff,false),HOWTO(  0, 0,  1,   16, true,0,   true,true,0,"pcrel16",true,0x0000ffff, 0x0000ffff,false),HOWTO(  0, 0,  2,   32, true,0,   true,true,0,"pcrel32",true,0xffffffff, 0xffffffff,false)};/* Read in all the section data and relocation stuff too */static boolean DEFUN(oasys_slurp_section_data,(abfd),  bfd *CONST abfd){  oasys_record_union_type record;  oasys_data_type *data = OASYS_DATA(abfd);  boolean loop = true;  oasys_per_section_type *per ;  asection *s;  /* See if the data has been slurped already .. */  for (s = abfd->sections; s != (asection *)NULL; s= s->next) {    per =  oasys_per_section(s);    if (per->initialized == true)       return true;  }  if (data->first_data_record == 0)  return true;  bfd_seek(abfd, data->first_data_record, SEEK_SET);  while (loop) {    oasys_read_record(abfd, &record);    switch (record.header.type) 	{	case oasys_record_is_header_enum:	  break;	case oasys_record_is_data_enum:	    {	      uint8e_type *src = record.data.data;	      uint8e_type *end_src = ((uint8e_type *)&record) +		record.header.length;	      unsigned int relbit;	      bfd_byte *dst_ptr ;	      bfd_byte *dst_base_ptr ;	      unsigned int count;	      asection *  section =		data->sections[record.data.relb & RELOCATION_SECT_BITS];	      bfd_vma dst_offset ;	      per =  oasys_per_section(section);	      if (per->initialized == false) 		  {		    per->data = (bfd_byte *) bfd_zalloc(abfd, section->_raw_size);		    per->reloc_tail_ptr = (oasys_reloc_type **)&(section->relocation);		    per->had_vma = false;		    per->initialized = true;		    section->reloc_count = 0;		    section->flags = SEC_ALLOC;		  }	      dst_offset = bfd_h_get_32(abfd, record.data.addr) ;	      if (per->had_vma == false) {		/* Take the first vma we see as the base */		section->vma = dst_offset;		per->had_vma = true;	      }	      dst_offset -=   section->vma;	      dst_base_ptr = oasys_per_section(section)->data;	      dst_ptr = oasys_per_section(section)->data +		dst_offset;	      if (src < end_src) {		section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;	      }	      while (src < end_src) {		uint8e_type mod_byte = *src++;		uint32_type gap = end_src - src;				count = 8;		if (mod_byte == 0 && gap >= 8) {		  dst_ptr[0] = src[0];		  dst_ptr[1] = src[1];		  dst_ptr[2] = src[2];		  dst_ptr[3] = src[3];		  dst_ptr[4] = src[4];		  dst_ptr[5] = src[5];		  dst_ptr[6] = src[6];		  dst_ptr[7] = src[7];		  dst_ptr+= 8;		  src += 8;		}		else {		  for (relbit = 1; count-- != 0 && src < end_src; relbit <<=1) 		      {			if (relbit & mod_byte) 			    {			      uint8e_type reloc = *src;			      /* This item needs to be relocated */			      switch (reloc & RELOCATION_TYPE_BITS) {			      case RELOCATION_TYPE_ABS:				break;			      case RELOCATION_TYPE_REL: 				  {				    /* Relocate the item relative to the section */				    oasys_reloc_type *r =				      (oasys_reloc_type *)					bfd_alloc(abfd,						  sizeof(oasys_reloc_type));				    *(per->reloc_tail_ptr) = r;				    per->reloc_tail_ptr = &r->next;				    r->next= (oasys_reloc_type *)NULL;				    /* Reference to undefined symbol */				    src++;				    /* There is no symbol */				    r->symbol = 0;				    /* Work out the howto */				    abort();#if 0				    r->relent.section =				      data->sections[reloc &						     RELOCATION_SECT_BITS];				    r->relent.addend = -				     r->relent.section->vma;#endif				    r->relent.address = dst_ptr - dst_base_ptr;				    r->relent.howto = &howto_table[reloc>>6];				    r->relent.sym_ptr_ptr = (asymbol **)NULL;				    section->reloc_count++;				    /* Fake up the data to look like it's got the -ve pc in it, this makes				       it much easier to convert into other formats. This is done by				       hitting the addend.				       */				    if (r->relent.howto->pc_relative == true) {				      r->relent.addend -= dst_ptr - dst_base_ptr;				    }				  }				break;			      case RELOCATION_TYPE_UND:				  { 				    oasys_reloc_type *r =				      (oasys_reloc_type *)					bfd_alloc(abfd,						  sizeof(oasys_reloc_type));				    *(per->reloc_tail_ptr) = r;				    per->reloc_tail_ptr = &r->next;				    r->next= (oasys_reloc_type *)NULL;				    /* Reference to undefined symbol */				    src++;				    /* Get symbol number */				    r->symbol = (src[0]<<8) | src[1];				    /* Work out the howto */				    abort();				    #if 0				    r->relent.section = (asection							 *)NULL;#endif				    r->relent.addend = 0;				    r->relent.address = dst_ptr - dst_base_ptr;				    r->relent.howto = &howto_table[reloc>>6];				    r->relent.sym_ptr_ptr = (asymbol **)NULL;				    section->reloc_count++;				    src+=2;				    /* Fake up the data to look like it's got the -ve pc in it, this makes				       it much easier to convert into other formats. This is done by				       hitting the addend.				       */				    if (r->relent.howto->pc_relative == true) {				      r->relent.addend -= dst_ptr - dst_base_ptr;				    }								  }				break;			      case RELOCATION_TYPE_COM:				BFD_FAIL();			      }			    }			*dst_ptr++ = *src++;		      }		}	      }	  	    }	  break;	case oasys_record_is_local_enum:	case oasys_record_is_symbol_enum:	case oasys_record_is_section_enum:	  break;	default:	  loop = false;	}  }  return true;}bfd_error_vector_type bfd_error_vector;static booleanDEFUN(oasys_new_section_hook,(abfd, newsect),      bfd *abfd AND      asection *newsect){  newsect->used_by_bfd = (PTR)    bfd_alloc(abfd, sizeof(oasys_per_section_type));  oasys_per_section( newsect)->data = (bfd_byte *)NULL;  oasys_per_section(newsect)->section = newsect;  oasys_per_section(newsect)->offset  = 0;  oasys_per_section(newsect)->initialized = false;  newsect->alignment_power = 1;  /* Turn the section string into an index */  sscanf(newsect->name,"%u", &newsect->target_index);  return true;}static unsigned intDEFUN(oasys_get_reloc_upper_bound, (abfd, asect),      bfd *abfd AND      sec_ptr asect){  oasys_slurp_section_data(abfd);  return (asect->reloc_count+1) * sizeof(arelent *);}static booleanDEFUN(oasys_get_section_contents,(abfd, section, location, offset, count),      bfd *abfd AND      sec_ptr section AND      PTR location AND      file_ptr offset AND      bfd_size_type count){  oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;  oasys_slurp_section_data(abfd);  if (p->initialized == false)       {	(void) memset(location, 0, (int)count);      }  else       {	(void) memcpy(location,(PTR)( p->data + offset), (int)count);      }  return true;}unsigned intDEFUN(oasys_canonicalize_reloc,(ignore_abfd, section, relptr, symbols),      bfd *ignore_abfd AND      sec_ptr section AND      arelent **relptr AND      asymbol **symbols){  unsigned int reloc_count = 0;  oasys_reloc_type *src = (oasys_reloc_type *)(section->relocation);  while (src != (oasys_reloc_type *)NULL) {      abort();      #if 0    if (src->relent.section == (asection *)NULL) 	{	  src->relent.sym_ptr_ptr = symbols + src->symbol;	}#endif    *relptr ++ = &src->relent;    src = src->next;    reloc_count++;  }  *relptr = (arelent *)NULL;  return section->reloc_count = reloc_count;}/* Writing *//* Calculate the checksum and write one record */static void DEFUN(oasys_write_record,(abfd, type, record, size),      bfd *CONST abfd AND      CONST oasys_record_enum_type type AND      oasys_record_union_type *record AND      CONST size_t size){  int checksum;  size_t i;  uint8e_type *ptr;  record->header.length = size;  record->header.type = (int)type;  record->header.check_sum = 0;  record->header.fill = 0;  ptr = &record->pad[0];  checksum = 0;  for (i = 0; i < size; i++) {    checksum += *ptr++;  }  record->header.check_sum = 0xff & (- checksum);  bfd_write((PTR)record, 1, size, abfd);}/* Write out all the symbols */static void DEFUN(oasys_write_syms, (abfd),      bfd * CONST abfd){  unsigned int count;  asymbol **generic = bfd_get_outsymbols(abfd);  unsigned int index = 0;  for (count = 0; count < bfd_get_symcount(abfd); count++) {    oasys_symbol_record_type symbol;    asymbol * CONST g = generic[count];    CONST    char *src = g->name;    char *dst = symbol.name;    unsigned int l = 0;    if (g->section == & bfd_com_section) {      symbol.relb = RELOCATION_TYPE_COM;      bfd_h_put_16(abfd, index, (uint8e_type *)(&symbol.refno[0]));      index++;    }    else if (g->section == & bfd_abs_section) {      symbol.relb = RELOCATION_TYPE_ABS;      bfd_h_put_16(abfd, 0, (uint8e_type *)(&symbol.refno[0]));    }    else if (g->section == &bfd_und_section) {      symbol.relb = RELOCATION_TYPE_UND ;      bfd_h_put_16(abfd, index, (uint8e_type *)(&symbol.refno[0]));      /* Overload the value field with the output index number */      index++;    }    else if (g->flags & BSF_DEBUGGING) {      /* throw it away */      continue;    }    else {      if (g->section == (asection *)NULL) {	/* Sometime, the oasys tools give out a symbol with illegal	   bits in it, we'll output it in the same broken way */		symbol.relb = RELOCATION_TYPE_REL | 0;      }      else {	symbol.relb = RELOCATION_TYPE_REL |g->section->output_section->target_index;      }      bfd_h_put_16(abfd, 0, (uint8e_type *)(&symbol.refno[0]));    }#ifdef UNDERSCORE_HACK    if (src[l] == '_')      dst[l++] = '.';#endif    while (src[l]) {      dst[l] = src[l];      l++;    }    bfd_h_put_32(abfd, g->value, (bfd_byte*) symbol.value);          if (g->flags & BSF_LOCAL) {      oasys_write_record(abfd, 				 oasys_record_is_local_enum,			 (oasys_record_union_type *) &symbol,			 offsetof(oasys_symbol_record_type, name[0]) + l);    }    else {      oasys_write_record(abfd, 				 oasys_record_is_symbol_enum,			 (oasys_record_union_type *) &symbol,			 offsetof(oasys_symbol_record_type, name[0]) + l);    }    g->value = index-1;  }}  /* Write a section header for each section */static void 

⌨️ 快捷键说明

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