📄 vms.c
字号:
*/ if (strcmp(Type,"COMMON") == 0) { /* * Common block psects are: PIC,OVR,REL,GBL,SHR,RD,WRT */ Psect_Attributes = (GPS$M_PIC|GPS$M_OVR|GPS$M_REL|GPS$M_GBL| GPS$M_SHR|GPS$M_RD|GPS$M_WRT); } else if (strcmp(Type,"CONST") == 0) { /* * Common block psects are: PIC,OVR,REL,GBL,SHR,RD */ Psect_Attributes = (GPS$M_PIC|GPS$M_OVR|GPS$M_REL|GPS$M_GBL| GPS$M_SHR|GPS$M_RD); } else if (strcmp(Type,"DATA") == 0) { /* * The Data psects are PIC,REL,RD,WRT */ Psect_Attributes = (GPS$M_PIC|GPS$M_REL|GPS$M_RD|GPS$M_WRT); } else if (strcmp(Type,"TEXT") == 0) { /* * The Text psects are PIC,REL,SHR,EXE,RD */ Psect_Attributes = (GPS$M_PIC|GPS$M_REL|GPS$M_SHR| GPS$M_EXE|GPS$M_RD); } else { /* * Error: Unknown psect type */ error("Unknown VMS psect type"); } /* * Modify the psect attributes according to any attribute string */ if (HAS_PSECT_ATTRIBUTES(Name)) VMS_Modify_Psect_Attributes(Name,&Psect_Attributes); /* * Specify the psect attributes */ PUT_SHORT(Psect_Attributes); /* * Specify the allocation */ PUT_LONG(Size); /* * Finally, the psect name */ VMS_Case_Hack_Symbol(Name,Local); PUT_COUNTED_STRING(Local); /* * 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();}/* * Define a global symbol */VMS_Global_Symbol_Spec(Name, Psect_Number, Psect_Offset, Defined)char *Name;int Psect_Number;int Psect_Offset;{ char Local[32]; /* * We are writing a GSD record */ Set_VMS_Object_File_Record(OBJ$C_GSD); /* * If the buffer is empty we must insert the GSD record type */ if (Object_Record_Offset == 0) PUT_CHAR(OBJ$C_GSD); /* * We are writing a Global symbol definition subrecord */ if (Psect_Number <= 255) { PUT_CHAR(GSD$C_SYM); } else { PUT_CHAR(GSD$C_SYMW); } /* * Data type is undefined */ PUT_CHAR(0); /* * Switch on Definition/Reference */ if (Defined) { /* * Definition: * Flags = "RELOCATABLE" and "DEFINED" */ PUT_SHORT(GSY$M_DEF|GSY$M_REL); /* * Psect Number */ if (Psect_Number <= 255) { PUT_CHAR(Psect_Number); } else { PUT_SHORT(Psect_Number); } /* * Offset */ PUT_LONG(Psect_Offset); } else { /* * Reference: * Flags = "RELOCATABLE" */ PUT_SHORT(GSY$M_REL); } /* * Finally, the global symbol name */ VMS_Case_Hack_Symbol(Name,Local); PUT_COUNTED_STRING(Local); /* * 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();}/* * Define a procedure entry pt/mask */VMS_Procedure_Entry_Pt(Name, Psect_Number, Psect_Offset, Entry_Mask)char *Name;int Psect_Number;int Psect_Offset;int Entry_Mask;{ char Local[32]; /* * We are writing a GSD record */ Set_VMS_Object_File_Record(OBJ$C_GSD); /* * If the buffer is empty we must insert the GSD record type */ if (Object_Record_Offset == 0) PUT_CHAR(OBJ$C_GSD); /* * We are writing a Procedure Entry Pt/Mask subrecord */ if (Psect_Number <= 255) { PUT_CHAR(GSD$C_EPM); } else { PUT_CHAR(GSD$C_EPMW); } /* * Data type is undefined */ PUT_CHAR(0); /* * Flags = "RELOCATABLE" and "DEFINED" */ PUT_SHORT(GSY$M_DEF|GSY$M_REL); /* * Psect Number */ if (Psect_Number <= 255) { PUT_CHAR(Psect_Number); } else { PUT_SHORT(Psect_Number); } /* * Offset */ PUT_LONG(Psect_Offset); /* * Entry mask */ PUT_SHORT(Entry_Mask); /* * Finally, the global symbol name */ VMS_Case_Hack_Symbol(Name,Local); PUT_COUNTED_STRING(Local); /* * 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();}/* * Set the current location counter to a particular Psect and Offset */VMS_Set_Psect(Psect_Index, Offset, Record_Type)int Psect_Index;int Offset;int Record_Type;{ /* * We are writing a "Record_Type" record */ 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 + Longword Offset */ if (Psect_Index < 255) { PUT_CHAR(TIR$C_STA_PL); PUT_CHAR(Psect_Index); } else { PUT_CHAR(TIR$C_STA_WPL); PUT_SHORT(Psect_Index); } PUT_LONG(Offset); /* * Set relocation base */ PUT_CHAR(TIR$C_CTL_SETRB); /* * 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 */VMS_Set_Data(Psect_Index, Offset, Record_Type,Force)int Psect_Index;int Offset;int Record_Type;int Force;{ /* * We are writing a "Record_Type" record */ 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 + Longword Offset */ if(Force==1){ if(Psect_Index>127){ PUT_CHAR(TIR$C_STA_WPL); PUT_SHORT(Psect_Index); PUT_LONG(Offset);} else { PUT_CHAR(TIR$C_STA_PL); PUT_CHAR(Psect_Index); PUT_LONG(Offset);} } else {if(Offset>32767){ PUT_CHAR(TIR$C_STA_WPL); PUT_SHORT(Psect_Index); PUT_LONG(Offset);} else if(Offset>127){ PUT_CHAR(TIR$C_STA_WPW); PUT_SHORT(Psect_Index); PUT_SHORT(Offset);} else{ PUT_CHAR(TIR$C_STA_WPB); PUT_SHORT(Psect_Index); PUT_CHAR(Offset);};}; /* * Set relocation base */ PUT_CHAR(TIR$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. */VMS_Store_Struct(int Struct_Index){ /* * We are writing a "OBJ$C_DBG" record */ Set_VMS_Object_File_Record(OBJ$C_DBG); /* * If the buffer is empty we must insert the record type */ if (Object_Record_Offset == 0) PUT_CHAR(OBJ$C_DBG); PUT_CHAR(TIR$C_STA_UW); PUT_SHORT(Struct_Index); PUT_CHAR(TIR$C_CTL_STKDL); PUT_CHAR(TIR$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. */VMS_Def_Struct(int Struct_Index){ /* * We are writing a "OBJ$C_DBG" record */ Set_VMS_Object_File_Record(OBJ$C_DBG); /* * If the buffer is empty we must insert the record type */ if (Object_Record_Offset == 0) PUT_CHAR(OBJ$C_DBG); PUT_CHAR(TIR$C_STA_UW); PUT_SHORT(Struct_Index); PUT_CHAR(TIR$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();}VMS_Set_Struct(int Struct_Index){/* see previous functions for comments */ Set_VMS_Object_File_Record(OBJ$C_DBG); if (Object_Record_Offset == 0) PUT_CHAR(OBJ$C_DBG); PUT_CHAR(TIR$C_STA_UW); PUT_SHORT(Struct_Index); PUT_CHAR(TIR$C_CTL_STLOC); if (Object_Record_Offset > (sizeof(Object_Record_Buffer)*3/4)) Flush_VMS_Object_Record_Buffer();}/* * Store immediate data in current Psect */VMS_Store_Immediate_Data(Pointer, Size, Record_Type)register char *Pointer;int Size;int Record_Type;{ register int i; /* * We are writing a "Record_Type" record */ Set_VMS_Object_File_Record(Record_Type); /* * We can only store 128 bytes at a time */ while(Size > 0) { /* * Store a maximum of 128 bytes */ 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 */ PUT_CHAR(-i & 0xff); /* * 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(); }}/* * Store repeated immediate data in current Psect */VMS_Store_Repeated_Data(Repeat_Count,Pointer, Size, Record_Type)int Repeat_Count;register char *Pointer;int Size;int Record_Type;{ /* * Ignore zero bytes/words/longwords */ if ((Size == sizeof(char)) && (*Pointer == 0)) return; if ((Size == sizeof(short)) && (*(short *)Pointer == 0)) return; if ((Size == sizeof(long)) && (*(long *)Pointer == 0)) return; /* * If the data is too big for a TIR$C_STO_RIVB sub-record * then we do it manually */ if (Size > 255) { while(--Repeat_Count >= 0) VMS_Store_Immediate_Data(Pointer,Size,Record_Type); return; } /* * We are writing a "Record_Type" record */ Set_VMS_Object_File_Record(Record_Type); /* * If the buffer is empty we must insert record type */ if (Object_Record_Offset == 0) PUT_CHAR(Record_Type); /* * Stack the repeat count */ PUT_CHAR(TIR$C_STA_LW); PUT_LONG(Repeat_Count); /* * And now the command and its data */ PUT_CHAR(TIR$C_STO_RIVB); PUT_CHAR(Size); while(--Size >= 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();}/* * Store a Position Independent Reference */VMS_Store_PIC_Symbol_Reference(Symbol, Offset, PC_Relative, Psect, Psect_Offset, Record_Type)struct symbol *Symbol;int Offset;int PC_Relative;int Psect;int Psect_Offset;int Record_Type;{ register struct VMS_Symbol *vsp = (struct VMS_Symbol *)(Symbol->sy_number); char Local[32]; /* * We are writing a "Record_Type" record */ Set_VMS_Object_File_Record(Record_Type); /* * If the buffer is empty we must insert record type */ if (Object_Record_Offset == 0) PUT_CHAR(Record_Type); /* * Set to the appropriate offset in the Psect */ if (PC_Relative) { /* * For a Code reference we need to fix the operand * specifier as well (so back up 1 byte) */ VMS_Set_Psect(Psect, Psect_Offset - 1, Record_Type); } else { /* * For a Data reference we just store HERE */ VMS_Set_Psect(Psect, Psect_Offset, Record_Type); } /* * Make sure we are still generating a "Record Type" record */ if (Object_Record_Offset == 0) PUT_CHAR(Record_Type); /* * Dispatch on symbol type (so we can stack its value) */ switch(Symbol->sy_nlist.n_type) { /* * Global symbol */#ifdef NOT_VAX_11_C_COMPATIBLE case N_UNDF | N_EXT: case N_DATA | N_EXT:#endif NOT_VAX_11_C_COMPATIBLE case N_UNDF: case N_TEXT | N_EXT: /* * Get the symbol name (case hacked) */ VMS_Case_Hack_Symbol(Symbol->sy_nlist.n_un.n_name,Local); /* * Stack the global symbol value */ PUT_CHAR(TIR$C_STA_GBL); PUT_COUNTED_STRING(Local); if (Offset) { /* * Stack the longword offset */ PUT_CHAR(TIR$C_STA_LW); PUT_LONG(Offset); /* * Add the two, leaving the result on the stack */ PUT_CHAR(TIR$C_OPR_ADD); } break; /* * Uninitialized local data */ case N_BSS: /* * Stack the Psect (+offset) */ if (vsp->Psect_Index < 255) { PUT_CHAR(TIR$C_STA_PL); PUT_CHAR(vsp->Psect_Index); } else { PUT_CHAR(TIR$C_STA_WPL); PUT_SHORT(vsp->Psect_Index); } PUT_LONG(vsp->Psect_Offset + Offset); break; /* * Local text */ case N_TEXT: /* * Stack the Psect (+offset) */ if (vsp->Psect_Index < 255) { PUT_CHAR(TIR$C_STA_PL); PUT_CHAR(vsp->Psect_Index); } else { PUT_CHAR(TIR$C_STA_WPL); PUT_SHORT(vsp->Psect_Index); } PUT_LONG(Symbol->sy_nlist.n_value); break; /* * Initialized local or global data */ case N_DATA:#ifndef NOT_VAX_11_C_COMPATIBLE case N_UNDF | N_EXT: case N_DATA | N_EXT:#endif NOT_VAX_11_C_COMPATIBLE /* * Stack the Psect (+offset) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -