hp300hpux.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 855 行 · 第 1/2 页

C
855
字号
NAME (aout,swap_exec_header_in) (abfd, raw_bytes, execp)     bfd *abfd;     struct external_exec *raw_bytes;     struct internal_exec *execp;{  struct external_exec *bytes = (struct external_exec *) raw_bytes;  /* The internal_exec structure has some fields that are unused in this     configuration (IE for i960), so ensure that all such uninitialized     fields are zero'd out.  There are places where two of these structs     are memcmp'd, and thus the contents do matter. */  memset (execp, 0, sizeof (struct internal_exec));  /* Now fill in fields in the execp, from the bytes in the raw data.  */  execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);  execp->a_text = GET_WORD (abfd, bytes->e_text);  execp->a_data = GET_WORD (abfd, bytes->e_data);  execp->a_bss = GET_WORD (abfd, bytes->e_bss);  execp->a_syms = GET_WORD (abfd, bytes->e_syms);  execp->a_entry = GET_WORD (abfd, bytes->e_entry);  execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);  execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);  /***************************************************************/  /* check the header to see if it was generated by a bfd output */  /* this is detected rather bizarely by requiring a bunch of    */  /* header fields to be zero and an old unused field (now used) */  /* to be set.                                                  */  /***************************************************************/  do    {      long syms;      struct aout_data_struct *rawptr;      if (bfd_h_get_32 (abfd, bytes->e_passize) != 0)	break;      if (bfd_h_get_32 (abfd, bytes->e_syms) != 0)	break;      if (bfd_h_get_32 (abfd, bytes->e_supsize) != 0)	break;      syms = bfd_h_get_32 (abfd, bytes->e_drelocs);      if (syms == 0)	break;      /* OK, we've passed the test as best as we can determine */      execp->a_syms = syms;      /* allocate storage for where we will store this result */      rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, sizeof (*rawptr));      if (rawptr == NULL)	return;      abfd->tdata.aout_data = rawptr;      obj_aout_subformat (abfd) = gnu_encap_format;    }  while (0);}/* The hp symbol table is a bit different than other a.out targets.  Instead   of having an array of nlist items and an array of strings, hp's format   has them mixed together in one structure.  In addition, the strings are   not null terminated.  It looks something like this:   nlist element 1   string1   nlist element 2   string2   ...   The whole symbol table is read as one chunk and then we march thru it   and convert it to canonical form.  As we march thru the table, we copy   the nlist data into the internal form and we compact the strings and null   terminate them, using storage from the already allocated symbol table:   string1   null   string2   null   ...*/booleanMY (slurp_symbol_table) (abfd)     bfd *abfd;{  bfd_size_type symbol_bytes;  struct external_nlist *syms;  struct external_nlist *sym_pointer;  struct external_nlist *sym_end;  char *strings;  aout_symbol_type *cached;  unsigned num_syms = 0;  /* If there's no work to be done, don't do any */  if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL)    return true;  symbol_bytes = exec_hdr (abfd)->a_syms;  strings = (char *) bfd_alloc (abfd,				symbol_bytes + SYM_EXTRA_BYTES);  if (!strings)    return false;  syms = (struct external_nlist *) (strings + SYM_EXTRA_BYTES);  if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0      || bfd_read ((PTR) syms, symbol_bytes, 1, abfd) != symbol_bytes)    {      bfd_release (abfd, syms);      return false;    }  sym_end = (struct external_nlist *) (((char *) syms) + symbol_bytes);  /* first, march thru the table and figure out how many symbols there are */  for (sym_pointer = syms; sym_pointer < sym_end; sym_pointer++, num_syms++)    {      /* skip over the embedded symbol. */      sym_pointer = (struct external_nlist *) (((char *) sym_pointer) +					       sym_pointer->e_length[0]);    }  /* now that we know the symbol count, update the bfd header */  bfd_get_symcount (abfd) = num_syms;  cached = ((aout_symbol_type *)	    bfd_zalloc (abfd,			bfd_get_symcount (abfd) * sizeof (aout_symbol_type)));  if (cached == NULL && bfd_get_symcount (abfd) != 0)    return false;  /* as we march thru the hp symbol table, convert it into a list of     null terminated strings to hold the symbol names.  Make sure any     assignment to the strings pointer is done after we're thru using     the nlist so we don't overwrite anything important. */  /* OK, now walk the new symtable, cacheing symbol properties */  {    aout_symbol_type *cache_ptr = cached;    aout_symbol_type cache_save;    /* Run through table and copy values */    for (sym_pointer = syms, cache_ptr = cached;	 sym_pointer < sym_end; sym_pointer++, cache_ptr++)      {	unsigned int length;	cache_ptr->symbol.the_bfd = abfd;	cache_ptr->symbol.value = GET_SWORD (abfd, sym_pointer->e_value);	cache_ptr->desc = bfd_get_16 (abfd, sym_pointer->e_almod);	cache_ptr->type = bfd_get_8 (abfd, sym_pointer->e_type);	cache_ptr->symbol.udata.p = NULL;	length = bfd_get_8 (abfd, sym_pointer->e_length);	cache_ptr->other = length;	/* other not used, save length here */	cache_save = *cache_ptr;	convert_sym_type (sym_pointer, cache_ptr, abfd);	if (!translate_from_native_sym_flags (abfd, cache_ptr))	  return false;	/********************************************************/	/* for hpux, the 'lenght' value indicates the length of */	/* the symbol name which follows the nlist entry.       */	/********************************************************/	if (length)	  {	    /**************************************************************/	    /* the hp string is not null terminated so we create a new one*/	    /* by copying the string to overlap the just vacated nlist    */	    /* structure before it in memory.                             */	    /**************************************************************/	    cache_ptr->symbol.name = strings;	    memcpy (strings, sym_pointer + 1, length);	    strings[length] = '\0';	    strings += length + 1;	  }	else	  cache_ptr->symbol.name = (char *) NULL;	/* skip over the embedded symbol. */	sym_pointer = (struct external_nlist *) (((char *) sym_pointer) +						 length);      }  }  obj_aout_symbols (abfd) = cached;  return true;}voidMY (swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)     bfd *abfd;     struct hp300hpux_reloc *bytes;     arelent *cache_ptr;     asymbol **symbols;     bfd_size_type symcount ATTRIBUTE_UNUSED;{  int r_index;  int r_extern = 0;  unsigned int r_length;  int r_pcrel = 0;  struct aoutdata *su = &(abfd->tdata.aout_data->a);  cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);  r_index = bfd_h_get_16 (abfd, bytes->r_index);  switch (bytes->r_type[0])    {    case HP_RSEGMENT_TEXT:      r_index = N_TEXT;      break;    case HP_RSEGMENT_DATA:      r_index = N_DATA;      break;    case HP_RSEGMENT_BSS:      r_index = N_BSS;      break;    case HP_RSEGMENT_EXTERNAL:      r_extern = 1;      break;    case HP_RSEGMENT_PCREL:      r_extern = 1;      r_pcrel = 1;      break;    case HP_RSEGMENT_RDLT:      break;    case HP_RSEGMENT_RPLT:      break;    case HP_RSEGMENT_NOOP:      break;    default:      abort ();      break;    }  switch (bytes->r_length[0])    {    case HP_RLENGTH_BYTE:      r_length = 0;      break;    case HP_RLENGTH_WORD:      r_length = 1;      break;    case HP_RLENGTH_LONG:      r_length = 2;      break;    default:      abort ();      break;    }  cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;  /* FIXME-soon:  Roll baserel, jmptable, relative bits into howto setting */  /* This macro uses the r_index value computed above */  if (r_pcrel && r_extern)    {      /* The GNU linker assumes any offset from beginning of section */      /* is already incorporated into the image while the HP linker  */      /* adds this in later.  Add it in now...                       */      MOVE_ADDRESS (-cache_ptr->address);    }  else    {      MOVE_ADDRESS (0);    }}booleanMY (slurp_reloc_table) (abfd, asect, symbols)     bfd *abfd;     sec_ptr asect;     asymbol **symbols;{  unsigned int count;  bfd_size_type reloc_size;  PTR relocs;  arelent *reloc_cache;  size_t each_size;  struct hp300hpux_reloc *rptr;  unsigned int counter;  arelent *cache_ptr;  if (asect->relocation)    return true;  if (asect->flags & SEC_CONSTRUCTOR)    return true;  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_set_error (bfd_error_invalid_operation);  return false;doit:  if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)    return false;  each_size = obj_reloc_entry_size (abfd);  count = reloc_size / each_size;  reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t) (count * sizeof							(arelent)));  if (!reloc_cache && count != 0)    return false;  relocs = (PTR) bfd_alloc (abfd, reloc_size);  if (!relocs && reloc_size != 0)    {      bfd_release (abfd, reloc_cache);      return false;    }  if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size)    {      bfd_release (abfd, relocs);      bfd_release (abfd, reloc_cache);      return false;    }  rptr = (struct hp300hpux_reloc *) relocs;  counter = 0;  cache_ptr = reloc_cache;  for (; counter < count; counter++, rptr++, cache_ptr++)    {      MY (swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols,			      bfd_get_symcount (abfd));    }  bfd_release (abfd, relocs);  asect->relocation = reloc_cache;  asect->reloc_count = count;  return true;}/************************************************************************//* The following functions are identical to functions in aoutx.h except *//* they refer to MY(func) rather than NAME(aout,func) and they also     *//* call aout_32 versions if the input file was generated by gcc         *//************************************************************************/long aout_32_get_symtab PARAMS ((bfd * abfd, asymbol ** location));long aout_32_get_symtab_upper_bound PARAMS ((bfd * abfd));long aout_32_canonicalize_reloc PARAMS ((bfd * abfd, sec_ptr section,					 arelent ** relptr,					 asymbol ** symbols));longMY (get_symtab) (abfd, location)     bfd *abfd;     asymbol **location;{  unsigned int counter = 0;  aout_symbol_type *symbase;  if (obj_aout_subformat (abfd) == gnu_encap_format)    return aout_32_get_symtab (abfd, location);  if (!MY (slurp_symbol_table) (abfd))    return -1;  for (symbase = obj_aout_symbols (abfd); counter++ < bfd_get_symcount (abfd);)    *(location++) = (asymbol *) (symbase++);  *location++ = 0;  return bfd_get_symcount (abfd);}longMY (get_symtab_upper_bound) (abfd)     bfd *abfd;{  if (obj_aout_subformat (abfd) == gnu_encap_format)    return aout_32_get_symtab_upper_bound (abfd);  if (!MY (slurp_symbol_table) (abfd))    return -1;  return (bfd_get_symcount (abfd) + 1) * (sizeof (aout_symbol_type *));}longMY (canonicalize_reloc) (abfd, section, relptr, symbols)     bfd *abfd;     sec_ptr section;     arelent **relptr;     asymbol **symbols;{  arelent *tblptr = section->relocation;  unsigned int count;  if (obj_aout_subformat (abfd) == gnu_encap_format)    return aout_32_canonicalize_reloc (abfd, section, relptr, symbols);  if (!(tblptr || MY (slurp_reloc_table) (abfd, section, symbols)))    return -1;  if (section->flags & SEC_CONSTRUCTOR)    {      arelent_chain *chain = section->constructor_chain;      for (count = 0; count < section->reloc_count; count++)	{	  *relptr++ = &chain->relent;	  chain = chain->next;	}    }  else    {      tblptr = section->relocation;      for (count = 0; count++ < section->reloc_count;)	{	  *relptr++ = tblptr++;	}    }  *relptr = 0;  return section->reloc_count;}#include "aout-target.h"

⌨️ 快捷键说明

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