obj-vms.c

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

C
2,166
字号
  /* Since we don't need `arg', use it as our scratch variable so that     we won't get any "not used" warnings about it.  */  arg = get_absolute_expression ();  subseg_set (SEG_DATA, (subsegT) arg);  const_flag = 1;  demand_empty_rest_of_line ();}const pseudo_typeS obj_pseudo_table[] ={  {"const", s_const, 0},  {0, 0, 0},};				/* obj_pseudo_table *//* Routine to perform RESOLVE_SYMBOL_REDEFINITION().  */intvms_resolve_symbol_redef (sym)     symbolS *sym;{  /*   *	If the new symbol is .comm AND it has a size of zero,   *	we ignore it (i.e. the old symbol overrides it)   */  if (SEGMENT_TO_SYMBOL_TYPE ((int) now_seg) == (N_UNDF | N_EXT)      && frag_now_fix () == 0)    {      as_warn (_("compiler emitted zero-size common symbol `%s' already defined"),	       S_GET_NAME (sym));      return 1;    }  /*   *	If the old symbol is .comm and it has a size of zero,   *	we override it with the new symbol value.   */  if (S_IS_EXTERNAL (sym) && S_IS_DEFINED (sym) && S_GET_VALUE (sym) == 0)    {      as_warn (_("compiler redefined zero-size common symbol `%s'"),	       S_GET_NAME (sym));      sym->sy_frag  = frag_now;      S_SET_OTHER (sym, const_flag);      S_SET_VALUE (sym, frag_now_fix ());      /* Keep N_EXT bit.  */      sym->sy_symbol.n_type |= SEGMENT_TO_SYMBOL_TYPE ((int) now_seg);      return 1;    }  return 0;}/* `tc_frob_label' handler for colon(symbols.c), used to examine the   dummy label(s) gcc inserts at the beginning of each file it generates.   gcc 1.x put "gcc_compiled."; gcc 2.x (as of 2.7) puts "gcc2_compiled."   and "__gnu_language_<name>" and possibly "__vax_<type>_doubles".  */voidvms_check_for_special_label (symbolP)symbolS *symbolP;{  /* Special labels only occur prior to explicit section directives.  */  if ((const_flag & IN_DEFAULT_SECTION) != 0)    {      char *sym_name = S_GET_NAME (symbolP);      if (*sym_name == '_')	++sym_name;      if (!strcmp (sym_name, "__vax_g_doubles"))	vax_g_doubles = 1;#if 0	/* not necessary */      else if (!strcmp (sym_name, "__vax_d_doubles"))	vax_g_doubles = 0;#endif#if 0	/* these are potential alternatives to tc-vax.c's md_parse_options() */      else if (!strcmp (sym_name, "gcc_compiled."))	flag_one = 1;      else if (!strcmp (sym_name, "__gnu_language_cplusplus"))	flag_hash_long_names = 1;#endif    }  return;}voidobj_read_begin_hook (){  return;}voidobj_crawl_symbol_chain (headers)     object_headers *headers;{  symbolS *symbolP;  symbolS **symbolPP;  int symbol_number = 0;  symbolPP = &symbol_rootP;	/* -> last symbol chain link.  */  while ((symbolP = *symbolPP) != NULL)    {      resolve_symbol_value (symbolP, 1);     /* OK, here is how we decide which symbols go out into the	brave new symtab.  Symbols that do are:	* symbols with no name (stabd's?)	* symbols with debug info in their N_TYPE	* symbols with \1 as their 3rd character (numeric labels)	* "local labels" needed for PIC fixups	Symbols that don't are:	* symbols that are registers	All other symbols are output.  We complain if a deleted	symbol was marked external.  */      if (!S_IS_REGISTER (symbolP))	{	  symbolP->sy_number = symbol_number++;	  symbolP->sy_name_offset = 0;	  symbolPP = &symbolP->sy_next;	}      else	{	  if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))	    {	      as_bad (_("Local symbol %s never defined"), S_GET_NAME (symbolP));	    }			/* oops.  */	  /* Unhook it from the chain.  */	  *symbolPP = symbol_next (symbolP);	}			/* if this symbol should be in the output */    }			/* for each symbol */  H_SET_STRING_SIZE (headers, string_byte_count);  H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);}				/* obj_crawl_symbol_chain() */ /****** VMS OBJECT FILE HACKING ROUTINES *******//* Create the VMS object file.  */static voidCreate_VMS_Object_File (){#if	defined(eunice) || !defined(VMS)  VMS_Object_File_FD = creat (out_file_name, 0777, "var");#else	/* eunice */  VMS_Object_File_FD = creat (out_file_name, 0, "rfm=var",			      "ctx=bin", "mbc=16", "deq=64", "fop=tef",			      "shr=nil");#endif	/* eunice */  /* Deal with errors.  */  if (VMS_Object_File_FD < 0)    as_fatal (_("Couldn't create VMS object file \"%s\""), out_file_name);  /* Initialize object file hacking variables.  */  Object_Record_Offset = 0;  Current_Object_Record_Type = -1;}/* Flush the object record buffer to the object file.  */static voidFlush_VMS_Object_Record_Buffer (){  /* If the buffer is empty, there's nothing to do.  */  if (Object_Record_Offset == 0)    return;#ifndef VMS			/* For cross-assembly purposes.  */  {    char RecLen[2];    /* "Variable-length record" files have a two byte length field       prepended to each record.  It's normally out-of-band, and native       VMS output will insert it automatically for this type of file.       When cross-assembling, we must write it explicitly.  */    md_number_to_chars (RecLen, Object_Record_Offset, 2);    if (write (VMS_Object_File_FD, RecLen, 2) != 2)      error (_("I/O error writing VMS object file (length prefix)"));    /* We also need to force the actual record to be an even number of       bytes.  For native output, that's automatic; when cross-assembling,       pad with a NUL byte if length is odd.  Do so _after_ writing the       pre-padded length.  Since our buffer is defined with even size,       an odd offset implies that it has some room left.  */    if ((Object_Record_Offset & 1) != 0)      Object_Record_Buffer[Object_Record_Offset++] = '\0';  }#endif /* not VMS */  /* Write the data to the file.  */  if (write (VMS_Object_File_FD, Object_Record_Buffer, Object_Record_Offset)      != Object_Record_Offset)    error (_("I/O error writing VMS object file"));  /* The buffer is now empty.  */  Object_Record_Offset = 0;}/* Declare a particular type of object file record.  */static voidSet_VMS_Object_File_Record (Type)     int Type;{  /* If the type matches, we are done.  */  if (Type == Current_Object_Record_Type)    return;  /* Otherwise: flush the buffer.  */  Flush_VMS_Object_Record_Buffer ();  /* Remember the new type.  */  Current_Object_Record_Type = Type;}/* Close the VMS Object file.  */static voidClose_VMS_Object_File (){  /* Flush (should never be necessary) and reset saved record-type context.  */  Set_VMS_Object_File_Record (-1);#ifndef VMS			/* For cross-assembly purposes.  */  {    char RecLen[2];    int minus_one = -1;    /* Write a 2 byte record-length field of -1 into the file, which       means end-of-block when read, hence end-of-file when occurring       in the file's last block.  It is only needed for variable-length       record files transferred to VMS as fixed-length record files       (typical for binary FTP; NFS shouldn't need it, but it won't hurt).  */    md_number_to_chars (RecLen, minus_one, 2);    write (VMS_Object_File_FD, RecLen, 2);  }#else    /* When written on a VMS system, the file header (cf inode) will record       the actual end-of-file position and no inline marker is needed.  */#endif  close (VMS_Object_File_FD);} /****** Text Information and Relocation routines ******//* Stack Psect base followed by signed, varying-sized offset.   Common to several object records.  */static voidvms_tir_stack_psect (Psect_Index, Offset, Force)     int Psect_Index;     int Offset;     int Force;{  int psect_width, offset_width;  psect_width = ((unsigned) Psect_Index > 255) ? 2 : 1;  offset_width = (Force || Offset > 32767 || Offset < -32768) ? 4		 : (Offset > 127 || Offset < -128) ? 2 : 1;#define Sta_P(p,o) (((o)<<1) | ((p)-1))  /* byte or word psect; byte, word, or longword offset */  switch (Sta_P(psect_width,offset_width))    {      case Sta_P(1,1):	PUT_CHAR (TIR_S_C_STA_PB);			PUT_CHAR ((char) (unsigned char) Psect_Index);			PUT_CHAR ((char) Offset);			break;      case Sta_P(1,2):	PUT_CHAR (TIR_S_C_STA_PW);			PUT_CHAR ((char) (unsigned char) Psect_Index);			PUT_SHORT (Offset);			break;      case Sta_P(1,4):	PUT_CHAR (TIR_S_C_STA_PL);			PUT_CHAR ((char) (unsigned char) Psect_Index);			PUT_LONG (Offset);			break;      case Sta_P(2,1):	PUT_CHAR (TIR_S_C_STA_WPB);			PUT_SHORT (Psect_Index);			PUT_CHAR ((char) Offset);			break;      case Sta_P(2,2):	PUT_CHAR (TIR_S_C_STA_WPW);			PUT_SHORT (Psect_Index);			PUT_SHORT (Offset);			break;      case Sta_P(2,4):	PUT_CHAR (TIR_S_C_STA_WPL);			PUT_SHORT (Psect_Index);			PUT_LONG (Offset);			break;    }#undef Sta_P}/* Store immediate data in current Psect.  */static voidVMS_Store_Immediate_Data (Pointer, Size, Record_Type)     const char *Pointer;     int Size;     int Record_Type;{  register int i;  Set_VMS_Object_File_Record (Record_Type);  /* We can only store as most 128 bytes at a time due to the way that     TIR commands are encoded.  */  while (Size > 0)    {      i = (Size > 128) ? 128 : Size;      Size -= i;      /* If we cannot accommodate this record, flush the buffer.  */      if ((Object_Record_Offset + i + 1) >= sizeof Object_Record_Buffer)	Flush_VMS_Object_Record_Buffer ();      /* If the buffer is empty we must insert record type.  */      if (Object_Record_Offset == 0)	PUT_CHAR (Record_Type);      /* Store the count.  The Store Immediate TIR command is implied by         a negative command byte, and the length of the immediate data         is abs(command_byte).  So, we write the negated length value.  */      PUT_CHAR ((char) (-i & 0xff));      /* Now store the data.  */      while (--i >= 0)	PUT_CHAR (*Pointer++);    }  /* Flush the buffer if it is more than 75% full.  */  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))    Flush_VMS_Object_Record_Buffer ();}/* Make a data reference.  */static voidVMS_Set_Data (Psect_Index, Offset, Record_Type, Force)     int Psect_Index;     int Offset;     int Record_Type;     int Force;{  Set_VMS_Object_File_Record (Record_Type);  /* If the buffer is empty we must insert the record type.  */  if (Object_Record_Offset == 0)    PUT_CHAR (Record_Type);  /* Stack the Psect base with its offset.  */  vms_tir_stack_psect (Psect_Index, Offset, Force);  /* Set relocation base.  */  PUT_CHAR (TIR_S_C_STO_PIDR);  /* Flush the buffer if it is more than 75% full.  */  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))    Flush_VMS_Object_Record_Buffer ();}/* Make a debugger reference to a struct, union or enum.  */static voidVMS_Store_Struct (Struct_Index)     int Struct_Index;{  /* We are writing a debug record.  */  Set_VMS_Object_File_Record (OBJ_S_C_DBG);  /* If the buffer is empty we must insert the record type.  */  if (Object_Record_Offset == 0)    PUT_CHAR (OBJ_S_C_DBG);  PUT_CHAR (TIR_S_C_STA_UW);  PUT_SHORT (Struct_Index);  PUT_CHAR (TIR_S_C_CTL_STKDL);  PUT_CHAR (TIR_S_C_STO_L);  /* Flush the buffer if it is more than 75% full.  */  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))    Flush_VMS_Object_Record_Buffer ();}/* Make a debugger reference to partially define a struct, union or enum.  */static voidVMS_Def_Struct (Struct_Index)     int Struct_Index;{  /* We are writing a debug record.  */  Set_VMS_Object_File_Record (OBJ_S_C_DBG);  /* If the buffer is empty we must insert the record type.  */  if (Object_Record_Offset == 0)    PUT_CHAR (OBJ_S_C_DBG);  PUT_CHAR (TIR_S_C_STA_UW);  PUT_SHORT (Struct_Index);  PUT_CHAR (TIR_S_C_CTL_DFLOC);  /* Flush the buffer if it is more than 75% full.  */  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))    Flush_VMS_Object_Record_Buffer ();}static voidVMS_Set_Struct (Struct_Index)     int Struct_Index;{				/* see previous functions for comments */  Set_VMS_Object_File_Record (OBJ_S_C_DBG);  if (Object_Record_Offset == 0)    PUT_CHAR (OBJ_S_C_DBG);  PUT_CHAR (TIR_S_C_STA_UW);  PUT_SHORT (Struct_Index);  PUT_CHAR (TIR_S_C_CTL_STLOC);  if (Object_Record_Offset > (sizeof (Object_Record_Buffer) * 3 / 4))    Flush_VMS_Object_Record_Buffer ();} /****** Traceback Information routines ******//* Write the Traceback Module Begin record.  */static voidVMS_TBT_Module_Begin (){  register char *cp, *cp1;  int Size;  char Local[256];  /* Arrange to store the data locally (leave room for size byte).  */  cp = &Local[1];  /* Begin module.  */  *cp++ = DST_S_C_MODBEG;  *cp++ = 0;		/* flags; not used */  /*   *	Language type == "C"   *   * (FIXME:  this should be based on the input...)   */  COPY_LONG (cp, DST_S_C_C);  cp += 4;  /* Store the module name.  */  *cp++ = (char) strlen (Module_Name);  cp1 = Module_Name;  while (*cp1)    *cp++ = *cp1++;

⌨️ 快捷键说明

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