vms.c

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

C
1,903
字号
/* vms.c -- BFD back-end for VAX (openVMS/VAX) and   EVAX (openVMS/Alpha) files.   Copyright 1996, 1997, 1998, 1999, 2000, 2001   Free Software Foundation, Inc.   Written by Klaus K"ampf (kkaempf@rmi.de)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 "vms.h"static boolean vms_initialize PARAMS ((bfd *));static unsigned int priv_section_count;static boolean fill_section_ptr PARAMS ((struct bfd_hash_entry *, PTR));static boolean vms_fixup_sections PARAMS ((bfd *));static boolean copy_symbols PARAMS ((struct bfd_hash_entry *, PTR));static bfd_reloc_status_type reloc_nil  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));static const struct bfd_target *vms_object_p PARAMS ((bfd *abfd));static const struct bfd_target *vms_archive_p PARAMS ((bfd *abfd));static boolean vms_mkobject PARAMS ((bfd *abfd));static boolean vms_write_object_contents PARAMS ((bfd *abfd));static boolean vms_close_and_cleanup PARAMS ((bfd *abfd));static boolean vms_bfd_free_cached_info PARAMS ((bfd *abfd));static boolean vms_new_section_hook PARAMS ((bfd *abfd, asection *section));static boolean vms_get_section_contents  PARAMS ((bfd *abfd, asection *section, PTR x1, file_ptr x2,	   bfd_size_type x3));static boolean vms_get_section_contents_in_window  PARAMS ((bfd *abfd, asection *section, bfd_window *w, file_ptr offset,	   bfd_size_type count));static boolean vms_bfd_copy_private_bfd_data PARAMS ((bfd *src, bfd *dest));static boolean vms_bfd_copy_private_section_data  PARAMS ((bfd *srcbfd, asection *srcsec, bfd *dstbfd, asection *dstsec));static boolean vms_bfd_copy_private_symbol_data  PARAMS ((bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym));static boolean vms_bfd_print_private_bfd_data  PARAMS ((bfd *abfd, void *file));static char *vms_core_file_failing_command PARAMS ((bfd *abfd));static int vms_core_file_failing_signal PARAMS ((bfd *abfd));static boolean vms_core_file_matches_executable_p  PARAMS ((bfd *abfd, bfd *bbfd));static boolean vms_slurp_armap PARAMS ((bfd *abfd));static boolean vms_slurp_extended_name_table PARAMS ((bfd *abfd));static boolean vms_construct_extended_name_table  PARAMS ((bfd *abfd, char **tabloc, bfd_size_type *tablen,	   const char **name));static void vms_truncate_arname  PARAMS ((bfd *abfd, CONST char *pathname, char *arhdr));static boolean vms_write_armap  PARAMS ((bfd *arch, unsigned int elength, struct orl *map,	   unsigned int orl_count, int stridx));static PTR vms_read_ar_hdr PARAMS ((bfd *abfd));static bfd *vms_get_elt_at_index PARAMS ((bfd *abfd, symindex index));static bfd *vms_openr_next_archived_file PARAMS ((bfd *arch, bfd *prev));static boolean vms_update_armap_timestamp PARAMS ((bfd *abfd));static int vms_generic_stat_arch_elt PARAMS ((bfd *abfd, struct stat *stat));static long vms_get_symtab_upper_bound PARAMS ((bfd *abfd));static long vms_get_symtab PARAMS ((bfd *abfd, asymbol **symbols));static void vms_print_symbol  PARAMS ((bfd *abfd, PTR file, asymbol *symbol, bfd_print_symbol_type how));static void vms_get_symbol_info  PARAMS ((bfd *abfd, asymbol *symbol, symbol_info *ret));static boolean vms_bfd_is_local_label_name PARAMS ((bfd *abfd, const char *));static alent *vms_get_lineno PARAMS ((bfd *abfd, asymbol *symbol));static boolean vms_find_nearest_line  PARAMS ((bfd *abfd, asection *section, asymbol **symbols, bfd_vma offset,	   const char **file, const char **func, unsigned int *line));static asymbol *vms_bfd_make_debug_symbol  PARAMS ((bfd *abfd, void *ptr, unsigned long size));static long vms_read_minisymbols  PARAMS ((bfd *abfd, boolean dynamic, PTR *minisymsp, unsigned int *sizep));static asymbol *vms_minisymbol_to_symbol  PARAMS ((bfd *abfd, boolean dynamic, const PTR minisym, asymbol *sym));static long vms_get_reloc_upper_bound PARAMS ((bfd *abfd, asection *sect));static long vms_canonicalize_reloc  PARAMS ((bfd *abfd, asection *srcsec, arelent **location,	   asymbol **symbols));static const struct reloc_howto_struct *vms_bfd_reloc_type_lookup  PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));static boolean vms_set_arch_mach  PARAMS ((bfd *abfd, enum bfd_architecture arch, unsigned long mach));static boolean vms_set_section_contents  PARAMS ((bfd *abfd, asection *section, PTR location, file_ptr offset,	   bfd_size_type count));static int vms_sizeof_headers PARAMS ((bfd *abfd, boolean reloc));static bfd_byte *vms_bfd_get_relocated_section_contents  PARAMS ((bfd *abfd, struct bfd_link_info *link_info,	   struct bfd_link_order *link_order, bfd_byte *data,	   boolean relocateable, asymbol **symbols));static boolean vms_bfd_relax_section  PARAMS ((bfd *abfd, asection *section, struct bfd_link_info *link_info,	   boolean *again));static boolean vms_bfd_gc_sections  PARAMS ((bfd *abfd, struct bfd_link_info *link_info));static struct bfd_link_hash_table *vms_bfd_link_hash_table_create  PARAMS ((bfd *abfd));static boolean vms_bfd_link_add_symbols  PARAMS ((bfd *abfd, struct bfd_link_info *link_info));static boolean vms_bfd_final_link  PARAMS ((bfd *abfd, struct bfd_link_info *link_info));static boolean vms_bfd_link_split_section  PARAMS ((bfd *abfd, asection *section));static long vms_get_dynamic_symtab_upper_bound PARAMS ((bfd *abfd));static long vms_canonicalize_dynamic_symtab  PARAMS ((bfd *abfd, asymbol **symbols));static long vms_get_dynamic_reloc_upper_bound PARAMS ((bfd *abfd));static long vms_canonicalize_dynamic_reloc  PARAMS ((bfd *abfd, arelent **arel, asymbol **symbols));static boolean vms_bfd_merge_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd));static boolean vms_bfd_set_private_flags PARAMS ((bfd *abfd, flagword flags));#define vms_make_empty_symbol _bfd_vms_make_empty_symbol/*===========================================================================*/const bfd_target vms_alpha_vec ={  "vms-alpha",			/* name */  bfd_target_evax_flavour,  BFD_ENDIAN_LITTLE,		/* data byte order is little */  BFD_ENDIAN_LITTLE,		/* header byte order is little */  (HAS_RELOC | HAS_SYMS   | WP_TEXT | D_PAGED),	/* object flags */  (SEC_ALLOC | SEC_LOAD | SEC_RELOC   | SEC_READONLY | SEC_CODE | SEC_DATA   | SEC_HAS_CONTENTS | SEC_IN_MEMORY),		/* sect flags */  0,				/* symbol_leading_char */  ' ',				/* ar_pad_char */  15,				/* ar_max_namelen */  bfd_getl64, bfd_getl_signed_64, bfd_putl64,  bfd_getl32, bfd_getl_signed_32, bfd_putl32,  bfd_getl16, bfd_getl_signed_16, bfd_putl16,  bfd_getl64, bfd_getl_signed_64, bfd_putl64,  bfd_getl32, bfd_getl_signed_32, bfd_putl32,  bfd_getl16, bfd_getl_signed_16, bfd_putl16,  {_bfd_dummy_target, vms_object_p,		/* bfd_check_format */   vms_archive_p, _bfd_dummy_target},  {bfd_false, vms_mkobject,			/* bfd_set_format */   _bfd_generic_mkarchive, bfd_false},  {bfd_false, vms_write_object_contents,	/* bfd_write_contents */   _bfd_write_archive_contents, bfd_false},  BFD_JUMP_TABLE_GENERIC (vms),  BFD_JUMP_TABLE_COPY (vms),  BFD_JUMP_TABLE_CORE (vms),  BFD_JUMP_TABLE_ARCHIVE (vms),  BFD_JUMP_TABLE_SYMBOLS (vms),  BFD_JUMP_TABLE_RELOCS (vms),  BFD_JUMP_TABLE_WRITE (vms),  BFD_JUMP_TABLE_LINK (vms),  BFD_JUMP_TABLE_DYNAMIC (vms),  NULL,  (PTR) 0};const bfd_target vms_vax_vec ={  "vms-vax",			/* name */  bfd_target_ovax_flavour,  BFD_ENDIAN_LITTLE,		/* data byte order is little */  BFD_ENDIAN_LITTLE,		/* header byte order is little */  (HAS_RELOC | HAS_SYMS 	/* object flags */   | WP_TEXT | D_PAGED   | HAS_LINENO | HAS_DEBUG | HAS_LOCALS),  (SEC_ALLOC | SEC_LOAD | SEC_RELOC   | SEC_READONLY | SEC_CODE | SEC_DATA   | SEC_HAS_CONTENTS | SEC_IN_MEMORY),		/* sect flags */  0,				/* symbol_leading_char */  ' ',				/* ar_pad_char */  15,				/* ar_max_namelen */  bfd_getl64, bfd_getl_signed_64, bfd_putl64,  bfd_getl32, bfd_getl_signed_32, bfd_putl32,  bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */  bfd_getl64, bfd_getl_signed_64, bfd_putl64,  bfd_getl32, bfd_getl_signed_32, bfd_putl32,  bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */  {_bfd_dummy_target, vms_object_p,		/* bfd_check_format */   vms_archive_p, _bfd_dummy_target},  {bfd_false, vms_mkobject,			/* bfd_set_format */   _bfd_generic_mkarchive, bfd_false},  {bfd_false, vms_write_object_contents,	/* bfd_write_contents */   _bfd_write_archive_contents, bfd_false},  BFD_JUMP_TABLE_GENERIC (vms),  BFD_JUMP_TABLE_COPY (vms),  BFD_JUMP_TABLE_CORE (vms),  BFD_JUMP_TABLE_ARCHIVE (vms),  BFD_JUMP_TABLE_SYMBOLS (vms),  BFD_JUMP_TABLE_RELOCS (vms),  BFD_JUMP_TABLE_WRITE (vms),  BFD_JUMP_TABLE_LINK (vms),  BFD_JUMP_TABLE_DYNAMIC (vms),  NULL,  (PTR) 0};/*===========================================================================*//* Initialize private data  */static booleanvms_initialize (abfd)     bfd *abfd;{  int i;  if (abfd->tdata.any != 0)    return true;  bfd_set_start_address (abfd, (bfd_vma)-1);  abfd->tdata.any = ((struct vms_private_data_struct*)		     bfd_malloc (sizeof (struct vms_private_data_struct)));  if (abfd->tdata.any == 0)    return false;#ifdef __ALPHA  PRIV (is_vax) = 0;#else  PRIV (is_vax) = 1;#endif  PRIV (vms_buf) = 0;  PRIV (buf_size) = 0;  PRIV (rec_length) = 0;  PRIV (file_format) = FF_UNKNOWN;  PRIV (fixup_done) = false;  PRIV (sections) = NULL;  PRIV (stack) = ((struct stack_struct *)		 bfd_malloc (sizeof (struct stack_struct) * STACKSIZE));  if (PRIV (stack) == 0)    {     vms_init_no_mem1:      free (abfd->tdata.any);      abfd->tdata.any = 0;      return false;    }  PRIV (stackptr) = 0;  PRIV (vms_symbol_table) = ((struct bfd_hash_table *)			     bfd_malloc (sizeof (struct bfd_hash_table)));  if (PRIV (vms_symbol_table) == 0)    {     vms_init_no_mem2:      free (PRIV (stack));      PRIV (stack) = 0;      goto vms_init_no_mem1;    }  if (!bfd_hash_table_init (PRIV (vms_symbol_table), _bfd_vms_hash_newfunc))    return false;  PRIV (location_stack) = ((struct location_struct *)			  bfd_malloc (sizeof (struct location_struct)				      * LOCATION_SAVE_SIZE));  if (PRIV (location_stack) == 0)    {     vms_init_no_mem3:      free (PRIV (vms_symbol_table));      PRIV (vms_symbol_table) = 0;      goto vms_init_no_mem2;    }  for (i = 0; i < VMS_SECTION_COUNT; i++)    PRIV (vms_section_table)[i] = NULL;  PRIV (output_buf) = (unsigned char *) malloc (MAX_OUTREC_SIZE);  if (PRIV (output_buf) == 0)    {      free (PRIV (location_stack));      PRIV (location_stack) = 0;      goto vms_init_no_mem3;    }  PRIV (push_level) = 0;  PRIV (pushed_size) = 0;  PRIV (length_pos) = 2;  PRIV (output_size) = 0;  PRIV (output_alignment) = 1;  return true;}/* Fill symbol->section with section ptr   symbol->section is filled with the section index for defined symbols   during reading the GSD/EGSD section. But we need the pointer to the   bfd section later.   It has the correct value for referenced (undefined section) symbols   called from bfd_hash_traverse in vms_fixup_sections  */static booleanfill_section_ptr (entry, sections)     struct bfd_hash_entry *entry;     PTR sections;{  asection *sec;  asymbol *sym;  sym =  ((vms_symbol_entry *)entry)->symbol;  sec = sym->section;#if VMS_DEBUG  vms_debug (6, "fill_section_ptr: sym %p, sec %p\n", sym, sec);#endif  /* fill forward references (these contain section number, not section ptr).  */  if ((unsigned int) sec < priv_section_count)    {      sec = ((vms_symbol_entry *)entry)->symbol->section =	((asection **)sections)[(int)sec];    }  if (strcmp (sym->name, sec->name) == 0)    sym->flags |= BSF_SECTION_SYM;  return true;}/* Fixup sections   set up all pointers and arrays, counters and sizes are fixed now   we build a private sections vector for easy access since sections   are always referenced by an index number.   alloc PRIV(sections) according to abfd->section_count	copy abfd->sections to PRIV(sections)  */static booleanvms_fixup_sections (abfd)     bfd *abfd;{  if (PRIV (fixup_done))    return true;  /*   * traverse symbol table and fill in all section pointers   */  /* can't provide section count as argument to fill_section_ptr().  */  priv_section_count = PRIV (section_count);  bfd_hash_traverse (PRIV (vms_symbol_table), fill_section_ptr,		    (PTR) (PRIV (sections)));  PRIV (fixup_done) = true;  return true;}/*===========================================================================*//* Check the format for a file being read.   Return a (bfd_target *) if it's an object file or zero if not.  */static const struct bfd_target *vms_object_p (abfd)     bfd *abfd;{  int err = 0;  int prev_type;  const struct bfd_target *target_vector = 0;  const bfd_arch_info_type *arch = 0;#if VMS_DEBUG  vms_debug (1, "vms_object_p(%p)\n", abfd);#endif  if (!vms_initialize (abfd))    {      fprintf (stderr, "vms_initialize () failed !!\n");      return 0;    }  if (bfd_seek (abfd, 0L, SEEK_SET))    {      bfd_set_error (bfd_error_file_truncated);      return 0;    }  prev_type = -1;  do    {#if VMS_DEBUG      vms_debug (7, "reading at %08lx\n", bfd_tell(abfd));#endif      if (_bfd_vms_next_record (abfd) < 0)	{#if VMS_DEBUG	  vms_debug (2, "next_record failed\n");#endif	  bfd_set_error (bfd_error_wrong_format);	  return 0;	}      if ((prev_type == EOBJ_S_C_EGSD)	   && (PRIV (rec_type) != EOBJ_S_C_EGSD))	{	  if (vms_fixup_sections (abfd) == false)	    {#if VMS_DEBUG	      vms_debug (2, "vms_fixup_sections failed\n");#endif	      bfd_set_error (bfd_error_wrong_format);	      return 0;	    }	}      prev_type = PRIV (rec_type);      if (target_vector == 0)	{	  if (prev_type <= OBJ_S_C_MAXRECTYP)	    target_vector = &vms_vax_vec;	  else	    target_vector = &vms_alpha_vec;	}      switch (prev_type)	{	  case OBJ_S_C_HDR:	  case EOBJ_S_C_EMH:	    err = _bfd_vms_slurp_hdr (abfd, prev_type);	    break;	  case OBJ_S_C_EOM:	  case OBJ_S_C_EOMW:	  case EOBJ_S_C_EEOM:	    err = _bfd_vms_slurp_eom (abfd, prev_type);	    break;	  case OBJ_S_C_GSD:	  case EOBJ_S_C_EGSD:	    err = _bfd_vms_slurp_gsd (abfd, prev_type);	    break;	  case OBJ_S_C_TIR:	  case EOBJ_S_C_ETIR:	    err = _bfd_vms_slurp_tir (abfd, prev_type);	    break;	  case OBJ_S_C_DBG:	  case EOBJ_S_C_EDBG:	    err = _bfd_vms_slurp_dbg (abfd, prev_type);	    break;	  case OBJ_S_C_TBT:	  case EOBJ_S_C_ETBT:	    err = _bfd_vms_slurp_tbt (abfd, prev_type);	    break;	  case OBJ_S_C_LNK:	    err = _bfd_vms_slurp_lnk (abfd, prev_type);	    break;

⌨️ 快捷键说明

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