3 #include "struc-symbol.h"
8 /* This file contains many of the routines needed to output debugging info into
9 * the object file that the VMS debugger needs to understand symbols. These
10 * routines are called very late in the assembly process, and thus we can be
11 * fairly lax about changing things, since the GSD and the TIR sections have
12 * already been output.
15 /* We need this info to cross correlate between the stabs def for a symbol and
16 * the actual symbol def. The actual symbol def contains the psect number and
17 * offset, which is needed to declare a variable to the debugger for global
18 * and static variables
21 struct VMS_Symbol
*Next
;
22 struct symbol
*Symbol
;
27 extern struct VMS_Symbol
*VMS_Symbols
;
29 enum advanced_type
{BASIC
,POINTER
,ARRAY
,ENUM
,STRUCT
,UNION
,FUNCTION
,VOID
,UNKNOWN
};
31 /* this structure contains the information from the stabs directives, and the
32 * information is filled in by VMS_typedef_parse. Everything that is needed
33 * to generate the debugging record for a given symbol is present here.
34 * This could be done more efficiently, using nested struct/unions, but for now
35 * I am happy that it works.
37 struct VMS_DBG_Symbol
{
38 struct VMS_DBG_Symbol
* next
;
39 enum advanced_type advanced
; /* description of what this is */
40 int dbx_type
; /* this record is for this type */
41 int type2
; /* For advanced types this is the type referred to.
42 i.e. the type a pointer points to, or the type
43 of object that makes up an array */
44 int VMS_type
; /* Use this type when generating a variable def */
45 int index_min
; /* used for arrays - this will be present for all */
46 int index_max
; /* entries, but will be meaningless for non-arrays */
47 int data_size
; /* size in bytes of the data type. For an array, this
48 is the size of one element in the array */
49 int struc_numb
; /* Number of the structure/union/enum - used for ref */
52 struct VMS_DBG_Symbol
*VMS_Symbol_type_list
={(struct VMS_DBG_Symbol
*) NULL
};
54 /* we need this structure to keep track of forward references to
55 * struct/union/enum that have not been defined yet. When they are ultimately
56 * defined, then we can go back and generate the TIR commands to make a back
61 struct forward_ref
* next
;
67 struct forward_ref
* f_ref_root
={(struct forward_ref
*) NULL
};
69 static char * symbol_name
;
70 static structure_count
=0;
72 /* this routine converts a number string into an integer, and stops when it
73 * sees an invalid character the return value is the address of the character
74 * just past the last character read. No error is generated.
76 static char * cvt_integer(char* str
,int * rtn
){
78 neg
= *str
== '-' ? ++str
, -1 : 1;
79 ival
=0; /* first get the number of the type for dbx */
80 while((*str
<= '9') && (*str
>= '0'))
81 ival
= 10*ival
+ *str
++ -'0';
86 /* this routine fixes the names that are generated by C++, ".this" is a good
87 * example. The period does not work for the debugger, since it looks like
88 * the syntax for a structure element, and thus it gets mightily confused
90 static fix_name(char* pnt
){
91 for( ;*pnt
!= 0; pnt
++){
92 if(*pnt
== '.') *pnt
= '$';
96 /* this routine is used to compare the names of certain types to various
97 * fixed types that are known by the debugger.
99 #define type_check(x) !strcmp( symbol_name , x )
101 /* When defining a structure, this routine is called to find the name of
102 * the actual structure. It is assumed that str points to the equal sign
103 * in the definition, and it moves backward until it finds the start of the
104 * name. If it finds a 0, then it knows that this structure def is in the
105 * outermost level, and thus symbol_name points to the symbol name.
107 static char* get_struct_name(char* str
){
110 while((*pnt
!= ':') && (*pnt
!= '\0')) pnt
--;
111 if(*pnt
== '\0') return symbol_name
;
113 while((*pnt
!= ';') && (*pnt
!= '=')) pnt
--;
114 if(*pnt
== ';') return pnt
+1;
115 while((*pnt
< '0') || (*pnt
> '9')) pnt
++;
116 while((*pnt
>= '0') && (*pnt
<= '9')) pnt
++;
119 /* search symbol list for type number dbx_type. Return a pointer to struct */
120 static struct VMS_DBG_Symbol
* find_symbol(int dbx_type
){
121 struct VMS_DBG_Symbol
* spnt
;
122 spnt
=VMS_Symbol_type_list
;
123 while (spnt
!=(struct VMS_DBG_Symbol
*) NULL
){
124 if(spnt
->dbx_type
==dbx_type
) break;
126 if(spnt
==(struct VMS_DBG_Symbol
*) NULL
) return 0;/*Dunno what this is*/
131 /* Many good programmers cringe when they see a fixed size array - since I am
132 * using this to generate the various descriptors for the data types present,
133 * you might argue that the descriptor could overflow the array for a
134 * complicated variable, and then I am in deep doo-doo. My answer to this is
135 * that the debugger records that we write have all sorts of length bytes
136 * stored in them all over the place, and if we exceed 127 bytes (since the top
137 * bit indicates data, rather than a command), we are dead anyhow. So I figure
138 * why not do this the easy way. Besides, to get 128 bytes, you need something
139 * like an array with 10 indicies, or something like
140 * char **************************************** var;
141 * Lets get real. If some idiot writes programs like that he/she gets what
142 * they deserve. (It is possible to overflow the record with a somewhat
143 * simpler example, like: int (*(*(*(*(*(* sarr6)[1])[1])[2])[3])[4])[5];
144 * but still...). And if someone in the peanut gallery wants to know "What
145 * does VAX-C do with something like this?", I will tell you. It crashes.
146 * At least this code has the good sense to convert it to *void.
147 * In practice, I do not think that this presents too much of a problem, since
148 * struct/union/enum all use defined types, which sort of terminate the
149 * definition. It occurs to me that we could possibly do the same thing with
150 * arrays and pointers, but I don't know quite how it would be coded.
152 * And now back to the regularly scheduled program...
154 #define MAX_DEBUG_RECORD 128
155 static char Local
[MAX_DEBUG_RECORD
]; /* buffer for variable descriptor */
156 static int Lpnt
; /* index into Local */
157 static char Asuffix
[MAX_DEBUG_RECORD
]; /* buffer for array descriptor */
158 static int Apoint
; /* index into Asuffix */
159 static char overflow
; /* flag to indicate we have written too much*/
160 static int total_len
; /* used to calculate the total length of variable
161 descriptor plus array descriptor - used for len byte*/
162 static int struct_number
; /* counter used to assign indexes to struct
165 /* this routine puts info into either Local or Asuffix, depending on the sign
166 * of size. The reason is that it is easier to build the variable descriptor
167 * backwards, while the array descriptor is best built forwards. In the end
168 * they get put together, if there is not a struct/union/enum along the way
170 push(int value
, int size
){
178 if (size
< 0) {size1
= -size
; pnt
+= size1
-1;};
180 for(i
=0;i
<size1
;i
++) {
181 Local
[Lpnt
--] = *pnt
--;
182 if(Lpnt
< 0) {overflow
= 1; Lpnt
= 1;};}
183 else for(i
=0;i
<size1
;i
++){
184 Asuffix
[Apoint
++] = *pnt
++;
185 if(Apoint
>= MAX_DEBUG_RECORD
)
186 {overflow
= 1; Apoint
=MAX_DEBUG_RECORD
-1;};}
189 /* this routine generates the array descriptor for a given array */
190 static array_suffix(struct VMS_DBG_Symbol
* spnt2
){
191 struct VMS_DBG_Symbol
* spnt
;
192 struct VMS_DBG_Symbol
* spnt1
;
198 while(spnt
->advanced
!= ARRAY
) {
199 spnt
=find_symbol(spnt
->type2
);
200 if(spnt
== (struct VMS_DBG_Symbol
*) NULL
) return;};
204 while(spnt1
->advanced
== ARRAY
) {rank
++;
205 total_size
*= (spnt1
->index_max
- spnt1
->index_min
+1);
206 spnt1
=find_symbol(spnt1
->type2
);};
207 total_size
= total_size
* spnt1
->data_size
;
208 push(spnt1
->data_size
,2);
209 if(spnt1
->VMS_type
== 0xa3) push(0,1);
210 else push(spnt1
->VMS_type
,1);
212 for(i
=0;i
<6;i
++) push(0,1);
218 while(spnt1
->advanced
== ARRAY
) {
219 push(spnt1
->index_max
- spnt1
->index_min
+1,4);
220 spnt1
=find_symbol(spnt1
->type2
);};
222 while(spnt1
->advanced
== ARRAY
) {
223 push(spnt1
->index_min
,4);
224 push(spnt1
->index_max
,4);
225 spnt1
=find_symbol(spnt1
->type2
);};
228 /* this routine generates the start of a variable descriptor based upon
229 * a struct/union/enum that has yet to be defined. We define this spot as
230 * a new location, and save four bytes for the address. When the struct is
231 * finally defined, then we can go back and plug in the correct address
233 static new_forward_ref(int dbx_type
){
234 struct forward_ref
* fpnt
;
235 fpnt
= (struct forward_ref
*) malloc(sizeof(struct forward_ref
));
236 fpnt
->next
= f_ref_root
;
238 fpnt
->dbx_type
= dbx_type
;
239 fpnt
->struc_numb
= ++structure_count
;
240 fpnt
->resolved
= 'N';
244 struct_number
= - fpnt
->struc_numb
;
247 /* this routine generates the variable descriptor used to describe non-basic
248 * variables. It calls itself recursively until it gets to the bottom of it
249 * all, and then builds the descriptor backwards. It is easiest to do it this
250 *way since we must periodically write length bytes, and it is easiest if we know
251 *the value when it is time to write it.
253 static int gen1(struct VMS_DBG_Symbol
* spnt
,int array_suffix_len
){
254 struct VMS_DBG_Symbol
* spnt1
;
256 switch(spnt
->advanced
){
264 if(array_suffix_len
== 0) {
265 push(spnt
->VMS_type
,-1);
266 push(DBG$C_BASIC
,-1);
277 struct_number
=spnt
->struc_numb
;
278 if(struct_number
< 0) {
279 new_forward_ref(spnt
->dbx_type
);
282 push(DBG$C_STRUCT
,-1);
287 spnt1
=find_symbol(spnt
->type2
);
289 if(spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
290 new_forward_ref(spnt
->type2
);
291 else i
=gen1(spnt1
,0);
292 if(i
){ /* (*void) is a special case, do not put pointer suffix*/
293 push(DBG$C_POINTER
,-1);
300 while(spnt1
->advanced
== ARRAY
)
301 {spnt1
= find_symbol(spnt1
->type2
);
302 if(spnt1
== (struct VMS_DBG_Symbol
*) NULL
) {
303 printf("gcc-as warning(debugger output):");
304 printf("Forward reference error, dbx type %d\n",
308 /* It is too late to generate forward references, so the user gets a message.
309 * This should only happen on a compiler error */
313 array_suffix_len
= Apoint
- i
;
314 switch(spnt1
->advanced
){
324 push(DBG$C_COMPLEX_ARRAY
,-1);
326 total_len
+= array_suffix_len
+ 8;
331 /* this generates a suffix for a variable. If it is not a defined type yet,
332 * then dbx_type contains the type we are expecting so we can generate a
333 * forward reference. This calls gen1 to build most of the descriptor, and
334 * then it puts the icing on at the end. It then dumps whatever is needed
335 * to get a complete descriptor (i.e. struct reference, array suffix ).
337 static generate_suffix(struct VMS_DBG_Symbol
* spnt
,int dbx_type
){
340 char pvoid
[6] = {5,0xaf,0,1,0,5};
341 struct VMS_DBG_Symbol
* spnt1
;
343 Lpnt
=MAX_DEBUG_RECORD
-1;
347 if(spnt
== (struct VMS_DBG_Symbol
*) NULL
)
348 new_forward_ref(dbx_type
);
350 if(spnt
->VMS_type
!= 0xa3) return 0; /* no suffix needed */
356 /* if the variable descriptor overflows the record, output a descriptor for
359 if((total_len
>= MAX_DEBUG_RECORD
) || overflow
) {
360 printf(" Variable descriptor %d too complicated. Defined as *void ",spnt
->dbx_type
);
361 VMS_Store_Immediate_Data(pvoid
, 6, OBJ$C_DBG
);
365 while(Lpnt
< MAX_DEBUG_RECORD
-1) Local
[i
++] = Local
[++Lpnt
];
367 /* we use this for a reference to a structure that has already been defined */
368 if(struct_number
> 0){
369 VMS_Store_Immediate_Data(Local
, Lpnt
, OBJ$C_DBG
);Lpnt
=0;
370 VMS_Store_Struct(struct_number
);};
371 /* we use this for a forward reference to a structure that has yet to be
372 *defined. We store four bytes of zero to make room for the actual address once
375 if(struct_number
< 0){
376 struct_number
= -struct_number
;
377 VMS_Store_Immediate_Data(Local
, Lpnt
,OBJ$C_DBG
);Lpnt
=0;
378 VMS_Def_Struct(struct_number
);
379 for(i
=0;i
<4;i
++) Local
[Lpnt
++] = 0;
380 VMS_Store_Immediate_Data(Local
, Lpnt
, OBJ$C_DBG
);Lpnt
=0;
383 while(i
<Apoint
) Local
[Lpnt
++] = Asuffix
[i
++];
385 VMS_Store_Immediate_Data(Local
, Lpnt
, OBJ$C_DBG
);
389 /* This routine generates a symbol definition for a C sybmol for the debugger.
390 * It takes a psect and offset for global symbols - if psect < 0, then this is
391 * a local variable and the offset is relative to FP. In this case it can
392 * be either a variable (Offset < 0) or a parameter (Offset > 0).
394 VMS_DBG_record(struct VMS_DBG_Symbol
* spnt
,int Psect
,int Offset
, char* Name
)
400 if(Psect
< 0) { /* this is a local variable, referenced to SP */
401 maxlen
=7+strlen(Name
);
403 Local
[i
++]=spnt
->VMS_type
;
404 if(Offset
> 0) Local
[i
++] = DBG$C_FUNCTION_PARAMETER
;
405 else Local
[i
++] = DBG$C_LOCAL_SYM
;
407 for(j
=0;j
<4;j
++) Local
[i
++]=*pnt
++; /* copy the offset */
409 maxlen
=7+strlen(Name
); /* symbols fixed in memory */
410 Local
[i
++]=7+strlen(Name
);
411 Local
[i
++]=spnt
->VMS_type
;
413 VMS_Store_Immediate_Data(Local
, i
, OBJ$C_DBG
); i
=0;
414 VMS_Set_Data(Psect
,Offset
,OBJ$C_DBG
,0);
416 Local
[i
++]=strlen(Name
);
418 fix_name(pnt
); /* if there are bad characters in name, convert them */
419 while(*pnt
!='\0') Local
[i
++]=*pnt
++;
420 VMS_Store_Immediate_Data(Local
, i
, OBJ$C_DBG
);
421 if(spnt
->VMS_type
== DBG$C_ADVANCED_TYPE
) generate_suffix(spnt
,0);
425 /* This routine parses the stabs entries in order to make the definition
426 * for the debugger of local symbols and function parameters
428 int VMS_local_stab_Parse(symbolS
* sp
){
432 struct VMS_DBG_Symbol
* spnt
;
433 struct VMS_Symbol
* vsp
;
437 str
=sp
->sy_nlist
.n_un
.n_name
;
438 pnt
=(char*) strchr(str
,':');
439 if(pnt
==(char*) NULL
) return; /* no colon present */
440 pnt1
=pnt
++; /* save this for later, and skip colon */
441 if(*pnt
== 'c') return 0; /* ignore static constants */
442 /* there is one little catch that we must be aware of. Sometimes function
443 * parameters are optimized into registers, and the compiler, in its infiite
444 * wisdom outputs stabs records for *both*. In general we want to use the
445 * register if it is present, so we must search the rest of the symbols for
446 * this function to see if this parameter is assigned to a register.
453 for(sp1
= symbol_next(sp
); sp1
; sp1
= symbol_next(sp1
)) {
454 if ((sp1
->sy_nlist
.n_type
& N_STAB
) == 0) continue;
455 if((unsigned char)sp1
->sy_nlist
.n_type
== N_FUN
) break;
456 if((unsigned char)sp1
->sy_nlist
.n_type
!= N_RSYM
) continue;
457 str1
=sp1
->sy_nlist
.n_un
.n_name
; /* and get the name */
459 while(*pnt2
!= ':') {
460 if(*pnt2
!= *str1
) break;
462 if((*str1
!= ':') || (*pnt2
!= ':') ) continue;
463 return; /* they are the same! lets skip this one */
465 /* first find the dbx symbol type from list, and then find VMS type */
466 pnt
++; /* skip p in case no register */
467 };/* if */ }; /* p block */
468 pnt
= cvt_integer( pnt
, &dbx_type
);
469 spnt
= find_symbol(dbx_type
);
470 if(spnt
==(struct VMS_DBG_Symbol
*) NULL
) return 0;/*Dunno what this is*/
472 VMS_DBG_record(spnt
,-1,sp
->sy_nlist
.n_value
,str
);
473 *pnt1
=':'; /* and restore the string */
477 /* this routine parses a stabs entry to find the information required to define
478 * a variable. It is used for global and static variables.
479 * Basically we need to know the address of the symbol. With older versions
480 * of the compiler, const symbols are
481 * treated differently, in that if they are global they are written into the
482 * text psect. The global symbol entry for such a const is actually written
483 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
484 * of psects, we must search the entry points as well. static consts are even
485 * harder, since they are never assigned a memory address. The compiler passes
486 * a stab to tell us the value, but I am not sure what to do with it.
488 static gave_compiler_message
= 0;
490 static int VMS_stab_parse(symbolS
* sp
,char expected_type
,
491 int type1
,int type2
,int Text_Psect
){
496 struct VMS_DBG_Symbol
* spnt
;
497 struct VMS_Symbol
* vsp
;
501 str
=sp
->sy_nlist
.n_un
.n_name
;
502 pnt
=(char*) strchr(str
,':');
503 if(pnt
==(char*) NULL
) return; /* no colon present */
504 pnt1
=pnt
; /* save this for later*/
506 if(*pnt
==expected_type
){
507 pnt
= cvt_integer(pnt
+1,&dbx_type
);
508 spnt
= find_symbol(dbx_type
);
509 if(spnt
==(struct VMS_DBG_Symbol
*) NULL
) return 0;/*Dunno what this is*/
510 /* now we need to search the symbol table to find the psect and offset for
515 while(vsp
!= (struct VMS_Symbol
*) NULL
)
516 {pnt
=vsp
->Symbol
->sy_nlist
.n_un
.n_name
;
517 if(pnt
!=(char*) NULL
) if(*pnt
++ == '_')
518 /* make sure name is the same, and make sure correct symbol type */
519 if((strlen(pnt
) == strlen(str
)) && (strcmp(pnt
,str
)==0)
520 && ((vsp
->Symbol
->sy_type
== type1
) ||
521 (vsp
->Symbol
->sy_type
== type2
))) break;
523 if(vsp
!= (struct VMS_Symbol
*) NULL
){
524 VMS_DBG_record(spnt
,vsp
->Psect_Index
,vsp
->Psect_Offset
,str
);
525 *pnt1
=':'; /* and restore the string */
527 /* the symbol was not in the symbol list, but it may be an "entry point"
528 if it was a constant */
529 for(sp1
= symbol_rootP
; sp1
; sp1
= symbol_next(sp1
)) {
531 * Dispatch on STAB type
533 if(sp1
->sy_type
!= (N_TEXT
| N_EXT
) && sp1
->sy_type
!=N_TEXT
)
535 pnt
= sp1
->sy_nlist
.n_un
.n_name
;
536 if(*pnt
== '_') pnt
++;
537 if(strcmp(pnt
,str
) == 0){
538 if(!gave_compiler_message
&& expected_type
=='G'){
539 printf("***Warning - the assembly code generated by the compiler has placed\n");
540 printf("global constant(s) in the text psect. These will not be available to\n");
541 printf("other modules, since this is not the correct way to handle this. You\n");
542 printf("have two options: 1) get a patched compiler that does not put global\n");
543 printf("constants in the text psect, or 2) remove the 'const' keyword from\n");
544 printf("definitions of global variables in your source module(s). Don't say\n");
545 printf("I didn't warn you!");
546 gave_compiler_message
= 1;};
549 sp1
->sy_nlist
.n_value
,
552 *(sp1
->sy_nlist
.n_un
.n_name
) = 'L';
553 /* fool assembler to not output this
554 * as a routine in the TBT */
558 *pnt1
=':'; /* and restore the string */
563 VMS_GSYM_Parse(symbolS
* sp
,int Text_Psect
){ /* Global variables */
564 VMS_stab_parse(sp
,'G',(N_UNDF
| N_EXT
),(N_DATA
| N_EXT
),Text_Psect
);
568 VMS_LCSYM_Parse(symbolS
* sp
,int Text_Psect
){/* Static symbols - uninitialized */
569 VMS_stab_parse(sp
,'S',N_BSS
,-1,Text_Psect
);
572 VMS_STSYM_Parse(symbolS
* sp
,int Text_Psect
){ /*Static symbols - initialized */
573 VMS_stab_parse(sp
,'S',N_DATA
,-1,Text_Psect
);
577 /* for register symbols, we must figure out what range of addresses within the
578 * psect are valid. We will use the brackets in the stab directives to give us
579 * guidance as to the PC range that this variable is in scope. I am still not
580 * completely comfortable with this but as I learn more, I seem to get a better
581 * handle on what is going on.
584 VMS_RSYM_Parse(symbolS
* sp
,symbolS
* Current_Routine
,int Text_Psect
){
589 struct VMS_DBG_Symbol
* spnt
;
594 int Min_Offset
=-1; /* min PC of validity */
595 int Max_Offset
=0; /* max PC of validity */
597 for(symbolP
= sp
; symbolP
; symbolP
= symbol_next(symbolP
)) {
599 * Dispatch on STAB type
601 switch((unsigned char)symbolP
->sy_type
) {
603 if(bcnt
++==0) Min_Offset
= symbolP
->sy_nlist
.n_value
;
606 if(--bcnt
==0) Max_Offset
=
607 symbolP
->sy_nlist
.n_value
-1;
610 if((Min_Offset
!= -1) && (bcnt
== 0)) break;
611 if((unsigned char)symbolP
->sy_type
== N_FUN
) break;
613 /* check to see that the addresses were defined. If not, then there were no
614 * brackets in the function, and we must try to search for the next function
615 * Since functions can be in any order, we should search all of the symbol list
616 * to find the correct ending address. */
617 if(Min_Offset
== -1){
618 int Max_Source_Offset
;
620 Min_Offset
= sp
->sy_nlist
.n_value
;
621 for(symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next(symbolP
)) {
623 * Dispatch on STAB type
625 This_Offset
= symbolP
->sy_nlist
.n_value
;
626 switch(symbolP
->sy_type
) {
628 if((This_Offset
> Min_Offset
) && (This_Offset
< Max_Offset
))
629 Max_Offset
= This_Offset
;
632 if(This_Offset
> Max_Source_Offset
)
633 Max_Source_Offset
=This_Offset
;
636 /* if this is the last routine, then we use the PC of the last source line
637 * as a marker of the max PC for which this reg is valid */
638 if(Max_Offset
== 0x7fffffff) Max_Offset
= Max_Source_Offset
;
641 str
=sp
->sy_nlist
.n_un
.n_name
;
642 pnt
=(char*) strchr(str
,':');
643 if(pnt
==(char*) NULL
) return; /* no colon present */
644 pnt1
=pnt
; /* save this for later*/
646 if(*pnt
!='r') return 0;
647 pnt
= cvt_integer( pnt
+1, &dbx_type
);
648 spnt
= find_symbol(dbx_type
);
649 if(spnt
==(struct VMS_DBG_Symbol
*) NULL
) return 0;/*Dunno what this is yet*/
651 maxlen
=25+strlen(sp
->sy_nlist
.n_un
.n_name
);
653 Local
[i
++]=spnt
->VMS_type
;
655 Local
[i
++]=strlen(sp
->sy_nlist
.n_un
.n_name
)+1;
659 Local
[i
++]=strlen(sp
->sy_nlist
.n_un
.n_name
);
660 pnt
=sp
->sy_nlist
.n_un
.n_name
;
661 fix_name(pnt
); /* if there are bad characters in name, convert them */
662 while(*pnt
!='\0') Local
[i
++]=*pnt
++;
668 VMS_Store_Immediate_Data(Local
, i
, OBJ$C_DBG
); i
=0;
669 VMS_Set_Data(Text_Psect
,Min_Offset
,OBJ$C_DBG
,1);
670 VMS_Set_Data(Text_Psect
,Max_Offset
,OBJ$C_DBG
,1);
672 Local
[i
++]=sp
->sy_nlist
.n_value
;
676 VMS_Store_Immediate_Data(Local
, i
, OBJ$C_DBG
);
678 if(spnt
->VMS_type
== DBG$C_ADVANCED_TYPE
) generate_suffix(spnt
,0);
681 /* this function examines a structure definition, checking all of the elements
682 * to make sure that all of them are fully defined. The only thing that we
683 * kick out are arrays of undefined structs, since we do not know how big
684 * they are. All others we can handle with a normal forward reference.
686 static int forward_reference(char* pnt
){
688 struct VMS_DBG_Symbol
* spnt
;
689 struct VMS_DBG_Symbol
* spnt1
;
690 pnt
= cvt_integer(pnt
+1,&i
);
691 if(*pnt
== ';') return 0; /* no forward references */
693 pnt
=(char*) strchr(pnt
,':');
694 pnt
= cvt_integer(pnt
+1,&i
);
695 spnt
= find_symbol(i
);
696 if(spnt
== (struct VMS_DBG_Symbol
*) NULL
) return 0;
697 while((spnt
->advanced
== POINTER
) || (spnt
->advanced
== ARRAY
)){
699 spnt1
= find_symbol(spnt
->type2
);
700 if((spnt
->advanced
== ARRAY
) &&
701 (spnt1
== (struct VMS_DBG_Symbol
*) NULL
))return 1;
702 if(spnt1
== (struct VMS_DBG_Symbol
*) NULL
) break;
705 pnt
= cvt_integer(pnt
+1,&i
);
706 pnt
= cvt_integer(pnt
+1,&i
);
707 }while(*++pnt
!= ';');
708 return 0; /* no forward refences found */
711 /* This routine parses the stabs directives to find any definitions of dbx type
712 * numbers. It makes a note of all of them, creating a structure element
713 * of VMS_DBG_Symbol that describes it. This also generates the info for the
714 * debugger that describes the struct/union/enum, so that further references
715 * to these data types will be by number
716 * We have to process pointers right away, since there can be references
717 * to them later in the same stabs directive. We cannot have forward
718 * references to pointers, (but we can have a forward reference to a pointer to
719 * a structure/enum/union) and this is why we process them immediately.
720 * After we process the pointer, then we search for defs that are nested even
723 static int VMS_typedef_parse(char* str
){
729 struct forward_ref
* fpnt
;
732 struct VMS_DBG_Symbol
* spnt
;
733 struct VMS_DBG_Symbol
* spnt1
;
734 /* check for any nested def's */
735 pnt
=(char*)strchr(str
+1,'=');
736 if((pnt
!= (char*) NULL
) && (*(str
+1) != '*'))
737 if(VMS_typedef_parse(pnt
) == 1 ) return 1;
738 /* now find dbx_type of entry */
740 if(*pnt
== 'c'){ /* check for static constants */
741 *str
= '\0'; /* for now we ignore them */
743 while((*pnt
<= '9')&& (*pnt
>= '0')) pnt
--;
744 pnt
++; /* and get back to the number */
745 cvt_integer(pnt
,&i1
);
746 spnt
= find_symbol(i1
);
747 /* first we see if this has been defined already, due to a forward reference*/
748 if(spnt
== (struct VMS_DBG_Symbol
*) NULL
) {
749 if(VMS_Symbol_type_list
==(struct VMS_DBG_Symbol
*) NULL
)
750 {spnt
=(struct VMS_DBG_Symbol
*) malloc(sizeof(struct VMS_DBG_Symbol
));
751 spnt
->next
= (struct VMS_DBG_Symbol
*) NULL
;
752 VMS_Symbol_type_list
=spnt
;}
754 {spnt
=(struct VMS_DBG_Symbol
*) malloc(sizeof(struct VMS_DBG_Symbol
));
755 spnt
->next
=VMS_Symbol_type_list
;
756 VMS_Symbol_type_list
= spnt
;};
757 spnt
->dbx_type
= i1
; /* and save the type */
759 /* for structs and unions, do a partial parse, otherwise we sometimes get
760 * circular definitions that are impossible to resolve. We read enough info
761 * so that any reference to this type has enough info to be resolved
763 pnt
=str
+ 1; /* point to character past equal sign */
764 if((*pnt
== 'u') || (*pnt
== 's')){
766 if((*pnt
<= '9') && (*pnt
>= '0')){
767 if(type_check("void")){ /* this is the void symbol */
769 spnt
->advanced
= VOID
;
771 printf("gcc-as warning(debugger output):");
772 printf(" %d is an unknown untyped variable.\n",spnt
->dbx_type
);
773 return 1; /* do not know what this is */
775 /* now define this module*/
776 pnt
=str
+ 1; /* point to character past equal sign */
779 spnt
->advanced
= BASIC
;
780 if(type_check("int")) {
781 spnt
->VMS_type
=DBG$C_SLINT
; spnt
->data_size
=4;}
782 else if(type_check("long int")) {
783 spnt
->VMS_type
=DBG$C_SLINT
; spnt
->data_size
=4;}
784 else if(type_check("unsigned int")) {
785 spnt
->VMS_type
=DBG$C_ULINT
; spnt
->data_size
= 4;}
786 else if(type_check("long unsigned int")) {
787 spnt
->VMS_type
=DBG$C_ULINT
; spnt
->data_size
= 4;}
788 else if(type_check("short int")) {
789 spnt
->VMS_type
=DBG$C_SSINT
; spnt
->data_size
= 2;}
790 else if(type_check("short unsigned int")) {
791 spnt
->VMS_type
=DBG$C_USINT
; spnt
->data_size
= 2;}
792 else if(type_check("char")) {
793 spnt
->VMS_type
=DBG$C_SCHAR
; spnt
->data_size
= 1;}
794 else if(type_check("signed char")) {
795 spnt
->VMS_type
=DBG$C_SCHAR
; spnt
->data_size
= 1;}
796 else if(type_check("unsigned char")) {
797 spnt
->VMS_type
=DBG$C_UCHAR
; spnt
->data_size
= 1;}
798 else if(type_check("float")) {
799 spnt
->VMS_type
=DBG$C_REAL4
; spnt
->data_size
= 4;}
800 else if(type_check("double")) {
801 spnt
->VMS_type
=DBG$C_REAL8
; spnt
->data_size
= 8;}
802 pnt1
=(char*) strchr(str
,';')+1;
806 if(*pnt
== 's') spnt
->advanced
= STRUCT
;
807 else spnt
->advanced
= UNION
;
808 spnt
->VMS_type
= DBG$C_ADVANCED_TYPE
;
809 pnt1
= cvt_integer(pnt
+1,&spnt
->data_size
);
810 if(forward_reference(pnt
)) {
811 spnt
->struc_numb
= -1;
814 spnt
->struc_numb
= ++structure_count
;
816 pnt
=get_struct_name(str
);
817 VMS_Def_Struct(spnt
->struc_numb
);
819 while(fpnt
!= (struct forward_ref
*) NULL
){
820 if(fpnt
->dbx_type
== spnt
->dbx_type
) {
821 fpnt
->resolved
= 'Y';
822 VMS_Set_Struct(fpnt
->struc_numb
);
823 VMS_Store_Struct(spnt
->struc_numb
);};
825 VMS_Set_Struct(spnt
->struc_numb
);
827 Local
[i
++] = 11+strlen(pnt
);
828 Local
[i
++] = DBG$C_STRUCT_START
;
830 for(i1
=0;i1
<4;i1
++) Local
[i
++] = 0x00;
831 Local
[i
++] = strlen(pnt
);
833 while(*pnt2
!= '\0') Local
[i
++] = *pnt2
++;
834 i2
=spnt
->data_size
* 8; /* number of bits */
836 for(i1
=0;i1
<4;i1
++) Local
[i
++] = *pnt2
++;
837 VMS_Store_Immediate_Data(Local
, i
, OBJ$C_DBG
); i
=0;
838 if(pnt
!= symbol_name
) {
840 *pnt
=':';}; /* replace colon for later */
841 while(*++pnt1
!= ';'){
842 pnt
=(char*) strchr(pnt1
,':');
845 pnt1
= cvt_integer(pnt
+1,&dtype
);
846 pnt1
= cvt_integer(pnt1
+1,&i2
);
847 pnt1
= cvt_integer(pnt1
+1,&i3
);
848 if((dtype
== 1) && (i3
!= 32)) { /* bitfield */
850 push(19+strlen(pnt2
),1);
852 push(1+strlen(pnt2
),4);
853 push(strlen(pnt2
),1);
854 while(*pnt2
!= '\0') push(*pnt2
++,1);
855 push(i3
,2); /* size of bitfield */
858 push(i2
,4); /* start position */
859 VMS_Store_Immediate_Data(Asuffix
,Apoint
,OBJ$C_DBG
);
862 Local
[i
++] = 7+strlen(pnt2
);
863 spnt1
= find_symbol(dtype
);
864 /* check if this is a forward reference */
865 if(spnt1
!= (struct VMS_DBG_Symbol
*) NULL
)
866 Local
[i
++] = spnt1
->VMS_type
;
868 Local
[i
++] = DBG$C_ADVANCED_TYPE
;
869 Local
[i
++] = DBG$C_STRUCT_ITEM
;
871 for(i1
=0;i1
<4;i1
++) Local
[i
++] = *pnt
++;
872 Local
[i
++] = strlen(pnt2
);
873 while(*pnt2
!= '\0') Local
[i
++] = *pnt2
++;
874 VMS_Store_Immediate_Data(Local
, i
, OBJ$C_DBG
); i
=0;
875 if(spnt1
== (struct VMS_DBG_Symbol
*) NULL
)
876 generate_suffix(spnt1
,dtype
);
877 else if(spnt1
->VMS_type
== DBG$C_ADVANCED_TYPE
)
878 generate_suffix(spnt1
,0);
882 Local
[i
++] = 0x01; /* length byte */
883 Local
[i
++] = DBG$C_STRUCT_END
;
884 VMS_Store_Immediate_Data(Local
, i
, OBJ$C_DBG
); i
=0;
887 spnt
->advanced
= ENUM
;
888 spnt
->VMS_type
= DBG$C_ADVANCED_TYPE
;
889 spnt
->struc_numb
= ++structure_count
;
891 VMS_Def_Struct(spnt
->struc_numb
);
893 while(fpnt
!= (struct forward_ref
*) NULL
){
894 if(fpnt
->dbx_type
== spnt
->dbx_type
) {
895 fpnt
->resolved
= 'Y';
896 VMS_Set_Struct(fpnt
->struc_numb
);
897 VMS_Store_Struct(spnt
->struc_numb
);};
899 VMS_Set_Struct(spnt
->struc_numb
);
901 Local
[i
++] = 3+strlen(symbol_name
);
902 Local
[i
++] = DBG$C_ENUM_START
;
904 Local
[i
++] = strlen(symbol_name
);
906 while(*pnt2
!= '\0') Local
[i
++] = *pnt2
++;
907 VMS_Store_Immediate_Data(Local
, i
, OBJ$C_DBG
); i
=0;
908 while(*++pnt
!= ';') {
909 pnt1
=(char*) strchr(pnt
,':');
911 pnt1
= cvt_integer(pnt1
,&i1
);
912 Local
[i
++] = 7+strlen(pnt
);
913 Local
[i
++] = DBG$C_ENUM_ITEM
;
916 for(i2
=0;i2
<4;i2
++) Local
[i
++] = *pnt2
++;
917 Local
[i
++] = strlen(pnt
);
919 while(*pnt
!= '\0') Local
[i
++] = *pnt
++;
920 VMS_Store_Immediate_Data(Local
, i
, OBJ$C_DBG
); i
=0;
921 pnt
= pnt1
; /* Skip final semicolon */
923 Local
[i
++] = 0x01; /* len byte */
924 Local
[i
++] = DBG$C_ENUM_END
;
925 VMS_Store_Immediate_Data(Local
, i
, OBJ$C_DBG
); i
=0;
929 spnt
->advanced
= ARRAY
;
930 spnt
->VMS_type
= DBG$C_ADVANCED_TYPE
;
931 pnt
=(char*)strchr(pnt
,';'); if (pnt
== (char*) NULL
) return 1;
932 pnt1
= cvt_integer(pnt
+1,&spnt
->index_min
);
933 pnt1
= cvt_integer(pnt1
+1,&spnt
->index_max
);
934 pnt1
= cvt_integer(pnt1
+1,&spnt
->type2
);
937 spnt
->advanced
= FUNCTION
;
938 spnt
->VMS_type
= DBG$C_FUNCTION_ADDR
;
939 /* this masquerades as a basic type*/
941 pnt1
= cvt_integer(pnt
+1,&spnt
->type2
);
944 spnt
->advanced
= POINTER
;
945 spnt
->VMS_type
= DBG$C_ADVANCED_TYPE
;
947 pnt1
= cvt_integer(pnt
+1,&spnt
->type2
);
948 pnt
=(char*)strchr(str
+1,'=');
949 if((pnt
!= (char*) NULL
))
950 if(VMS_typedef_parse(pnt
) == 1 ) return 1;
953 spnt
->advanced
= UNKNOWN
;
955 printf("gcc-as warning(debugger output):");
956 printf(" %d is an unknown type of variable.\n",spnt
->dbx_type
);
957 return 1; /* unable to decipher */
959 /* this removes the evidence of the definition so that the outer levels of
960 parsing do not have to worry about it */
962 while (*pnt1
!= '\0') *pnt
++ = *pnt1
++;
969 * This is the root routine that parses the stabs entries for definitions.
970 * it calls VMS_typedef_parse, which can in turn call itself.
971 * We need to be careful, since sometimes there are forward references to
972 * other symbol types, and these cannot be resolved until we have completed
975 int VMS_LSYM_Parse(){
981 int incomplete
,i
,pass
,incom1
;
982 struct VMS_DBG_Symbol
* spnt
;
983 struct VMS_Symbol
* vsp
;
984 struct forward_ref
* fpnt
;
991 for(sp
= symbol_rootP
; sp
; sp
= symbol_next(sp
)) {
993 * Deal with STAB symbols
995 if ((sp
->sy_nlist
.n_type
& N_STAB
) != 0) {
997 * Dispatch on STAB type
999 switch((unsigned char)sp
->sy_nlist
.n_type
) {
1006 case N_FUN
: /*sometimes these contain typedefs*/
1007 str
=sp
->sy_nlist
.n_un
.n_name
;
1009 pnt
=(char*)strchr(str
,':');
1010 if(pnt
== (char*) NULL
) break;
1013 pnt2
=(char*)strchr(pnt1
,'=');
1014 if(pnt2
== (char*) NULL
){
1015 *pnt
=':'; /* replace colon */
1016 break;}; /* no symbol here */
1017 incomplete
+= VMS_typedef_parse(pnt2
);
1018 *pnt
=':'; /* put back colon so variable def code finds dbx_type*/
1024 } while((incomplete
!= 0) && (incomplete
!= incom1
));
1025 /* repeat until all refs resolved if possible */
1026 /* if(pass > 1) printf(" Required %d passes\n",pass);*/
1027 if(incomplete
!= 0){
1028 printf("gcc-as warning(debugger output):");
1029 printf("Unable to resolve %d circular references.\n",incomplete
);
1033 while(fpnt
!= (struct forward_ref
*) NULL
){
1034 if(fpnt
->resolved
!= 'Y') {
1035 if( find_symbol(fpnt
->dbx_type
) !=
1036 (struct VMS_DBG_Symbol
*) NULL
){
1037 printf("gcc-as warning(debugger output):");
1038 printf("Forward reference error, dbx type %d\n",
1042 sprintf(&fixit
[1],"%d=s4;",fpnt
->dbx_type
);
1043 pnt2
=(char*)strchr(&fixit
[1],'=');
1044 VMS_typedef_parse(pnt2
);
1046 fpnt
= fpnt
->next
;};
1049 static symbolS
* Current_Routine
;
1050 static int Text_Psect
;
1052 static Define_Local_Symbols(symbolS
* s1
,symbolS
* s2
){
1054 for(symbolP1
= symbol_next(s1
); symbolP1
!= s2
; symbolP1
= symbol_next(symbolP1
)) {
1055 if (symbolP1
== (symbolS
*)NULL
) return;
1056 if (symbolP1
->sy_nlist
.n_type
== N_FUN
) return;
1058 * Deal with STAB symbols
1060 if ((symbolP1
->sy_nlist
.n_type
& N_STAB
) != 0) {
1062 * Dispatch on STAB type
1064 switch((unsigned char)symbolP1
->sy_nlist
.n_type
) {
1067 VMS_local_stab_Parse(symbolP1
);
1070 VMS_RSYM_Parse(symbolP1
,Current_Routine
,Text_Psect
);
1077 static symbolS
* Define_Routine(symbolS
* symbolP
,int Level
){
1085 for(symbolP1
= symbol_next(symbolP
); symbolP1
; symbolP1
= symbol_next(symbolP1
)) {
1086 if (symbolP1
->sy_nlist
.n_type
== N_FUN
) break;
1088 * Deal with STAB symbols
1090 if ((symbolP1
->sy_nlist
.n_type
& N_STAB
) != 0) {
1092 * Dispatch on STAB type
1094 if((unsigned char)symbolP1
->sy_nlist
.n_type
== N_FUN
) break;
1095 switch((unsigned char)symbolP1
->sy_nlist
.n_type
) {
1098 pnt
= str
+sprintf(str
,"$%d",rcount
++);
1100 VMS_TBT_Block_Begin(symbolP1
,Text_Psect
,str
);
1102 Offset
= symbolP1
->sy_nlist
.n_value
;
1103 Define_Local_Symbols(sstart
,symbolP1
);
1105 Define_Routine(symbolP1
,Level
+1);
1107 VMS_TBT_Block_End(symbolP1
->sy_nlist
.n_value
-
1116 /* we end up here if there were no brackets in this function. Define
1118 Define_Local_Symbols(sstart
,(symbolS
*) 0);
1121 VMS_DBG_Define_Routine(symbolS
* symbolP
,symbolS
* Curr_Routine
,int Txt_Psect
){
1122 Current_Routine
= Curr_Routine
;
1123 Text_Psect
= Txt_Psect
;
1124 Define_Routine(symbolP
,0);
1127 /* end of vms-dbg.c */
This page took 0.055988 seconds and 4 git commands to generate.