ecoff.c

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

C
2,282
字号
/* Generic ECOFF (Extended-COFF) routines.   Copyright 1990, 1991, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001   Free Software Foundation, Inc.   Original version by Per Bothner.   Full support added by Ian Lance Taylor, ian@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.  */#include "bfd.h"#include "sysdep.h"#include "bfdlink.h"#include "libbfd.h"#include "aout/ar.h"#include "aout/ranlib.h"#include "aout/stab_gnu.h"/* FIXME: We need the definitions of N_SET[ADTB], but aout64.h defines   some other stuff which we don't want and which conflicts with stuff   we do want.  */#include "libaout.h"#include "aout/aout64.h"#undef N_ABS#undef exec_hdr#undef obj_sym_filepos#include "coff/internal.h"#include "coff/sym.h"#include "coff/symconst.h"#include "coff/ecoff.h"#include "libcoff.h"#include "libecoff.h"/* Prototypes for static functions.  */static int ecoff_get_magic PARAMS ((bfd *abfd));static long ecoff_sec_to_styp_flags PARAMS ((const char *name,					     flagword flags));static boolean ecoff_slurp_symbolic_header PARAMS ((bfd *abfd));static boolean ecoff_set_symbol_info PARAMS ((bfd *abfd, SYMR *ecoff_sym,					   asymbol *asym, int ext, int weak));static void ecoff_emit_aggregate PARAMS ((bfd *abfd, FDR *fdr,					  char *string,					  RNDXR *rndx, long isym,					  const char *which));static char *ecoff_type_to_string PARAMS ((bfd *abfd, FDR *fdr,					   unsigned int indx));static boolean ecoff_slurp_reloc_table PARAMS ((bfd *abfd, asection *section,						asymbol **symbols));static int ecoff_sort_hdrs PARAMS ((const PTR, const PTR));static boolean ecoff_compute_section_file_positions PARAMS ((bfd *abfd));static bfd_size_type ecoff_compute_reloc_file_positions PARAMS ((bfd *abfd));static boolean ecoff_get_extr PARAMS ((asymbol *, EXTR *));static void ecoff_set_index PARAMS ((asymbol *, bfd_size_type));static unsigned int ecoff_armap_hash PARAMS ((CONST char *s,					      unsigned int *rehash,					      unsigned int size,					      unsigned int hlog));/* This stuff is somewhat copied from coffcode.h.  */static asection bfd_debug_section ={  /* name,   id,  index, next, flags, user_set_vma, reloc_done,    */  "*DEBUG*", 0,   0,     NULL, 0,     0,            0,  /* linker_mark, linker_has_input, gc_mark, segment_mark,         */     0,           0,                0,       0,  /* vma, lma, _cooked_size, _raw_size,                            */      0,   0,   0,            0,  /* output_offset, output_section, alignment_power,               */     0,             NULL,           0,  /* relocation, orelocation, reloc_count, filepos, rel_filepos,   */     NULL,       NULL,        0,           0,       0,  /* line_filepos, userdata, contents, lineno, lineno_count,       */     0,            NULL,     NULL,     NULL,   0,  /* comdat, kept_section, moving_line_filepos,                    */     NULL,   NULL,         0,  /* target_index, used_by_bfd, constructor_chain, owner,          */     0,            NULL,        NULL,              NULL,  /* symbol,                                                       */     (struct symbol_cache_entry *) NULL,  /* symbol_ptr_ptr,                                               */     (struct symbol_cache_entry **) NULL,  /* link_order_head, link_order_tail                              */     NULL,            NULL};/* Create an ECOFF object.  */boolean_bfd_ecoff_mkobject (abfd)     bfd *abfd;{  abfd->tdata.ecoff_obj_data = ((struct ecoff_tdata *)				bfd_zalloc (abfd, sizeof (ecoff_data_type)));  if (abfd->tdata.ecoff_obj_data == NULL)    return false;  return true;}/* This is a hook called by coff_real_object_p to create any backend   specific information.  */PTR_bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr)     bfd *abfd;     PTR filehdr;     PTR aouthdr;{  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;  struct internal_aouthdr *internal_a = (struct internal_aouthdr *) aouthdr;  ecoff_data_type *ecoff;  if (_bfd_ecoff_mkobject (abfd) == false)    return NULL;  ecoff = ecoff_data (abfd);  ecoff->gp_size = 8;  ecoff->sym_filepos = internal_f->f_symptr;  if (internal_a != (struct internal_aouthdr *) NULL)    {      int i;      ecoff->text_start = internal_a->text_start;      ecoff->text_end = internal_a->text_start + internal_a->tsize;      ecoff->gp = internal_a->gp_value;      ecoff->gprmask = internal_a->gprmask;      for (i = 0; i < 4; i++)	ecoff->cprmask[i] = internal_a->cprmask[i];      ecoff->fprmask = internal_a->fprmask;      if (internal_a->magic == ECOFF_AOUT_ZMAGIC)	abfd->flags |= D_PAGED;      else	abfd->flags &=~ D_PAGED;    }  /* It turns out that no special action is required by the MIPS or     Alpha ECOFF backends.  They have different information in the     a.out header, but we just copy it all (e.g., gprmask, cprmask and     fprmask) and let the swapping routines ensure that only relevant     information is written out.  */  return (PTR) ecoff;}/* Initialize a new section.  */boolean_bfd_ecoff_new_section_hook (abfd, section)     bfd *abfd ATTRIBUTE_UNUSED;     asection *section;{  section->alignment_power = 4;  if (strcmp (section->name, _TEXT) == 0      || strcmp (section->name, _INIT) == 0      || strcmp (section->name, _FINI) == 0)    section->flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC;  else if (strcmp (section->name, _DATA) == 0	   || strcmp (section->name, _SDATA) == 0)    section->flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC;  else if (strcmp (section->name, _RDATA) == 0	   || strcmp (section->name, _LIT8) == 0	   || strcmp (section->name, _LIT4) == 0	   || strcmp (section->name, _RCONST) == 0	   || strcmp (section->name, _PDATA) == 0)    section->flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY;  else if (strcmp (section->name, _BSS) == 0	   || strcmp (section->name, _SBSS) == 0)    section->flags |= SEC_ALLOC;  else if (strcmp (section->name, _LIB) == 0)    {      /* An Irix 4 shared libary.  */      section->flags |= SEC_COFF_SHARED_LIBRARY;    }  /* Probably any other section name is SEC_NEVER_LOAD, but I'm     uncertain about .init on some systems and I don't know how shared     libraries work.  */  return true;}/* Determine the machine architecture and type.  This is called from   the generic COFF routines.  It is the inverse of ecoff_get_magic,   below.  This could be an ECOFF backend routine, with one version   for each target, but there aren't all that many ECOFF targets.  */boolean_bfd_ecoff_set_arch_mach_hook (abfd, filehdr)     bfd *abfd;     PTR filehdr;{  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;  enum bfd_architecture arch;  unsigned long mach;  switch (internal_f->f_magic)    {    case MIPS_MAGIC_1:    case MIPS_MAGIC_LITTLE:    case MIPS_MAGIC_BIG:      arch = bfd_arch_mips;      mach = 3000;      break;    case MIPS_MAGIC_LITTLE2:    case MIPS_MAGIC_BIG2:      /* MIPS ISA level 2: the r6000 */      arch = bfd_arch_mips;      mach = 6000;      break;    case MIPS_MAGIC_LITTLE3:    case MIPS_MAGIC_BIG3:      /* MIPS ISA level 3: the r4000 */      arch = bfd_arch_mips;      mach = 4000;      break;    case ALPHA_MAGIC:      arch = bfd_arch_alpha;      mach = 0;      break;    default:      arch = bfd_arch_obscure;      mach = 0;      break;    }  return bfd_default_set_arch_mach (abfd, arch, mach);}/* Get the magic number to use based on the architecture and machine.   This is the inverse of _bfd_ecoff_set_arch_mach_hook, above.  */static intecoff_get_magic (abfd)     bfd *abfd;{  int big, little;  switch (bfd_get_arch (abfd))    {    case bfd_arch_mips:      switch (bfd_get_mach (abfd))	{	default:	case 0:	case 3000:	  big = MIPS_MAGIC_BIG;	  little = MIPS_MAGIC_LITTLE;	  break;	case 6000:	  big = MIPS_MAGIC_BIG2;	  little = MIPS_MAGIC_LITTLE2;	  break;	case 4000:	  big = MIPS_MAGIC_BIG3;	  little = MIPS_MAGIC_LITTLE3;	  break;	}      return bfd_big_endian (abfd) ? big : little;    case bfd_arch_alpha:      return ALPHA_MAGIC;    default:      abort ();      return 0;    }}/* Get the section s_flags to use for a section.  */static longecoff_sec_to_styp_flags (name, flags)     const char *name;     flagword flags;{  long styp;  styp = 0;  if (strcmp (name, _TEXT) == 0)    styp = STYP_TEXT;  else if (strcmp (name, _DATA) == 0)    styp = STYP_DATA;  else if (strcmp (name, _SDATA) == 0)    styp = STYP_SDATA;  else if (strcmp (name, _RDATA) == 0)    styp = STYP_RDATA;  else if (strcmp (name, _LITA) == 0)    styp = STYP_LITA;  else if (strcmp (name, _LIT8) == 0)    styp = STYP_LIT8;  else if (strcmp (name, _LIT4) == 0)    styp = STYP_LIT4;  else if (strcmp (name, _BSS) == 0)    styp = STYP_BSS;  else if (strcmp (name, _SBSS) == 0)    styp = STYP_SBSS;  else if (strcmp (name, _INIT) == 0)    styp = STYP_ECOFF_INIT;  else if (strcmp (name, _FINI) == 0)    styp = STYP_ECOFF_FINI;  else if (strcmp (name, _PDATA) == 0)    styp = STYP_PDATA;  else if (strcmp (name, _XDATA) == 0)    styp = STYP_XDATA;  else if (strcmp (name, _LIB) == 0)    styp = STYP_ECOFF_LIB;  else if (strcmp (name, _GOT) == 0)    styp = STYP_GOT;  else if (strcmp (name, _HASH) == 0)    styp = STYP_HASH;  else if (strcmp (name, _DYNAMIC) == 0)    styp = STYP_DYNAMIC;  else if (strcmp (name, _LIBLIST) == 0)    styp = STYP_LIBLIST;  else if (strcmp (name, _RELDYN) == 0)    styp = STYP_RELDYN;  else if (strcmp (name, _CONFLIC) == 0)    styp = STYP_CONFLIC;  else if (strcmp (name, _DYNSTR) == 0)    styp = STYP_DYNSTR;  else if (strcmp (name, _DYNSYM) == 0)    styp = STYP_DYNSYM;  else if (strcmp (name, _COMMENT) == 0)    {      styp = STYP_COMMENT;      flags &=~ SEC_NEVER_LOAD;    }  else if (strcmp (name, _RCONST) == 0)    styp = STYP_RCONST;  else if (flags & SEC_CODE)    styp = STYP_TEXT;  else if (flags & SEC_DATA)    styp = STYP_DATA;  else if (flags & SEC_READONLY)    styp = STYP_RDATA;  else if (flags & SEC_LOAD)    styp = STYP_REG;  else    styp = STYP_BSS;  if (flags & SEC_NEVER_LOAD)    styp |= STYP_NOLOAD;  return styp;}/* Get the BFD flags to use for a section.  */flagword_bfd_ecoff_styp_to_sec_flags (abfd, hdr, name, section)     bfd *abfd ATTRIBUTE_UNUSED;     PTR hdr;     const char *name ATTRIBUTE_UNUSED;     asection *section ATTRIBUTE_UNUSED;{  struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;  long styp_flags = internal_s->s_flags;  flagword sec_flags=0;  if (styp_flags & STYP_NOLOAD)    sec_flags |= SEC_NEVER_LOAD;  /* For 386 COFF, at least, an unloadable text or data section is     actually a shared library section.  */  if ((styp_flags & STYP_TEXT)      || (styp_flags & STYP_ECOFF_INIT)      || (styp_flags & STYP_ECOFF_FINI)      || (styp_flags & STYP_DYNAMIC)      || (styp_flags & STYP_LIBLIST)      || (styp_flags & STYP_RELDYN)      || styp_flags == STYP_CONFLIC      || (styp_flags & STYP_DYNSTR)      || (styp_flags & STYP_DYNSYM)      || (styp_flags & STYP_HASH))    {      if (sec_flags & SEC_NEVER_LOAD)	sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY;      else	sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC;    }  else if ((styp_flags & STYP_DATA)	   || (styp_flags & STYP_RDATA)	   || (styp_flags & STYP_SDATA)	   || styp_flags == STYP_PDATA	   || styp_flags == STYP_XDATA	   || (styp_flags & STYP_GOT)	   || styp_flags == STYP_RCONST)    {      if (sec_flags & SEC_NEVER_LOAD)	sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY;      else	sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC;      if ((styp_flags & STYP_RDATA)	  || styp_flags == STYP_PDATA	  || styp_flags == STYP_RCONST)	sec_flags |= SEC_READONLY;    }  else if ((styp_flags & STYP_BSS)	   || (styp_flags & STYP_SBSS))    {      sec_flags |= SEC_ALLOC;    }  else if ((styp_flags & STYP_INFO) || styp_flags == STYP_COMMENT)    {      sec_flags |= SEC_NEVER_LOAD;    }  else if ((styp_flags & STYP_LITA)	   || (styp_flags & STYP_LIT8)	   || (styp_flags & STYP_LIT4))    {      sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY;    }  else if (styp_flags & STYP_ECOFF_LIB)    {      sec_flags |= SEC_COFF_SHARED_LIBRARY;    }  else    {      sec_flags |= SEC_ALLOC | SEC_LOAD;    }  return sec_flags;}/* Read in the symbolic header for an ECOFF object file.  */static booleanecoff_slurp_symbolic_header (abfd)     bfd *abfd;{  const struct ecoff_backend_data * const backend = ecoff_backend (abfd);  bfd_size_type external_hdr_size;

⌨️ 快捷键说明

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