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

📄 vms-dbg.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
		  VMS_Store_Immediate_Data(Local, Lpnt,OBJ$C_DBG);Lpnt=0;		  VMS_Def_Struct(struct_number);		 for(i=0;i<4;i++) Local[Lpnt++] = 0;		 VMS_Store_Immediate_Data(Local, Lpnt, OBJ$C_DBG);Lpnt=0;		  };	i=0;	while(i<Apoint) Local[Lpnt++] = Asuffix[i++];	if(Lpnt != 0)	VMS_Store_Immediate_Data(Local, Lpnt, OBJ$C_DBG);	Lpnt=0; }/* This routine generates a symbol definition for a C sybmol for the debugger. * It takes a psect and offset for global symbols - if psect < 0, then this is * a local variable and the offset is relative to FP.  In this case it can * be either a variable (Offset < 0) or a parameter (Offset > 0). */VMS_DBG_record(struct VMS_DBG_Symbol* spnt,int Psect,int  Offset, char* Name){	char* pnt;	int j;	int maxlen;	int i=0;	if(Psect < 0) {	/* this is a local variable, referenced to SP */	  maxlen=7+strlen(Name);	  Local[i++] = maxlen;	  Local[i++]=spnt->VMS_type;	  if(Offset > 0) Local[i++] = DBG$C_FUNCTION_PARAMETER;		else Local[i++] = DBG$C_LOCAL_SYM;	  pnt=(char*) &Offset;	  for(j=0;j<4;j++) Local[i++]=*pnt++; /* copy the offset */	} else {	  maxlen=7+strlen(Name); /* symbols fixed in memory */	  Local[i++]=7+strlen(Name);	  Local[i++]=spnt->VMS_type;	  Local[i++]=1;	  VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;	  VMS_Set_Data(Psect,Offset,OBJ$C_DBG,0);	}	Local[i++]=strlen(Name);	pnt=Name;	fix_name(pnt);	/* if there are bad characters in name, convert them */	while(*pnt!='\0') Local[i++]=*pnt++;	VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG);	if(spnt->VMS_type == DBG$C_ADVANCED_TYPE) generate_suffix(spnt,0);}/* This routine parses the stabs entries in order to make the definition * for the debugger of local symbols and function parameters */int VMS_local_stab_Parse(symbolS * sp){	char *pnt;	char *pnt1;	char *str;	struct VMS_DBG_Symbol* spnt;   	struct VMS_Symbol *	vsp;	int dbx_type;	int VMS_type;	dbx_type=0;	str=sp->sy_nlist.n_un.n_name;	pnt=(char*) strchr(str,':');	if(pnt==(char*) NULL) return;	/* no colon present */	pnt1=pnt++;	/* save this for later, and skip colon */	if(*pnt == 'c') return 0;	/* ignore static constants *//* there is one little catch that we must be aware of.  Sometimes function * parameters are optimized into registers, and the compiler, in its infiite * wisdom outputs stabs records for *both*.  In general we want to use the * register if it is present, so we must search the rest of the symbols for  * this function to see if this parameter is assigned to a register. */	{	char *str1;	char *pnt2;	symbolS * sp1;	if(*pnt == 'p'){	  for(sp1 = sp->sy_next; sp1; sp1 = sp1->sy_next) {	    if ((sp1->sy_nlist.n_type & N_STAB) == 0) continue;	    if((unsigned char)sp1->sy_nlist.n_type == N_FUN) break;	    if((unsigned char)sp1->sy_nlist.n_type != N_RSYM) continue;	    str1=sp1->sy_nlist.n_un.n_name;	/* and get the name */	    pnt2=str;	    while(*pnt2 != ':') {		if(*pnt2 != *str1) break;		pnt2++; str1++;};	    if((*str1 != ':') || (*pnt2 != ':') ) continue;	    return;	/* they are the same!  lets skip this one */	  }; /* for *//* first find the dbx symbol type from list, and then find VMS type */	  pnt++;	/* skip p in case no register */	};/* if */ }; /* p block */	pnt = cvt_integer( pnt, &dbx_type);	spnt = find_symbol(dbx_type);	if(spnt==(struct VMS_DBG_Symbol*) NULL) return 0;/*Dunno what this is*/	*pnt1='\0';	VMS_DBG_record(spnt,-1,sp->sy_nlist.n_value,str);	*pnt1=':';	/* and restore the string */	return 1;}/* this routine parses a stabs entry to find the information required to define * a variable.  It is used for global and static variables.  * Basically we need to know the address of the symbol.  With older versions * of the compiler, const symbols are * treated differently, in that if they are global they are written into the * text psect.  The global symbol entry for such a const is actually written * as a program entry point (Yuk!!), so if we cannot find a symbol in the list * of psects, we must search the entry points as well.  static consts are even * harder, since they are never assigned a memory address.  The compiler passes * a stab to tell us the value, but I am not sure what to do with it. */static gave_compiler_message = 0;static int VMS_stab_parse(symbolS * sp,char expected_type,	int type1,int type2,int Text_Psect){	char *pnt;	char *pnt1;	char *str;	symbolS * sp1;	struct VMS_DBG_Symbol* spnt;   	struct VMS_Symbol *	vsp;	int dbx_type;	int VMS_type;	dbx_type=0;	str=sp->sy_nlist.n_un.n_name;	pnt=(char*) strchr(str,':');	if(pnt==(char*) NULL) return;	/* no colon present */	pnt1=pnt;	/* save this for later*/	pnt++;	if(*pnt==expected_type){		pnt = cvt_integer(pnt+1,&dbx_type);		spnt = find_symbol(dbx_type);		if(spnt==(struct VMS_DBG_Symbol*) NULL) return 0;/*Dunno what this is*//* now we need to search the symbol table to find the psect and offset for * this variable. */	*pnt1='\0';	vsp=VMS_Symbols;	while(vsp != (struct VMS_Symbol*) NULL) 	  {pnt=vsp->Symbol->sy_nlist.n_un.n_name;	   if(pnt!=(char*) NULL)  if(*pnt++ == '_') /* make sure name is the same, and make sure correct symbol type */	   if((strlen(pnt) == strlen(str)) && (strcmp(pnt,str)==0) 		&& ((vsp->Symbol->sy_type == type1) ||		(vsp->Symbol->sy_type == type2))) break;			vsp=vsp->Next;};		if(vsp != (struct VMS_Symbol*) NULL){	    VMS_DBG_record(spnt,vsp->Psect_Index,vsp->Psect_Offset,str);		*pnt1=':';	/* and restore the string */		return 1;};/* the symbol was not in the symbol list, but it may be an "entry point"   if it was a constant */	   for(sp1 = symbol_rootP; sp1; sp1 = sp1->sy_next) {		  /*		   *	Dispatch on STAB type		   */		  if(sp1->sy_type != (N_TEXT | N_EXT) && sp1->sy_type!=N_TEXT)		      continue;		  pnt = sp1->sy_nlist.n_un.n_name;		  if(*pnt == '_') pnt++;		  if(strcmp(pnt,str) == 0){			if(!gave_compiler_message && expected_type=='G'){printf("***Warning - the assembly code generated by the compiler has placed\n");printf("global constant(s) in the text psect.  These will not be available to\n");printf("other modules, since this is not the correct way to handle this. You\n");printf("have two options: 1) get a patched compiler that does not put global\n");printf("constants in the text psect, or 2) remove the 'const' keyword from\n");printf("definitions of global variables in your source module(s).  Don't say\n");printf("I didn't warn you!");gave_compiler_message = 1;};				VMS_DBG_record(spnt,	 			Text_Psect,	 			sp1->sy_nlist.n_value,	 			str);	 		*pnt1=':';	 		*(sp1->sy_nlist.n_un.n_name) = 'L';					/* fool assembler to not output this					 * as a routine in the TBT */			return 1;};	    };	};	*pnt1=':';	/* and restore the string */	return 0;}VMS_GSYM_Parse(symbolS * sp,int Text_Psect){ /* Global variables */	VMS_stab_parse(sp,'G',(N_UNDF | N_EXT),(N_DATA | N_EXT),Text_Psect);}VMS_LCSYM_Parse(symbolS * sp,int Text_Psect){/* Static symbols - uninitialized */	VMS_stab_parse(sp,'S',N_BSS,-1,Text_Psect);}VMS_STSYM_Parse(symbolS * sp,int Text_Psect){ /*Static symbols - initialized */	VMS_stab_parse(sp,'S',N_DATA,-1,Text_Psect);}/* for register symbols, we must figure out what range of addresses within the * psect are valid. We will use the brackets in the stab directives to give us * guidance as to the PC range that this variable is in scope.  I am still not * completely comfortable with this but as I learn more, I seem to get a better * handle on what is going on. * Caveat Emptor. */VMS_RSYM_Parse(symbolS * sp,symbolS * Current_Routine,int Text_Psect){	char* pnt;	char* pnt1;	char* str;	int dbx_type;	struct VMS_DBG_Symbol* spnt;	int j;	int maxlen;	int i=0;	int bcnt=0;	int Min_Offset=-1;	/* min PC of validity */	int Max_Offset=0; /* max PC of validity */	symbolS * symbolP;	   for(symbolP = sp; symbolP; symbolP = symbolP->sy_next) {		  /*		   *	Dispatch on STAB type		   */		  switch((unsigned char)symbolP->sy_type) {		     case N_LBRAC:				if(bcnt++==0) Min_Offset = symbolP->sy_nlist.n_value;				break;		     case N_RBRAC:				if(--bcnt==0) Max_Offset = 					symbolP->sy_nlist.n_value-1;				break; 		  }	   if((Min_Offset != -1) && (bcnt == 0)) break;	   if((unsigned char)symbolP->sy_type == N_FUN) break; 	   }/* check to see that the addresses were defined.  If not, then there were no * brackets in the function, and we must try to search for the next function * Since functions can be in any order, we should search all of the symbol list * to find the correct ending address. */	if(Min_Offset == -1){	  int Max_Source_Offset;	  int This_Offset;	  Min_Offset = sp->sy_nlist.n_value;	   for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next) {		  /*		   *	Dispatch on STAB type		   */		  This_Offset = symbolP->sy_nlist.n_value;		  switch(symbolP->sy_type) { 		     case N_TEXT | N_EXT:			if((This_Offset > Min_Offset) && (This_Offset < Max_Offset))					Max_Offset = This_Offset;				break;		     case N_SLINE:			if(This_Offset > Max_Source_Offset)				Max_Source_Offset=This_Offset; 		  } 	   }/* if this is the last routine, then we use the PC of the last source line * as a marker of the max PC for which this reg is valid */	  if(Max_Offset == 0x7fffffff) Max_Offset = Max_Source_Offset;	};	dbx_type=0;	str=sp->sy_nlist.n_un.n_name;	pnt=(char*) strchr(str,':');	if(pnt==(char*) NULL) return;	/* no colon present */	pnt1=pnt;	/* save this for later*/	pnt++;	if(*pnt!='r') return 0;	pnt = cvt_integer( pnt+1, &dbx_type);	spnt = find_symbol(dbx_type);	if(spnt==(struct VMS_DBG_Symbol*) NULL) return 0;/*Dunno what this is yet*/	*pnt1='\0';	maxlen=25+strlen(sp->sy_nlist.n_un.n_name);	Local[i++]=maxlen;	Local[i++]=spnt->VMS_type;	Local[i++]=0xfb;	Local[i++]=strlen(sp->sy_nlist.n_un.n_name)+1;	Local[i++]=0x00;	Local[i++]=0x00;	Local[i++]=0x00;	Local[i++]=strlen(sp->sy_nlist.n_un.n_name);	pnt=sp->sy_nlist.n_un.n_name;	fix_name(pnt);	/* if there are bad characters in name, convert them */	while(*pnt!='\0') Local[i++]=*pnt++;	Local[i++]=0xfd;	Local[i++]=0x0f;	Local[i++]=0x00;	Local[i++]=0x03;	Local[i++]=0x01;	VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;	VMS_Set_Data(Text_Psect,Min_Offset,OBJ$C_DBG,1);	VMS_Set_Data(Text_Psect,Max_Offset,OBJ$C_DBG,1);	Local[i++]=0x03;	Local[i++]=sp->sy_nlist.n_value;	Local[i++]=0x00;	Local[i++]=0x00;	Local[i++]=0x00;	VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG);	*pnt1=':';	if(spnt->VMS_type == DBG$C_ADVANCED_TYPE) generate_suffix(spnt,0);}/* this function examines a structure definition, checking all of the elements * to make sure that all of them are fully defined.  The only thing that we * kick out are arrays of undefined structs, since we do not know how big * they are.  All others we can handle with a normal forward reference. */static int forward_reference(char* pnt){	int i;	struct VMS_DBG_Symbol * spnt;	struct VMS_DBG_Symbol * spnt1;	pnt = cvt_integer(pnt+1,&i);	if(*pnt == ';') return 0; /* no forward references */	do{	  pnt=(char*) strchr(pnt,':');	  pnt = cvt_integer(pnt+1,&i);	  spnt = find_symbol(i);	  if(spnt == (struct VMS_DBG_Symbol*) NULL) return 0;	  while((spnt->advanced == POINTER) || (spnt->advanced == ARRAY)){		  i=spnt->type2;		  spnt1 = find_symbol(spnt->type2);		  if((spnt->advanced == ARRAY) &&			(spnt1 == (struct VMS_DBG_Symbol*) NULL))return 1;		  if(spnt1 == (struct VMS_DBG_Symbol*) NULL) break;		  spnt=spnt1;	  };	  pnt = cvt_integer(pnt+1,&i);	  pnt = cvt_integer(pnt+1,&i);	}while(*++pnt != ';');	return 0;	/* no forward refences found */}/* This routine parses the stabs directives to find any definitions of dbx type * numbers.  It makes a note of all of them, creating a structure element * of VMS_DBG_Symbol that describes it.  This also generates the info for the * debugger that describes the struct/union/enum, so that further references * to these data types will be by number * 	We have to process pointers right away, since there can be references * to them later in the same stabs directive.  We cannot have forward * references to pointers, (but we can have a forward reference to a pointer to * a structure/enum/union) and this is why we process them immediately. * After we process the pointer, then we search for defs that are nested even * deeper. */static int VMS_typedef_parse(char* str){	char* pnt;	char* pnt1;	char* pnt2;	int i;	int dtype;	struct forward_ref * fpnt;	int i1,i2,i3;	int convert_integer;	struct VMS_DBG_Symbol* spnt;	struct VMS_DBG_Symbol* spnt1;/* check for any nested def's */	pnt=(char*)strchr(str+1,'=');	if((pnt != (char*) NULL) && (*(str+1) != '*')) 		if(VMS_typedef_parse(pnt) == 1 ) return 1;/* now find dbx_type of entry */	pnt=str-1;	if(*pnt == 'c'){	/* check for static constants */		*str = '\0';	/* for now we ignore them */		return 0;};	while((*pnt <= '9')&& (*pnt >= '0')) pnt--;	pnt++;	/* and get back to the number */	cvt_integer(pnt,&i1);	spnt = find_symbol(i1);/* first we see if this has been defined already, due to a forward reference*/	if(spnt == (struct VMS_DBG_Symbol*) NULL) {	  if(VMS_Symbol_type_list==(struct VMS_DBG_Symbol*) NULL)	    {spnt=(struct VMS_DBG_Symbol*) malloc(sizeof(struct VMS_DBG_Symbol));	     spnt->next = (struct VMS_DBG_Symbol*) NULL;	    VMS_Symbol_type_list=spnt;}

⌨️ 快捷键说明

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