diff options
author | Ken Raeburn <raeburn@cygnus> | 1992-12-08 09:31:57 +0000 |
---|---|---|
committer | Ken Raeburn <raeburn@cygnus> | 1992-12-08 09:31:57 +0000 |
commit | 6c2b38e0870a9ad417c525a2d9e88683aa4bdd5b (patch) | |
tree | 9103dfc609e186a6fc16f9aa86eb6b092847b83c /gas/config/vms/vms-dbg.c | |
parent | b41390d23d47e9e0c3eb15b22e2cf9f5a6c579a6 (diff) | |
download | gdb-6c2b38e0870a9ad417c525a2d9e88683aa4bdd5b.zip gdb-6c2b38e0870a9ad417c525a2d9e88683aa4bdd5b.tar.gz gdb-6c2b38e0870a9ad417c525a2d9e88683aa4bdd5b.tar.bz2 |
replaced with newer code
Diffstat (limited to 'gas/config/vms/vms-dbg.c')
-rw-r--r-- | gas/config/vms/vms-dbg.c | 1147 |
1 files changed, 0 insertions, 1147 deletions
diff --git a/gas/config/vms/vms-dbg.c b/gas/config/vms/vms-dbg.c deleted file mode 100644 index 5e0e8ec..0000000 --- a/gas/config/vms/vms-dbg.c +++ /dev/null @@ -1,1147 +0,0 @@ -/* This file is vms-dbg.c - - Copyright (C) 1987-1992 Free Software Foundation, Inc. - - This file is part of GAS, the GNU Assembler. - - GAS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the 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 of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GAS; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include <stdio.h> -#include "as.h" -#include "struc-symbol.h" -#include "symbols.h" -#include "objrecdef.h" -#include <stab.h> - -/* This file contains many of the routines needed to output debugging info into - * the object file that the VMS debugger needs to understand symbols. These - * routines are called very late in the assembly process, and thus we can be - * fairly lax about changing things, since the GSD and the TIR sections have - * already been output. - */ - -/* We need this info to cross correlate between the stabs def for a symbol and - * the actual symbol def. The actual symbol def contains the psect number and - * offset, which is needed to declare a variable to the debugger for global - * and static variables - */ -struct VMS_Symbol { - struct VMS_Symbol *Next; - struct symbol *Symbol; - int Size; - int Psect_Index; - int Psect_Offset; -}; -extern struct VMS_Symbol *VMS_Symbols; - -enum advanced_type {BASIC,POINTER,ARRAY,ENUM,STRUCT,UNION,FUNCTION,VOID,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; - enum advanced_type advanced; /* description of what this is */ - int dbx_type; /* this record is for this type */ - int type2; /* 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 VMS_type; /* Use this type when generating a variable def */ - int index_min; /* used for arrays - this will be present for all */ - int index_max; /* entries, but will be meaningless for non-arrays */ - int data_size; /* size in bytes of the data type. For an array, this - is the size of one element in the array */ - int struc_numb; /* Number of the structure/union/enum - used for ref */ -}; - -struct VMS_DBG_Symbol *VMS_Symbol_type_list={(struct VMS_DBG_Symbol*) NULL}; - - /* 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}; - - static char * symbol_name; - static structure_count=0; - - /* this routine converts a number string into an integer, and stops when it - * sees an invalid character the return value is the address of the character - * just past the last character read. No error is generated. - */ - static char * cvt_integer(char* str,int * rtn){ - int ival, neg; - neg = *str == '-' ? ++str, -1 : 1; - ival=0; /* first get the number of the type for dbx */ - while((*str <= '9') && (*str >= '0')) - ival = 10*ival + *str++ -'0'; - *rtn = neg*ival; - return str; - } - - /* this routine fixes the names that are generated by C++, ".this" is a good - * example. The period does not work for the debugger, since it looks like - * the syntax for a structure element, and thus it gets mightily confused - */ - static fix_name(char* pnt){ - for( ;*pnt != 0; pnt++){ - if(*pnt == '.') *pnt = '$'; - }; - } - - /* 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 ) - - /* When defining a structure, this routine is called to find the name of - * the actual structure. It is assumed that str points to the equal sign - * in the definition, and it moves backward until it finds the start of the - * name. If it finds a 0, then it knows that this structure def is in the - * outermost level, and thus symbol_name points to the symbol name. - */ - static char* get_struct_name(char* str){ - char* pnt; - pnt=str; - while((*pnt != ':') && (*pnt != '\0')) pnt--; - if(*pnt == '\0') return symbol_name; - *pnt-- = '\0'; - while((*pnt != ';') && (*pnt != '=')) pnt--; - if(*pnt == ';') return pnt+1; - while((*pnt < '0') || (*pnt > '9')) pnt++; - while((*pnt >= '0') && (*pnt <= '9')) pnt++; - return pnt; - } - /* search symbol list for type number dbx_type. Return a pointer to struct */ - static struct VMS_DBG_Symbol* find_symbol(int dbx_type){ - struct VMS_DBG_Symbol* spnt; - spnt=VMS_Symbol_type_list; - while (spnt!=(struct VMS_DBG_Symbol*) NULL){ - if(spnt->dbx_type==dbx_type) break; - spnt=spnt->next;}; - if(spnt==(struct VMS_DBG_Symbol*) NULL) return 0;/*Dunno what this is*/ - return spnt; - } - - - /* Many good programmers cringe when they see a fixed size array - since I am - * using this to generate the various descriptors for the data types present, - * you might argue that the descriptor could overflow the array for a - * complicated variable, and then I am in deep doo-doo. My answer to this is - * that the debugger records that we write have all sorts of length bytes - * stored in them all over the place, and if we exceed 127 bytes (since the top - * bit indicates data, rather than a command), we are dead anyhow. So I figure - * why not do this the easy way. Besides, to get 128 bytes, you need something - * like an array with 10 indicies, or something like - * char **************************************** var; - * Lets get real. If some idiot writes programs like that he/she gets what - * they deserve. (It is possible to overflow the record with a somewhat - * simpler example, like: int (*(*(*(*(*(* sarr6)[1])[1])[2])[3])[4])[5]; - * but still...). And if someone in the peanut gallery wants to know "What - * does VAX-C do with something like this?", I will tell you. It crashes. - * At least this code has the good sense to convert it to *void. - * In practice, I do not think that this presents too much of a problem, since - * struct/union/enum all use defined types, which sort of terminate the - * definition. It occurs to me that we could possibly do the same thing with - * arrays and pointers, but I don't know quite how it would be coded. - * - * And now back to the regularly scheduled program... - */ -#define MAX_DEBUG_RECORD 128 - static char Local[MAX_DEBUG_RECORD]; /* buffer for variable descriptor */ - static int Lpnt; /* index into Local */ - static char Asuffix[MAX_DEBUG_RECORD]; /* buffer for array descriptor */ - 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*/ - static int struct_number; /* counter used to assign indexes to struct - unions and enums */ - - /* this routine puts info into either Local or Asuffix, depending on the sign - * of size. The reason is that it is easier to build the variable descriptor - * backwards, while the array descriptor is best built forwards. In the end - * they get put together, if there is not a struct/union/enum along the way - */ - push(int value, int size){ - char * pnt; - int i; - int size1; - long int val; - val=value; - pnt=(char*) &val; - size1 = size; - if (size < 0) {size1 = -size; pnt += size1-1;}; - if(size < 0) - for(i=0;i<size1;i++) { - Local[Lpnt--] = *pnt--; - if(Lpnt < 0) {overflow = 1; Lpnt = 1;};} - else for(i=0;i<size1;i++){ - Asuffix[Apoint++] = *pnt++; - if(Apoint >= MAX_DEBUG_RECORD) - {overflow = 1; Apoint =MAX_DEBUG_RECORD-1;};} - } - - /* this routine generates the array descriptor for a given array */ - static array_suffix(struct VMS_DBG_Symbol* spnt2){ - struct VMS_DBG_Symbol * spnt; - struct VMS_DBG_Symbol * spnt1; - int rank; - int total_size; - int i; - rank=0; - spnt=spnt2; - while(spnt->advanced != ARRAY) { - spnt=find_symbol(spnt->type2); - if(spnt == (struct VMS_DBG_Symbol *) NULL) return;}; - spnt1=spnt; - spnt1=spnt; - total_size= 1; - while(spnt1->advanced == ARRAY) {rank++; - total_size *= (spnt1->index_max - spnt1->index_min +1); - spnt1=find_symbol(spnt1->type2);}; - total_size = total_size * spnt1->data_size; - push(spnt1->data_size,2); - if(spnt1->VMS_type == 0xa3) push(0,1); - else push(spnt1->VMS_type,1); - push(4,1); - for(i=0;i<6;i++) push(0,1); - push(0xc0,1); - push(rank,1); - push(total_size,4); - push(0,4); - spnt1=spnt; - while(spnt1->advanced == ARRAY) { - push(spnt1->index_max - spnt1->index_min+1,4); - spnt1=find_symbol(spnt1->type2);}; - spnt1=spnt; - while(spnt1->advanced == ARRAY) { - push(spnt1->index_min,4); - push(spnt1->index_max,4); - spnt1=find_symbol(spnt1->type2);}; - } - - /* this routine generates the start of a variable descriptor based upon - * a struct/union/enum that has yet to be defined. We define this spot as - * a new location, and save four bytes for the address. When the struct is - * finally defined, then we can go back and plug in the correct address - */ - static new_forward_ref(int dbx_type){ - struct forward_ref* fpnt; - fpnt = (struct forward_ref*) malloc(sizeof(struct forward_ref)); - fpnt->next = f_ref_root; - f_ref_root = fpnt; - fpnt->dbx_type = dbx_type; - fpnt->struc_numb = ++structure_count; - fpnt->resolved = 'N'; - push(3,-1); - total_len = 5; - push(total_len,-2); - struct_number = - fpnt->struc_numb; - } - - /* this routine generates the variable descriptor used to describe non-basic - * variables. It calls itself recursively until it gets to the bottom of it - * all, and then builds the descriptor backwards. It is easiest to do it this - *way since we must periodically write length bytes, and it is easiest if we know - *the value when it is time to write it. - */ - static int gen1(struct VMS_DBG_Symbol * spnt,int array_suffix_len){ - struct VMS_DBG_Symbol * spnt1; - int i; - switch(spnt->advanced){ - case VOID: - push(DBG$C_VOID,-1); - total_len += 1; - push(total_len,-2); - return 0; - case BASIC: - case FUNCTION: - if(array_suffix_len == 0) { - push(spnt->VMS_type,-1); - push(DBG$C_BASIC,-1); - total_len = 2; - push(total_len,-2); - return 1;}; - push(0,-4); - push(0xfa02,-2); - total_len = -2; - return 1; - case STRUCT: - case UNION: - case ENUM: - struct_number=spnt->struc_numb; - if(struct_number < 0) { - new_forward_ref(spnt->dbx_type); - return 1; - } - push(DBG$C_STRUCT,-1); - total_len = 5; - push(total_len,-2); - return 1; - case POINTER: - spnt1=find_symbol(spnt->type2); - i=1; - if(spnt1 == (struct VMS_DBG_Symbol *) NULL) - new_forward_ref(spnt->type2); - else i=gen1(spnt1,0); - if(i){ /* (*void) is a special case, do not put pointer suffix*/ - push(DBG$C_POINTER,-1); - total_len += 3; - push(total_len,-2); - }; - return 1; - case ARRAY: - spnt1=spnt; - while(spnt1->advanced == ARRAY) - {spnt1 = find_symbol(spnt1->type2); - if(spnt1 == (struct VMS_DBG_Symbol *) NULL) { - printf("gcc-as warning(debugger output):"); - printf("Forward reference error, dbx type %d\n", - spnt->type2); - return;} - }; - /* It is too late to generate forward references, so the user gets a message. - * This should only happen on a compiler error */ - i=gen1(spnt1,1); - i=Apoint; - array_suffix(spnt); - array_suffix_len = Apoint - i; - switch(spnt1->advanced){ - case BASIC: - case FUNCTION: - break; - default: - push(0,-2); - total_len += 2; - push(total_len,-2); - push(0xfa,-1); - push(0x0101,-2); - push(DBG$C_COMPLEX_ARRAY,-1); - }; - total_len += array_suffix_len + 8; - push(total_len,-2); - }; - } - - /* this generates a suffix for a variable. If it is not a defined type yet, - * then dbx_type contains the type we are expecting so we can generate a - * forward reference. This calls gen1 to build most of the descriptor, and - * then it puts the icing on at the end. It then dumps whatever is needed - * to get a complete descriptor (i.e. struct reference, array suffix ). - */ - static generate_suffix(struct VMS_DBG_Symbol * spnt,int dbx_type){ - int ilen; - int i; - char pvoid[6] = {5,0xaf,0,1,0,5}; - struct VMS_DBG_Symbol * spnt1; - Apoint=0; - Lpnt =MAX_DEBUG_RECORD-1; - total_len=0; - struct_number = 0; - overflow = 0; - if(spnt == (struct VMS_DBG_Symbol*) NULL) - new_forward_ref(dbx_type); - else{ - if(spnt->VMS_type != 0xa3) return 0; /* no suffix needed */ - gen1(spnt,0); - }; - push(0x00af,-2); - total_len += 4; - push(total_len,-1); - /* if the variable descriptor overflows the record, output a descriptor for - * a pointer to void. - */ - if((total_len >= MAX_DEBUG_RECORD) || overflow) { - printf(" Variable descriptor %d too complicated. Defined as *void ",spnt->dbx_type); - VMS_Store_Immediate_Data(pvoid, 6, OBJ$C_DBG); - return; - }; - i=0; - while(Lpnt < MAX_DEBUG_RECORD-1) Local[i++] = Local[++Lpnt]; - Lpnt = i; - /* we use this for a reference to a structure that has already been defined */ - if(struct_number > 0){ - VMS_Store_Immediate_Data(Local, Lpnt, OBJ$C_DBG);Lpnt=0; - VMS_Store_Struct(struct_number);}; - /* we use this for a forward reference to a structure that has yet to be - *defined. We store four bytes of zero to make room for the actual address once - * it is known - */ - if(struct_number < 0){ - struct_number = -struct_number; - 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 = symbol_next(sp); sp1; sp1 = symbol_next(sp1)) { - 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 = symbol_next(sp1)) { - /* - * 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 = symbol_next(symbolP)) { - /* - * 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 = symbol_next(symbolP)) { - /* - * 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;} - else - {spnt=(struct VMS_DBG_Symbol*) malloc(sizeof(struct VMS_DBG_Symbol)); - spnt->next=VMS_Symbol_type_list; - VMS_Symbol_type_list = spnt;}; - spnt->dbx_type = i1; /* and save the type */ - }; - /* for structs and unions, do a partial parse, otherwise we sometimes get - * circular definitions that are impossible to resolve. We read enough info - * so that any reference to this type has enough info to be resolved - */ - pnt=str + 1; /* point to character past equal sign */ - if((*pnt == 'u') || (*pnt == 's')){ - }; - if((*pnt <= '9') && (*pnt >= '0')){ - if(type_check("void")){ /* this is the void symbol */ - *str='\0'; - spnt->advanced = VOID; - return 0;}; - printf("gcc-as warning(debugger output):"); - printf(" %d is an unknown untyped variable.\n",spnt->dbx_type); - return 1; /* do not know what this is */ - }; - /* now define this module*/ - pnt=str + 1; /* point to character past equal sign */ - switch (*pnt){ - case 'r': - spnt->advanced= BASIC; - if(type_check("int")) { - spnt->VMS_type=DBG$C_SLINT; spnt->data_size=4;} - else if(type_check("long int")) { - spnt->VMS_type=DBG$C_SLINT; spnt->data_size=4;} - else if(type_check("unsigned int")) { - spnt->VMS_type=DBG$C_ULINT; spnt->data_size = 4;} - else if(type_check("long unsigned int")) { - spnt->VMS_type=DBG$C_ULINT; spnt->data_size = 4;} - else if(type_check("short int")) { - spnt->VMS_type=DBG$C_SSINT; spnt->data_size = 2;} - else if(type_check("short unsigned int")) { - spnt->VMS_type=DBG$C_USINT; spnt->data_size = 2;} - else if(type_check("char")) { - spnt->VMS_type=DBG$C_SCHAR; spnt->data_size = 1;} - else if(type_check("signed char")) { - spnt->VMS_type=DBG$C_SCHAR; spnt->data_size = 1;} - else if(type_check("unsigned char")) { - spnt->VMS_type=DBG$C_UCHAR; spnt->data_size = 1;} - else if(type_check("float")) { - spnt->VMS_type=DBG$C_REAL4; spnt->data_size = 4;} - else if(type_check("double")) { - spnt->VMS_type=DBG$C_REAL8; spnt->data_size = 8;} - pnt1=(char*) strchr(str,';')+1; - break; - case 's': - case 'u': - if(*pnt == 's') spnt->advanced= STRUCT; - else spnt->advanced= UNION; - spnt->VMS_type = DBG$C_ADVANCED_TYPE; - pnt1 = cvt_integer(pnt+1,&spnt->data_size); - if(forward_reference(pnt)) { - spnt->struc_numb = -1; - return 1; - } - spnt->struc_numb = ++structure_count; - pnt1--; - pnt=get_struct_name(str); - VMS_Def_Struct(spnt->struc_numb); - fpnt = f_ref_root; - while(fpnt != (struct forward_ref*) NULL){ - if(fpnt->dbx_type == spnt->dbx_type) { - fpnt->resolved = 'Y'; - VMS_Set_Struct(fpnt->struc_numb); - VMS_Store_Struct(spnt->struc_numb);}; - fpnt = fpnt->next;}; - VMS_Set_Struct(spnt->struc_numb); - i=0; - Local[i++] = 11+strlen(pnt); - Local[i++] = DBG$C_STRUCT_START; - Local[i++] = 0x80; - for(i1=0;i1<4;i1++) Local[i++] = 0x00; - Local[i++] = strlen(pnt); - pnt2=pnt; - while(*pnt2 != '\0') Local[i++] = *pnt2++; - i2=spnt->data_size * 8; /* number of bits */ - pnt2=(char*) &i2; - for(i1=0;i1<4;i1++) Local[i++] = *pnt2++; - VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0; - if(pnt != symbol_name) { - pnt += strlen(pnt); - *pnt=':';}; /* replace colon for later */ - while(*++pnt1 != ';'){ - pnt=(char*) strchr(pnt1,':'); - *pnt='\0'; - pnt2=pnt1; - pnt1 = cvt_integer(pnt+1,&dtype); - pnt1 = cvt_integer(pnt1+1,&i2); - pnt1 = cvt_integer(pnt1+1,&i3); - if((dtype == 1) && (i3 != 32)) { /* bitfield */ - Apoint = 0; - push(19+strlen(pnt2),1); - push(0xfa22,2); - push(1+strlen(pnt2),4); - push(strlen(pnt2),1); - while(*pnt2 != '\0') push(*pnt2++,1); - push(i3,2); /* size of bitfield */ - push(0x0d22,2); - push(0x00,4); - push(i2,4); /* start position */ - VMS_Store_Immediate_Data(Asuffix,Apoint,OBJ$C_DBG); - Apoint=0; - }else{ - Local[i++] = 7+strlen(pnt2); - spnt1 = find_symbol(dtype); - /* check if this is a forward reference */ - if(spnt1 != (struct VMS_DBG_Symbol*) NULL) - Local[i++] = spnt1->VMS_type; - else - Local[i++] = DBG$C_ADVANCED_TYPE; - Local[i++] = DBG$C_STRUCT_ITEM; - pnt=(char*) &i2; - for(i1=0;i1<4;i1++) Local[i++] = *pnt++; - Local[i++] = strlen(pnt2); - while(*pnt2 != '\0') Local[i++] = *pnt2++; - VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0; - if(spnt1 == (struct VMS_DBG_Symbol*) NULL) - generate_suffix(spnt1,dtype); - else if(spnt1->VMS_type == DBG$C_ADVANCED_TYPE) - generate_suffix(spnt1,0); - }; - }; - pnt1++; - Local[i++] = 0x01; /* length byte */ - Local[i++] = DBG$C_STRUCT_END; - VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0; - break; - case 'e': - spnt->advanced= ENUM; - spnt->VMS_type = DBG$C_ADVANCED_TYPE; - spnt->struc_numb = ++structure_count; - spnt->data_size=4; - VMS_Def_Struct(spnt->struc_numb); - fpnt = f_ref_root; - while(fpnt != (struct forward_ref*) NULL){ - if(fpnt->dbx_type == spnt->dbx_type) { - fpnt->resolved = 'Y'; - VMS_Set_Struct(fpnt->struc_numb); - VMS_Store_Struct(spnt->struc_numb);}; - fpnt = fpnt->next;}; - VMS_Set_Struct(spnt->struc_numb); - i=0; - Local[i++] = 3+strlen(symbol_name); - Local[i++] = DBG$C_ENUM_START; - Local[i++] = 0x20; - Local[i++] = strlen(symbol_name); - pnt2=symbol_name; - while(*pnt2 != '\0') Local[i++] = *pnt2++; - VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0; - while(*++pnt != ';') { - pnt1=(char*) strchr(pnt,':'); - *pnt1++='\0'; - pnt1 = cvt_integer(pnt1,&i1); - Local[i++] = 7+strlen(pnt); - Local[i++] = DBG$C_ENUM_ITEM; - Local[i++] = 0x00; - pnt2=(char*) &i1; - for(i2=0;i2<4;i2++) Local[i++] = *pnt2++; - Local[i++] = strlen(pnt); - pnt2=pnt; - while(*pnt != '\0') Local[i++] = *pnt++; - VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0; - pnt= pnt1; /* Skip final semicolon */ - }; - Local[i++] = 0x01; /* len byte */ - Local[i++] = DBG$C_ENUM_END; - VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0; - pnt1=pnt + 1; - break; - case 'a': - spnt->advanced= ARRAY; - spnt->VMS_type = DBG$C_ADVANCED_TYPE; - pnt=(char*)strchr(pnt,';'); if (pnt == (char*) NULL) return 1; - pnt1 = cvt_integer(pnt+1,&spnt->index_min); - pnt1 = cvt_integer(pnt1+1,&spnt->index_max); - pnt1 = cvt_integer(pnt1+1,&spnt->type2); - break; - case 'f': - spnt->advanced= FUNCTION; - spnt->VMS_type = DBG$C_FUNCTION_ADDR; - /* this masquerades as a basic type*/ - spnt->data_size=4; - pnt1 = cvt_integer(pnt+1,&spnt->type2); - break; - case '*': - spnt->advanced= POINTER; - spnt->VMS_type = DBG$C_ADVANCED_TYPE; - spnt->data_size=4; - pnt1 = cvt_integer(pnt+1,&spnt->type2); - pnt=(char*)strchr(str+1,'='); - if((pnt != (char*) NULL)) - if(VMS_typedef_parse(pnt) == 1 ) return 1; - break; - default: - spnt->advanced= UNKNOWN; - spnt->VMS_type = 0; - printf("gcc-as warning(debugger output):"); - printf(" %d is an unknown type of variable.\n",spnt->dbx_type); - return 1; /* unable to decipher */ - }; - /* this removes the evidence of the definition so that the outer levels of - parsing do not have to worry about it */ - pnt=str; - while (*pnt1 != '\0') *pnt++ = *pnt1++; - *pnt = '\0'; - return 0; -} - - -/* - * This is the root routine that parses the stabs entries for definitions. - * it calls VMS_typedef_parse, which can in turn call itself. - * We need to be careful, since sometimes there are forward references to - * other symbol types, and these cannot be resolved until we have completed - * the parse. - */ -int VMS_LSYM_Parse(){ - char *pnt; - char *pnt1; - char *pnt2; - char *str; - char fixit[10]; - int incomplete,i,pass,incom1; - struct VMS_DBG_Symbol* spnt; - struct VMS_Symbol * vsp; - struct forward_ref * fpnt; - symbolS * sp; - pass=0; - incomplete = 0; - do{ - incom1=incomplete; - incomplete = 0; - for(sp = symbol_rootP; sp; sp = symbol_next(sp)) { - /* - * Deal with STAB symbols - */ - if ((sp->sy_nlist.n_type & N_STAB) != 0) { - /* - * Dispatch on STAB type - */ - switch((unsigned char)sp->sy_nlist.n_type) { - case N_GSYM: - case N_LCSYM: - case N_STSYM: - case N_PSYM: - case N_RSYM: - case N_LSYM: - case N_FUN: /*sometimes these contain typedefs*/ - str=sp->sy_nlist.n_un.n_name; - symbol_name = str; - pnt=(char*)strchr(str,':'); - if(pnt== (char*) NULL) break; - *pnt='\0'; - pnt1=pnt+1; - pnt2=(char*)strchr(pnt1,'='); - if(pnt2 == (char*) NULL){ - *pnt=':'; /* replace colon */ - break;}; /* no symbol here */ - incomplete += VMS_typedef_parse(pnt2); - *pnt=':'; /* put back colon so variable def code finds dbx_type*/ - break; - } /*switch*/ - } /* if */ - } /*for*/ - pass++; - } while((incomplete != 0) && (incomplete != incom1 )); - /* repeat until all refs resolved if possible */ - /* if(pass > 1) printf(" Required %d passes\n",pass);*/ - if(incomplete != 0){ - printf("gcc-as warning(debugger output):"); - printf("Unable to resolve %d circular references.\n",incomplete); - }; - fpnt = f_ref_root; - symbol_name="\0"; - while(fpnt != (struct forward_ref*) NULL){ - if(fpnt->resolved != 'Y') { - if( find_symbol(fpnt->dbx_type) != - (struct VMS_DBG_Symbol*) NULL){ - printf("gcc-as warning(debugger output):"); - printf("Forward reference error, dbx type %d\n", - fpnt->dbx_type); - break;}; - fixit[0]=0; - sprintf(&fixit[1],"%d=s4;",fpnt->dbx_type); - pnt2=(char*)strchr(&fixit[1],'='); - VMS_typedef_parse(pnt2); - }; - fpnt = fpnt->next;}; -} - -static symbolS* Current_Routine; -static int Text_Psect; - -static Define_Local_Symbols(symbolS* s1,symbolS* s2){ - symbolS * symbolP1; - for(symbolP1 = symbol_next(s1); symbolP1 != s2; symbolP1 = symbol_next(symbolP1)) { - if (symbolP1 == (symbolS *)NULL) return; - if (symbolP1->sy_nlist.n_type == N_FUN) return; - /* - * Deal with STAB symbols - */ - if ((symbolP1->sy_nlist.n_type & N_STAB) != 0) { - /* - * Dispatch on STAB type - */ - switch((unsigned char)symbolP1->sy_nlist.n_type) { - case N_LSYM: - case N_PSYM: - VMS_local_stab_Parse(symbolP1); - break; - case N_RSYM: - VMS_RSYM_Parse(symbolP1,Current_Routine,Text_Psect); - break; - } /*switch*/ - } /* if */ - } /* for */ -} - -static symbolS* Define_Routine(symbolS* symbolP,int Level){ - symbolS * sstart; - symbolS * symbolP1; - char str[10]; - char * pnt; - int rcount = 0; - int Offset; - sstart = symbolP; - for(symbolP1 = symbol_next(symbolP); symbolP1; symbolP1 = symbol_next(symbolP1)) { - if (symbolP1->sy_nlist.n_type == N_FUN) break; - /* - * Deal with STAB symbols - */ - if ((symbolP1->sy_nlist.n_type & N_STAB) != 0) { - /* - * Dispatch on STAB type - */ - if((unsigned char)symbolP1->sy_nlist.n_type == N_FUN) break; - switch((unsigned char)symbolP1->sy_nlist.n_type) { - case N_LBRAC: - if(Level != 0) { - pnt = str +sprintf(str,"$%d",rcount++); - *pnt = '\0'; - VMS_TBT_Block_Begin(symbolP1,Text_Psect,str); - }; - Offset = symbolP1->sy_nlist.n_value; - Define_Local_Symbols(sstart,symbolP1); - symbolP1 = - Define_Routine(symbolP1,Level+1); - if(Level != 0) - VMS_TBT_Block_End(symbolP1->sy_nlist.n_value - - Offset); - sstart=symbolP1; - break; - case N_RBRAC: - return symbolP1; - } /*switch*/ - } /* if */ - } /* for */ - /* we end up here if there were no brackets in this function. Define - everything */ - Define_Local_Symbols(sstart,(symbolS *) 0); -} - -VMS_DBG_Define_Routine(symbolS* symbolP,symbolS* Curr_Routine,int Txt_Psect){ - Current_Routine = Curr_Routine; - Text_Psect = Txt_Psect; - Define_Routine(symbolP,0); -} - -/* end of vms-dbg.c */ |