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

📄 vms.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
				     Entry_Point_Symbol->sy_nlist.n_value);   /*    *	All done, close the object file    */   Close_VMS_Object_File();}	/****** VMS OBJECT FILE HACKING ROUTINES *******//* *	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 placing data into the object record buffer */#define	PUT_LONG(val)	*((long *)(Object_Record_Buffer + \				  Object_Record_Offset)) = val; \			Object_Record_Offset += sizeof(long)#define	PUT_SHORT(val)	*((short *)(Object_Record_Buffer + \				  Object_Record_Offset)) = val; \			Object_Record_Offset += sizeof(short)#define	PUT_CHAR(val)	Object_Record_Buffer[Object_Record_Offset++] = val#define	PUT_COUNTED_STRING(cp) {\			register char *p = cp; \			PUT_CHAR(strlen(p)); \			while(*p) PUT_CHAR(*p++);}/* *	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[0] == '_' ? Name + 1 : Name), \		 PSECT_ATTRIBUTES_STRING, \		 PSECT_ATTRIBUTES_STRING_LENGTH) == 0)/* *	Create the VMS object file */Create_VMS_Object_File(){#ifdef	eunice	VMS_Object_File_FD = creat(out_file_name, 0777, "var");#else	eunice	VMS_Object_File_FD = creat(out_file_name, 0, "rfm=var");#endif	eunice	/*	 *	Deal with errors	 */	if (VMS_Object_File_FD < 0) {		char Error_Line[256];		sprintf(Error_Line,"Couldn't create VMS object file \"%s\"",				out_file_name);		error(Error_Line);	}	/*	 *	Initialize object file hacking variables	 */	Object_Record_Offset = 0;	Current_Object_Record_Type = -1;}/* *	Declare a particular type of object file record */Set_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();	/*	 *	Set the new type	 */	Current_Object_Record_Type = Type;}/* *	Flush the object record buffer to the object file */Flush_VMS_Object_Record_Buffer(){	int i;	/*	 *	If the buffer is empty, we are done	 */	if (Object_Record_Offset == 0) return;	/*	 *	Write the data to the file	 */	i= write(VMS_Object_File_FD,		 Object_Record_Buffer,		 Object_Record_Offset);	if (i != Object_Record_Offset)		error("I/O error writing VMS object file");	/*	 *	The buffer is now empty	 */	Object_Record_Offset = 0;}/* *	Close the VMS Object file */Close_VMS_Object_File(){	close(VMS_Object_File_FD);}/* *	Write the MHD (Module Header) records */Write_VMS_MHD_Records(){	register char *cp,*cp1;	register int i;	struct {int Size; char *Ptr;} Descriptor;	char Module_Name[256];	char Now[17];	/*	 *	We are writing a module header record	 */	Set_VMS_Object_File_Record(OBJ$C_HDR);	/*	 *	***************************	 *	*MAIN MODULE HEADER RECORD*	 *	***************************	 *	 *	Store record type and header type	 */	PUT_CHAR(OBJ$C_HDR);	PUT_CHAR(MHD$C_MHD);	/*	 *	Structure level is 0	 */	PUT_CHAR(OBJ$C_STRLVL);	/*	 *	Maximum record size is size of the object record buffer	 */	PUT_SHORT(sizeof(Object_Record_Buffer));	/*	 *	Get module name (the FILENAME part of the object file)	 */	cp = out_file_name;	cp1 = Module_Name;	while(*cp) {		if ((*cp == ']') || (*cp == '>') ||		    (*cp == ':') || (*cp == '/')) {			cp1 = Module_Name;			cp++;			continue;		}		*cp1++ = islower(*cp) ? toupper(*cp++) : *cp++;	}	*cp1 = 0;	/*	 *	Limit it to 31 characters and store in the object record	 */	while(--cp1 >= Module_Name)		if (*cp1 == '.') *cp1 = 0;	if (strlen(Module_Name) > 31) { 		if(flagseen['+'])			printf("%s: Module name truncated: %s\n", myname, Module_Name);		Module_Name[31] = 0;	}	PUT_COUNTED_STRING(Module_Name);	/*	 *	Module Version is "V1.0"	 */	PUT_COUNTED_STRING("V1.0");	/*	 *	Creation time is "now" (17 chars of time string)	 */	Descriptor.Size = 17;	Descriptor.Ptr = Now;	sys$asctim(0,&Descriptor,0,0);	for(i = 0; i < 17; i++) PUT_CHAR(Now[i]);	/*	 *	Patch time is "never" (17 zeros)	 */	for(i = 0; i < 17; i++) PUT_CHAR(0);	/*	 *	Flush the record	 */	Flush_VMS_Object_Record_Buffer();	/*	 *	*************************	 *	*LANGUAGE PROCESSOR NAME*	 *	*************************	 *	 *	Store record type and header type	 */	PUT_CHAR(OBJ$C_HDR);	PUT_CHAR(MHD$C_LNM);	/*	 *	Store language processor name and version	 *	(not a counted string!)	 */	cp = compiler_version_string;	if (cp == 0) {		cp ="GNU AS  V";		while(*cp) PUT_CHAR(*cp++);		cp = strchr(&version_string,'.');				while(*cp != ' ') cp--; cp++;		};	while(*cp >= 32) PUT_CHAR(*cp++);	/*	 *	Flush the record	 */	Flush_VMS_Object_Record_Buffer();}/* *	Write the EOM (End Of Module) record */Write_VMS_EOM_Record(Psect, Offset)int Psect;int Offset;{	/*	 *	We are writing an end-of-module record	 */	Set_VMS_Object_File_Record(OBJ$C_EOM);	/*	 *	Store record Type	 */	PUT_CHAR(OBJ$C_EOM);	/*	 *	Store the error severity (0)	 */	PUT_CHAR(0);	/*	 *	Store the entry point, if it exists	 */	if (Psect >= 0) {		/*		 *	Store the entry point Psect		 */		PUT_CHAR(Psect);		/*		 *	Store the entry point Psect offset		 */		PUT_LONG(Offset);	}	/*	 *	Flush the record	 */	Flush_VMS_Object_Record_Buffer();}/* this hash routine borrowed from GNU-EMACS, and strengthened slightly  ERY*/static inthash_string (ptr)     unsigned char *ptr;{  register unsigned char *p = ptr;  register unsigned char *end = p + strlen(ptr);  register unsigned char c;  register int hash = 0;  while (p != end)    {      c = *p++;      hash = ((hash<<3) + (hash<<15) + (hash>>28) + c);    }  return hash;}/* *	Generate a Case-Hacked VMS symbol name (limited to 31 chars) */VMS_Case_Hack_Symbol(In,Out)register char *In;register char *Out;{	long int init = 0;	long int result;	char *pnt;	char *new_name;	char *old_name;	register int i;	int destructor = 0;	/*hack to allow for case sens in a destructor*/	int truncate = 0;	int Case_Hack_Bits = 0;	int Saw_Dollar = 0;	static char Hex_Table[16] =	 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};	/*	 *	Kill any leading "_"	 */	if (*In == '_') In++;	new_name=Out;	/* save this for later*/	if((In[0]=='_')&&(In[1]=='$')&&(In[2]=='_'))						 destructor=1;	/* We may need to truncate the symbol, save the hash for later*/	if(strlen(In)>23)  result = hash_string(In);	/*	 *	Is there a Psect Attribute to skip??	 */	if (HAS_PSECT_ATTRIBUTES(In)) {		/*		 *	Yes: Skip it		 */		In += PSECT_ATTRIBUTES_STRING_LENGTH;		while(*In) {			if ((In[0] == '$') && (In[1] == '$')) {				In += 2;				break;			}			In++;		}	}	old_name=In;/*	if(strlen(In) > 31 && flagseen['+'])		printf("%s: Symbol name truncated: %s\n",myname,In);*/	/*	 *	Do the case conversion	 */	i = 23;		/* Maximum of 23 chars */	while(*In && (--i >= 0)) {		Case_Hack_Bits <<= 1;		if (*In == '$') Saw_Dollar = 1;		if ((destructor==1)&&(i==21)) Saw_Dollar = 0;		if (isupper(*In)) {			*Out++ = *In++;			Case_Hack_Bits |= 1;		} else {			*Out++ = islower(*In) ? toupper(*In++) : *In++;		}	}	/*	 *	If we saw a dollar sign, we don't do case hacking	 */	if(flagseen['h'] || Saw_Dollar)		Case_Hack_Bits = 0;	/*	 *	If we have more than 23 characters and everything is lowercase	 *	we can insert the full 31 characters	 */	if (*In) {		/*		 *	We  have more than 23 characters		 * If we must add the case hack, then we have truncated the str		 */		pnt=Out;		truncate=1;		if (Case_Hack_Bits == 0) {			/*			 *	And so far they are all lower case:			 *		Check up to 8 more characters			 *		and ensure that they are lowercase			 */			if(flagseen['h'])				i=8;			else				for(i = 0; (In[i] != 0) && (i < 8); i++)					if (isupper(In[i]) && !Saw_Dollar)						break;			if(In[i]==0)				truncate=0;			if ((i >= 8) || (In[i] == 0)) {				/*				 *	They are:  Copy up to 31 characters				 *			to the output string				 */				i = 8;				while((--i >= 0) && (*In))					*Out++ = islower(*In) ?							toupper(*In++) :							*In++;			}		}	}	/*	 *	If there were any uppercase characters in the name we	 *	take on the case hacking string	 */	/* Old behavior for regular GNU-C compiler */	if (!flagseen['+'])		truncate=0;	if ((Case_Hack_Bits != 0)||(truncate==1)) {		if(truncate==0) {			*Out++ = '_';			for(i = 0; i < 6; i++) {				*Out++ = Hex_Table[Case_Hack_Bits & 0xf];				Case_Hack_Bits >>= 4;			}			*Out++ = 'X';		} else {			Out=pnt;	/*Cut back to 23 characters maximum */			*Out++ = '_';			for( i=0; i < 7; i++) {				init = result & 0x01f;				if (init < 10) 					*Out++='0'+init;				else					*Out++ = 'A'+init-10;					result = result >> 5;			}		}	} /*Case Hack */	/*	 *	Done	 */	*Out = 0;	if( truncate==1 && flagseen['+'] && flagseen['H'])		printf("%s: Symbol %s replaced by %s\n",myname,old_name,new_name);}/* *	Scan a symbol name for a psect attribute specification */VMS_Modify_Psect_Attributes(Name, Attribute_Pointer)char *Name;int *Attribute_Pointer;{	register int i;	register char *cp;	int Negate;	static struct {		char *Name;		int   Value;		} Attributes[] = {		{"PIC",		GPS$M_PIC},		{"LIB",		GPS$M_LIB},		{"OVR",		GPS$M_OVR},		{"REL",		GPS$M_REL},		{"GBL",		GPS$M_GBL},		{"SHR",		GPS$M_SHR},		{"EXE",		GPS$M_EXE},		{"RD",		GPS$M_RD},		{"WRT",		GPS$M_WRT},		{"VEC",		GPS$M_VEC},		{0,		0}};	/*	 *	Kill leading "_"	 */	if (*Name == '_') Name++;	/*	 *	Check for a PSECT attribute list	 */	if (!HAS_PSECT_ATTRIBUTES(Name)) return;	/* If not, return */	/*	 *	Skip the attribute list indicator	 */	Name += PSECT_ATTRIBUTES_STRING_LENGTH;	/*	 *	Process the attributes ("_" separated, "$" terminated)	 */	while(*Name != '$') {		/*		 *	Assume not negating		 */		Negate = 0;		/*		 *	Check for "NO"		 */		if ((Name[0] == 'N') && (Name[1] == 'O')) {			/*			 *	We are negating (and skip the NO)			 */			Negate = 1;			Name += 2;		}		/*		 *	Find the token delimiter		 */		cp = Name;		while(*cp && (*cp != '_') && (*cp != '$')) cp++;		/*		 *	Look for the token in the attribute list		 */		for(i = 0; Attributes[i].Name; i++) {			/*			 *	If the strings match, set/clear the attr.			 */			if (strncmp(Name, Attributes[i].Name, cp - Name) == 0) {				/*				 *	Set or clear				 */				if (Negate)					*Attribute_Pointer &=						~Attributes[i].Value;				else					*Attribute_Pointer |=						 Attributes[i].Value;				/*				 *	Done				 */				break;			}		}		/*		 *	Now skip the attribute		 */		Name = cp;		if (*Name == '_') Name++;	}	/*	 *	Done	 */	return;}/* *	Define a psect */VMS_Psect_Spec(Name, Size, Type)char *Name;int Size;char *Type;{	char Local[32];	int Psect_Attributes;	/*	 *	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 PSECT definition subrecord	 */	PUT_CHAR(GSD$C_PSC);	/*	 *	Psects are always LONGWORD aligned	 */	PUT_CHAR(2);	/*	 *	Generate the appropriate PSECT flags given the PSECT type

⌨️ 快捷键说明

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