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

📄 vms-gsd.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 2 页
字号:
/* vms-gsd.c -- BFD back-end for VAX (openVMS/VAX) and   EVAX (openVMS/Alpha) files.   Copyright 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.   go and read the openVMS linker manual (esp. appendix B)   if you don't know what's going on here :-)   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 <ctype.h>#include "bfd.h"#include "sysdep.h"#include "bfdlink.h"#include "libbfd.h"#include "vms.h"/*-----------------------------------------------------------------------------*//* typical sections for vax object files  */#define VAX_CODE_NAME		"$CODE"#define VAX_DATA_NAME		"$DATA"#define VAX_ADDRESS_DATA_NAME	"$ADDRESS_DATA"/* typical sections for evax object files  */#define EVAX_ABS_NAME		"$ABS$"#define EVAX_CODE_NAME		"$CODE$"#define EVAX_LINK_NAME		"$LINK$"#define EVAX_DATA_NAME		"$DATA$"#define EVAX_BSS_NAME		"$BSS$"#define EVAX_READONLYADDR_NAME	"$READONLY_ADDR$"#define EVAX_READONLY_NAME	"$READONLY$"#define EVAX_LITERAL_NAME	"$LITERAL$"#define EVAX_COMMON_NAME	"$COMMON$"#define EVAX_LOCAL_NAME		"$LOCAL$"struct sec_flags_struct {  char *name;			/* name of section */  int vflags_always;  flagword flags_always;	/* flags we set always */  int vflags_hassize;  flagword flags_hassize;	/* flags we set if the section has a size > 0 */};/* These flags are deccrtl/vaxcrtl (openVMS 6.2 VAX) compatible  */static struct sec_flags_struct vax_section_flags[] = {  { VAX_CODE_NAME,	(GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE|GPS_S_M_RD),	(SEC_CODE),	(GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE|GPS_S_M_RD),	(SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },  { VAX_DATA_NAME,	(GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT),	(SEC_DATA),	(GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT),	(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },  { VAX_ADDRESS_DATA_NAME,	(GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD),	(SEC_DATA|SEC_READONLY),	(GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD),	(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },  { NULL,	(GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD|GPS_S_M_WRT),	(SEC_DATA),	(GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD|GPS_S_M_WRT),	(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }};/* These flags are deccrtl/vaxcrtl (openVMS 6.2 Alpha) compatible  */static struct sec_flags_struct evax_section_flags[] = {  { EVAX_ABS_NAME,	(EGPS_S_V_SHR),	(SEC_DATA),	(EGPS_S_V_SHR),	(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },  { EVAX_CODE_NAME,	(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE),	(SEC_CODE),	(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE),	(SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },  { EVAX_LITERAL_NAME,	(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD),	(SEC_DATA|SEC_READONLY),	(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),	(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },  { EVAX_LINK_NAME,	(EGPS_S_V_REL|EGPS_S_V_RD),	(SEC_DATA|SEC_READONLY),	(EGPS_S_V_REL|EGPS_S_V_RD),	(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },  { EVAX_DATA_NAME,	(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),	(SEC_DATA),	(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),	(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },  { EVAX_BSS_NAME,	(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),	(SEC_NO_FLAGS),	(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),	(SEC_IN_MEMORY|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },  { EVAX_READONLYADDR_NAME,	(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD),	(SEC_DATA|SEC_READONLY),	(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD),	(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },  { EVAX_READONLY_NAME,	(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD),	(SEC_DATA|SEC_READONLY),	(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),	(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },  { EVAX_LOCAL_NAME,	(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),	(SEC_DATA),	(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),	(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },  { NULL,	(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),	(SEC_DATA),	(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),	(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }};/* Retrieve bfd section flags by name and size  */static flagwordvms_secflag_by_name (abfd, section_flags, name, size)     bfd *abfd;     struct sec_flags_struct *section_flags;     char *name;     int size;{  int i = 0;  while (section_flags[i].name != NULL)    {      if ((PRIV(is_vax)?	    strcasecmp (name, section_flags[i].name):	    strcmp (name, section_flags[i].name)) == 0)	{	  if (size > 0)	    return section_flags[i].flags_hassize;	  else	    return section_flags[i].flags_always;	}      i++;    }  if (size > 0)    return section_flags[i].flags_hassize;  return section_flags[i].flags_always;}/* Retrieve vms section flags by name and size  */static flagwordvms_esecflag_by_name (section_flags, name, size)     struct sec_flags_struct *section_flags;     char *name;     int size;{  int i = 0;  while (section_flags[i].name != NULL)    {      if (strcmp (name, section_flags[i].name) == 0)	{	  if (size > 0)	    return section_flags[i].vflags_hassize;	  else	    return section_flags[i].vflags_always;	}      i++;    }  if (size > 0)    return section_flags[i].vflags_hassize;  return section_flags[i].vflags_always;}/*-----------------------------------------------------------------------------*/#if VMS_DEBUG/* debug */struct flagdescstruct { char *name; flagword value; };/* Convert flag to printable string  */static char *flag2str(flagdesc, flags)     struct flagdescstruct *flagdesc;     flagword flags;{  static char res[64];  int next = 0;  res[0] = 0;  while (flagdesc->name != NULL)    {      if ((flags & flagdesc->value) != 0)	{	  if (next)	    strcat(res, ",");	  else	    next = 1;	  strcat (res, flagdesc->name);	}      flagdesc++;    }  return res;}#endif/*-----------------------------------------------------------------------------*//* input routines *//* Process GSD/EGSD record   return 0 on success, -1 on error  */int_bfd_vms_slurp_gsd (abfd, objtype)     bfd *abfd;     int objtype;{#if VMS_DEBUG  static struct flagdescstruct gpsflagdesc[] =  {    { "PIC", 0x0001 },    { "LIB", 0x0002 },    { "OVR", 0x0004 },    { "REL", 0x0008 },    { "GBL", 0x0010 },    { "SHR", 0x0020 },    { "EXE", 0x0040 },    { "RD",  0x0080 },    { "WRT", 0x0100 },    { "VEC", 0x0200 },    { "NOMOD", 0x0400 },    { "COM", 0x0800 },    { NULL, 0 }  };  static struct flagdescstruct gsyflagdesc[] =  {    { "WEAK", 0x0001 },    { "DEF",  0x0002 },    { "UNI",  0x0004 },    { "REL",  0x0008 },    { "COMM", 0x0010 },    { "VECEP", 0x0020 },    { "NORM", 0x0040 },    { NULL, 0 }  };#endif  int gsd_type, gsd_size;  asection *section;  unsigned char *vms_rec;  flagword new_flags, old_flags;  char *name;  asymbol *symbol;  vms_symbol_entry *entry;  unsigned long base_addr;  unsigned long align_addr;  static unsigned int psect_idx = 0;#if VMS_DEBUG  vms_debug (2, "GSD/EGSD (%d/%x)\n", objtype, objtype);#endif  switch (objtype)    {      case EOBJ_S_C_EGSD: 	PRIV(vms_rec) += 8;	/* skip type, size, l_temp */	PRIV(rec_size) -= 8;	break;      case OBJ_S_C_GSD:	PRIV(vms_rec) += 1;	PRIV(rec_size) -= 1;	break;      default:	return -1;    }  /* calculate base address for each section  */  base_addr = 0L;  abfd->symcount = 0;  while (PRIV(rec_size) > 0)    {      vms_rec = PRIV(vms_rec);      if (objtype == OBJ_S_C_GSD)	{	  gsd_type = *vms_rec;	}      else	{	  _bfd_vms_get_header_values (abfd, vms_rec, &gsd_type, &gsd_size);	  gsd_type += EVAX_OFFSET;	}#if VMS_DEBUG  vms_debug (3, "gsd_type %d\n", gsd_type);#endif      switch (gsd_type)	{	  case GSD_S_C_PSC:	    {	      /*	       * program section definition	       */	      asection *old_section = 0;#if VMS_DEBUG  vms_debug (4, "GSD_S_C_PSC\n");#endif	      /* If this section isn't a bfd section.  */	      if (PRIV(is_vax) && (psect_idx < (abfd->section_count-1)))		{		  /* check for temporary section from TIR record.  */		  if (psect_idx < PRIV(section_count))		    old_section = PRIV(sections)[psect_idx];		  else		    old_section = 0;		}	      name = _bfd_vms_save_counted_string (vms_rec + 8);	      section = bfd_make_section (abfd, name);	      if (!section)		{		  (*_bfd_error_handler) (_("bfd_make_section (%s) failed"),					 name);		  return -1;		}	      old_flags = bfd_getl16 (vms_rec + 2);	      section->_raw_size = bfd_getl32(vms_rec + 4);	/* allocation */	      new_flags = vms_secflag_by_name (abfd, vax_section_flags, name, section->_raw_size);	      if (old_flags & EGPS_S_V_REL)		new_flags |= SEC_RELOC;	      if (old_flags & GPS_S_M_OVR)		new_flags |= SEC_IS_COMMON;	      if (!bfd_set_section_flags (abfd, section, new_flags))		{		  (*_bfd_error_handler)		    (_("bfd_set_section_flags (%s, %x) failed"),		     name, new_flags);		  return -1;		}	      section->alignment_power = vms_rec[1];	      align_addr = (1 << section->alignment_power);	      if ((base_addr % align_addr) != 0)		base_addr += (align_addr - (base_addr % align_addr));	      section->vma = (bfd_vma)base_addr;	      base_addr += section->_raw_size;	      /* global section is common symbol  */	      if (old_flags & GPS_S_M_GBL)		{		  entry = _bfd_vms_enter_symbol (abfd, name);		  if (entry == (vms_symbol_entry *)NULL)		    {		      bfd_set_error (bfd_error_no_memory);		      return -1;		    }		  symbol = entry->symbol;		  symbol->value = 0;		  symbol->section = section;		  symbol->flags = (BSF_GLOBAL|BSF_SECTION_SYM|BSF_OLD_COMMON);		}	      /* copy saved contents if old_section set  */	      if (old_section != 0)		{		  section->contents = old_section->contents;		  if (section->_raw_size < old_section->_raw_size)		    {		      (*_bfd_error_handler)			(_("Size mismatch section %s=%lx, %s=%lx"),			 old_section->name,			 (unsigned long) old_section->_raw_size,			 section->name,			 (unsigned long) section->_raw_size);		      return -1;		    }		  else if (section->_raw_size > old_section->_raw_size)		    {		      section->contents = ((unsigned char *)				    bfd_realloc (old_section->contents, section->_raw_size));		      if (section->contents == NULL)			{			  bfd_set_error (bfd_error_no_memory);			  return -1;		        }		    }		}	      else		{		  section->contents = ((unsigned char *)					bfd_malloc (section->_raw_size));		  if (section->contents == NULL)		    {		      bfd_set_error (bfd_error_no_memory);		      return -1;		    }		  memset (section->contents, 0, (size_t)section->_raw_size);		}	      section->_cooked_size = section->_raw_size;#if VMS_DEBUG	      vms_debug (4, "gsd psc %d (%s, flags %04x=%s) ",			 section->index, name, old_flags, flag2str (gpsflagdesc, old_flags));	      vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n",			 section->_raw_size, section->vma, section->contents);#endif	      gsd_size = vms_rec[8] + 9;	      psect_idx++;	    }	  break;	  case GSD_S_C_EPM:	  case GSD_S_C_EPMW:#if VMS_DEBUG		vms_debug(4, "gsd epm\n");#endif	  /*FALLTHRU*/	  case GSD_S_C_SYM:	  case GSD_S_C_SYMW:	    {	      int name_offset, value_offset;	      /*	       * symbol specification (definition or reference)	       */#if VMS_DEBUG  vms_debug (4, "GSD_S_C_SYM(W)\n");

⌨️ 快捷键说明

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