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

📄 bout.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
  int incode_mask;  int size_mask;  bfd_vma prev_addr = 0;  unsigned int count;  size_t  reloc_size;  struct relocation_info *relocs;  arelent *reloc_cache;  if (asect->relocation) return true;  if (!aout_32_slurp_symbol_table (abfd)) return false;  if (asect == obj_datasec (abfd)) {    reloc_size = exec_hdr(abfd)->a_drsize;    goto doit;  }  if (asect == obj_textsec (abfd)) {    reloc_size = exec_hdr(abfd)->a_trsize;    goto doit;  }  bfd_error = invalid_operation;  return false; doit:  bfd_seek (abfd, (file_ptr)(asect->rel_filepos),  SEEK_SET);  count = reloc_size / sizeof (struct relocation_info);  relocs = (struct relocation_info *) bfd_xmalloc (reloc_size);  if (!relocs) {    bfd_error = no_memory;    return false;  }  reloc_cache = (arelent *) bfd_xmalloc ((count+1) * sizeof (arelent));  if (!reloc_cache) {    free ((char*)relocs);    bfd_error = no_memory;    return false;  }  if (bfd_read ((PTR) relocs, 1, reloc_size, abfd) != reloc_size) {    bfd_error = system_call_error;    free (reloc_cache);    free (relocs);    return false;  }    if (abfd->xvec->header_byteorder_big_p) {    /* big-endian bit field allocation order */    pcrel_mask  = 0x80;    extern_mask = 0x10;    incode_mask = 0x08;    callj_mask  = 0x02;    size_mask =   0x20;    length_shift = 5;  } else {    /* little-endian bit field allocation order */    pcrel_mask  = 0x01;    extern_mask = 0x08;    incode_mask = 0x10;    callj_mask  = 0x40;    size_mask   = 0x02;    length_shift = 1;  }  for (rptr = relocs, cache_ptr = reloc_cache, counter = 0;       counter < count;       counter++, rptr++, cache_ptr++)   {    unsigned char *raw = (unsigned char *)rptr;    unsigned int symnum;    cache_ptr->address = bfd_h_get_32 (abfd, raw + 0);    cache_ptr->howto = 0;    if (abfd->xvec->header_byteorder_big_p)     {      symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6];    }     else    {      symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4];    }    if (raw[7] & extern_mask)     {      /* if this is set then the r_index is a index into the symbol table;       * if the bit is not set then r_index contains a section map.       * we either fill in the sym entry with a pointer to the symbol,       * or point to the correct section       */      cache_ptr->sym_ptr_ptr = symbols + symnum;      cache_ptr->addend = 0;    } else     {      /* in a.out symbols are relative to the beginning of the       * file rather than sections ?       * (look in translate_from_native_sym_flags)       * the reloc entry addend has added to it the offset into the       * file of the data, so subtract the base to make the reloc       * section relative */      int s;      {	/* sign-extend symnum from 24 bits to whatever host uses */	s = symnum;	if (s & (1 << 23))	  s |= (~0) << 24;      }      cache_ptr->sym_ptr_ptr = (asymbol **)NULL;      switch (s)      {       case N_TEXT:       case N_TEXT | N_EXT:	cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr;	cache_ptr->addend = - obj_textsec(abfd)->vma;	break;       case N_DATA:       case N_DATA | N_EXT:	cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr;	cache_ptr->addend = - obj_datasec(abfd)->vma;	break;       case N_BSS:       case N_BSS | N_EXT:	cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;	cache_ptr->addend =  - obj_bsssec(abfd)->vma;	break;       case N_ABS:       case N_ABS | N_EXT:	cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;	cache_ptr->addend = 0;	break;      case -2: /* .align */	if (raw[7] & pcrel_mask)	  {	    cache_ptr->howto = &howto_align_table[(raw[7] >> length_shift) & 3];	    cache_ptr->sym_ptr_ptr = &bfd_abs_symbol;	  }	else	  {	    /* .org? */	    abort ();	  }	cache_ptr->addend = 0;	break;       default:	BFD_ASSERT(0);	break;      }	    }    /* the i960 only has a few relocation types:       abs 32-bit and pcrel 24bit.   except for callj's!  */    if (cache_ptr->howto != 0)      ;    else if (raw[7] & callj_mask)    {      cache_ptr->howto = &howto_reloc_callj;    }    else if ( raw[7] & pcrel_mask)    {      if (raw[7] & size_mask)       cache_ptr->howto = &howto_reloc_pcrel13;      else       cache_ptr->howto = &howto_reloc_pcrel24;    }    else     {      if (raw[7] & incode_mask)       {	cache_ptr->howto = &howto_reloc_abs32code;      }      else       {	cache_ptr->howto = &howto_reloc_abs32;      }    }    if (cache_ptr->address < prev_addr)     {      /* Ouch! this reloc is out of order, insert into the right place       */      arelent tmp;      arelent *cursor = cache_ptr-1;      bfd_vma stop = cache_ptr->address;      tmp  = *cache_ptr;      while (cursor->address > stop && cursor >= reloc_cache)      {	cursor[1] = cursor[0];	cursor--;      }       cursor[1] = tmp;    }    else     {      prev_addr = cache_ptr->address;    }  }  free (relocs);  asect->relocation = reloc_cache;  asect->reloc_count = count;  return true;}static booleanb_out_squirt_out_relocs (abfd, section)     bfd *abfd;     asection *section;{  arelent **generic;  int r_extern;  int r_idx;  int incode_mask;    int len_1;  unsigned int count = section->reloc_count;  struct relocation_info *native, *natptr;  size_t natsize = count * sizeof (struct relocation_info);  int extern_mask, pcrel_mask,  len_2, callj_mask;  if (count == 0) return true;  generic   = section->orelocation;  native = ((struct relocation_info *) bfd_xmalloc (natsize));  if (!native) {    bfd_error = no_memory;    return false;  }  if (abfd->xvec->header_byteorder_big_p)   {    /* Big-endian bit field allocation order */    pcrel_mask  = 0x80;    extern_mask = 0x10;    len_2       = 0x40;    len_1       = 0x20;    callj_mask  = 0x02;    incode_mask = 0x08;  }   else   {    /* Little-endian bit field allocation order */    pcrel_mask  = 0x01;    extern_mask = 0x08;    len_2       = 0x04;    len_1       = 0x02;    callj_mask  = 0x40;    incode_mask = 0x10;  }  for (natptr = native; count > 0; --count, ++natptr, ++generic)   {    arelent *g = *generic;    unsigned char *raw = (unsigned char *)natptr;    asymbol *sym = *(g->sym_ptr_ptr);          asection *output_section = sym->section->output_section;    bfd_h_put_32(abfd, g->address, raw);      /* Find a type in the output format which matches the input howto -      * at the moment we assume input format == output format FIXME!!     */    /* FIXME:  Need callj stuff here, and to check the howto entries to       be sure they are real for this architecture.  */    if (g->howto== &howto_reloc_callj)     {      raw[7] = callj_mask + pcrel_mask + len_2;    }    else if (g->howto == &howto_reloc_pcrel24)     {      raw[7] = pcrel_mask + len_2;    }    else if (g->howto == &howto_reloc_pcrel13)     {      raw[7] = pcrel_mask + len_1;    }    else if (g->howto == &howto_reloc_abs32code)     {      raw[7] = len_2 + incode_mask;    }    else {      raw[7] = len_2;    }    if (output_section == &bfd_com_section 	|| output_section == &bfd_abs_section	|| output_section == &bfd_und_section)     {      if (bfd_abs_section.symbol == sym)      {	/* Whoops, looked like an abs symbol, but is really an offset	   from the abs section */	r_idx = 0;	r_extern = 0;       }      else       {	/* Fill in symbol */	r_extern = 1;	r_idx =  stoi((*(g->sym_ptr_ptr))->flags);      }    }    else     {      /* Just an ordinary section */      r_extern = 0;      r_idx  = output_section->target_index;          }    if (abfd->xvec->header_byteorder_big_p) {      raw[4] = (unsigned char) (r_idx >> 16);      raw[5] = (unsigned char) (r_idx >>  8);      raw[6] = (unsigned char) (r_idx     );    } else {      raw[6] = (unsigned char) (r_idx >> 16);      raw[5] = (unsigned char) (r_idx>>  8);      raw[4] = (unsigned char) (r_idx     );    }      if (r_extern)     raw[7] |= extern_mask;   }  if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {    free((PTR)native);    return false;  }  free ((PTR)native);  return true;}/* This is stupid.  This function should be a boolean predicate */static unsigned intb_out_canonicalize_reloc (abfd, section, relptr, symbols)     bfd *abfd;     sec_ptr section;     arelent **relptr;     asymbol **symbols;{  arelent *tblptr = section->relocation;  unsigned int count = 0; if (!(tblptr || b_out_slurp_reloc_table (abfd, section, symbols))) return 0;  tblptr = section->relocation; if (!tblptr) return 0;  for (; count++ < section->reloc_count;)    *relptr++ = tblptr++;  *relptr = 0;  return section->reloc_count;}static unsigned intb_out_get_reloc_upper_bound (abfd, asect)     bfd *abfd;     sec_ptr asect;{  if (bfd_get_format (abfd) != bfd_object) {    bfd_error = invalid_operation;    return 0;  }  if (asect == obj_datasec (abfd))    return (sizeof (arelent *) *	    ((exec_hdr(abfd)->a_drsize / sizeof (struct relocation_info))	     +1));  if (asect == obj_textsec (abfd))    return (sizeof (arelent *) *	    ((exec_hdr(abfd)->a_trsize / sizeof (struct relocation_info))	     +1));  bfd_error = invalid_operation;  return 0;}static booleanb_out_set_section_contents (abfd, section, location, offset, count)     bfd *abfd;     sec_ptr section;     unsigned char *location;     file_ptr offset;      int count;{  if (abfd->output_has_begun == false) { /* set by bfd.c handler */    if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL) /*||        (obj_textsec (abfd)->_cooked_size == 0) || (obj_datasec (abfd)->_cooked_size == 0)*/) {      bfd_error = invalid_operation;      return false;    }    obj_textsec (abfd)->filepos = sizeof(struct internal_exec);    obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos                                  +  obj_textsec (abfd)->_raw_size;  }  /* regardless, once we know what we're doing, we might as well get going */  bfd_seek (abfd, section->filepos + offset, SEEK_SET);  if (count != 0) {    return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false;  }  return true;}static booleanb_out_set_arch_mach (abfd, arch, machine)     bfd *abfd;     enum bfd_architecture arch;     unsigned long machine;{  bfd_default_set_arch_mach(abfd, arch, machine);  if (arch == bfd_arch_unknown)	/* Unknown machine arch is OK */    return true;  if (arch == bfd_arch_i960)	/* i960 default is OK */    switch (machine) {    case bfd_mach_i960_core:    case bfd_mach_i960_kb_sb:    case bfd_mach_i960_mc:    case bfd_mach_i960_xa:    case bfd_mach_i960_ca:    case bfd_mach_i960_ka_sa:    case 0:      return true;    default:      return false;    }  return false;

⌨️ 快捷键说明

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