obj-vms.c

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

C
2,166
字号
/* vms.c -- Write out a VAX/VMS object file   Copyright 1987, 1988, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001   Free Software Foundation, Inc.This file is part of GAS, the GNU Assembler.GAS 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, or (at your option)any later version.GAS 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 GAS; see the file COPYING.  If not, write to the FreeSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA02111-1307, USA.  *//* Written by David L. Kashtan *//* Modified by Eric Youngdale to write VMS debug records for program   variables *//* Want all of obj-vms.h (as obj-format.h, via targ-env.h, via as.h).  */#define WANT_VMS_OBJ_DEFS#include "as.h"#include "config.h"#include "subsegs.h"#include "obstack.h"/* What we do if there is a goof.  */#define error as_fatal#ifdef VMS			/* These are of no use if we are cross assembling.  */#include <fab.h>		/* Define File Access Block	  */#include <nam.h>		/* Define NAM Block		  */#include <xab.h>		/* Define XAB - all different types*/extern int sys$open(), sys$close(), sys$asctim();#endif/* *	Version string of the compiler that produced the code we are *	assembling.  (And this assembler, if we do not have compiler info.) */char *compiler_version_string;extern int flag_hash_long_names;	/* -+ */extern int flag_one;			/* -1; compatibility with gcc 1.x */extern int flag_show_after_trunc;	/* -H */extern int flag_no_hash_mixed_case;	/* -h NUM *//* Flag that determines how we map names.  This takes several values, and * is set with the -h switch.  A value of zero implies names should be * upper case, and the presence of the -h switch inhibits the case hack. * No -h switch at all sets vms_name_mapping to 0, and allows case hacking. * A value of 2 (set with -h2) implies names should be * all lower case, with no case hack.  A value of 3 (set with -h3) implies * that case should be preserved.  *//* If the -+ switch is given, then the hash is appended to any name that is * longer than 31 characters, regardless of the setting of the -h switch. */char vms_name_mapping = 0;static symbolS *Entry_Point_Symbol = 0;	/* Pointer to "_main" *//* *	We augment the "gas" symbol structure with this */struct VMS_Symbol{  struct VMS_Symbol *Next;  symbolS *Symbol;  int Size;  int Psect_Index;  int Psect_Offset;};struct VMS_Symbol *VMS_Symbols = 0;struct VMS_Symbol *Ctors_Symbols = 0;struct VMS_Symbol *Dtors_Symbols = 0;/* We need this to keep track of the various input files, so that we can * give the debugger the correct source line. */struct input_file{  struct input_file *next;  struct input_file *same_file_fpnt;  int file_number;  int max_line;  int min_line;  int offset;  char flag;  char *name;  symbolS *spnt;};static struct input_file *file_root = (struct input_file *) NULL;/* * Styles of PSECTS (program sections) that we generate; just shorthand * to avoid lists of section attributes.  Used by VMS_Psect_Spec(). */enum ps_type{  ps_TEXT, ps_DATA, ps_COMMON, ps_CONST, ps_CTORS, ps_DTORS};/* * This enum is used to keep track of the various types of variables that * may be present. */enum advanced_type{  BASIC, POINTER, ARRAY, ENUM, STRUCT, UNION, FUNCTION, VOID, ALIAS, UNKNOWN};/* * This structure contains the information from the stabs directives, and the * information is filled in by VMS_typedef_parse.  Everything that is needed * to generate the debugging record for a given symbol is present here. * This could be done more efficiently, using nested struct/unions, but for now * I am happy that it works. */struct VMS_DBG_Symbol{  struct VMS_DBG_Symbol *next;  /* description of what this is */  enum advanced_type advanced;  /* this record is for this type */  int dbx_type;  /* For advanced types this is the type referred to.  I.e., the type     a pointer points to, or the type of object that makes up an     array.  */  int type2;  /* Use this type when generating a variable def */  int VMS_type;  /* used for arrays - this will be present for all */  int index_min;  /* entries, but will be meaningless for non-arrays */  int index_max;  /* Size in bytes of the data type.  For an array, this is the size     of one element in the array */  int data_size;  /* Number of the structure/union/enum - used for ref */  int struc_numb;};#define SYMTYPLST_SIZE (1<<4)	/* 16; must be power of two */#define SYMTYP_HASH(x) ((unsigned) (x) & (SYMTYPLST_SIZE-1))struct VMS_DBG_Symbol *VMS_Symbol_type_list[SYMTYPLST_SIZE];/* * We need this structure to keep track of forward references to * struct/union/enum that have not been defined yet.  When they are ultimately * defined, then we can go back and generate the TIR commands to make a back * reference. */struct forward_ref{  struct forward_ref *next;  int dbx_type;  int struc_numb;  char resolved;};struct forward_ref *f_ref_root = (struct forward_ref *) NULL;/* * This routine is used to compare the names of certain types to various * fixed types that are known by the debugger. */#define type_check(X)  !strcmp (symbol_name, X)/* * This variable is used to keep track of the name of the symbol we are * working on while we are parsing the stabs directives. */static const char *symbol_name;/* We use this counter to assign numbers to all of the structures, unions * and enums that we define.  When we actually declare a variable to the * debugger, we can simply do it by number, rather than describing the * whole thing each time. */static structure_count = 0;/* This variable is used to indicate that we are making the last attempt to   parse the stabs, and that we should define as much as we can, and ignore   the rest */static int final_pass;/* This variable is used to keep track of the current structure number * for a given variable.  If this is < 0, that means that the structure * has not yet been defined to the debugger.  This is still cool, since * the VMS object language has ways of fixing things up after the fact, * so we just make a note of this, and generate fixups at the end. */static int struct_number;/* This is used to distinguish between D_float and G_float for telling   the debugger about doubles.  gcc outputs the same .stabs regardless   of whether -mg is used to select alternate doubles.  */static int vax_g_doubles = 0;/* Local symbol references (used to handle N_ABS symbols; gcc does not   generate those, but they're possible with hand-coded assembler input)   are always made relative to some particular environment.  If the current   input has any such symbols, then we expect this to get incremented   exactly once and end up having all of them be in environment #0.  */static int Current_Environment = -1;/* Every object file must specify an module name, which is also used by   traceback records.  Set in Write_VMS_MHD_Records().  */static char Module_Name[255+1];/* * Variable descriptors are used tell the debugger the data types of certain * more complicated variables (basically anything involving a structure, * union, enum, array or pointer).  Some non-pointer variables of the * basic types that the debugger knows about do not require a variable * descriptor. * * Since it is impossible to have a variable descriptor longer than 128 * bytes by virtue of the way that the VMS object language is set up, * it makes not sense to make the arrays any longer than this, or worrying * about dynamic sizing of the array. * * These are the arrays and counters that we use to build a variable * descriptor. */#define MAX_DEBUG_RECORD 128static char Local[MAX_DEBUG_RECORD];	/* buffer for variable descriptor */static char Asuffix[MAX_DEBUG_RECORD];	/* buffer for array descriptor */static int Lpnt;		/* index into Local */static int Apoint;		/* index into Asuffix */static char overflow;		/* flag to indicate we have written too much*/static int total_len;		/* used to calculate the total length of variable				descriptor plus array descriptor - used for len byte*//* Flag if we have told user about finding global constants in the text   section.  */static int gave_compiler_message = 0;/* *	Global data (Object records limited to 512 bytes by VAX-11 "C" runtime) */static int VMS_Object_File_FD;	/* File Descriptor for object file */static char Object_Record_Buffer[512];	/* Buffer for object file records  */static int Object_Record_Offset;/* Offset to end of data	   */static int Current_Object_Record_Type;	/* Type of record in above	   *//* *	Macros for moving data around.  Must work on big-endian systems. */#ifdef VMS  /* These are more efficient for VMS->VMS systems */#define COPY_LONG(dest,val)	( *(long *) (dest) = (val) )#define COPY_SHORT(dest,val)	( *(short *) (dest) = (val) )#else#define COPY_LONG(dest,val)	md_number_to_chars ((dest), (val), 4)#define COPY_SHORT(dest,val)	md_number_to_chars ((dest), (val), 2)#endif/* *	Macros for placing data into the object record buffer. */#define PUT_LONG(val) \	( COPY_LONG (&Object_Record_Buffer[Object_Record_Offset], (val)), \	  Object_Record_Offset += 4 )#define PUT_SHORT(val) \	( COPY_SHORT (&Object_Record_Buffer[Object_Record_Offset], (val)), \	  Object_Record_Offset += 2 )#define PUT_CHAR(val) ( Object_Record_Buffer[Object_Record_Offset++] = (val) )#define PUT_COUNTED_STRING(cp) do { \			register const char *p = (cp); \			PUT_CHAR ((char) strlen (p)); \			while (*p) PUT_CHAR (*p++); } while (0)/* *	Macro for determining if a Name has psect attributes attached *	to it. */#define PSECT_ATTRIBUTES_STRING		"$$PsectAttributes_"#define PSECT_ATTRIBUTES_STRING_LENGTH	18#define HAS_PSECT_ATTRIBUTES(Name) \		(strncmp ((*Name == '_' ? Name + 1 : Name), \			  PSECT_ATTRIBUTES_STRING, \			  PSECT_ATTRIBUTES_STRING_LENGTH) == 0) /* in: segT   out: N_TYPE bits */const short seg_N_TYPE[] ={  N_ABS,  N_TEXT,  N_DATA,  N_BSS,  N_UNDF,			/* unknown */  N_UNDF,			/* error */  N_UNDF,			/* expression */  N_UNDF,			/* debug */  N_UNDF,			/* ntv */  N_UNDF,			/* ptv */  N_REGISTER,			/* register */};const segT N_TYPE_seg[N_TYPE + 2] ={				/* N_TYPE == 0x1E = 32-2 */  SEG_UNKNOWN,			/* N_UNDF == 0 */  SEG_GOOF,  SEG_ABSOLUTE,			/* N_ABS == 2 */  SEG_GOOF,  SEG_TEXT,			/* N_TEXT == 4 */  SEG_GOOF,  SEG_DATA,			/* N_DATA == 6 */  SEG_GOOF,  SEG_BSS,			/* N_BSS == 8 */  SEG_GOOF,  SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,  SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,  SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,  SEG_REGISTER,			/* dummy N_REGISTER for regs = 30 */  SEG_GOOF,};/* Local support routines which return a value.  */static struct input_file *find_file PARAMS ((symbolS *));static struct VMS_DBG_Symbol *find_symbol PARAMS ((int));static symbolS *Define_Routine PARAMS ((symbolS *,int,symbolS *,int));static char *cvt_integer PARAMS ((char *,int *));static char *fix_name PARAMS ((char *));static char *get_struct_name PARAMS ((char *));static offsetT VMS_Initialized_Data_Size PARAMS ((symbolS *,unsigned));static int VMS_TBT_Source_File PARAMS ((char *,int));static int gen1 PARAMS ((struct VMS_DBG_Symbol *,int));static int forward_reference PARAMS ((char *));static int final_forward_reference PARAMS ((struct VMS_DBG_Symbol *));static int VMS_typedef_parse PARAMS ((char *));static int hash_string PARAMS ((const char *));static int VMS_Psect_Spec PARAMS ((const char *,int,enum ps_type,				   struct VMS_Symbol *));/* Local support routines which don't directly return any value.  */static void s_const PARAMS ((int));static void Create_VMS_Object_File PARAMS ((void));static void Flush_VMS_Object_Record_Buffer PARAMS ((void));static void Set_VMS_Object_File_Record PARAMS ((int));static void Close_VMS_Object_File PARAMS ((void));static void vms_tir_stack_psect PARAMS ((int,int,int));static void VMS_Store_Immediate_Data PARAMS ((const char *,int,int));static void VMS_Set_Data PARAMS ((int,int,int,int));static void VMS_Store_Struct PARAMS ((int));static void VMS_Def_Struct PARAMS ((int));static void VMS_Set_Struct PARAMS ((int));static void VMS_TBT_Module_Begin PARAMS ((void));static void VMS_TBT_Module_End PARAMS ((void));static void VMS_TBT_Routine_Begin PARAMS ((symbolS *,int));static void VMS_TBT_Routine_End PARAMS ((int,symbolS *));static void VMS_TBT_Block_Begin PARAMS ((symbolS *,int,char *));static void VMS_TBT_Block_End PARAMS ((valueT));static void VMS_TBT_Line_PC_Correlation PARAMS ((int,int,int,int));static void VMS_TBT_Source_Lines PARAMS ((int,int,int));static void fpush PARAMS ((int,int));static void rpush PARAMS ((int,int));static void array_suffix PARAMS ((struct VMS_DBG_Symbol *));static void new_forward_ref PARAMS ((int));static void generate_suffix PARAMS ((struct VMS_DBG_Symbol *,int));static void bitfield_suffix PARAMS ((struct VMS_DBG_Symbol *,int));static void setup_basic_type PARAMS ((struct VMS_DBG_Symbol *));static void VMS_DBG_record PARAMS ((struct VMS_DBG_Symbol *,int,int,char *));static void VMS_local_stab_Parse PARAMS ((symbolS *));static void VMS_stab_parse PARAMS ((symbolS *,int,int,int,int));static void VMS_GSYM_Parse PARAMS ((symbolS *,int));static void VMS_LCSYM_Parse PARAMS ((symbolS *,int));static void VMS_STSYM_Parse PARAMS ((symbolS *,int));static void VMS_RSYM_Parse PARAMS ((symbolS *,symbolS *,int));static void VMS_LSYM_Parse PARAMS ((void));static void Define_Local_Symbols PARAMS ((symbolS *,symbolS *,symbolS *,int));static void Write_VMS_MHD_Records PARAMS ((void));static void Write_VMS_EOM_Record PARAMS ((int,valueT));static void VMS_Case_Hack_Symbol PARAMS ((const char *,char *));static void VMS_Modify_Psect_Attributes PARAMS ((const char *,int *));static void VMS_Global_Symbol_Spec PARAMS ((const char *,int,int,int));static void VMS_Local_Environment_Setup PARAMS ((const char *));static void VMS_Emit_Globalvalues PARAMS ((unsigned,unsigned,char *));static void VMS_Procedure_Entry_Pt PARAMS ((char *,int,int,int));static void VMS_Set_Psect PARAMS ((int,int,int));static void VMS_Store_Repeated_Data PARAMS ((int,char *,int,int));static void VMS_Store_PIC_Symbol_Reference PARAMS ((symbolS *,int,						    int,int,int,int));static void VMS_Fix_Indirect_Reference PARAMS ((int,int,fragS *,fragS *));/* Support code which used to be inline within vms_write_object_file.  */static void vms_fixup_text_section PARAMS ((unsigned,struct frag *,struct frag *));static void synthesize_data_segment PARAMS ((unsigned,unsigned,struct frag *));static void vms_fixup_data_section PARAMS ((unsigned,unsigned));static void global_symbol_directory PARAMS ((unsigned,unsigned));static void local_symbols_DST PARAMS ((symbolS *,symbolS *));static void vms_build_DST PARAMS ((unsigned));static void vms_fixup_xtors_section PARAMS ((struct VMS_Symbol *, int));/* The following code defines the special types of pseudo-ops that we   use with VMS.  */unsigned char const_flag = IN_DEFAULT_SECTION;static voids_const (arg)     int arg;	/* 3rd field from obj_pseudo_table[]; not needed here */{

⌨️ 快捷键说明

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