19c6c93f28f47b4f30f3af86f0bc968f29a73fb2
[deliverable/binutils-gdb.git] / gas / config / vms / vms-dbg.c
1 #include <stdio.h>
2 #include "as.h"
3 #include "struc-symbol.h"
4 #include "symbols.h"
5 #include "objrecdef.h"
6 #include <stab.h>
7
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.
13 */
14
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
19 */
20 struct VMS_Symbol {
21 struct VMS_Symbol *Next;
22 struct symbol *Symbol;
23 int Size;
24 int Psect_Index;
25 int Psect_Offset;
26 };
27 extern struct VMS_Symbol *VMS_Symbols;
28
29 enum advanced_type {BASIC,POINTER,ARRAY,ENUM,STRUCT,UNION,FUNCTION,VOID,UNKNOWN};
30
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.
36 */
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 */
50 };
51
52 struct VMS_DBG_Symbol *VMS_Symbol_type_list={(struct VMS_DBG_Symbol*) NULL};
53
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
57 * reference.
58 */
59
60 struct forward_ref{
61 struct forward_ref * next;
62 int dbx_type;
63 int struc_numb;
64 char resolved;
65 };
66
67 struct forward_ref * f_ref_root={(struct forward_ref*) NULL};
68
69 static char * symbol_name;
70 static structure_count=0;
71
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.
75 */
76 static char * cvt_integer(char* str,int * rtn){
77 int ival, neg;
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';
82 *rtn = neg*ival;
83 return str;
84 }
85
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
89 */
90 static fix_name(char* pnt){
91 for( ;*pnt != 0; pnt++){
92 if(*pnt == '.') *pnt = '$';
93 };
94 }
95
96 /* this routine is used to compare the names of certain types to various
97 * fixed types that are known by the debugger.
98 */
99 #define type_check(x) !strcmp( symbol_name , x )
100
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.
106 */
107 static char* get_struct_name(char* str){
108 char* pnt;
109 pnt=str;
110 while((*pnt != ':') && (*pnt != '\0')) pnt--;
111 if(*pnt == '\0') return symbol_name;
112 *pnt-- = '\0';
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++;
117 return pnt;
118 }
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;
125 spnt=spnt->next;};
126 if(spnt==(struct VMS_DBG_Symbol*) NULL) return 0;/*Dunno what this is*/
127 return spnt;
128 }
129
130
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.
151 *
152 * And now back to the regularly scheduled program...
153 */
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
163 unions and enums */
164
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
169 */
170 push(int value, int size){
171 char * pnt;
172 int i;
173 int size1;
174 long int val;
175 val=value;
176 pnt=(char*) &val;
177 size1 = size;
178 if (size < 0) {size1 = -size; pnt += size1-1;};
179 if(size < 0)
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;};}
187 }
188
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;
193 int rank;
194 int total_size;
195 int i;
196 rank=0;
197 spnt=spnt2;
198 while(spnt->advanced != ARRAY) {
199 spnt=find_symbol(spnt->type2);
200 if(spnt == (struct VMS_DBG_Symbol *) NULL) return;};
201 spnt1=spnt;
202 spnt1=spnt;
203 total_size= 1;
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);
211 push(4,1);
212 for(i=0;i<6;i++) push(0,1);
213 push(0xc0,1);
214 push(rank,1);
215 push(total_size,4);
216 push(0,4);
217 spnt1=spnt;
218 while(spnt1->advanced == ARRAY) {
219 push(spnt1->index_max - spnt1->index_min+1,4);
220 spnt1=find_symbol(spnt1->type2);};
221 spnt1=spnt;
222 while(spnt1->advanced == ARRAY) {
223 push(spnt1->index_min,4);
224 push(spnt1->index_max,4);
225 spnt1=find_symbol(spnt1->type2);};
226 }
227
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
232 */
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;
237 f_ref_root = fpnt;
238 fpnt->dbx_type = dbx_type;
239 fpnt->struc_numb = ++structure_count;
240 fpnt->resolved = 'N';
241 push(3,-1);
242 total_len = 5;
243 push(total_len,-2);
244 struct_number = - fpnt->struc_numb;
245 }
246
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.
252 */
253 static int gen1(struct VMS_DBG_Symbol * spnt,int array_suffix_len){
254 struct VMS_DBG_Symbol * spnt1;
255 int i;
256 switch(spnt->advanced){
257 case VOID:
258 push(DBG$C_VOID,-1);
259 total_len += 1;
260 push(total_len,-2);
261 return 0;
262 case BASIC:
263 case FUNCTION:
264 if(array_suffix_len == 0) {
265 push(spnt->VMS_type,-1);
266 push(DBG$C_BASIC,-1);
267 total_len = 2;
268 push(total_len,-2);
269 return 1;};
270 push(0,-4);
271 push(0xfa02,-2);
272 total_len = -2;
273 return 1;
274 case STRUCT:
275 case UNION:
276 case ENUM:
277 struct_number=spnt->struc_numb;
278 if(struct_number < 0) {
279 new_forward_ref(spnt->dbx_type);
280 return 1;
281 }
282 push(DBG$C_STRUCT,-1);
283 total_len = 5;
284 push(total_len,-2);
285 return 1;
286 case POINTER:
287 spnt1=find_symbol(spnt->type2);
288 i=1;
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);
294 total_len += 3;
295 push(total_len,-2);
296 };
297 return 1;
298 case ARRAY:
299 spnt1=spnt;
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",
305 spnt->type2);
306 return;}
307 };
308 /* It is too late to generate forward references, so the user gets a message.
309 * This should only happen on a compiler error */
310 i=gen1(spnt1,1);
311 i=Apoint;
312 array_suffix(spnt);
313 array_suffix_len = Apoint - i;
314 switch(spnt1->advanced){
315 case BASIC:
316 case FUNCTION:
317 break;
318 default:
319 push(0,-2);
320 total_len += 2;
321 push(total_len,-2);
322 push(0xfa,-1);
323 push(0x0101,-2);
324 push(DBG$C_COMPLEX_ARRAY,-1);
325 };
326 total_len += array_suffix_len + 8;
327 push(total_len,-2);
328 };
329 }
330
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 ).
336 */
337 static generate_suffix(struct VMS_DBG_Symbol * spnt,int dbx_type){
338 int ilen;
339 int i;
340 char pvoid[6] = {5,0xaf,0,1,0,5};
341 struct VMS_DBG_Symbol * spnt1;
342 Apoint=0;
343 Lpnt =MAX_DEBUG_RECORD-1;
344 total_len=0;
345 struct_number = 0;
346 overflow = 0;
347 if(spnt == (struct VMS_DBG_Symbol*) NULL)
348 new_forward_ref(dbx_type);
349 else{
350 if(spnt->VMS_type != 0xa3) return 0; /* no suffix needed */
351 gen1(spnt,0);
352 };
353 push(0x00af,-2);
354 total_len += 4;
355 push(total_len,-1);
356 /* if the variable descriptor overflows the record, output a descriptor for
357 * a pointer to void.
358 */
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);
362 return;
363 };
364 i=0;
365 while(Lpnt < MAX_DEBUG_RECORD-1) Local[i++] = Local[++Lpnt];
366 Lpnt = i;
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
373 * it is known
374 */
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;
381 };
382 i=0;
383 while(i<Apoint) Local[Lpnt++] = Asuffix[i++];
384 if(Lpnt != 0)
385 VMS_Store_Immediate_Data(Local, Lpnt, OBJ$C_DBG);
386 Lpnt=0;
387 }
388
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).
393 */
394 VMS_DBG_record(struct VMS_DBG_Symbol* spnt,int Psect,int Offset, char* Name)
395 {
396 char* pnt;
397 int j;
398 int maxlen;
399 int i=0;
400 if(Psect < 0) { /* this is a local variable, referenced to SP */
401 maxlen=7+strlen(Name);
402 Local[i++] = maxlen;
403 Local[i++]=spnt->VMS_type;
404 if(Offset > 0) Local[i++] = DBG$C_FUNCTION_PARAMETER;
405 else Local[i++] = DBG$C_LOCAL_SYM;
406 pnt=(char*) &Offset;
407 for(j=0;j<4;j++) Local[i++]=*pnt++; /* copy the offset */
408 } else {
409 maxlen=7+strlen(Name); /* symbols fixed in memory */
410 Local[i++]=7+strlen(Name);
411 Local[i++]=spnt->VMS_type;
412 Local[i++]=1;
413 VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
414 VMS_Set_Data(Psect,Offset,OBJ$C_DBG,0);
415 }
416 Local[i++]=strlen(Name);
417 pnt=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);
422 }
423
424
425 /* This routine parses the stabs entries in order to make the definition
426 * for the debugger of local symbols and function parameters
427 */
428 int VMS_local_stab_Parse(symbolS * sp){
429 char *pnt;
430 char *pnt1;
431 char *str;
432 struct VMS_DBG_Symbol* spnt;
433 struct VMS_Symbol * vsp;
434 int dbx_type;
435 int VMS_type;
436 dbx_type=0;
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.
447 */
448 {
449 char *str1;
450 char *pnt2;
451 symbolS * sp1;
452 if(*pnt == 'p'){
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 */
458 pnt2=str;
459 while(*pnt2 != ':') {
460 if(*pnt2 != *str1) break;
461 pnt2++; str1++;};
462 if((*str1 != ':') || (*pnt2 != ':') ) continue;
463 return; /* they are the same! lets skip this one */
464 }; /* for */
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*/
471 *pnt1='\0';
472 VMS_DBG_record(spnt,-1,sp->sy_nlist.n_value,str);
473 *pnt1=':'; /* and restore the string */
474 return 1;
475 }
476
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.
487 */
488 static gave_compiler_message = 0;
489
490 static int VMS_stab_parse(symbolS * sp,char expected_type,
491 int type1,int type2,int Text_Psect){
492 char *pnt;
493 char *pnt1;
494 char *str;
495 symbolS * sp1;
496 struct VMS_DBG_Symbol* spnt;
497 struct VMS_Symbol * vsp;
498 int dbx_type;
499 int VMS_type;
500 dbx_type=0;
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*/
505 pnt++;
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
511 * this variable.
512 */
513 *pnt1='\0';
514 vsp=VMS_Symbols;
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;
522 vsp=vsp->Next;};
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 */
526 return 1;};
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)) {
530 /*
531 * Dispatch on STAB type
532 */
533 if(sp1->sy_type != (N_TEXT | N_EXT) && sp1->sy_type!=N_TEXT)
534 continue;
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;};
547 VMS_DBG_record(spnt,
548 Text_Psect,
549 sp1->sy_nlist.n_value,
550 str);
551 *pnt1=':';
552 *(sp1->sy_nlist.n_un.n_name) = 'L';
553 /* fool assembler to not output this
554 * as a routine in the TBT */
555 return 1;};
556 };
557 };
558 *pnt1=':'; /* and restore the string */
559 return 0;
560 }
561
562
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);
565 }
566
567
568 VMS_LCSYM_Parse(symbolS * sp,int Text_Psect){/* Static symbols - uninitialized */
569 VMS_stab_parse(sp,'S',N_BSS,-1,Text_Psect);
570 }
571
572 VMS_STSYM_Parse(symbolS * sp,int Text_Psect){ /*Static symbols - initialized */
573 VMS_stab_parse(sp,'S',N_DATA,-1,Text_Psect);
574 }
575
576
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.
582 * Caveat Emptor.
583 */
584 VMS_RSYM_Parse(symbolS * sp,symbolS * Current_Routine,int Text_Psect){
585 char* pnt;
586 char* pnt1;
587 char* str;
588 int dbx_type;
589 struct VMS_DBG_Symbol* spnt;
590 int j;
591 int maxlen;
592 int i=0;
593 int bcnt=0;
594 int Min_Offset=-1; /* min PC of validity */
595 int Max_Offset=0; /* max PC of validity */
596 symbolS * symbolP;
597 for(symbolP = sp; symbolP; symbolP = symbol_next(symbolP)) {
598 /*
599 * Dispatch on STAB type
600 */
601 switch((unsigned char)symbolP->sy_type) {
602 case N_LBRAC:
603 if(bcnt++==0) Min_Offset = symbolP->sy_nlist.n_value;
604 break;
605 case N_RBRAC:
606 if(--bcnt==0) Max_Offset =
607 symbolP->sy_nlist.n_value-1;
608 break;
609 }
610 if((Min_Offset != -1) && (bcnt == 0)) break;
611 if((unsigned char)symbolP->sy_type == N_FUN) break;
612 }
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;
619 int This_Offset;
620 Min_Offset = sp->sy_nlist.n_value;
621 for(symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
622 /*
623 * Dispatch on STAB type
624 */
625 This_Offset = symbolP->sy_nlist.n_value;
626 switch(symbolP->sy_type) {
627 case N_TEXT | N_EXT:
628 if((This_Offset > Min_Offset) && (This_Offset < Max_Offset))
629 Max_Offset = This_Offset;
630 break;
631 case N_SLINE:
632 if(This_Offset > Max_Source_Offset)
633 Max_Source_Offset=This_Offset;
634 }
635 }
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;
639 };
640 dbx_type=0;
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*/
645 pnt++;
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*/
650 *pnt1='\0';
651 maxlen=25+strlen(sp->sy_nlist.n_un.n_name);
652 Local[i++]=maxlen;
653 Local[i++]=spnt->VMS_type;
654 Local[i++]=0xfb;
655 Local[i++]=strlen(sp->sy_nlist.n_un.n_name)+1;
656 Local[i++]=0x00;
657 Local[i++]=0x00;
658 Local[i++]=0x00;
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++;
663 Local[i++]=0xfd;
664 Local[i++]=0x0f;
665 Local[i++]=0x00;
666 Local[i++]=0x03;
667 Local[i++]=0x01;
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);
671 Local[i++]=0x03;
672 Local[i++]=sp->sy_nlist.n_value;
673 Local[i++]=0x00;
674 Local[i++]=0x00;
675 Local[i++]=0x00;
676 VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG);
677 *pnt1=':';
678 if(spnt->VMS_type == DBG$C_ADVANCED_TYPE) generate_suffix(spnt,0);
679 }
680
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.
685 */
686 static int forward_reference(char* pnt){
687 int i;
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 */
692 do{
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)){
698 i=spnt->type2;
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;
703 spnt=spnt1;
704 };
705 pnt = cvt_integer(pnt+1,&i);
706 pnt = cvt_integer(pnt+1,&i);
707 }while(*++pnt != ';');
708 return 0; /* no forward refences found */
709 }
710
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
721 * deeper.
722 */
723 static int VMS_typedef_parse(char* str){
724 char* pnt;
725 char* pnt1;
726 char* pnt2;
727 int i;
728 int dtype;
729 struct forward_ref * fpnt;
730 int i1,i2,i3;
731 int convert_integer;
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 */
739 pnt=str-1;
740 if(*pnt == 'c'){ /* check for static constants */
741 *str = '\0'; /* for now we ignore them */
742 return 0;};
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;}
753 else
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 */
758 };
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
762 */
763 pnt=str + 1; /* point to character past equal sign */
764 if((*pnt == 'u') || (*pnt == 's')){
765 };
766 if((*pnt <= '9') && (*pnt >= '0')){
767 if(type_check("void")){ /* this is the void symbol */
768 *str='\0';
769 spnt->advanced = VOID;
770 return 0;};
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 */
774 };
775 /* now define this module*/
776 pnt=str + 1; /* point to character past equal sign */
777 switch (*pnt){
778 case 'r':
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;
803 break;
804 case 's':
805 case 'u':
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;
812 return 1;
813 }
814 spnt->struc_numb = ++structure_count;
815 pnt1--;
816 pnt=get_struct_name(str);
817 VMS_Def_Struct(spnt->struc_numb);
818 fpnt = f_ref_root;
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);};
824 fpnt = fpnt->next;};
825 VMS_Set_Struct(spnt->struc_numb);
826 i=0;
827 Local[i++] = 11+strlen(pnt);
828 Local[i++] = DBG$C_STRUCT_START;
829 Local[i++] = 0x80;
830 for(i1=0;i1<4;i1++) Local[i++] = 0x00;
831 Local[i++] = strlen(pnt);
832 pnt2=pnt;
833 while(*pnt2 != '\0') Local[i++] = *pnt2++;
834 i2=spnt->data_size * 8; /* number of bits */
835 pnt2=(char*) &i2;
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) {
839 pnt += strlen(pnt);
840 *pnt=':';}; /* replace colon for later */
841 while(*++pnt1 != ';'){
842 pnt=(char*) strchr(pnt1,':');
843 *pnt='\0';
844 pnt2=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 */
849 Apoint = 0;
850 push(19+strlen(pnt2),1);
851 push(0xfa22,2);
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 */
856 push(0x0d22,2);
857 push(0x00,4);
858 push(i2,4); /* start position */
859 VMS_Store_Immediate_Data(Asuffix,Apoint,OBJ$C_DBG);
860 Apoint=0;
861 }else{
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;
867 else
868 Local[i++] = DBG$C_ADVANCED_TYPE;
869 Local[i++] = DBG$C_STRUCT_ITEM;
870 pnt=(char*) &i2;
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);
879 };
880 };
881 pnt1++;
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;
885 break;
886 case 'e':
887 spnt->advanced= ENUM;
888 spnt->VMS_type = DBG$C_ADVANCED_TYPE;
889 spnt->struc_numb = ++structure_count;
890 spnt->data_size=4;
891 VMS_Def_Struct(spnt->struc_numb);
892 fpnt = f_ref_root;
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);};
898 fpnt = fpnt->next;};
899 VMS_Set_Struct(spnt->struc_numb);
900 i=0;
901 Local[i++] = 3+strlen(symbol_name);
902 Local[i++] = DBG$C_ENUM_START;
903 Local[i++] = 0x20;
904 Local[i++] = strlen(symbol_name);
905 pnt2=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,':');
910 *pnt1++='\0';
911 pnt1 = cvt_integer(pnt1,&i1);
912 Local[i++] = 7+strlen(pnt);
913 Local[i++] = DBG$C_ENUM_ITEM;
914 Local[i++] = 0x00;
915 pnt2=(char*) &i1;
916 for(i2=0;i2<4;i2++) Local[i++] = *pnt2++;
917 Local[i++] = strlen(pnt);
918 pnt2=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 */
922 };
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;
926 pnt1=pnt + 1;
927 break;
928 case 'a':
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);
935 break;
936 case 'f':
937 spnt->advanced= FUNCTION;
938 spnt->VMS_type = DBG$C_FUNCTION_ADDR;
939 /* this masquerades as a basic type*/
940 spnt->data_size=4;
941 pnt1 = cvt_integer(pnt+1,&spnt->type2);
942 break;
943 case '*':
944 spnt->advanced= POINTER;
945 spnt->VMS_type = DBG$C_ADVANCED_TYPE;
946 spnt->data_size=4;
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;
951 break;
952 default:
953 spnt->advanced= UNKNOWN;
954 spnt->VMS_type = 0;
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 */
958 };
959 /* this removes the evidence of the definition so that the outer levels of
960 parsing do not have to worry about it */
961 pnt=str;
962 while (*pnt1 != '\0') *pnt++ = *pnt1++;
963 *pnt = '\0';
964 return 0;
965 }
966
967
968 /*
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
973 * the parse.
974 */
975 int VMS_LSYM_Parse(){
976 char *pnt;
977 char *pnt1;
978 char *pnt2;
979 char *str;
980 char fixit[10];
981 int incomplete,i,pass,incom1;
982 struct VMS_DBG_Symbol* spnt;
983 struct VMS_Symbol * vsp;
984 struct forward_ref * fpnt;
985 symbolS * sp;
986 pass=0;
987 incomplete = 0;
988 do{
989 incom1=incomplete;
990 incomplete = 0;
991 for(sp = symbol_rootP; sp; sp = symbol_next(sp)) {
992 /*
993 * Deal with STAB symbols
994 */
995 if ((sp->sy_nlist.n_type & N_STAB) != 0) {
996 /*
997 * Dispatch on STAB type
998 */
999 switch((unsigned char)sp->sy_nlist.n_type) {
1000 case N_GSYM:
1001 case N_LCSYM:
1002 case N_STSYM:
1003 case N_PSYM:
1004 case N_RSYM:
1005 case N_LSYM:
1006 case N_FUN: /*sometimes these contain typedefs*/
1007 str=sp->sy_nlist.n_un.n_name;
1008 symbol_name = str;
1009 pnt=(char*)strchr(str,':');
1010 if(pnt== (char*) NULL) break;
1011 *pnt='\0';
1012 pnt1=pnt+1;
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*/
1019 break;
1020 } /*switch*/
1021 } /* if */
1022 } /*for*/
1023 pass++;
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);
1030 };
1031 fpnt = f_ref_root;
1032 symbol_name="\0";
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",
1039 fpnt->dbx_type);
1040 break;};
1041 fixit[0]=0;
1042 sprintf(&fixit[1],"%d=s4;",fpnt->dbx_type);
1043 pnt2=(char*)strchr(&fixit[1],'=');
1044 VMS_typedef_parse(pnt2);
1045 };
1046 fpnt = fpnt->next;};
1047 }
1048
1049 static symbolS* Current_Routine;
1050 static int Text_Psect;
1051
1052 static Define_Local_Symbols(symbolS* s1,symbolS* s2){
1053 symbolS * symbolP1;
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;
1057 /*
1058 * Deal with STAB symbols
1059 */
1060 if ((symbolP1->sy_nlist.n_type & N_STAB) != 0) {
1061 /*
1062 * Dispatch on STAB type
1063 */
1064 switch((unsigned char)symbolP1->sy_nlist.n_type) {
1065 case N_LSYM:
1066 case N_PSYM:
1067 VMS_local_stab_Parse(symbolP1);
1068 break;
1069 case N_RSYM:
1070 VMS_RSYM_Parse(symbolP1,Current_Routine,Text_Psect);
1071 break;
1072 } /*switch*/
1073 } /* if */
1074 } /* for */
1075 }
1076
1077 static symbolS* Define_Routine(symbolS* symbolP,int Level){
1078 symbolS * sstart;
1079 symbolS * symbolP1;
1080 char str[10];
1081 char * pnt;
1082 int rcount = 0;
1083 int Offset;
1084 sstart = symbolP;
1085 for(symbolP1 = symbol_next(symbolP); symbolP1; symbolP1 = symbol_next(symbolP1)) {
1086 if (symbolP1->sy_nlist.n_type == N_FUN) break;
1087 /*
1088 * Deal with STAB symbols
1089 */
1090 if ((symbolP1->sy_nlist.n_type & N_STAB) != 0) {
1091 /*
1092 * Dispatch on STAB type
1093 */
1094 if((unsigned char)symbolP1->sy_nlist.n_type == N_FUN) break;
1095 switch((unsigned char)symbolP1->sy_nlist.n_type) {
1096 case N_LBRAC:
1097 if(Level != 0) {
1098 pnt = str +sprintf(str,"$%d",rcount++);
1099 *pnt = '\0';
1100 VMS_TBT_Block_Begin(symbolP1,Text_Psect,str);
1101 };
1102 Offset = symbolP1->sy_nlist.n_value;
1103 Define_Local_Symbols(sstart,symbolP1);
1104 symbolP1 =
1105 Define_Routine(symbolP1,Level+1);
1106 if(Level != 0)
1107 VMS_TBT_Block_End(symbolP1->sy_nlist.n_value -
1108 Offset);
1109 sstart=symbolP1;
1110 break;
1111 case N_RBRAC:
1112 return symbolP1;
1113 } /*switch*/
1114 } /* if */
1115 } /* for */
1116 /* we end up here if there were no brackets in this function. Define
1117 everything */
1118 Define_Local_Symbols(sstart,(symbolS *) 0);
1119 }
1120
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);
1125 }
This page took 0.101226 seconds and 3 git commands to generate.