updated for current list of files
[deliverable/binutils-gdb.git] / gas / config / vms / vms-dbg.c
CommitLineData
01170860
RP
1/* This file is vms-dbg.c
2
3 Copyright (C) 1987-1992 Free Software Foundation, Inc.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
0e39a8bb
RP
21#include <stdio.h>
22#include "as.h"
23#include "struc-symbol.h"
24#include "symbols.h"
25#include "objrecdef.h"
26#include <stab.h>
27
28/* This file contains many of the routines needed to output debugging info into
29 * the object file that the VMS debugger needs to understand symbols. These
30 * routines are called very late in the assembly process, and thus we can be
31 * fairly lax about changing things, since the GSD and the TIR sections have
32 * already been output.
33 */
34
35/* We need this info to cross correlate between the stabs def for a symbol and
36 * the actual symbol def. The actual symbol def contains the psect number and
37 * offset, which is needed to declare a variable to the debugger for global
38 * and static variables
39 */
40struct VMS_Symbol {
8b228fe9
RP
41 struct VMS_Symbol *Next;
42 struct symbol *Symbol;
43 int Size;
44 int Psect_Index;
45 int Psect_Offset;
46};
0e39a8bb
RP
47extern struct VMS_Symbol *VMS_Symbols;
48
49enum advanced_type {BASIC,POINTER,ARRAY,ENUM,STRUCT,UNION,FUNCTION,VOID,UNKNOWN};
50
51/* this structure contains the information from the stabs directives, and the
52 * information is filled in by VMS_typedef_parse. Everything that is needed
53 * to generate the debugging record for a given symbol is present here.
54 * This could be done more efficiently, using nested struct/unions, but for now
55 * I am happy that it works.
56 */
57struct VMS_DBG_Symbol{
8b228fe9
RP
58 struct VMS_DBG_Symbol * next;
59 enum advanced_type advanced; /* description of what this is */
60 int dbx_type; /* this record is for this type */
61 int type2; /* For advanced types this is the type referred to.
62 i.e. the type a pointer points to, or the type
63 of object that makes up an array */
64 int VMS_type; /* Use this type when generating a variable def */
65 int index_min; /* used for arrays - this will be present for all */
66 int index_max; /* entries, but will be meaningless for non-arrays */
67 int data_size; /* size in bytes of the data type. For an array, this
0e39a8bb 68 is the size of one element in the array */
8b228fe9 69 int struc_numb; /* Number of the structure/union/enum - used for ref */
0e39a8bb
RP
70};
71
72struct VMS_DBG_Symbol *VMS_Symbol_type_list={(struct VMS_DBG_Symbol*) NULL};
8b228fe9
RP
73
74 /* we need this structure to keep track of forward references to
75 * struct/union/enum that have not been defined yet. When they are ultimately
76 * defined, then we can go back and generate the TIR commands to make a back
77 * reference.
78 */
79
80 struct forward_ref{
0e39a8bb
RP
81 struct forward_ref * next;
82 int dbx_type;
83 int struc_numb;
84 char resolved;
8b228fe9
RP
85 };
86
87 struct forward_ref * f_ref_root={(struct forward_ref*) NULL};
88
89 static char * symbol_name;
90 static structure_count=0;
91
92 /* this routine converts a number string into an integer, and stops when it
93 * sees an invalid character the return value is the address of the character
94 * just past the last character read. No error is generated.
95 */
96 static char * cvt_integer(char* str,int * rtn){
0e39a8bb 97 int ival, neg;
8b228fe9
RP
98 neg = *str == '-' ? ++str, -1 : 1;
99 ival=0; /* first get the number of the type for dbx */
100 while((*str <= '9') && (*str >= '0'))
101 ival = 10*ival + *str++ -'0';
0e39a8bb
RP
102 *rtn = neg*ival;
103 return str;
8b228fe9
RP
104 }
105
106 /* this routine fixes the names that are generated by C++, ".this" is a good
107 * example. The period does not work for the debugger, since it looks like
108 * the syntax for a structure element, and thus it gets mightily confused
109 */
110 static fix_name(char* pnt){
0e39a8bb 111 for( ;*pnt != 0; pnt++){
8b228fe9 112 if(*pnt == '.') *pnt = '$';
0e39a8bb 113 };
8b228fe9
RP
114 }
115
116 /* this routine is used to compare the names of certain types to various
117 * fixed types that are known by the debugger.
118 */
0e39a8bb 119#define type_check(x) !strcmp( symbol_name , x )
8b228fe9
RP
120
121 /* When defining a structure, this routine is called to find the name of
122 * the actual structure. It is assumed that str points to the equal sign
123 * in the definition, and it moves backward until it finds the start of the
124 * name. If it finds a 0, then it knows that this structure def is in the
125 * outermost level, and thus symbol_name points to the symbol name.
126 */
127 static char* get_struct_name(char* str){
0e39a8bb
RP
128 char* pnt;
129 pnt=str;
130 while((*pnt != ':') && (*pnt != '\0')) pnt--;
131 if(*pnt == '\0') return symbol_name;
132 *pnt-- = '\0';
133 while((*pnt != ';') && (*pnt != '=')) pnt--;
134 if(*pnt == ';') return pnt+1;
135 while((*pnt < '0') || (*pnt > '9')) pnt++;
136 while((*pnt >= '0') && (*pnt <= '9')) pnt++;
137 return pnt;
8b228fe9
RP
138 }
139 /* search symbol list for type number dbx_type. Return a pointer to struct */
140 static struct VMS_DBG_Symbol* find_symbol(int dbx_type){
0e39a8bb
RP
141 struct VMS_DBG_Symbol* spnt;
142 spnt=VMS_Symbol_type_list;
143 while (spnt!=(struct VMS_DBG_Symbol*) NULL){
8b228fe9
RP
144 if(spnt->dbx_type==dbx_type) break;
145 spnt=spnt->next;};
0e39a8bb
RP
146 if(spnt==(struct VMS_DBG_Symbol*) NULL) return 0;/*Dunno what this is*/
147 return spnt;
8b228fe9
RP
148 }
149
150
151 /* Many good programmers cringe when they see a fixed size array - since I am
152 * using this to generate the various descriptors for the data types present,
153 * you might argue that the descriptor could overflow the array for a
154 * complicated variable, and then I am in deep doo-doo. My answer to this is
155 * that the debugger records that we write have all sorts of length bytes
156 * stored in them all over the place, and if we exceed 127 bytes (since the top
157 * bit indicates data, rather than a command), we are dead anyhow. So I figure
158 * why not do this the easy way. Besides, to get 128 bytes, you need something
159 * like an array with 10 indicies, or something like
160 * char **************************************** var;
161 * Lets get real. If some idiot writes programs like that he/she gets what
162 * they deserve. (It is possible to overflow the record with a somewhat
163 * simpler example, like: int (*(*(*(*(*(* sarr6)[1])[1])[2])[3])[4])[5];
164 * but still...). And if someone in the peanut gallery wants to know "What
165 * does VAX-C do with something like this?", I will tell you. It crashes.
166 * At least this code has the good sense to convert it to *void.
167 * In practice, I do not think that this presents too much of a problem, since
168 * struct/union/enum all use defined types, which sort of terminate the
169 * definition. It occurs to me that we could possibly do the same thing with
170 * arrays and pointers, but I don't know quite how it would be coded.
171 *
172 * And now back to the regularly scheduled program...
173 */
0e39a8bb 174#define MAX_DEBUG_RECORD 128
8b228fe9
RP
175 static char Local[MAX_DEBUG_RECORD]; /* buffer for variable descriptor */
176 static int Lpnt; /* index into Local */
177 static char Asuffix[MAX_DEBUG_RECORD]; /* buffer for array descriptor */
178 static int Apoint; /* index into Asuffix */
179 static char overflow; /* flag to indicate we have written too much*/
180 static int total_len; /* used to calculate the total length of variable
181 descriptor plus array descriptor - used for len byte*/
182 static int struct_number; /* counter used to assign indexes to struct
183 unions and enums */
184
185 /* this routine puts info into either Local or Asuffix, depending on the sign
186 * of size. The reason is that it is easier to build the variable descriptor
187 * backwards, while the array descriptor is best built forwards. In the end
188 * they get put together, if there is not a struct/union/enum along the way
189 */
190 push(int value, int size){
0e39a8bb
RP
191 char * pnt;
192 int i;
193 int size1;
194 long int val;
195 val=value;
196 pnt=(char*) &val;
197 size1 = size;
198 if (size < 0) {size1 = -size; pnt += size1-1;};
199 if(size < 0)
8b228fe9 200 for(i=0;i<size1;i++) {
0e39a8bb
RP
201 Local[Lpnt--] = *pnt--;
202 if(Lpnt < 0) {overflow = 1; Lpnt = 1;};}
203 else for(i=0;i<size1;i++){
8b228fe9
RP
204 Asuffix[Apoint++] = *pnt++;
205 if(Apoint >= MAX_DEBUG_RECORD)
206 {overflow = 1; Apoint =MAX_DEBUG_RECORD-1;};}
207 }
208
209 /* this routine generates the array descriptor for a given array */
210 static array_suffix(struct VMS_DBG_Symbol* spnt2){
0e39a8bb
RP
211 struct VMS_DBG_Symbol * spnt;
212 struct VMS_DBG_Symbol * spnt1;
213 int rank;
214 int total_size;
215 int i;
216 rank=0;
217 spnt=spnt2;
218 while(spnt->advanced != ARRAY) {
8b228fe9
RP
219 spnt=find_symbol(spnt->type2);
220 if(spnt == (struct VMS_DBG_Symbol *) NULL) return;};
0e39a8bb
RP
221 spnt1=spnt;
222 spnt1=spnt;
223 total_size= 1;
224 while(spnt1->advanced == ARRAY) {rank++;
8b228fe9
RP
225 total_size *= (spnt1->index_max - spnt1->index_min +1);
226 spnt1=find_symbol(spnt1->type2);};
0e39a8bb
RP
227 total_size = total_size * spnt1->data_size;
228 push(spnt1->data_size,2);
229 if(spnt1->VMS_type == 0xa3) push(0,1);
8b228fe9 230 else push(spnt1->VMS_type,1);
0e39a8bb
RP
231 push(4,1);
232 for(i=0;i<6;i++) push(0,1);
233 push(0xc0,1);
234 push(rank,1);
235 push(total_size,4);
236 push(0,4);
237 spnt1=spnt;
238 while(spnt1->advanced == ARRAY) {
8b228fe9
RP
239 push(spnt1->index_max - spnt1->index_min+1,4);
240 spnt1=find_symbol(spnt1->type2);};
0e39a8bb
RP
241 spnt1=spnt;
242 while(spnt1->advanced == ARRAY) {
8b228fe9
RP
243 push(spnt1->index_min,4);
244 push(spnt1->index_max,4);
245 spnt1=find_symbol(spnt1->type2);};
246 }
247
248 /* this routine generates the start of a variable descriptor based upon
249 * a struct/union/enum that has yet to be defined. We define this spot as
250 * a new location, and save four bytes for the address. When the struct is
251 * finally defined, then we can go back and plug in the correct address
252 */
253 static new_forward_ref(int dbx_type){
0e39a8bb
RP
254 struct forward_ref* fpnt;
255 fpnt = (struct forward_ref*) malloc(sizeof(struct forward_ref));
256 fpnt->next = f_ref_root;
257 f_ref_root = fpnt;
258 fpnt->dbx_type = dbx_type;
259 fpnt->struc_numb = ++structure_count;
260 fpnt->resolved = 'N';
261 push(3,-1);
262 total_len = 5;
263 push(total_len,-2);
264 struct_number = - fpnt->struc_numb;
8b228fe9
RP
265 }
266
267 /* this routine generates the variable descriptor used to describe non-basic
268 * variables. It calls itself recursively until it gets to the bottom of it
269 * all, and then builds the descriptor backwards. It is easiest to do it this
270 *way since we must periodically write length bytes, and it is easiest if we know
271 *the value when it is time to write it.
272 */
273 static int gen1(struct VMS_DBG_Symbol * spnt,int array_suffix_len){
0e39a8bb
RP
274 struct VMS_DBG_Symbol * spnt1;
275 int i;
276 switch(spnt->advanced){
277 case VOID:
8b228fe9
RP
278 push(DBG$C_VOID,-1);
279 total_len += 1;
280 push(total_len,-2);
281 return 0;
0e39a8bb
RP
282 case BASIC:
283 case FUNCTION:
8b228fe9
RP
284 if(array_suffix_len == 0) {
285 push(spnt->VMS_type,-1);
286 push(DBG$C_BASIC,-1);
287 total_len = 2;
288 push(total_len,-2);
289 return 1;};
290 push(0,-4);
291 push(0xfa02,-2);
292 total_len = -2;
293 return 1;
0e39a8bb
RP
294 case STRUCT:
295 case UNION:
296 case ENUM:
8b228fe9
RP
297 struct_number=spnt->struc_numb;
298 if(struct_number < 0) {
299 new_forward_ref(spnt->dbx_type);
0e39a8bb 300 return 1;
8b228fe9
RP
301 }
302 push(DBG$C_STRUCT,-1);
303 total_len = 5;
304 push(total_len,-2);
305 return 1;
0e39a8bb 306 case POINTER:
8b228fe9
RP
307 spnt1=find_symbol(spnt->type2);
308 i=1;
309 if(spnt1 == (struct VMS_DBG_Symbol *) NULL)
310 new_forward_ref(spnt->type2);
311 else i=gen1(spnt1,0);
312 if(i){ /* (*void) is a special case, do not put pointer suffix*/
313 push(DBG$C_POINTER,-1);
314 total_len += 3;
315 push(total_len,-2);
316 };
317 return 1;
0e39a8bb 318 case ARRAY:
8b228fe9
RP
319 spnt1=spnt;
320 while(spnt1->advanced == ARRAY)
321 {spnt1 = find_symbol(spnt1->type2);
322 if(spnt1 == (struct VMS_DBG_Symbol *) NULL) {
323 printf("gcc-as warning(debugger output):");
324 printf("Forward reference error, dbx type %d\n",
325 spnt->type2);
326 return;}
327 };
328 /* It is too late to generate forward references, so the user gets a message.
329 * This should only happen on a compiler error */
330 i=gen1(spnt1,1);
331 i=Apoint;
332 array_suffix(spnt);
333 array_suffix_len = Apoint - i;
334 switch(spnt1->advanced){
335 case BASIC:
336 case FUNCTION:
337 break;
338 default:
339 push(0,-2);
340 total_len += 2;
341 push(total_len,-2);
342 push(0xfa,-1);
343 push(0x0101,-2);
344 push(DBG$C_COMPLEX_ARRAY,-1);
345 };
346 total_len += array_suffix_len + 8;
347 push(total_len,-2);
0e39a8bb 348 };
8b228fe9
RP
349 }
350
351 /* this generates a suffix for a variable. If it is not a defined type yet,
352 * then dbx_type contains the type we are expecting so we can generate a
353 * forward reference. This calls gen1 to build most of the descriptor, and
354 * then it puts the icing on at the end. It then dumps whatever is needed
355 * to get a complete descriptor (i.e. struct reference, array suffix ).
356 */
357 static generate_suffix(struct VMS_DBG_Symbol * spnt,int dbx_type){
0e39a8bb
RP
358 int ilen;
359 int i;
360 char pvoid[6] = {5,0xaf,0,1,0,5};
361 struct VMS_DBG_Symbol * spnt1;
362 Apoint=0;
363 Lpnt =MAX_DEBUG_RECORD-1;
364 total_len=0;
365 struct_number = 0;
366 overflow = 0;
367 if(spnt == (struct VMS_DBG_Symbol*) NULL)
8b228fe9 368 new_forward_ref(dbx_type);
0e39a8bb 369 else{
8b228fe9
RP
370 if(spnt->VMS_type != 0xa3) return 0; /* no suffix needed */
371 gen1(spnt,0);
0e39a8bb
RP
372 };
373 push(0x00af,-2);
374 total_len += 4;
375 push(total_len,-1);
8b228fe9
RP
376 /* if the variable descriptor overflows the record, output a descriptor for
377 * a pointer to void.
378 */
0e39a8bb 379 if((total_len >= MAX_DEBUG_RECORD) || overflow) {
8b228fe9
RP
380 printf(" Variable descriptor %d too complicated. Defined as *void ",spnt->dbx_type);
381 VMS_Store_Immediate_Data(pvoid, 6, OBJ$C_DBG);
382 return;
383 };
0e39a8bb
RP
384 i=0;
385 while(Lpnt < MAX_DEBUG_RECORD-1) Local[i++] = Local[++Lpnt];
386 Lpnt = i;
8b228fe9 387 /* we use this for a reference to a structure that has already been defined */
0e39a8bb 388 if(struct_number > 0){
8b228fe9
RP
389 VMS_Store_Immediate_Data(Local, Lpnt, OBJ$C_DBG);Lpnt=0;
390 VMS_Store_Struct(struct_number);};
391 /* we use this for a forward reference to a structure that has yet to be
392 *defined. We store four bytes of zero to make room for the actual address once
393 * it is known
394 */
0e39a8bb 395 if(struct_number < 0){
8b228fe9
RP
396 struct_number = -struct_number;
397 VMS_Store_Immediate_Data(Local, Lpnt,OBJ$C_DBG);Lpnt=0;
398 VMS_Def_Struct(struct_number);
399 for(i=0;i<4;i++) Local[Lpnt++] = 0;
400 VMS_Store_Immediate_Data(Local, Lpnt, OBJ$C_DBG);Lpnt=0;
401 };
0e39a8bb
RP
402 i=0;
403 while(i<Apoint) Local[Lpnt++] = Asuffix[i++];
404 if(Lpnt != 0)
8b228fe9 405 VMS_Store_Immediate_Data(Local, Lpnt, OBJ$C_DBG);
0e39a8bb 406 Lpnt=0;
8b228fe9
RP
407 }
408
409 /* This routine generates a symbol definition for a C sybmol for the debugger.
410 * It takes a psect and offset for global symbols - if psect < 0, then this is
411 * a local variable and the offset is relative to FP. In this case it can
412 * be either a variable (Offset < 0) or a parameter (Offset > 0).
413 */
414 VMS_DBG_record(struct VMS_DBG_Symbol* spnt,int Psect,int Offset, char* Name)
0e39a8bb 415{
8b228fe9
RP
416 char* pnt;
417 int j;
418 int maxlen;
419 int i=0;
420 if(Psect < 0) { /* this is a local variable, referenced to SP */
421 maxlen=7+strlen(Name);
422 Local[i++] = maxlen;
423 Local[i++]=spnt->VMS_type;
424 if(Offset > 0) Local[i++] = DBG$C_FUNCTION_PARAMETER;
425 else Local[i++] = DBG$C_LOCAL_SYM;
426 pnt=(char*) &Offset;
427 for(j=0;j<4;j++) Local[i++]=*pnt++; /* copy the offset */
428 } else {
429 maxlen=7+strlen(Name); /* symbols fixed in memory */
430 Local[i++]=7+strlen(Name);
431 Local[i++]=spnt->VMS_type;
432 Local[i++]=1;
433 VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
434 VMS_Set_Data(Psect,Offset,OBJ$C_DBG,0);
435 }
436 Local[i++]=strlen(Name);
437 pnt=Name;
438 fix_name(pnt); /* if there are bad characters in name, convert them */
439 while(*pnt!='\0') Local[i++]=*pnt++;
440 VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG);
441 if(spnt->VMS_type == DBG$C_ADVANCED_TYPE) generate_suffix(spnt,0);
0e39a8bb
RP
442}
443
444
445/* This routine parses the stabs entries in order to make the definition
446 * for the debugger of local symbols and function parameters
447 */
448int VMS_local_stab_Parse(symbolS * sp){
8b228fe9
RP
449 char *pnt;
450 char *pnt1;
451 char *str;
452 struct VMS_DBG_Symbol* spnt;
453 struct VMS_Symbol * vsp;
454 int dbx_type;
455 int VMS_type;
456 dbx_type=0;
457 str=sp->sy_nlist.n_un.n_name;
458 pnt=(char*) strchr(str,':');
459 if(pnt==(char*) NULL) return; /* no colon present */
460 pnt1=pnt++; /* save this for later, and skip colon */
461 if(*pnt == 'c') return 0; /* ignore static constants */
462 /* there is one little catch that we must be aware of. Sometimes function
463 * parameters are optimized into registers, and the compiler, in its infiite
464 * wisdom outputs stabs records for *both*. In general we want to use the
465 * register if it is present, so we must search the rest of the symbols for
466 * this function to see if this parameter is assigned to a register.
467 */
468{
469 char *str1;
470 char *pnt2;
471 symbolS * sp1;
472 if(*pnt == 'p'){
473 for(sp1 = symbol_next(sp); sp1; sp1 = symbol_next(sp1)) {
0e39a8bb
RP
474 if ((sp1->sy_nlist.n_type & N_STAB) == 0) continue;
475 if((unsigned char)sp1->sy_nlist.n_type == N_FUN) break;
476 if((unsigned char)sp1->sy_nlist.n_type != N_RSYM) continue;
477 str1=sp1->sy_nlist.n_un.n_name; /* and get the name */
478 pnt2=str;
479 while(*pnt2 != ':') {
480 if(*pnt2 != *str1) break;
481 pnt2++; str1++;};
482 if((*str1 != ':') || (*pnt2 != ':') ) continue;
483 return; /* they are the same! lets skip this one */
8b228fe9
RP
484 }; /* for */
485 /* first find the dbx symbol type from list, and then find VMS type */
486 pnt++; /* skip p in case no register */
487 };/* if */ }; /* p block */
488pnt = cvt_integer( pnt, &dbx_type);
489spnt = find_symbol(dbx_type);
490if(spnt==(struct VMS_DBG_Symbol*) NULL) return 0;/*Dunno what this is*/
491 *pnt1='\0';
492 VMS_DBG_record(spnt,-1,sp->sy_nlist.n_value,str);
493 *pnt1=':'; /* and restore the string */
494 return 1;
0e39a8bb
RP
495}
496
497/* this routine parses a stabs entry to find the information required to define
498 * a variable. It is used for global and static variables.
499 * Basically we need to know the address of the symbol. With older versions
500 * of the compiler, const symbols are
501 * treated differently, in that if they are global they are written into the
502 * text psect. The global symbol entry for such a const is actually written
503 * as a program entry point (Yuk!!), so if we cannot find a symbol in the list
504 * of psects, we must search the entry points as well. static consts are even
505 * harder, since they are never assigned a memory address. The compiler passes
506 * a stab to tell us the value, but I am not sure what to do with it.
507 */
508static gave_compiler_message = 0;
509
510static int VMS_stab_parse(symbolS * sp,char expected_type,
8b228fe9 511 int type1,int type2,int Text_Psect){
0e39a8bb 512 char *pnt;
8b228fe9
RP
513 char *pnt1;
514 char *str;
515 symbolS * sp1;
516 struct VMS_DBG_Symbol* spnt;
517 struct VMS_Symbol * vsp;
518 int dbx_type;
519 int VMS_type;
520 dbx_type=0;
521 str=sp->sy_nlist.n_un.n_name;
522 pnt=(char*) strchr(str,':');
523 if(pnt==(char*) NULL) return; /* no colon present */
524 pnt1=pnt; /* save this for later*/
525 pnt++;
526 if(*pnt==expected_type){
527 pnt = cvt_integer(pnt+1,&dbx_type);
528 spnt = find_symbol(dbx_type);
529 if(spnt==(struct VMS_DBG_Symbol*) NULL) return 0;/*Dunno what this is*/
530 /* now we need to search the symbol table to find the psect and offset for
531 * this variable.
532 */
0e39a8bb
RP
533 *pnt1='\0';
534 vsp=VMS_Symbols;
535 while(vsp != (struct VMS_Symbol*) NULL)
8b228fe9
RP
536 {pnt=vsp->Symbol->sy_nlist.n_un.n_name;
537 if(pnt!=(char*) NULL) if(*pnt++ == '_')
538 /* make sure name is the same, and make sure correct symbol type */
539 if((strlen(pnt) == strlen(str)) && (strcmp(pnt,str)==0)
0e39a8bb 540 && ((vsp->Symbol->sy_type == type1) ||
8b228fe9
RP
541 (vsp->Symbol->sy_type == type2))) break;
542 vsp=vsp->Next;};
543 if(vsp != (struct VMS_Symbol*) NULL){
0e39a8bb 544 VMS_DBG_record(spnt,vsp->Psect_Index,vsp->Psect_Offset,str);
8b228fe9
RP
545 *pnt1=':'; /* and restore the string */
546 return 1;};
547 /* the symbol was not in the symbol list, but it may be an "entry point"
548 if it was a constant */
549 for(sp1 = symbol_rootP; sp1; sp1 = symbol_next(sp1)) {
550 /*
551 * Dispatch on STAB type
552 */
553 if(sp1->sy_type != (N_TEXT | N_EXT) && sp1->sy_type!=N_TEXT)
554 continue;
555 pnt = sp1->sy_nlist.n_un.n_name;
556 if(*pnt == '_') pnt++;
557 if(strcmp(pnt,str) == 0){
558 if(!gave_compiler_message && expected_type=='G'){
559 printf("***Warning - the assembly code generated by the compiler has placed\n");
560 printf("global constant(s) in the text psect. These will not be available to\n");
561 printf("other modules, since this is not the correct way to handle this. You\n");
562 printf("have two options: 1) get a patched compiler that does not put global\n");
563 printf("constants in the text psect, or 2) remove the 'const' keyword from\n");
564 printf("definitions of global variables in your source module(s). Don't say\n");
565 printf("I didn't warn you!");
566 gave_compiler_message = 1;};
567 VMS_DBG_record(spnt,
568 Text_Psect,
569 sp1->sy_nlist.n_value,
570 str);
571 *pnt1=':';
572 *(sp1->sy_nlist.n_un.n_name) = 'L';
573 /* fool assembler to not output this
574 * as a routine in the TBT */
0e39a8bb 575 return 1;};
0e39a8bb 576 };
8b228fe9
RP
577 };
578 *pnt1=':'; /* and restore the string */
579 return 0;
0e39a8bb
RP
580}
581
582
583VMS_GSYM_Parse(symbolS * sp,int Text_Psect){ /* Global variables */
584 VMS_stab_parse(sp,'G',(N_UNDF | N_EXT),(N_DATA | N_EXT),Text_Psect);
585}
586
587
588VMS_LCSYM_Parse(symbolS * sp,int Text_Psect){/* Static symbols - uninitialized */
589 VMS_stab_parse(sp,'S',N_BSS,-1,Text_Psect);
590}
591
592VMS_STSYM_Parse(symbolS * sp,int Text_Psect){ /*Static symbols - initialized */
593 VMS_stab_parse(sp,'S',N_DATA,-1,Text_Psect);
594}
595
596
597/* for register symbols, we must figure out what range of addresses within the
598 * psect are valid. We will use the brackets in the stab directives to give us
599 * guidance as to the PC range that this variable is in scope. I am still not
600 * completely comfortable with this but as I learn more, I seem to get a better
601 * handle on what is going on.
602 * Caveat Emptor.
603 */
604VMS_RSYM_Parse(symbolS * sp,symbolS * Current_Routine,int Text_Psect){
605 char* pnt;
8b228fe9
RP
606 char* pnt1;
607 char* str;
608 int dbx_type;
609 struct VMS_DBG_Symbol* spnt;
610 int j;
611 int maxlen;
612 int i=0;
613 int bcnt=0;
614 int Min_Offset=-1; /* min PC of validity */
615 int Max_Offset=0; /* max PC of validity */
616 symbolS * symbolP;
617 for(symbolP = sp; symbolP; symbolP = symbol_next(symbolP)) {
618 /*
619 * Dispatch on STAB type
620 */
621 switch((unsigned char)symbolP->sy_type) {
622 case N_LBRAC:
623 if(bcnt++==0) Min_Offset = symbolP->sy_nlist.n_value;
624 break;
625 case N_RBRAC:
626 if(--bcnt==0) Max_Offset =
627 symbolP->sy_nlist.n_value-1;
628 break;
629 }
630 if((Min_Offset != -1) && (bcnt == 0)) break;
631 if((unsigned char)symbolP->sy_type == N_FUN) break;
632 }
633 /* check to see that the addresses were defined. If not, then there were no
634 * brackets in the function, and we must try to search for the next function
635 * Since functions can be in any order, we should search all of the symbol list
636 * to find the correct ending address. */
637 if(Min_Offset == -1){
638 int Max_Source_Offset;
639 int This_Offset;
640 Min_Offset = sp->sy_nlist.n_value;
641 for(symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
642 /*
643 * Dispatch on STAB type
644 */
645 This_Offset = symbolP->sy_nlist.n_value;
646 switch(symbolP->sy_type) {
647 case N_TEXT | N_EXT:
648 if((This_Offset > Min_Offset) && (This_Offset < Max_Offset))
649 Max_Offset = This_Offset;
650 break;
651 case N_SLINE:
652 if(This_Offset > Max_Source_Offset)
653 Max_Source_Offset=This_Offset;
654 }
655 }
656 /* if this is the last routine, then we use the PC of the last source line
657 * as a marker of the max PC for which this reg is valid */
658 if(Max_Offset == 0x7fffffff) Max_Offset = Max_Source_Offset;
659 };
660 dbx_type=0;
661 str=sp->sy_nlist.n_un.n_name;
662 pnt=(char*) strchr(str,':');
663 if(pnt==(char*) NULL) return; /* no colon present */
664 pnt1=pnt; /* save this for later*/
665 pnt++;
666 if(*pnt!='r') return 0;
667 pnt = cvt_integer( pnt+1, &dbx_type);
668 spnt = find_symbol(dbx_type);
669 if(spnt==(struct VMS_DBG_Symbol*) NULL) return 0;/*Dunno what this is yet*/
670 *pnt1='\0';
671 maxlen=25+strlen(sp->sy_nlist.n_un.n_name);
672 Local[i++]=maxlen;
673 Local[i++]=spnt->VMS_type;
674 Local[i++]=0xfb;
675 Local[i++]=strlen(sp->sy_nlist.n_un.n_name)+1;
676 Local[i++]=0x00;
677 Local[i++]=0x00;
678 Local[i++]=0x00;
679 Local[i++]=strlen(sp->sy_nlist.n_un.n_name);
680 pnt=sp->sy_nlist.n_un.n_name;
681 fix_name(pnt); /* if there are bad characters in name, convert them */
682 while(*pnt!='\0') Local[i++]=*pnt++;
683 Local[i++]=0xfd;
684 Local[i++]=0x0f;
685 Local[i++]=0x00;
686 Local[i++]=0x03;
687 Local[i++]=0x01;
688 VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
689 VMS_Set_Data(Text_Psect,Min_Offset,OBJ$C_DBG,1);
690 VMS_Set_Data(Text_Psect,Max_Offset,OBJ$C_DBG,1);
691 Local[i++]=0x03;
692 Local[i++]=sp->sy_nlist.n_value;
693 Local[i++]=0x00;
694 Local[i++]=0x00;
695 Local[i++]=0x00;
696 VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG);
697 *pnt1=':';
698 if(spnt->VMS_type == DBG$C_ADVANCED_TYPE) generate_suffix(spnt,0);
0e39a8bb
RP
699}
700
701/* this function examines a structure definition, checking all of the elements
702 * to make sure that all of them are fully defined. The only thing that we
703 * kick out are arrays of undefined structs, since we do not know how big
704 * they are. All others we can handle with a normal forward reference.
705 */
706static int forward_reference(char* pnt){
707 int i;
8b228fe9
RP
708 struct VMS_DBG_Symbol * spnt;
709 struct VMS_DBG_Symbol * spnt1;
710 pnt = cvt_integer(pnt+1,&i);
711 if(*pnt == ';') return 0; /* no forward references */
712 do{
713 pnt=(char*) strchr(pnt,':');
0e39a8bb 714 pnt = cvt_integer(pnt+1,&i);
8b228fe9
RP
715 spnt = find_symbol(i);
716 if(spnt == (struct VMS_DBG_Symbol*) NULL) return 0;
717 while((spnt->advanced == POINTER) || (spnt->advanced == ARRAY)){
718 i=spnt->type2;
719 spnt1 = find_symbol(spnt->type2);
720 if((spnt->advanced == ARRAY) &&
721 (spnt1 == (struct VMS_DBG_Symbol*) NULL))return 1;
722 if(spnt1 == (struct VMS_DBG_Symbol*) NULL) break;
723 spnt=spnt1;
724 };
725 pnt = cvt_integer(pnt+1,&i);
726 pnt = cvt_integer(pnt+1,&i);
727 }while(*++pnt != ';');
728 return 0; /* no forward refences found */
0e39a8bb
RP
729}
730
731/* This routine parses the stabs directives to find any definitions of dbx type
732 * numbers. It makes a note of all of them, creating a structure element
733 * of VMS_DBG_Symbol that describes it. This also generates the info for the
734 * debugger that describes the struct/union/enum, so that further references
735 * to these data types will be by number
736 * We have to process pointers right away, since there can be references
737 * to them later in the same stabs directive. We cannot have forward
738 * references to pointers, (but we can have a forward reference to a pointer to
739 * a structure/enum/union) and this is why we process them immediately.
740 * After we process the pointer, then we search for defs that are nested even
741 * deeper.
742 */
743static int VMS_typedef_parse(char* str){
744 char* pnt;
8b228fe9
RP
745 char* pnt1;
746 char* pnt2;
747 int i;
748 int dtype;
749 struct forward_ref * fpnt;
750 int i1,i2,i3;
751 int convert_integer;
752 struct VMS_DBG_Symbol* spnt;
753 struct VMS_DBG_Symbol* spnt1;
754 /* check for any nested def's */
755 pnt=(char*)strchr(str+1,'=');
756 if((pnt != (char*) NULL) && (*(str+1) != '*'))
757 if(VMS_typedef_parse(pnt) == 1 ) return 1;
758 /* now find dbx_type of entry */
759 pnt=str-1;
760 if(*pnt == 'c'){ /* check for static constants */
761 *str = '\0'; /* for now we ignore them */
762 return 0;};
763 while((*pnt <= '9')&& (*pnt >= '0')) pnt--;
764 pnt++; /* and get back to the number */
765 cvt_integer(pnt,&i1);
766 spnt = find_symbol(i1);
767 /* first we see if this has been defined already, due to a forward reference*/
768 if(spnt == (struct VMS_DBG_Symbol*) NULL) {
769 if(VMS_Symbol_type_list==(struct VMS_DBG_Symbol*) NULL)
770 {spnt=(struct VMS_DBG_Symbol*) malloc(sizeof(struct VMS_DBG_Symbol));
771 spnt->next = (struct VMS_DBG_Symbol*) NULL;
772 VMS_Symbol_type_list=spnt;}
773 else
774 {spnt=(struct VMS_DBG_Symbol*) malloc(sizeof(struct VMS_DBG_Symbol));
775 spnt->next=VMS_Symbol_type_list;
776 VMS_Symbol_type_list = spnt;};
777 spnt->dbx_type = i1; /* and save the type */
778 };
779 /* for structs and unions, do a partial parse, otherwise we sometimes get
780 * circular definitions that are impossible to resolve. We read enough info
781 * so that any reference to this type has enough info to be resolved
782 */
783 pnt=str + 1; /* point to character past equal sign */
784 if((*pnt == 'u') || (*pnt == 's')){
785 };
786 if((*pnt <= '9') && (*pnt >= '0')){
787 if(type_check("void")){ /* this is the void symbol */
788 *str='\0';
789 spnt->advanced = VOID;
790 return 0;};
791 printf("gcc-as warning(debugger output):");
792 printf(" %d is an unknown untyped variable.\n",spnt->dbx_type);
793 return 1; /* do not know what this is */
794 };
795 /* now define this module*/
796 pnt=str + 1; /* point to character past equal sign */
797 switch (*pnt){
798 case 'r':
799 spnt->advanced= BASIC;
800 if(type_check("int")) {
801 spnt->VMS_type=DBG$C_SLINT; spnt->data_size=4;}
802 else if(type_check("long int")) {
803 spnt->VMS_type=DBG$C_SLINT; spnt->data_size=4;}
804 else if(type_check("unsigned int")) {
805 spnt->VMS_type=DBG$C_ULINT; spnt->data_size = 4;}
806 else if(type_check("long unsigned int")) {
807 spnt->VMS_type=DBG$C_ULINT; spnt->data_size = 4;}
808 else if(type_check("short int")) {
809 spnt->VMS_type=DBG$C_SSINT; spnt->data_size = 2;}
810 else if(type_check("short unsigned int")) {
811 spnt->VMS_type=DBG$C_USINT; spnt->data_size = 2;}
812 else if(type_check("char")) {
813 spnt->VMS_type=DBG$C_SCHAR; spnt->data_size = 1;}
814 else if(type_check("signed char")) {
815 spnt->VMS_type=DBG$C_SCHAR; spnt->data_size = 1;}
816 else if(type_check("unsigned char")) {
817 spnt->VMS_type=DBG$C_UCHAR; spnt->data_size = 1;}
818 else if(type_check("float")) {
819 spnt->VMS_type=DBG$C_REAL4; spnt->data_size = 4;}
820 else if(type_check("double")) {
821 spnt->VMS_type=DBG$C_REAL8; spnt->data_size = 8;}
822 pnt1=(char*) strchr(str,';')+1;
823 break;
824 case 's':
825 case 'u':
826 if(*pnt == 's') spnt->advanced= STRUCT;
827 else spnt->advanced= UNION;
828 spnt->VMS_type = DBG$C_ADVANCED_TYPE;
829 pnt1 = cvt_integer(pnt+1,&spnt->data_size);
830 if(forward_reference(pnt)) {
831 spnt->struc_numb = -1;
832 return 1;
833 }
834 spnt->struc_numb = ++structure_count;
835 pnt1--;
836 pnt=get_struct_name(str);
837 VMS_Def_Struct(spnt->struc_numb);
838 fpnt = f_ref_root;
839 while(fpnt != (struct forward_ref*) NULL){
840 if(fpnt->dbx_type == spnt->dbx_type) {
841 fpnt->resolved = 'Y';
842 VMS_Set_Struct(fpnt->struc_numb);
843 VMS_Store_Struct(spnt->struc_numb);};
844 fpnt = fpnt->next;};
845 VMS_Set_Struct(spnt->struc_numb);
846 i=0;
847 Local[i++] = 11+strlen(pnt);
848 Local[i++] = DBG$C_STRUCT_START;
849 Local[i++] = 0x80;
850 for(i1=0;i1<4;i1++) Local[i++] = 0x00;
851 Local[i++] = strlen(pnt);
852 pnt2=pnt;
853 while(*pnt2 != '\0') Local[i++] = *pnt2++;
854 i2=spnt->data_size * 8; /* number of bits */
855 pnt2=(char*) &i2;
856 for(i1=0;i1<4;i1++) Local[i++] = *pnt2++;
857 VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
858 if(pnt != symbol_name) {
859 pnt += strlen(pnt);
860 *pnt=':';}; /* replace colon for later */
861 while(*++pnt1 != ';'){
862 pnt=(char*) strchr(pnt1,':');
863 *pnt='\0';
864 pnt2=pnt1;
865 pnt1 = cvt_integer(pnt+1,&dtype);
866 pnt1 = cvt_integer(pnt1+1,&i2);
867 pnt1 = cvt_integer(pnt1+1,&i3);
868 if((dtype == 1) && (i3 != 32)) { /* bitfield */
869 Apoint = 0;
870 push(19+strlen(pnt2),1);
871 push(0xfa22,2);
872 push(1+strlen(pnt2),4);
873 push(strlen(pnt2),1);
874 while(*pnt2 != '\0') push(*pnt2++,1);
875 push(i3,2); /* size of bitfield */
876 push(0x0d22,2);
877 push(0x00,4);
878 push(i2,4); /* start position */
879 VMS_Store_Immediate_Data(Asuffix,Apoint,OBJ$C_DBG);
880 Apoint=0;
881 }else{
882 Local[i++] = 7+strlen(pnt2);
883 spnt1 = find_symbol(dtype);
0e39a8bb 884 /* check if this is a forward reference */
8b228fe9
RP
885 if(spnt1 != (struct VMS_DBG_Symbol*) NULL)
886 Local[i++] = spnt1->VMS_type;
887 else
888 Local[i++] = DBG$C_ADVANCED_TYPE;
889 Local[i++] = DBG$C_STRUCT_ITEM;
890 pnt=(char*) &i2;
891 for(i1=0;i1<4;i1++) Local[i++] = *pnt++;
892 Local[i++] = strlen(pnt2);
0e39a8bb
RP
893 while(*pnt2 != '\0') Local[i++] = *pnt2++;
894 VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
8b228fe9
RP
895 if(spnt1 == (struct VMS_DBG_Symbol*) NULL)
896 generate_suffix(spnt1,dtype);
897 else if(spnt1->VMS_type == DBG$C_ADVANCED_TYPE)
898 generate_suffix(spnt1,0);
899 };
0e39a8bb 900 };
8b228fe9
RP
901 pnt1++;
902 Local[i++] = 0x01; /* length byte */
903 Local[i++] = DBG$C_STRUCT_END;
904 VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
905 break;
906 case 'e':
907 spnt->advanced= ENUM;
908 spnt->VMS_type = DBG$C_ADVANCED_TYPE;
909 spnt->struc_numb = ++structure_count;
910 spnt->data_size=4;
911 VMS_Def_Struct(spnt->struc_numb);
912 fpnt = f_ref_root;
913 while(fpnt != (struct forward_ref*) NULL){
914 if(fpnt->dbx_type == spnt->dbx_type) {
915 fpnt->resolved = 'Y';
916 VMS_Set_Struct(fpnt->struc_numb);
917 VMS_Store_Struct(spnt->struc_numb);};
918 fpnt = fpnt->next;};
919 VMS_Set_Struct(spnt->struc_numb);
920 i=0;
921 Local[i++] = 3+strlen(symbol_name);
922 Local[i++] = DBG$C_ENUM_START;
923 Local[i++] = 0x20;
924 Local[i++] = strlen(symbol_name);
925 pnt2=symbol_name;
926 while(*pnt2 != '\0') Local[i++] = *pnt2++;
927 VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
928 while(*++pnt != ';') {
929 pnt1=(char*) strchr(pnt,':');
930 *pnt1++='\0';
931 pnt1 = cvt_integer(pnt1,&i1);
932 Local[i++] = 7+strlen(pnt);
933 Local[i++] = DBG$C_ENUM_ITEM;
934 Local[i++] = 0x00;
935 pnt2=(char*) &i1;
936 for(i2=0;i2<4;i2++) Local[i++] = *pnt2++;
937 Local[i++] = strlen(pnt);
938 pnt2=pnt;
939 while(*pnt != '\0') Local[i++] = *pnt++;
940 VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
941 pnt= pnt1; /* Skip final semicolon */
942 };
943 Local[i++] = 0x01; /* len byte */
944 Local[i++] = DBG$C_ENUM_END;
945 VMS_Store_Immediate_Data(Local, i, OBJ$C_DBG); i=0;
946 pnt1=pnt + 1;
947 break;
948 case 'a':
949 spnt->advanced= ARRAY;
950 spnt->VMS_type = DBG$C_ADVANCED_TYPE;
951 pnt=(char*)strchr(pnt,';'); if (pnt == (char*) NULL) return 1;
952 pnt1 = cvt_integer(pnt+1,&spnt->index_min);
953 pnt1 = cvt_integer(pnt1+1,&spnt->index_max);
954 pnt1 = cvt_integer(pnt1+1,&spnt->type2);
955 break;
956 case 'f':
957 spnt->advanced= FUNCTION;
958 spnt->VMS_type = DBG$C_FUNCTION_ADDR;
959 /* this masquerades as a basic type*/
960 spnt->data_size=4;
961 pnt1 = cvt_integer(pnt+1,&spnt->type2);
962 break;
963 case '*':
964 spnt->advanced= POINTER;
965 spnt->VMS_type = DBG$C_ADVANCED_TYPE;
966 spnt->data_size=4;
967 pnt1 = cvt_integer(pnt+1,&spnt->type2);
968 pnt=(char*)strchr(str+1,'=');
969 if((pnt != (char*) NULL))
970 if(VMS_typedef_parse(pnt) == 1 ) return 1;
971 break;
972 default:
973 spnt->advanced= UNKNOWN;
974 spnt->VMS_type = 0;
975 printf("gcc-as warning(debugger output):");
976 printf(" %d is an unknown type of variable.\n",spnt->dbx_type);
977 return 1; /* unable to decipher */
978 };
979 /* this removes the evidence of the definition so that the outer levels of
980 parsing do not have to worry about it */
981 pnt=str;
982 while (*pnt1 != '\0') *pnt++ = *pnt1++;
983 *pnt = '\0';
984 return 0;
0e39a8bb
RP
985}
986
987
988/*
989 * This is the root routine that parses the stabs entries for definitions.
990 * it calls VMS_typedef_parse, which can in turn call itself.
991 * We need to be careful, since sometimes there are forward references to
992 * other symbol types, and these cannot be resolved until we have completed
993 * the parse.
994 */
995int VMS_LSYM_Parse(){
996 char *pnt;
8b228fe9
RP
997 char *pnt1;
998 char *pnt2;
999 char *str;
1000 char fixit[10];
1001 int incomplete,i,pass,incom1;
1002 struct VMS_DBG_Symbol* spnt;
1003 struct VMS_Symbol * vsp;
1004 struct forward_ref * fpnt;
1005 symbolS * sp;
1006 pass=0;
1007 incomplete = 0;
1008 do{
1009 incom1=incomplete;
0e39a8bb 1010 incomplete = 0;
8b228fe9
RP
1011 for(sp = symbol_rootP; sp; sp = symbol_next(sp)) {
1012 /*
1013 * Deal with STAB symbols
1014 */
1015 if ((sp->sy_nlist.n_type & N_STAB) != 0) {
0e39a8bb 1016 /*
8b228fe9 1017 * Dispatch on STAB type
0e39a8bb 1018 */
8b228fe9
RP
1019 switch((unsigned char)sp->sy_nlist.n_type) {
1020 case N_GSYM:
1021 case N_LCSYM:
1022 case N_STSYM:
1023 case N_PSYM:
1024 case N_RSYM:
1025 case N_LSYM:
1026 case N_FUN: /*sometimes these contain typedefs*/
1027 str=sp->sy_nlist.n_un.n_name;
1028 symbol_name = str;
1029 pnt=(char*)strchr(str,':');
1030 if(pnt== (char*) NULL) break;
1031 *pnt='\0';
1032 pnt1=pnt+1;
1033 pnt2=(char*)strchr(pnt1,'=');
1034 if(pnt2 == (char*) NULL){
1035 *pnt=':'; /* replace colon */
1036 break;}; /* no symbol here */
1037 incomplete += VMS_typedef_parse(pnt2);
1038 *pnt=':'; /* put back colon so variable def code finds dbx_type*/
1039 break;
1040 } /*switch*/
1041 } /* if */
1042 } /*for*/
0e39a8bb 1043 pass++;
8b228fe9
RP
1044 } while((incomplete != 0) && (incomplete != incom1 ));
1045 /* repeat until all refs resolved if possible */
1046 /* if(pass > 1) printf(" Required %d passes\n",pass);*/
1047 if(incomplete != 0){
1048 printf("gcc-as warning(debugger output):");
1049 printf("Unable to resolve %d circular references.\n",incomplete);
1050 };
1051 fpnt = f_ref_root;
1052 symbol_name="\0";
1053 while(fpnt != (struct forward_ref*) NULL){
1054 if(fpnt->resolved != 'Y') {
1055 if( find_symbol(fpnt->dbx_type) !=
1056 (struct VMS_DBG_Symbol*) NULL){
0e39a8bb 1057 printf("gcc-as warning(debugger output):");
8b228fe9
RP
1058 printf("Forward reference error, dbx type %d\n",
1059 fpnt->dbx_type);
1060 break;};
1061 fixit[0]=0;
1062 sprintf(&fixit[1],"%d=s4;",fpnt->dbx_type);
1063 pnt2=(char*)strchr(&fixit[1],'=');
1064 VMS_typedef_parse(pnt2);
1065 };
1066 fpnt = fpnt->next;};
0e39a8bb
RP
1067}
1068
1069static symbolS* Current_Routine;
1070static int Text_Psect;
1071
1072static Define_Local_Symbols(symbolS* s1,symbolS* s2){
1073 symbolS * symbolP1;
8b228fe9
RP
1074 for(symbolP1 = symbol_next(s1); symbolP1 != s2; symbolP1 = symbol_next(symbolP1)) {
1075 if (symbolP1 == (symbolS *)NULL) return;
1076 if (symbolP1->sy_nlist.n_type == N_FUN) return;
1077 /*
1078 * Deal with STAB symbols
1079 */
1080 if ((symbolP1->sy_nlist.n_type & N_STAB) != 0) {
1081 /*
1082 * Dispatch on STAB type
1083 */
1084 switch((unsigned char)symbolP1->sy_nlist.n_type) {
1085 case N_LSYM:
1086 case N_PSYM:
1087 VMS_local_stab_Parse(symbolP1);
1088 break;
1089 case N_RSYM:
1090 VMS_RSYM_Parse(symbolP1,Current_Routine,Text_Psect);
1091 break;
1092 } /*switch*/
1093 } /* if */
1094 } /* for */
0e39a8bb
RP
1095}
1096
1097static symbolS* Define_Routine(symbolS* symbolP,int Level){
1098 symbolS * sstart;
8b228fe9
RP
1099 symbolS * symbolP1;
1100 char str[10];
1101 char * pnt;
1102 int rcount = 0;
1103 int Offset;
1104 sstart = symbolP;
1105 for(symbolP1 = symbol_next(symbolP); symbolP1; symbolP1 = symbol_next(symbolP1)) {
1106 if (symbolP1->sy_nlist.n_type == N_FUN) break;
1107 /*
1108 * Deal with STAB symbols
1109 */
1110 if ((symbolP1->sy_nlist.n_type & N_STAB) != 0) {
1111 /*
1112 * Dispatch on STAB type
1113 */
1114 if((unsigned char)symbolP1->sy_nlist.n_type == N_FUN) break;
1115 switch((unsigned char)symbolP1->sy_nlist.n_type) {
1116 case N_LBRAC:
1117 if(Level != 0) {
1118 pnt = str +sprintf(str,"$%d",rcount++);
1119 *pnt = '\0';
1120 VMS_TBT_Block_Begin(symbolP1,Text_Psect,str);
1121 };
1122 Offset = symbolP1->sy_nlist.n_value;
1123 Define_Local_Symbols(sstart,symbolP1);
1124 symbolP1 =
1125 Define_Routine(symbolP1,Level+1);
1126 if(Level != 0)
1127 VMS_TBT_Block_End(symbolP1->sy_nlist.n_value -
1128 Offset);
1129 sstart=symbolP1;
1130 break;
1131 case N_RBRAC:
1132 return symbolP1;
1133 } /*switch*/
1134 } /* if */
1135 } /* for */
1136 /* we end up here if there were no brackets in this function. Define
1137 everything */
1138 Define_Local_Symbols(sstart,(symbolS *) 0);
0e39a8bb
RP
1139}
1140
1141VMS_DBG_Define_Routine(symbolS* symbolP,symbolS* Curr_Routine,int Txt_Psect){
1142 Current_Routine = Curr_Routine;
8b228fe9
RP
1143 Text_Psect = Txt_Psect;
1144 Define_Routine(symbolP,0);
0e39a8bb 1145}
8b228fe9
RP
1146
1147/* end of vms-dbg.c */
This page took 0.100491 seconds and 4 git commands to generate.