* src/SDCCval.c (valForArray): applied Maarteen Brock's patch #947682
[fw/sdcc] / src / SDCCdwarf2.c
1 /*-------------------------------------------------------------------------
2   SDCCdwarf2.c - generate DWARF2 debug information
3
4              Written By -  Erik Petrich . epetrich@users.sourceforge.net (2004)
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20    In other words, you are welcome to use, share and improve this program.
21    You are forbidden to forbid anyone else to use, share and improve
22    what you give them.   Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
24
25
26 #include "common.h"
27 #include "SDCCdwarf2.h"
28
29 /*************************************************************
30  *
31  *
32  *
33  *
34  *************************************************************/
35
36 extern set *includeDirsSet;
37
38 int dwOpenFile(char *file);
39 int dwCloseFile(void);
40 int dwWriteFunction(symbol *pSym, iCode *ic);
41 int dwWriteEndFunction(symbol *pSym, iCode *ic, int offset);
42 int dwWriteLabel(symbol *pSym, iCode *ic);
43 int dwWriteScope(iCode *ic);
44 int dwWriteSymbol(symbol *pSym);
45 int dwWriteType(structdef *sdef, int block, int inStruct, char *tag);
46 int dwWriteModule(char *name);
47 int dwWriteCLine(iCode *ic);
48 int dwWriteALine(char *module, int Line);
49 int dwWriteFrameAddress(char *variable, struct regs *reg, int offset);
50 int dwWriteBasicSymbol(symbol *sym, int isStructSym, int isFunc);
51      
52
53 DEBUGFILE dwarf2DebugFile = 
54   {
55     &dwOpenFile,
56     &dwCloseFile,
57     &dwWriteModule,
58     &dwWriteFunction,
59     &dwWriteEndFunction,
60     &dwWriteLabel,
61     &dwWriteScope,
62     &dwWriteSymbol,
63     &dwWriteType,
64     &dwWriteCLine,
65     &dwWriteALine,
66     &dwWriteFrameAddress
67   };
68
69 FILE *dwarf2FilePtr = NULL;
70 char *dwModuleName = NULL;
71 dwtag *dwRootTag = NULL;
72 dwtag *dwFuncTag = NULL;
73 dwtag *dwScopeTag = NULL;
74 hTab * dwAbbrevTable;
75 int dwAbbrevNum = 0;
76 hTab * dwTypeTagTable;
77 int dwRefNum = 0;
78 int dwScopeBlock = 0;
79 int dwScopeLevel = 0;
80 int dwDebugSymbol = 0;
81 //dwcfins * dwCIEins = NULL;
82 dwlocregion * dwFrameLastLoc = NULL;
83 dwloclist * dwRootLocList = NULL;
84 dwloclist * dwFrameLocList = NULL;
85 int dwLineBase = -5;
86 int dwLineRange = 15;
87 int dwLineOpcodeBase = 10;
88 set * dwFilenameSet = NULL;
89 dwline * dwLineFirst = NULL;
90 dwline * dwLineLast = NULL;
91
92
93 /*----------------------------------------------------------------------*/
94 /* dwNewDebugSymbol - returns the name for a new debug symbol           */
95 /*----------------------------------------------------------------------*/
96 static char *
97 dwNewDebugSymbol ()
98 {
99   char debugSym[SDCC_NAME_MAX];
100         
101   sprintf (debugSym, "S%s$%s$%d", dwModuleName, currFunc->name, dwDebugSymbol);
102   dwDebugSymbol++;
103   return Safe_strdup (debugSym);
104 }
105
106
107 /*----------------------------------------------------------------------*/
108 /* dwWriteByte - generate a single byte assembler constant in the form: */
109 /*                                                                      */
110 /*       .db label+offset  ; comment                                    */
111 /*                                                                      */
112 /* The label and comment parameters are optional                        */
113 /*----------------------------------------------------------------------*/
114 static void
115 dwWriteByte (char * label, int offset, char * comment)
116 {
117   tfprintf (dwarf2FilePtr, "\t!db\t");
118   if (label)
119     {
120       if (offset)
121         fprintf (dwarf2FilePtr, "%s+%d", label, offset);
122       else
123         fprintf (dwarf2FilePtr, "%s", label);
124     }
125   else
126     fprintf (dwarf2FilePtr, "%d", offset);
127   
128   if (comment)
129     fprintf (dwarf2FilePtr, "\t;%s\n", comment);
130   else
131     fprintf (dwarf2FilePtr, "\n");
132 }
133
134 /*----------------------------------------------------------------------*/
135 /* dwWriteHalf - generate a two byte assembler constant in the form:    */
136 /*                                                                      */
137 /*       .dw label+offset  ; comment                                    */
138 /*                                                                      */
139 /* The label and comment parameters are optional                        */
140 /*----------------------------------------------------------------------*/
141 static void
142 dwWriteHalf (char * label, int offset, char * comment)
143 {
144   tfprintf (dwarf2FilePtr, "\t!dw\t");
145   if (label)
146     {
147       if (offset)
148         fprintf (dwarf2FilePtr, "%s+%d", label, offset);
149       else
150         fprintf (dwarf2FilePtr, "%s", label);
151     }
152   else
153     fprintf (dwarf2FilePtr, "%d", offset);
154   
155   if (comment)
156     fprintf (dwarf2FilePtr, "\t;%s\n", comment);
157   else
158     fprintf (dwarf2FilePtr, "\n");
159 }
160
161 /*----------------------------------------------------------------------*/
162 /* dwWriteWord - generate a four byte assembler constant in the form:   */
163 /*                                                                      */
164 /*       .dd label+offset  ; comment                                    */
165 /*                                                                      */
166 /* The label and comment parameters are optional                        */
167 /*----------------------------------------------------------------------*/
168 static void
169 dwWriteWord (char * label, int offset, char * comment)
170 {
171   /* FIXME: need to implement !dd pseudo-op in the assember. In the */
172   /* meantime, we use dw with zero padding and hope the values fit  */
173   /* in only 16 bits.                                               */
174 #if 0
175   tfprintf (dwarf2FilePtr, "\t!dd\t");
176   if (label)
177     {
178       if (offset)
179         fprintf (dwarf2FilePtr, "%s+%d", label, offset);
180       else
181         fprintf (dwarf2FilePtr, "%s", label);
182     }
183   else
184     fprintf (dwarf2FilePtr, "%d", offset);
185 #else
186   tfprintf (dwarf2FilePtr, "\t!dw\t");
187   if (port->little_endian)
188     {
189       if (label)
190         {
191           if (offset)
192             fprintf (dwarf2FilePtr, "(%s+%d),0", label, offset);
193           else
194             fprintf (dwarf2FilePtr, "(%s),0", label);
195         }
196       else
197         fprintf (dwarf2FilePtr, "%d,%d", offset, offset >> 16);
198     }
199   else
200     {
201       if (label)
202         {
203           if (offset)
204             fprintf (dwarf2FilePtr, "0,(%s+%d)", label, offset);
205           else
206             fprintf (dwarf2FilePtr, "0,(%s)", label);
207         }
208       else
209         fprintf (dwarf2FilePtr, "%d,%d", offset >> 16, offset);
210     }
211 #endif
212   
213   if (comment)
214     fprintf (dwarf2FilePtr, "\t;%s\n", comment);
215   else
216     fprintf (dwarf2FilePtr, "\n");
217 }
218
219
220 /*----------------------------------------------------------------------*/
221 /* dwWriteULEB128 - generate an unsigned variable length assembler      */
222 /*                  constant in the form:                               */
223 /*                                                                      */
224 /*       .uleb128 label+offset  ; comment                               */
225 /*                                                                      */
226 /* The label and comment parameters are optional                        */
227 /*----------------------------------------------------------------------*/
228 static void
229 dwWriteULEB128 (char * label, int offset, char * comment)
230 {
231   tfprintf (dwarf2FilePtr, "\t.uleb128\t");
232   if (label)
233     {
234       if (offset)
235         fprintf (dwarf2FilePtr, "%s+%d", label, offset);
236       else
237         fprintf (dwarf2FilePtr, "%s", label);
238     }
239   else
240     fprintf (dwarf2FilePtr, "%d", offset);
241   
242   if (comment)
243     fprintf (dwarf2FilePtr, "\t;%s\n", comment);
244   else
245     fprintf (dwarf2FilePtr, "\n");
246 }
247
248 /*----------------------------------------------------------------------*/
249 /* dwWriteSLEB128 - generate a signed variable length assembler         */
250 /*                  constant in the form:                               */
251 /*                                                                      */
252 /*       .sleb128 label+offset  ; comment                               */
253 /*                                                                      */
254 /* The label and comment parameters are optional                        */
255 /*----------------------------------------------------------------------*/
256 static void
257 dwWriteSLEB128 (char * label, int offset, char * comment)
258 {
259   tfprintf (dwarf2FilePtr, "\t.sleb128\t");
260   if (label)
261     {
262       if (offset)
263         fprintf (dwarf2FilePtr, "%s+%d", label, offset);
264       else
265         fprintf (dwarf2FilePtr, "%s", label);
266     }
267   else
268     fprintf (dwarf2FilePtr, "%d", offset);
269   
270   if (comment)
271     fprintf (dwarf2FilePtr, "\t;%s\n", comment);
272   else
273     fprintf (dwarf2FilePtr, "\n");
274 }
275
276
277 /*----------------------------------------------------------------------*/
278 /* dwSizeofULEB128 - return the size (in bytes) of an unsigned variable */
279 /*                   length constant                                    */
280 /*----------------------------------------------------------------------*/
281 static int
282 dwSizeofULEB128 (int unsigned value)
283 {
284   int size = 0;
285   
286   do
287     {
288       value >>= 7;
289       size++;
290     }
291   while (value);
292   
293   return size;
294 }
295
296 /*----------------------------------------------------------------------*/
297 /* dwSizeofSLEB128 - return the size (in bytes) of a signed variable    */
298 /*                   length constant                                    */
299 /*----------------------------------------------------------------------*/
300 static int
301 dwSizeofSLEB128 (int value)
302 {
303   int size = 0;
304   int negative = (value < 0);
305   int sign;
306   
307   while (1)
308     {
309       size++;
310       sign = value & 0x40;
311       value >>= 7;
312       if (negative)
313         value |= (0x7f << (sizeof(int)*8 - 7));
314       if ((value == 0 && !sign) || (value == -1 && sign))
315         break;
316     }
317   
318   return size;
319 }
320
321 /*----------------------------------------------------------------------*/
322 /* dwWriteString - generate a string constant in the form:              */
323 /*                                                                      */
324 /*       .ascii /string/  ; comment                                     */
325 /*                                                                      */
326 /* The comment parameter is optional. The string may contain any        */
327 /* non-null characters                                                  */
328 /*----------------------------------------------------------------------*/
329 static void
330 dwWriteString (char * string, char * comment)
331 {
332   /* FIXME: need to safely handle nonalphanumeric data in string */
333   
334   tfprintf (dwarf2FilePtr, "\t!ascii\n", string);
335   dwWriteByte (NULL, 0, comment);
336 }
337
338
339 /*----------------------------------------------------------------------*/
340 /* dwWriteAddress - generate an assembler constant in the form:         */
341 /*                                                                      */
342 /*       .dw label+offset  ; comment                                    */
343 /* or    .dd label+offset  ; comment                                    */
344 /*                                                                      */
345 /* depending on how the relevant ABI defines the address size (may be   */
346 /* larger than the CPU's actual address size). The label and comment    */
347 /* parameters are optional                                              */
348 /*----------------------------------------------------------------------*/
349 static void
350 dwWriteAddress (char * label, int offset, char * comment)
351 {
352   switch (port->debugger.dwarf.addressSize)
353     {
354     case 2:
355       dwWriteHalf (label, offset, comment);
356       break;
357     case 4:
358       dwWriteWord (label, offset, comment);
359       break;
360     default:
361       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
362               "unsupported port->debugger.dwarf.addressSize");
363     }
364 }
365
366
367 /*----------------------------------------------------------------------*/
368 /* dwWriteHalfDelta - generate a two byte assembler constant in the     */
369 /*                    form:                                             */
370 /*                                                                      */
371 /*       .dw offset+label1-label2                                       */
372 /*                                                                      */
373 /* The offset parameter is optional                                     */
374 /*----------------------------------------------------------------------*/
375 static void
376 dwWriteHalfDelta (char * label1, char * label2, int offset)
377 {
378   if (offset)
379     tfprintf (dwarf2FilePtr, "\t!dw\t%d+%s-%s\n", offset, label1, label2);
380   else
381     tfprintf (dwarf2FilePtr, "\t!dw\t%s-%s\n", label1, label2);
382 }
383
384 /*----------------------------------------------------------------------*/
385 /* dwWriteWordDelta - generate a four byte assembler constant in the    */
386 /*                    form:                                             */
387 /*                                                                      */
388 /*       .dd label1-label2                                              */
389 /*----------------------------------------------------------------------*/
390 static void 
391 dwWriteWordDelta (char * label1, char * label2)
392 {
393   /* FIXME: need to implement !dd pseudo-op; this hack only */
394   /* works for positive offsets of less than 64k            */
395 #if 0
396   tfprintf (dwarf2FilePtr, "\t!dd\t%s-%s\n", label1,label2);
397 #else
398   if (port->little_endian)
399     {
400       tfprintf (dwarf2FilePtr, "\t!dw\t%s-%s,%d\n", label1, label2, 0);
401     }
402   else
403     {
404       tfprintf (dwarf2FilePtr, "\t!dw\t%d,%s-%s\n", 0, label1, label2);
405     }
406 #endif
407 }
408
409
410 /* disabled to eliminiate unused function warning */
411 #if 0 
412 /*----------------------------------------------------------------------*/
413 /* dwWriteAddressDelta - generate an assembler constant in the form:    */
414 /*                                                                      */
415 /*       .dw label1-label2                                              */
416 /* or    .dd label1-label2                                              */
417 /*                                                                      */
418 /* depending on how the relevant ABI defines the address size (may be   */
419 /* larger than the CPU's actual address size)                           */
420 /*----------------------------------------------------------------------*/
421 static void
422 dwWriteAddressDelta (char * label1, char * label2)
423 {
424   switch (port->debugger.dwarf.addressSize)
425     {
426     case 2:
427       dwWriteHalfDelta (label1, label2, 0);
428       break;
429     case 4:
430       dwWriteWordDelta (label1, label2);
431       break;
432     default:
433       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
434               "unsupported port->debugger.dwarf.addressSize");
435     }
436 }
437
438 /*----------------------------------------------------------------------*/
439 /* dwWriteULEB128Delta - generate an unsigned variable byte assembler   */
440 /*                       constant in the form:                          */
441 /*                                                                      */
442 /*       .uleb128 offset+label1-label2                                  */
443 /*                                                                      */
444 /* The offset parameter is optional                                     */
445 /*----------------------------------------------------------------------*/
446 static void
447 dwWriteULEB128Delta (char * label1, char * label2, int offset)
448 {
449   if (offset)
450     tfprintf (dwarf2FilePtr, "\t.uleb128\t%d+%s-%s\n", offset, label1, label2);
451   else
452     tfprintf (dwarf2FilePtr, "\t.uleb128\t%s-%s\n", label1, label2);
453 }
454 #endif
455
456 /*------------------------------------------------------------------------*/
457
458 /*----------------------------------------------------------------------*/
459 /* dwNewLoc - allocates a new location expression node                  */
460 /*----------------------------------------------------------------------*/
461 dwloc *
462 dwNewLoc (int opcode, char * label, int offset)
463 {
464   dwloc * lp;
465   
466   lp = Safe_alloc (sizeof (dwloc));
467   
468   lp->opcode = opcode;
469   lp->operand.label = label;
470   lp->operand.offset = offset;
471
472   return lp;
473 }
474
475 /*-------------------------------------------------------------------------*/
476 /* dwSizeofLoc - returns the size (in bytes) of a chain of location        */
477 /*               expression nodes as they would be encoded by dwWriteLoc() */
478 /*-------------------------------------------------------------------------*/
479 static int
480 dwSizeofLoc (dwloc * lp)
481 {
482   int size = 0;
483   
484   while (lp)
485     {
486       size++;
487       switch (lp->opcode)
488         {
489         case DW_OP_addr:
490           size += port->debugger.dwarf.addressSize;
491           break;
492           
493         case DW_OP_deref_size:
494         case DW_OP_xderef_size:
495         case DW_OP_pick:
496         case DW_OP_const1u:
497         case DW_OP_const1s:
498           size += 1;
499           break;
500         
501         case DW_OP_skip:
502         case DW_OP_bra:
503         case DW_OP_const2u:
504         case DW_OP_const2s:
505           size += 2;
506           break;
507         
508         case DW_OP_const4u:
509         case DW_OP_const4s:
510           size += 4;
511           break;
512         
513         case DW_OP_const8u:
514         case DW_OP_const8s:
515           size += 8;
516           break;
517
518         case DW_OP_piece:
519         case DW_OP_regx:
520         case DW_OP_plus_uconst:
521           size += dwSizeofULEB128 (lp->operand.offset);
522           break;
523         
524         case DW_OP_breg0:
525         case DW_OP_breg1:
526         case DW_OP_breg2:
527         case DW_OP_breg3:
528         case DW_OP_breg4:
529         case DW_OP_breg5:
530         case DW_OP_breg6:
531         case DW_OP_breg7:
532         case DW_OP_breg8:
533         case DW_OP_breg9:
534         case DW_OP_breg10:
535         case DW_OP_breg11:
536         case DW_OP_breg12:
537         case DW_OP_breg13:
538         case DW_OP_breg14:
539         case DW_OP_breg15:
540         case DW_OP_breg16:
541         case DW_OP_breg17:
542         case DW_OP_breg18:
543         case DW_OP_breg19:
544         case DW_OP_breg20:
545         case DW_OP_breg21:
546         case DW_OP_breg22:
547         case DW_OP_breg23:
548         case DW_OP_breg24:
549         case DW_OP_breg25:
550         case DW_OP_breg26:
551         case DW_OP_breg27:
552         case DW_OP_breg28:
553         case DW_OP_breg29:
554         case DW_OP_breg30:
555         case DW_OP_breg31:
556         case DW_OP_fbreg:
557           size += dwSizeofSLEB128 (lp->operand.offset);
558           break;
559         }
560       
561       lp = lp->next;
562     }
563   
564   return size;
565 }
566
567 /*------------------------------------------------------------------------*/
568 /* dwWriteLoc - writes a chain of location expression nodes               */
569 /*------------------------------------------------------------------------*/
570 static void
571 dwWriteLoc (dwloc *lp)
572 {
573   while (lp)
574     {
575       dwWriteByte (NULL, lp->opcode, NULL);
576       switch (lp->opcode)
577         {
578         case DW_OP_addr:
579           dwWriteAddress (lp->operand.label, lp->operand.offset, NULL);
580           break;
581           
582         case DW_OP_deref_size:
583         case DW_OP_xderef_size:
584         case DW_OP_pick:
585         case DW_OP_const1u:
586         case DW_OP_const1s:
587           dwWriteByte (NULL, lp->operand.offset, NULL);
588           break;
589         
590         case DW_OP_skip:
591         case DW_OP_bra:
592         case DW_OP_const2u:
593         case DW_OP_const2s:
594           dwWriteHalf (NULL, lp->operand.offset, NULL);
595           break;
596         
597         case DW_OP_const4u:
598         case DW_OP_const4s:
599           dwWriteWord (NULL, lp->operand.offset, NULL);
600           break;
601         
602         case DW_OP_piece:
603         case DW_OP_regx:
604         case DW_OP_plus_uconst:
605           dwWriteULEB128 (NULL, lp->operand.offset, NULL);
606           break;
607         
608         case DW_OP_breg0:
609         case DW_OP_breg1:
610         case DW_OP_breg2:
611         case DW_OP_breg3:
612         case DW_OP_breg4:
613         case DW_OP_breg5:
614         case DW_OP_breg6:
615         case DW_OP_breg7:
616         case DW_OP_breg8:
617         case DW_OP_breg9:
618         case DW_OP_breg10:
619         case DW_OP_breg11:
620         case DW_OP_breg12:
621         case DW_OP_breg13:
622         case DW_OP_breg14:
623         case DW_OP_breg15:
624         case DW_OP_breg16:
625         case DW_OP_breg17:
626         case DW_OP_breg18:
627         case DW_OP_breg19:
628         case DW_OP_breg20:
629         case DW_OP_breg21:
630         case DW_OP_breg22:
631         case DW_OP_breg23:
632         case DW_OP_breg24:
633         case DW_OP_breg25:
634         case DW_OP_breg26:
635         case DW_OP_breg27:
636         case DW_OP_breg28:
637         case DW_OP_breg29:
638         case DW_OP_breg30:
639         case DW_OP_breg31:
640         case DW_OP_fbreg:
641           dwWriteSLEB128 (NULL, lp->operand.offset, NULL);
642           break;
643         }
644         
645       lp = lp->next;
646     }
647 }
648
649 /*----------------------------------------------------------------------*/
650 /* dwNewLocList - allocates a new list of location expression node      */
651 /*----------------------------------------------------------------------*/
652 static dwloclist *
653 dwNewLocList (void)
654 {
655   dwloclist * llp;
656   
657   llp = Safe_alloc (sizeof (dwloclist));
658   
659   return llp;
660 }
661
662 /*----------------------------------------------------------------------*/
663 /* dwSizeofLocRegion - returns the size (in bytes) of a chain of        */
664 /*                     location regions (inluding their location        */
665 /*                     expression nodes) as encoded by dwWriteLocLists  */
666 /*----------------------------------------------------------------------*/
667 static int
668 dwSizeofLocRegion (dwlocregion * lrp)
669 {
670   int size = 0;
671   
672   while (lrp)
673     {
674       size += 2 * port->debugger.dwarf.addressSize;
675       size += 2 + dwSizeofLoc (lrp->loc);
676       lrp = lrp->next;
677     }
678   
679   size += 2 * port->debugger.dwarf.addressSize;
680   return size;
681 }
682
683 /*-----------------------------------------------------------------------*/
684 /* dwAssignLocListAddresses - assign the address offsets of the location */
685 /*                            lists so that they can be referenced from  */
686 /*                            the tag structure                          */
687 /*-----------------------------------------------------------------------*/
688 static void
689 dwAssignLocListAddresses (void)
690 {
691   dwloclist * llp;
692   int address = 0;
693
694   llp = dwRootLocList;
695   while (llp)
696     {
697       llp->baseOffset = address;
698       address += dwSizeofLocRegion (llp->region);
699
700       llp = llp->next;
701     }
702 }
703
704 /*-----------------------------------------------------------------------*/
705 /* dwWriteLocLists - write all of the location lists in dwRootLocList to */
706 /*                   the .debug_loc section                              */
707 /*-----------------------------------------------------------------------*/
708 static void
709 dwWriteLocLists (void)
710 {
711   dwlocregion * lrp;
712   dwloclist * llp;
713
714   tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_loc (NOLOAD)");
715   tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_loc_start");
716
717   llp = dwRootLocList;
718   while (llp)
719     {
720       //fprintf (dwarf2FilePtr, "; baseOffset = 0x%x\n", llp->baseOffset);
721       lrp = llp->region;
722       while (lrp)
723         {
724           dwWriteAddress (lrp->startLabel, 0, NULL);
725           dwWriteAddress (lrp->endLabel, 0, NULL);
726           dwWriteHalf (NULL, dwSizeofLoc (lrp->loc), NULL);
727           dwWriteLoc (lrp->loc);
728           lrp = lrp ->next;
729         }
730
731       dwWriteAddress (NULL, 0, NULL);
732       dwWriteAddress (NULL, 0, NULL);
733
734       llp = llp->next;
735     }
736     
737 }
738
739
740 /*------------------------------------------------------------------------*/
741
742
743 /*----------------------------------------------------------------------*/
744 /* dwNewAttr - allocate a new tag attribute node                        */
745 /*----------------------------------------------------------------------*/
746 static dwattr *
747 dwNewAttr (int attr)
748 {
749   dwattr * ap;
750   
751   ap = Safe_alloc ( sizeof (dwattr));
752   ap->attr = attr;
753   
754   return ap;
755 }
756
757 /*----------------------------------------------------------------------*/
758 /* dwFreeAttr - deallocate a tag attribute node                         */
759 /*----------------------------------------------------------------------*/
760 static void
761 dwFreeAttr (dwattr * ap)
762 {
763   Safe_free (ap);
764 }
765
766
767
768 /*-------------------------------------------------------------------------*/
769 /* dwNewAttrString - allocate a new tag attribute node with a string value */
770 /*-------------------------------------------------------------------------*/
771 static dwattr *
772 dwNewAttrString (int attr, char * string)
773 {
774   dwattr * ap;
775   
776   ap = dwNewAttr (attr);
777   ap->form = DW_FORM_string;
778   ap->val.string = string;
779   return ap;
780 }
781
782
783 /*---------------------------------------------------------------------*/
784 /* dwNewAttrConst - allocate a new tag attribute node with an unsigned */
785 /*                  numeric constant value                             */
786 /*---------------------------------------------------------------------*/
787 static dwattr *
788 dwNewAttrConst (int attr, unsigned int data)
789 {
790   dwattr * ap;
791   
792   ap = dwNewAttr (attr);
793   if (data <= 0xffu)
794     ap->form = DW_FORM_data1;
795   else if (data <= 0xffffu)
796     ap->form = DW_FORM_data2;
797   else
798     ap->form = DW_FORM_data4;
799   
800   ap->val.data = data;
801   return ap;
802 }
803
804 /* disabled to eliminiate unused function warning */
805 #if 0
806 /*---------------------------------------------------------------------*/
807 /* dwNewAttrSignedConst - allocate a new tag attribute node with a     */
808 /*                        signed numeric constant value                */
809 /*---------------------------------------------------------------------*/
810 static dwattr *
811 dwNewAttrSignedConst (int attr, int data)
812 {
813   dwattr * ap;
814   
815   ap = dwNewAttr (attr);
816   if (data <= 0x7f && data >= -0x80)
817     ap->form = DW_FORM_data1;
818   else if (data <= 0xffff && data >= -0x8000)
819     ap->form = DW_FORM_data2;
820   else
821     ap->form = DW_FORM_data4;
822   
823   ap->val.data = data;
824   return ap;
825 }
826 #endif
827
828 /*---------------------------------------------------------------------*/
829 /* dwNewAttrFlag - allocate a new tag attribute node with a boolean    */
830 /*                 flag value (zero/non-zero)                          */
831 /*---------------------------------------------------------------------*/
832 static dwattr *
833 dwNewAttrFlag (int attr, int data)
834 {
835   dwattr * ap;
836   
837   ap = dwNewAttr (attr);
838   ap->form = DW_FORM_flag;
839   
840   ap->val.data = data;
841   return ap;
842 }
843
844 /*---------------------------------------------------------------------*/
845 /* dwNewAttrAddrSymbol - allocate a new tag attribute node with the    */
846 /*                       address of a C symbol plus an offset          */
847 /*---------------------------------------------------------------------*/
848 static dwattr *
849 dwNewAttrAddrSymbol (int attr, symbol * sym, int offset)
850 {
851   dwattr * ap;
852   
853   ap = dwNewAttr (attr);
854   ap->form = DW_FORM_addr;
855   
856   ap->val.symaddr.label = sym->rname;
857   ap->val.symaddr.offset = offset;
858   return ap;
859 }
860
861 /*---------------------------------------------------------------------*/
862 /* dwNewAttrAddrLabel - allocate a new tag attribute node with the     */
863 /*                      address of an assembler label plus an offset   */
864 /*---------------------------------------------------------------------*/
865 static dwattr *
866 dwNewAttrAddrLabel (int attr, char * label, int offset)
867 {
868   dwattr * ap;
869   
870   ap = dwNewAttr (attr);
871   ap->form = DW_FORM_addr;
872   
873   ap->val.symaddr.label = label;
874   ap->val.symaddr.offset = offset;
875   return ap;
876 }
877
878 /*---------------------------------------------------------------------*/
879 /* dwNewAttrTagRef - allocate a new tag attribute node that references */
880 /*                   a tag node                                        */
881 /*---------------------------------------------------------------------*/
882 static dwattr *
883 dwNewAttrTagRef (int attr, dwtag * tp)
884 {
885   dwattr * ap;
886   
887   ap = dwNewAttr (attr);
888   ap->form = DW_FORM_ref4;
889   
890   ap->val.ref = tp;
891   return ap;
892 }
893
894 /*---------------------------------------------------------------------*/
895 /* dwNewAttrLocRef - allocate a new tag attribute node that references */
896 /*                   a location list                                   */
897 /*---------------------------------------------------------------------*/
898 static dwattr *
899 dwNewAttrLocRef (int attr, dwloclist * llp)
900 {
901   dwattr * ap;
902   
903   ap = dwNewAttr (attr);
904   ap->form = DW_FORM_data4;
905   
906   ap->val.loclist = llp;
907   return ap;
908 }
909
910 /*-----------------------------------------------------------------------*/
911 /* dwNewAttrLabelRef - allocate a new tag attribute node that references */
912 /*                     the address of an assembler label plus an offset  */
913 /*-----------------------------------------------------------------------*/
914 static dwattr *
915 dwNewAttrLabelRef (int attr, char * label, int offset)
916 {
917   dwattr * ap;
918   
919   ap = dwNewAttr (attr);
920   ap->form = DW_FORM_data4;
921   
922   ap->val.symaddr.label = label;
923   ap->val.symaddr.offset = offset;
924   return ap;
925 }
926
927 /*---------------------------------------------------------------------*/
928 /* dwNewAttrLoc - allocate a new tag attribute node for a chain of     */
929 /*                location expression nodes                            */
930 /*---------------------------------------------------------------------*/
931 dwattr *
932 dwNewAttrLoc (int attr, dwloc * lp)
933 {
934   dwattr * ap;
935   
936   ap = dwNewAttr (attr);
937   ap->form = DW_FORM_block1;
938   ap->val.loc = lp;
939   
940   return ap;
941 }
942
943 /*---------------------------------------------------------------------*/
944 /* dwWriteAttr - write a tag attribute node                            */
945 /*---------------------------------------------------------------------*/
946 static void
947 dwWriteAttr (dwattr * ap)
948 {
949   
950   switch (ap->form)
951     {
952       case DW_FORM_addr:
953         dwWriteAddress (ap->val.symaddr.label, ap->val.symaddr.offset, NULL);
954         break;
955       
956       case DW_FORM_block:
957         dwWriteULEB128 (NULL, dwSizeofLoc (ap->val.loc), NULL);
958         dwWriteLoc (ap->val.loc);
959         break;
960       
961       case DW_FORM_block1:
962         dwWriteByte (NULL, dwSizeofLoc (ap->val.loc), NULL);
963         dwWriteLoc (ap->val.loc);
964         break;
965       
966       case DW_FORM_block2:
967         dwWriteHalf (NULL, dwSizeofLoc (ap->val.loc), NULL);
968         dwWriteLoc (ap->val.loc);
969         break;
970       
971       case DW_FORM_block4:
972         dwWriteWord (NULL, dwSizeofLoc (ap->val.loc), NULL);
973         dwWriteLoc (ap->val.loc);
974         break;
975       
976       case DW_FORM_data1:
977       case DW_FORM_flag:
978         dwWriteByte (NULL, ap->val.data, NULL);
979         break;
980       
981       case DW_FORM_data2:
982         dwWriteHalf (NULL, ap->val.data, NULL);
983         break;
984       
985       case DW_FORM_data4:
986         switch (ap->attr)
987           {
988           case DW_AT_stmt_list:
989             dwWriteWord (ap->val.symaddr.label, ap->val.symaddr.offset, NULL);
990             break;
991           case DW_AT_location:
992           case DW_AT_frame_base:
993             dwWriteWord (NULL, ap->val.loclist->baseOffset, NULL);
994             break;
995           default:
996             dwWriteWord (NULL, ap->val.data, NULL);
997           }
998         break;
999       
1000       case DW_FORM_udata:
1001         dwWriteULEB128 (NULL, ap->val.data, NULL);
1002         break;
1003       
1004       case DW_FORM_sdata:
1005         dwWriteSLEB128 (NULL, ap->val.data, NULL);
1006         break;
1007
1008       case DW_FORM_string:
1009         dwWriteString (ap->val.string, NULL);
1010         break;
1011       
1012       case DW_FORM_ref1:
1013         dwWriteByte (NULL, ap->val.ref->baseOffset, NULL);
1014         break;
1015       
1016       case DW_FORM_ref2:
1017         dwWriteHalf (NULL, ap->val.ref->baseOffset, NULL);
1018         break;
1019       
1020       case DW_FORM_ref4:
1021         dwWriteWord (NULL, ap->val.ref->baseOffset, NULL);
1022         break;
1023         
1024       default:
1025         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1026                 "unsupported DWARF form");
1027         exit (1);
1028     }
1029 }
1030
1031 /*---------------------------------------------------------------------*/
1032 /* dwSizeofAttr - returns the size (in bytes) of a tag attribute node  */
1033 /*                as encoded by dwWriteAttr                            */
1034 /*---------------------------------------------------------------------*/
1035 static int
1036 dwSizeofAttr (dwattr * ap)
1037 {
1038   int size;
1039   
1040   switch (ap->form)
1041     {
1042       case DW_FORM_addr:
1043         return port->debugger.dwarf.addressSize;
1044       
1045       case DW_FORM_block:
1046         size = dwSizeofLoc (ap->val.loc);
1047         return size + dwSizeofULEB128 (size);
1048       
1049       case DW_FORM_block1:
1050         size = dwSizeofLoc (ap->val.loc);
1051         return size + 1;
1052       
1053       case DW_FORM_block2:
1054         size = dwSizeofLoc (ap->val.loc);
1055         return size + 2;
1056       
1057       case DW_FORM_block4:
1058         size = dwSizeofLoc (ap->val.loc);
1059         return size + 4;
1060       
1061       case DW_FORM_data1:
1062       case DW_FORM_flag:
1063         return 1;
1064       
1065       case DW_FORM_data2:
1066         return 2;
1067       
1068       case DW_FORM_data4:
1069         return 4;
1070       
1071       case DW_FORM_udata:
1072         return dwSizeofULEB128 (ap->val.data);
1073       
1074       case DW_FORM_sdata:
1075         return dwSizeofSLEB128 (ap->val.data);
1076
1077       case DW_FORM_string:
1078         return 1 + strlen (ap->val.string);
1079       
1080       case DW_FORM_ref1:
1081         return 1;
1082       
1083       case DW_FORM_ref2:
1084         return 2;
1085       
1086       case DW_FORM_ref4:
1087         return 4;
1088         
1089       default:
1090         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1091                 "unsupported DWARF form");
1092         exit (1);
1093     }
1094     
1095 }
1096
1097
1098 /*---------------------------------------------------------------------*/
1099 /* dwFindAttr - for a tag node, return a pointer to a particular       */
1100 /*              attribute node, or NULL if not found                   */
1101 /*---------------------------------------------------------------------*/
1102 static dwattr *
1103 dwFindAttr (dwtag * tp, int attr)
1104 {
1105   dwattr * ap;
1106   
1107   ap = tp->attribs;
1108   while (ap)
1109     {
1110       if (ap->attr == attr)
1111         return ap;
1112       ap = ap->next;
1113     }
1114   
1115   return NULL;
1116 }
1117
1118
1119
1120 /*------------------------------------------------------------------------*/
1121
1122
1123 /*----------------------------------------------------------------------*/
1124 /* dwNewTag - allocate a new tag node                                   */
1125 /*----------------------------------------------------------------------*/
1126 static dwtag *
1127 dwNewTag (int tag)
1128 {
1129   dwtag * tp;
1130   
1131   tp = Safe_alloc ( sizeof (dwtag));
1132   tp->tag = tag;
1133   
1134   return tp;
1135 }
1136
1137 /*----------------------------------------------------------------------*/
1138 /* dwAddTagAttr - add an attribute to a tag                             */
1139 /*----------------------------------------------------------------------*/
1140 static void
1141 dwAddTagAttr (dwtag * tp, dwattr * ap)
1142 {
1143   dwattr * curap;
1144   
1145   if (!tp->attribs)
1146     tp->attribs = ap;
1147   else if (ap->attr < tp->attribs->attr)
1148     {
1149       ap->next = tp->attribs;
1150       tp->attribs = ap;
1151     }
1152   else
1153     {
1154       curap = tp->attribs;
1155       while (curap->next && curap->next->attr < ap->attr)
1156         curap = curap->next;
1157       ap->next = curap->next;
1158       curap->next = ap;
1159     }
1160 }
1161
1162 /*----------------------------------------------------------------------*/
1163 /* dwSetTagAttr - repleace an existing attribute of a tag with a new    */
1164 /*                attribute or add if non-existent                      */
1165 /*----------------------------------------------------------------------*/
1166 static void
1167 dwSetTagAttr (dwtag *tp, dwattr * ap)
1168 {
1169   dwattr * curap;
1170   
1171   curap = dwFindAttr (tp, ap->attr);
1172   if (curap)
1173     {
1174       ap->next = curap->next;
1175       *curap = *ap;
1176       dwFreeAttr (ap);
1177     }
1178   else
1179     dwAddTagAttr (tp, ap);
1180 }
1181
1182
1183 /*----------------------------------------------------------------------*/
1184 /* dwAddTagChild - add a tag as a child of another tag                  */
1185 /*----------------------------------------------------------------------*/
1186 static dwtag *
1187 dwAddTagChild (dwtag * parent, dwtag * child)
1188 {
1189   child->parent = parent;
1190   if (parent->lastChild)
1191     {
1192       parent->lastChild->siblings = child;
1193       parent->lastChild = child;
1194     }
1195   else
1196     {
1197       parent->firstChild = child;
1198       parent->lastChild = child;
1199     }
1200   return parent;
1201 }
1202
1203 /*----------------------------------------------------------------------*/
1204 /* dwMatchTagAttr - returns true if two tags are equal in value,        */
1205 /*                  attributes, and offspring status (the child tags    */
1206 /*                  need not match, but they must both have children or */
1207 /*                  both not have children)                             */
1208 /*----------------------------------------------------------------------*/
1209 static int
1210 dwMatchTagAttr (const void * tp1v, const void * tp2v)
1211 {
1212   const dwtag * tp1 = tp1v;
1213   const dwtag * tp2 = tp2v;
1214   dwattr * ap1 = tp1->attribs;
1215   dwattr * ap2 = tp2->attribs;
1216
1217   if (!tp1 || !tp2)
1218     return 0;
1219     
1220   if (tp1->tag != tp2->tag)
1221     return 0;
1222   
1223   if (tp1->firstChild && !tp2->lastChild)
1224     return 0;
1225   if (!tp1->firstChild && tp2->lastChild)
1226     return 0;
1227     
1228   while (ap1 && ap2)
1229     {
1230       if (ap1->attr != ap2->attr)
1231         return 0;
1232       if (ap1->form != ap2->form)
1233         return 0;
1234
1235       ap1 = ap1->next;
1236       ap2 = ap2->next;
1237     }
1238   
1239   return 1;
1240 }
1241
1242 /*----------------------------------------------------------------------*/
1243 /* dwHashTag - return a hash code for a tag based on its value and      */
1244 /*             attributes                                               */
1245 /*----------------------------------------------------------------------*/
1246 static int
1247 dwHashTag (dwtag * tp)
1248 {
1249   dwattr * ap = tp->attribs;
1250   int hash = tp->tag;
1251
1252   while (ap)
1253     {
1254       hash = (hash << 6) ^ ((hash >> 11) & 0xff);
1255       hash ^= (ap->attr) | (ap->form << 8);
1256       
1257       ap = ap->next;
1258     }  
1259   if (hash<0)
1260     return -hash;
1261   else
1262     return hash;
1263 }
1264
1265 /*----------------------------------------------------------------------*/
1266 /* dwTraverseTag - perform a depth-first preorder traversal of a tag    */
1267 /*                 tree, calling the user function at each node. The    */
1268 /*                 user function is also called with a NULL tag pointer */
1269 /*                 after the last sibling of each immediate family is   */
1270 /*                 processed.                                           */
1271 /*----------------------------------------------------------------------*/
1272 static int
1273 dwTraverseTag (dwtag *tp, int (*somefunc)(dwtag *tp, void * info), void * info)
1274 {
1275   int rvalue = 0;
1276   
1277   while (tp)
1278     {
1279       rvalue += (*somefunc)(tp, info);
1280       if (tp->firstChild)
1281         rvalue += dwTraverseTag (tp->firstChild, somefunc, info);
1282       tp = tp->siblings;
1283     }
1284   rvalue += (*somefunc)(NULL, info);
1285   
1286   return rvalue;
1287 }
1288
1289 /*----------------------------------------------------------------------*/
1290 /* dwAssignAbbrev - find a matching abbreviation for a tag or create a  */
1291 /*                  a new one and assign it                             */
1292 /*----------------------------------------------------------------------*/
1293 static int
1294 dwAssignAbbrev (dwtag *tp, void *info)
1295 {
1296   dwtag * oldtp;
1297   int * anp = info;     /* pointer to current abbreviation number */
1298   int key;
1299   
1300   if (!tp)
1301     return 0;
1302
1303   key = dwHashTag (tp) % dwAbbrevTable->size;
1304   oldtp = hTabFindByKey (dwAbbrevTable, key, tp, dwMatchTagAttr);
1305   if (oldtp)
1306     {
1307       tp->abbrev = oldtp->abbrev;
1308       return 0;
1309     }
1310   else
1311     {
1312       tp->abbrev = ++(*anp);
1313       hTabAddItemLong (&dwAbbrevTable, key, tp, tp);
1314       return 1;
1315     }
1316 }
1317
1318 /*-----------------------------------------------------------------------*/
1319 /* dwWriteAbbrevs - write the abbreviations to the .debug_abbrev section */
1320 /*-----------------------------------------------------------------------*/
1321 static void
1322 dwWriteAbbrevs (void)
1323 {
1324   dwtag * tp;
1325   dwattr * ap;
1326   int key;
1327   
1328   tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_abbrev (NOLOAD)");
1329   tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_abbrev");
1330
1331   tp = hTabFirstItem (dwAbbrevTable, &key);
1332   for (; tp; tp = hTabNextItem (dwAbbrevTable, &key))
1333     {
1334       dwWriteULEB128 (NULL, tp->abbrev, NULL);
1335       dwWriteULEB128 (NULL, tp->tag, NULL);
1336       dwWriteByte (NULL, tp->firstChild ? DW_CHILDREN_yes : DW_CHILDREN_no,
1337                    NULL);
1338       ap = tp->attribs;
1339       while (ap)
1340         {
1341           dwWriteULEB128 (NULL, ap->attr, NULL);
1342           dwWriteULEB128 (NULL, ap->form, NULL);
1343           ap = ap->next;
1344         }
1345       dwWriteULEB128 (NULL, 0, NULL);
1346       dwWriteULEB128 (NULL, 0, NULL);
1347       
1348     }
1349   dwWriteULEB128 (NULL, 0, NULL);
1350   
1351   hTabDeleteAll (dwAbbrevTable);
1352 }
1353
1354
1355
1356 /*-----------------------------------------------------------------------*/
1357 /* dwWriteTag - write the encoded tag information                        */
1358 /*-----------------------------------------------------------------------*/
1359 static int
1360 dwWriteTag (dwtag *tp, void *info)
1361 {
1362   dwattr * ap;
1363
1364   if (!tp)
1365     {
1366       /* mark the end of this series of siblings */
1367       dwWriteULEB128 (NULL, 0, NULL);
1368       return 0;
1369     }
1370
1371   //fprintf (dwarf2FilePtr, "; baseOffset = 0x%x\n", tp->baseOffset);
1372   
1373   /* write the tag abbreviation */
1374   dwWriteULEB128 (NULL, tp->abbrev, NULL);
1375   
1376   /* write the values of the attributes */
1377   ap = tp->attribs;
1378   while (ap)
1379     {
1380       dwWriteAttr (ap);
1381       ap = ap->next;
1382     }
1383     
1384   return 1;
1385 }
1386
1387
1388 /*-----------------------------------------------------------------------*/
1389 /* dwWriteTags - write all the tags to the .debug_info section           */
1390 /*-----------------------------------------------------------------------*/
1391 static void
1392 dwWriteTags (void)
1393 {  
1394   tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_info (NOLOAD)");
1395   
1396   dwWriteWordDelta ("Ldebug_info_end", "Ldebug_info_start");
1397   
1398   tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_info_start");
1399   
1400   dwWriteHalf (NULL, 2, NULL); /* DWARF version */
1401   
1402   dwWriteWord ("Ldebug_abbrev", 0, NULL);
1403     
1404   dwWriteByte (NULL, port->debugger.dwarf.addressSize, NULL);
1405     
1406   dwTraverseTag (dwRootTag, dwWriteTag, NULL);
1407   
1408   dwWriteULEB128 (NULL, 0, NULL);
1409   
1410   tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_info_end");
1411
1412 }
1413
1414 /*-----------------------------------------------------------------------*/
1415 /* dwAssignTagAddress - assign the current address to the current tag.   */
1416 /*                      Compute the next address based on the tag size   */
1417 /*-----------------------------------------------------------------------*/
1418 static int
1419 dwAssignTagAddress (dwtag *tp, void *info)
1420 {
1421   int * tap = info;
1422   dwattr * ap;
1423
1424   if (!tp)
1425     {
1426       *tap += 1;
1427       return 0;
1428     }
1429       
1430   tp->baseOffset = *tap;
1431
1432   *tap += dwSizeofULEB128 (tp->abbrev);
1433   
1434   ap = tp->attribs;
1435   while (ap)
1436     {
1437       *tap += dwSizeofAttr (ap);
1438       ap = ap->next;
1439     }
1440     
1441   return 0;
1442 }
1443
1444 /*-----------------------------------------------------------------------*/
1445 /* dwAddSibAttr - if a tag has children and a sibling, add a sibling     */
1446 /*                attribute (it allows debuggers to jump to the sibling  */
1447 /*                and skip the child data)                               */
1448 /*-----------------------------------------------------------------------*/
1449 static int
1450 dwAddSibAttr (dwtag *tp, void *info)
1451 {
1452   if (!tp)
1453     return 0;
1454   if (tp == dwRootTag)
1455     return 0;
1456   
1457   if (tp->firstChild && tp->siblings)
1458     dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_sibling, tp->siblings));
1459
1460   return 0;
1461 }
1462
1463 /*-----------------------------------------------------------------------*/
1464 /* dwDeleteTagAttr - given a pointer to an attribute type, delete any    */
1465 /*                   matching attribute                                  */
1466 /*-----------------------------------------------------------------------*/
1467 static int
1468 dwDeleteTagAttr (dwtag *tp, void *info)
1469 {
1470   int attr = *((int *) info);
1471   dwattr * ap;
1472   
1473   if (!tp)
1474     return 0;
1475
1476   ap = tp->attribs;
1477   if (ap && ap->attr == attr)
1478     {
1479       tp->attribs = ap->next;
1480       return 1;
1481     }
1482   
1483   while (ap)
1484     {
1485       if (ap->next && ap->next->attr == attr)
1486         {
1487           ap->next = ap->next->next;
1488           return 1;
1489         }
1490       ap = ap->next;
1491     }
1492   
1493   return 0;
1494 }
1495
1496
1497 /*------------------------------------------------------------------------*/
1498
1499 /*-----------------------------------------------------------------------*/
1500 /* dwWritePubnames - write all the public names to the .debug_pubnames   */
1501 /*                   section. Externally visible functions and variables */
1502 /*                   are considered to have public names.                */
1503 /*-----------------------------------------------------------------------*/
1504 static void
1505 dwWritePubnames (void)
1506 {
1507   dwtag * tp;
1508   dwattr * ap1;
1509   dwattr * ap2;
1510   
1511   tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_pubnames (NOLOAD)");
1512   
1513   dwWriteWordDelta ("Ldebug_pubnames_end", "Ldebug_pubnames_start");
1514   
1515   tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_pubnames_start");
1516   
1517   dwWriteHalf (NULL, 2, NULL); /* DWARF version */
1518   
1519   dwWriteWord ("Ldebug_info_start-4", 0, NULL);
1520   dwWriteWordDelta ("4+Ldebug_info_end", "Ldebug_info_start");
1521
1522   if (dwRootTag && dwRootTag->firstChild)
1523     {
1524       tp = dwRootTag->firstChild;
1525       while (tp)
1526         {
1527           if (tp->tag == DW_TAG_variable || tp->tag == DW_TAG_subprogram)
1528             {
1529               /* If it has a name and is externally visible, it's a pubname */
1530               ap1 = dwFindAttr (tp, DW_AT_external);
1531               ap2 = dwFindAttr (tp, DW_AT_name);
1532               if (ap1 && ap1->val.data && ap2)
1533                 {
1534                   dwWriteWord (NULL, tp->baseOffset, NULL);
1535                   dwWriteString (ap2->val.string, NULL);
1536                 }
1537             }
1538         
1539           tp = tp->siblings;
1540         }
1541     }  
1542   dwWriteWord (NULL, 0, NULL);
1543   tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_pubnames_end");
1544 }
1545
1546 /*------------------------------------------------------------------------*/
1547
1548 /*-----------------------------------------------------------------------*/
1549 /* dwFindFileIndex - find the index of a filename in dwFilenameSet; if   */
1550 /*                   it does not exist, it is added                      */
1551 /*-----------------------------------------------------------------------*/
1552 static int
1553 dwFindFileIndex (char * filename)
1554 {
1555   char * includeDir;
1556   dwfile * srcfile;
1557   int fileIndex = 1;
1558   int dirIndex = 1;
1559
1560   /* Just do a linear search for the file. There should be hardly */
1561   /* a penalty since 1) most calls search for the first file, and */
1562   /* 2) the file set is usually small (often just 1 item)         */
1563   for (srcfile = setFirstItem (dwFilenameSet);
1564        srcfile;
1565        srcfile = setNextItem(dwFilenameSet), fileIndex++ )
1566     {
1567       if (!strcmp (srcfile->name, filename))
1568         return fileIndex;
1569     }
1570
1571   for (includeDir = setFirstItem (includeDirsSet);
1572        includeDir;
1573        includeDir = setNextItem(includeDirsSet), dirIndex++ )
1574     {
1575       if (!strncmp (includeDir, filename, strlen (includeDir))
1576           && strlen (filename) > strlen (includeDir))
1577         {
1578           if (*(filename+strlen (includeDir)) == DIR_SEPARATOR_CHAR)
1579             break;
1580         }
1581     }
1582   if (!includeDir)
1583     dirIndex = 0;
1584
1585   srcfile = Safe_alloc (sizeof (dwfile));
1586   srcfile->name = filename;
1587   srcfile->dirIndex = dirIndex;
1588   srcfile->timestamp = 0;
1589   srcfile->length = 0;
1590
1591   addSet (&dwFilenameSet, srcfile);
1592   return fileIndex;
1593 }
1594
1595 /*-----------------------------------------------------------------------*/
1596 /* dwWriteLineNumber - write line number (and related position info) to  */
1597 /*                     address corespondence data for a single node      */
1598 /*-----------------------------------------------------------------------*/
1599 static void
1600 dwWriteLineNumber (dwline * lp)
1601 {
1602   static int curFileIndex = 1;
1603   static int curLine = 1;
1604   static char * curLabel = NULL;
1605   static int curOffset = 0;
1606   int deltaLine = lp->line - curLine;
1607   int deltaAddr = lp->offset - curOffset;
1608   int deltaAddrValid = curLabel && lp->label && !strcmp (lp->label, curLabel);
1609
1610   //fprintf (dwarf2FilePtr, "; line %d\n", lp->line);
1611   if (lp->begin_sequence)
1612     {
1613       curFileIndex = 1;
1614       curLine = 1;
1615       curLabel = NULL;
1616       curOffset = 0;
1617       
1618       if (lp->end_sequence)
1619         return;
1620     }
1621   
1622   if (lp->fileIndex != curFileIndex)
1623     {
1624       dwWriteByte (NULL, DW_LNS_set_file, NULL);
1625       dwWriteULEB128 (NULL, lp->fileIndex, NULL);
1626       curFileIndex = lp->fileIndex;
1627     }
1628   
1629   if (lp->basic_block)
1630     {
1631       dwWriteByte (NULL, DW_LNS_set_basic_block, NULL);
1632     }
1633   
1634   if (lp->begin_sequence)
1635     {
1636       dwWriteByte (NULL, 0, NULL);
1637       dwWriteULEB128 (NULL, 1+port->debugger.dwarf.addressSize, NULL);
1638       dwWriteByte (NULL, DW_LNE_set_address, NULL);
1639       dwWriteAddress (lp->label, lp->offset, NULL);
1640       curLabel = lp->label;
1641       curOffset = lp->offset;
1642
1643       dwWriteByte (NULL, DW_LNS_advance_line, NULL);
1644       dwWriteSLEB128 (NULL, lp->line - 1, NULL);
1645       curLine = lp->line;
1646
1647       dwWriteByte (NULL, DW_LNS_copy, NULL);
1648     }
1649   else if (lp->end_sequence)
1650     {
1651       if (deltaAddrValid)
1652         {
1653           dwWriteByte (NULL, DW_LNS_advance_pc, NULL);
1654           dwWriteULEB128 (NULL, deltaAddr, NULL);
1655         }
1656       else
1657         {
1658           dwWriteByte (NULL, DW_LNS_fixed_advance_pc, NULL);
1659           dwWriteHalfDelta (lp->label, curLabel, lp->offset-curOffset);
1660           curLabel = lp->label;
1661           curOffset = lp->offset;
1662         }
1663       
1664       dwWriteByte (NULL, 0, NULL);
1665       dwWriteULEB128 (NULL, 1, NULL);
1666       dwWriteByte (NULL, DW_LNE_end_sequence, NULL);
1667     }
1668   else
1669     {
1670       int usedSpecial = 0;
1671       
1672       /* Metrowerks CW08 V3.0 gets confused by this. Just use the long */
1673       /* encoding until we can find a more compatible phrasing.        */
1674       #if 0
1675       if (deltaLine >= dwLineBase && deltaLine < (dwLineBase+dwLineRange))
1676         {
1677           int opcode;
1678           
1679           /* try to build a "special" opcode */
1680           opcode = dwLineOpcodeBase + (deltaLine - dwLineBase);
1681           if (deltaAddrValid)
1682             opcode += deltaAddr*dwLineRange;
1683           
1684           if (opcode >= dwLineOpcodeBase && opcode <= 255)
1685             {
1686               /* ok, we can use a "special" opcode */
1687               
1688               /* If the deltaAddr value was symbolic, it can't be part */
1689               /* of the "special" opcode, so encode it seperately      */
1690               if (!deltaAddrValid)
1691                 {
1692                   dwWriteByte (NULL, DW_LNS_advance_pc, NULL);
1693                   dwWriteULEB128Delta (lp->label, curLabel, lp->offset-curOffset);
1694                   curLabel = lp->label;
1695                   curOffset = lp->offset;
1696                 }
1697
1698               /* Write the "special" opcode */        
1699               dwWriteByte (NULL, opcode, NULL);
1700               curLine = lp->line;
1701               usedSpecial = 1;
1702             }
1703         }
1704       #endif
1705       
1706       /* If we couldn't use the "special" opcode, we will have to */
1707       /* encode this the long way.                                */
1708       if (!usedSpecial)
1709         {
1710           dwWriteByte (NULL, DW_LNS_fixed_advance_pc, NULL);
1711           dwWriteHalfDelta (lp->label, curLabel, lp->offset-curOffset);
1712           curLabel = lp->label;
1713           curOffset = lp->offset;
1714         
1715           dwWriteByte (NULL, DW_LNS_advance_line, NULL);
1716           dwWriteSLEB128 (NULL, deltaLine, NULL);
1717           curLine = lp->line;
1718           
1719           dwWriteByte (NULL, DW_LNS_copy, NULL);
1720         }
1721         
1722     }
1723     
1724 }
1725
1726 /*-----------------------------------------------------------------------*/
1727 /* dwWriteLineNumbers - write all the source line number position data   */
1728 /*                      to the .debug_line section                       */
1729 /*-----------------------------------------------------------------------*/
1730 static void
1731 dwWriteLineNumbers (void)
1732 {
1733   char * includeDir;
1734   dwfile * srcfile;
1735   dwline * lp;
1736   
1737   tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_line (NOLOAD)");
1738   
1739   dwWriteWordDelta ("Ldebug_line_end", "Ldebug_line_start");
1740   
1741   tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_line_start");
1742   
1743   dwWriteHalf (NULL, 2, NULL); /* DWARF version */
1744
1745   dwWriteWordDelta ("Ldebug_line_stmt-6", "Ldebug_line_start");
1746
1747   dwWriteByte (NULL, 1, NULL); /* we track everything in 1 byte increments */
1748   
1749   dwWriteByte (NULL, 1, NULL); /* assume every line is a new statement */
1750
1751   dwWriteByte (NULL, dwLineBase, NULL);
1752   dwWriteByte (NULL, dwLineRange, NULL);
1753   
1754   dwWriteByte (NULL, 9+1, NULL);  /* there are 9 standard opcodes */
1755   
1756   dwWriteByte (NULL, 0, NULL);  /* number of DW_LNS_copy arguments */
1757   dwWriteByte (NULL, 1, NULL);  /* number of DW_LNS_advance_pc arguments */
1758   dwWriteByte (NULL, 1, NULL);  /* number of DW_LNS_advance_line arguments */
1759   dwWriteByte (NULL, 1, NULL);  /* number of DW_LNS_set_file arguments */
1760   dwWriteByte (NULL, 1, NULL);  /* number of DW_LNS_set_column arguments */
1761   dwWriteByte (NULL, 0, NULL);  /* number of DW_LNS_negate_stmt arguments */
1762   dwWriteByte (NULL, 0, NULL);  /* number of DW_LNS_set_basic_block arguments */
1763   dwWriteByte (NULL, 0, NULL);  /* number of DW_LNS_const_add_pc arguments */
1764   dwWriteByte (NULL, 1, NULL);  /* number of DW_LNS_fixed_advance_pc arguments */
1765
1766   /* Write the list of source directories searched */
1767   for (includeDir = setFirstItem (includeDirsSet);
1768        includeDir;
1769        includeDir = setNextItem(includeDirsSet) )
1770     dwWriteString (includeDir, NULL);
1771   dwWriteByte (NULL, 0, NULL);
1772   
1773   /* Write the list of source files used */
1774   for (srcfile = setFirstItem (dwFilenameSet);
1775        srcfile;
1776        srcfile = setNextItem(dwFilenameSet) )
1777     {
1778       dwWriteString (srcfile->name, NULL);
1779       dwWriteULEB128 (NULL, srcfile->dirIndex, NULL);
1780       dwWriteULEB128 (NULL, srcfile->timestamp, NULL);
1781       dwWriteULEB128 (NULL, srcfile->length, NULL);
1782     }
1783   dwWriteByte (NULL, 0, NULL);
1784   
1785   tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_line_stmt");
1786
1787   lp = dwLineFirst;
1788   if (lp)
1789     lp->begin_sequence = 1;
1790   while (lp)
1791     {
1792       dwWriteLineNumber (lp);
1793       if (lp->end_sequence && lp->next)
1794         lp->next->begin_sequence = 1;
1795       lp = lp->next;
1796     }
1797     
1798   tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_line_end");
1799 }
1800
1801 /*------------------------------------------------------------------------*/
1802
1803
1804 /* I have disabled all of this canonical frame address related code */
1805 /* until I better understand this part of the DWARF2 spec. -- EEP   */
1806 #if 0
1807 static void
1808 dwWriteCFAinstructions (dwcfins *ip)
1809 {
1810   dwcfop * op = ip->first;
1811   
1812   while (op)
1813     {
1814       dwWriteByte (NULL, op->opcode, NULL);
1815       switch (op->opcode >> 6)
1816         {
1817         case 0:
1818           switch (op->opcode)
1819             {
1820             case DW_CFA_set_loc:
1821               dwWriteAddress (NULL, op->label, op->operand1);
1822               break;
1823             
1824             case DW_CFA_advance_loc1:
1825               dwWriteByte (NULL, op->operand1, NULL);
1826               break;
1827             
1828             case DW_CFA_advance_loc2:
1829               dwWriteHalf (NULL, op->operand1, NULL);
1830               break;
1831             
1832             case DW_CFA_advance_loc4:
1833               dwWriteWord (NULL, op->operand1, NULL);
1834               break;
1835             
1836             case DW_CFA_def_cfa:
1837             case DW_CFA_register:
1838             case DW_CFA_offset_extended:
1839               dwWriteULEB128 (NULL, op->operand1, NULL);
1840               dwWriteULEB128 (NULL, op->operand2, NULL);
1841               break;
1842             
1843             case DW_CFA_undefined:
1844             case DW_CFA_same_value:
1845             case DW_CFA_def_cfa_register:
1846             case DW_CFA_def_cfa_offset:
1847             case DW_CFA_restore_extended:
1848               dwWriteULEB128 (NULL, op->operand1, NULL);
1849               break;
1850             }
1851           break;
1852         
1853         case DW_CFA_restore >> 6:
1854         case DW_CFA_advance_loc >> 6:
1855           break;
1856         
1857         case DW_CFA_offset >> 6:
1858           dwWriteULEB128 (NULL, op->operand1, NULL);
1859           break;
1860         }
1861       op = op->next;
1862     }
1863 }
1864
1865 static int
1866 dwSizeofCFAinstructions (dwcfins *ip)
1867 {
1868   int size = 0;
1869   dwcfop * op = ip->first;
1870   
1871   while (op)
1872     {
1873       size++;
1874       switch (op->opcode >> 6)
1875         {
1876         case 0:
1877           switch (op->opcode)
1878             {
1879             case DW_CFA_set_loc:
1880               size += port->debugger.dwarf.addressSize;
1881               break;
1882             
1883             case DW_CFA_advance_loc1:
1884               size += 1;
1885               break;
1886             
1887             case DW_CFA_advance_loc2:
1888               size += 2;
1889               break;
1890             
1891             case DW_CFA_advance_loc4:
1892               size += 4;
1893               break;
1894             
1895             case DW_CFA_def_cfa:
1896             case DW_CFA_register:
1897             case DW_CFA_offset_extended:
1898               size += dwSizeofULEB128 (op->operand1);
1899               size += dwSizeofULEB128 (op->operand2);
1900               break;
1901             
1902             case DW_CFA_undefined:
1903             case DW_CFA_same_value:
1904             case DW_CFA_def_cfa_register:
1905             case DW_CFA_def_cfa_offset:
1906             case DW_CFA_restore_extended:
1907               size += dwSizeofULEB128 (op->operand1);
1908               break;
1909             }
1910           break;
1911         
1912         case DW_CFA_restore >> 6:
1913         case DW_CFA_advance_loc >> 6:
1914           break;
1915         
1916         case DW_CFA_offset >> 6:
1917           size += dwSizeofULEB128 (op->operand1);
1918           break;
1919         }
1920       op = op->next;
1921     }
1922   return size;
1923 }
1924
1925 static dwcfop *
1926 dwNewCFop (int opcode)
1927 {
1928   dwcfop * op;
1929   
1930   op = Safe_alloc (sizeof (dwcfop));
1931   op->opcode = opcode;
1932   
1933   return op;
1934 }
1935
1936 static dwcfins *
1937 dwNewCFins (void)
1938 {
1939   return (dwcfins *) Safe_alloc (sizeof (dwcfins));
1940 }
1941
1942 static void
1943 dwAddCFinsOp (dwcfins * ip, dwcfop *op)
1944 {
1945   if (ip->last)
1946     ip->last->next = op;
1947   else
1948     ip->first = op;
1949   ip->last = op;
1950 }
1951
1952 static dwcfins *
1953 dwGenCFIins (void)
1954 {
1955   dwcfins * ip;
1956   dwcfop * op;
1957   int i;
1958   
1959   ip = dwNewCFins ();
1960   
1961   /* Define the CFA as the top of the stack at function start. */
1962   /* The return address is then at cfa+0                       */
1963   op = dwNewCFop (DW_CFA_def_cfa);
1964   op->operand1 = port->debugger.dwarf.regNumSP;
1965   op->operand2 = port->debugger.dwarf.offsetSP;
1966   dwAddCFinsOp (ip, op);
1967
1968   op = dwNewCFop (DW_CFA_offset + port->debugger.dwarf.regNumRet);
1969   op->operand1 = 0;
1970   dwAddCFinsOp (ip, op);
1971
1972   if (port->debugger.dwarf.cfiUndef)
1973     for (i=0; i < port->debugger.dwarf.cfiUndef->size; i++)
1974       {
1975         if (bitVectBitValue (port->debugger.dwarf.cfiUndef, i))
1976           {
1977             op = dwNewCFop (DW_CFA_undefined);
1978             dwAddCFinsOp (ip, op);
1979           }
1980     }
1981   
1982   if (port->debugger.dwarf.cfiSame)
1983     for (i=0; i < port->debugger.dwarf.cfiSame->size; i++)
1984       {
1985         if (bitVectBitValue (port->debugger.dwarf.cfiSame, i))
1986           {
1987             op = dwNewCFop (DW_CFA_undefined);
1988             dwAddCFinsOp (ip, op);
1989           }
1990       }
1991
1992   return ip;
1993 }
1994
1995
1996 static void
1997 dwWriteFDE (dwfde * fp)
1998 {
1999   dwWriteWord (NULL, dwSizeofCFAinstructions(fp->ins) + 4
2000                 + port->debugger.dwarf.addressSize * 2, NULL);
2001   
2002   dwWriteWord ("Ldebug_CIE_start-4", 0, NULL);
2003   
2004   dwWriteAddressDelta (fp->endLabel, fp->startLabel);
2005   
2006   dwWriteCFAinstructions (fp->ins);
2007   
2008 }
2009
2010 static void
2011 dwWriteFrames (void)
2012 {  
2013   tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_frame (NOLOAD)");
2014
2015   /* FIXME: these two dw should be combined into a dd */
2016   tfprintf (dwarf2FilePtr, "\t!dw\t0\n");
2017   tfprintf (dwarf2FilePtr, "\t!dw\t%s\n", "Ldebug_CIE_end-Ldebug_CIE_start");
2018
2019   tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_CIE_start");
2020   
2021   tfprintf (dwarf2FilePtr, "\t!dw\t0xffff\n");
2022   tfprintf (dwarf2FilePtr, "\t!dw\t0xffff\n");  /* CIE_id */
2023
2024   tfprintf (dwarf2FilePtr, "\t!db\t%d\n",1);    /* CIE version number */
2025
2026   tfprintf (dwarf2FilePtr, "\t!db\t%d\n",0);    /* augmentation (none) */
2027
2028   dwWriteULEB128 (NULL, 1, NULL);       /* code alignment factor */
2029   
2030   dwWriteSLEB128 (NULL, (port->stack.direction > 0) ? -1 : 1, NULL); /* data alignment factor */
2031   
2032   dwWriteByte (NULL, port->debugger.dwarf.regNumRet, NULL);
2033   
2034   if (!dwCIEins)
2035     {
2036       #if 0
2037       if (port->debugger.dwarf.genCFIins)
2038         dwCIEins = port->debugger.dwarf.genCFIins ();
2039       else
2040       #endif
2041         dwCIEins = dwGenCFIins ();
2042     }
2043   dwWriteCFAinstructions (dwCIEins);
2044   
2045   tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_CIE_end");
2046 }
2047 #endif
2048
2049
2050
2051
2052 /*------------------------------------------------------------------------*/
2053
2054
2055
2056
2057 /*-----------------------------------------------------------------------*/
2058 /* dwHashType - return a hash code for a type chain                      */
2059 /*-----------------------------------------------------------------------*/
2060 static int
2061 dwHashType (sym_link * type)
2062 {
2063   int hash = 0;
2064
2065   while (type)
2066     {
2067       hash = (hash << 5) ^ ((hash >> 8) & 0xff);
2068       if (IS_DECL (type))
2069         {
2070           hash ^= DCL_TYPE (type);
2071         }
2072       else
2073         {
2074           hash ^= SPEC_NOUN (type)
2075                | (SPEC_CONST (type) << 4)
2076                | (SPEC_VOLATILE (type) << 5)
2077                | (SPEC_LONG (type) << 6);
2078         }
2079       
2080       type = type->next;
2081     }  
2082
2083   if (hash<0)
2084     return -hash;
2085   else
2086     return hash;
2087 }
2088
2089 /*-----------------------------------------------------------------------*/
2090 /* dwMatchType - returns true if two types match exactly (including type */
2091 /*               qualifiers)                                             */
2092 /*-----------------------------------------------------------------------*/
2093 static int
2094 dwMatchTypes (const void * type1v, const void * type2v)
2095 {
2096   sym_link * type1 = (sym_link *)type1v;
2097   sym_link * type2 = (sym_link *)type2v;
2098   
2099   if (!type1 || !type2)
2100     return 0;
2101   
2102   while (type1 && type2)
2103     {
2104       if (IS_SPEC(type1))
2105         {
2106           if (IS_SPEC (type2))
2107             {
2108               if (SPEC_NOUN (type1) != SPEC_NOUN (type2))
2109                 return 0;
2110               if (SPEC_NOUN (type1) == V_STRUCT
2111                   && SPEC_STRUCT (type1) != SPEC_STRUCT (type2))
2112                 return 0;
2113               if (SPEC_CONST (type1) != SPEC_CONST (type2))
2114                 return 0;
2115               if (SPEC_VOLATILE (type1) != SPEC_VOLATILE (type2))
2116                 return 0;
2117               if (SPEC_SHORT (type1) != SPEC_SHORT (type2))
2118                 return 0;
2119               if (SPEC_LONG (type1) != SPEC_LONG (type2))
2120                 return 0;
2121               if (SPEC_USIGN (type1) != SPEC_USIGN (type2))
2122                 return 0;
2123             }
2124           else
2125             return 0;
2126         }
2127       else
2128         {
2129           if (IS_DECL (type2))
2130             {
2131               if (DCL_TYPE (type1) != DCL_TYPE (type2))
2132                 return 0;
2133               if (DCL_PTR_CONST (type1) != DCL_PTR_CONST (type2))
2134                 return 0;
2135               if (DCL_PTR_VOLATILE (type1) != DCL_PTR_VOLATILE (type2))
2136                 return 0;
2137               if (DCL_TYPE (type1) == ARRAY
2138                   && DCL_ELEM (type1) != DCL_ELEM (type2))
2139                 return 0;
2140               /* FIXME: need to match function pointer parameters */
2141             }
2142           else
2143             return 0;
2144         }
2145       
2146       type1 = type1->next;
2147       type2 = type2->next;
2148     }
2149
2150   if (!type1 && !type2)
2151     return 1;
2152   else
2153     return 0;
2154 }
2155
2156 /*-----------------------------------------------------------------------*/
2157 /* dwTagFromType - returns the tag describing a type. If new tags need   */
2158 /*                 to be created, they will be added under the specified */
2159 /*                 parent tag                                            */
2160 /*-----------------------------------------------------------------------*/
2161 static dwtag *
2162 dwTagFromType (sym_link * type, dwtag * parent)
2163 {
2164   dwtag * oldtp;
2165   dwtag * tp = NULL;
2166   dwtag * modtp;
2167   dwtag * subtp;
2168   int key;
2169   int tableUpdated = 0;
2170   
2171   key = dwHashType (type) % dwTypeTagTable->size;
2172   oldtp = hTabFindByKey (dwTypeTagTable, key, type, dwMatchTypes);
2173   if (oldtp)
2174     return oldtp;
2175   else
2176     {
2177       if (IS_DECL (type))
2178         {
2179           switch (DCL_TYPE (type))
2180             {
2181             case POINTER:
2182             case FPOINTER:
2183             case CPOINTER:
2184             case GPOINTER:
2185             case PPOINTER:
2186             case IPOINTER:
2187             case EEPPOINTER:
2188             case UPOINTER:
2189               tp = dwNewTag (DW_TAG_pointer_type);
2190               if (type->next && !IS_VOID (type->next))
2191                 {
2192                   subtp = dwTagFromType (type->next, parent);
2193                   dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2194                 }
2195               dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2196                                                 getSize (type)));
2197               dwAddTagChild (parent, tp);
2198               if (DCL_PTR_VOLATILE (type))
2199                 {
2200                   modtp = dwNewTag (DW_TAG_volatile_type);
2201                   dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2202                   dwAddTagChild (parent, modtp);
2203                   tp = modtp;
2204                 }
2205               if (DCL_PTR_CONST (type))
2206                 {
2207                   modtp = dwNewTag (DW_TAG_const_type);
2208                   dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2209                   dwAddTagChild (parent, modtp);
2210                   tp = modtp;
2211                 }
2212               break;
2213               
2214             case ARRAY:
2215               tp = dwNewTag (DW_TAG_array_type);
2216               subtp = dwTagFromType (type->next, parent);
2217               dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2218               if (!subtp->parent)
2219                 dwAddTagChild (tp, subtp);
2220               if (DCL_ELEM (type))
2221                 {
2222                   dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2223                                                     getSize (type)));
2224                   subtp = dwNewTag (DW_TAG_subrange_type);
2225                   dwAddTagAttr (subtp, dwNewAttrConst (DW_AT_upper_bound,
2226                                                        DCL_ELEM (type)-1));
2227                   dwAddTagChild (tp, subtp);
2228                 }
2229
2230               break;
2231             
2232             case FUNCTION:
2233               tp = dwNewTag (DW_TAG_subroutine_type);
2234               if (type->next && !IS_VOID (type->next))
2235                 {
2236                   subtp = dwTagFromType (type->next, parent);
2237                   dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2238                 }
2239               /* FIXME: need to handle function parameters */
2240               break;
2241               
2242             default:
2243               werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2244                       "unknown DCL_TYPE");
2245               exit (1);
2246             }
2247         }
2248       else
2249         {
2250           if (IS_STRUCT (type))
2251             {
2252               struct structdef * sdp = SPEC_STRUCT (type);
2253               symbol * field;
2254               
2255               tp = dwNewTag (sdp->type == STRUCT ? DW_TAG_structure_type
2256                                                  : DW_TAG_union_type);
2257               if (*(sdp->tag))
2258                 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, sdp->tag));
2259               
2260               /* FIXME: should only specify the size if we know this */
2261               /* is a complete type */
2262               dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2263                                                 getSize (type)));
2264               
2265               /* Must add this before processing the struct fields */
2266               /* in case there is a recursive definition.          */
2267               hTabAddItemLong (&dwTypeTagTable, key, type, tp);
2268               tableUpdated = 1;
2269
2270               field = sdp->fields;
2271               while (field)
2272                 {
2273                   dwtag * memtp;
2274                   dwloc * lp;
2275
2276                   if (IS_BITFIELD (field->type) && !SPEC_BLEN(field->type))
2277                     {
2278                       field = field->next;
2279                       continue;
2280                     }
2281
2282                   memtp = dwNewTag (DW_TAG_member);
2283                   if (*(field->name))
2284                     dwAddTagAttr (memtp, dwNewAttrString (DW_AT_name,
2285                                                           field->name));
2286                   if (IS_BITFIELD (field->type))
2287                     {
2288                       int blen = SPEC_BLEN (field->type);
2289                       int bstr = SPEC_BSTR (field->type);
2290                       sym_link * type;
2291                       
2292                       dwAddTagAttr (memtp,
2293                                     dwNewAttrConst (DW_AT_byte_size,
2294                                                     (blen+7)/8));
2295                       dwAddTagAttr (memtp,
2296                                     dwNewAttrConst (DW_AT_bit_size, blen));
2297                       dwAddTagAttr (memtp,
2298                                     dwNewAttrConst (DW_AT_bit_offset,
2299                                                     ((blen+7) & ~7)
2300                                                     - (blen+bstr)));
2301                       if (blen < 8)
2302                         type = typeFromStr ("uc");
2303                       else
2304                         type = typeFromStr ("ui");
2305                       subtp = dwTagFromType (type, tp);
2306                       dwAddTagAttr (memtp, dwNewAttrTagRef (DW_AT_type, subtp));
2307                     }
2308                   else
2309                     {
2310                       subtp = dwTagFromType (field->type, tp);
2311                       dwAddTagAttr (memtp, dwNewAttrTagRef (DW_AT_type, subtp));
2312                       if (!subtp->parent)
2313                         dwAddTagChild (parent, subtp);
2314                     }
2315
2316                   lp = dwNewLoc (DW_OP_plus_uconst, NULL, field->offset);
2317                   dwAddTagAttr (memtp,
2318                                 dwNewAttrLoc (DW_AT_data_member_location, lp));
2319
2320                   dwAddTagChild (tp, memtp);
2321                   
2322                   field = field->next;
2323                 }
2324             }
2325           else if (SPEC_VOLATILE (type) || SPEC_CONST (type))
2326             {
2327               sym_link temptype = *type;
2328               
2329               SPEC_VOLATILE (&temptype) = 0;
2330               SPEC_CONST (&temptype) = 0;
2331               tp = dwTagFromType (&temptype, parent);
2332               if (SPEC_VOLATILE (type))
2333                 {
2334                   modtp = dwNewTag (DW_TAG_volatile_type);
2335                   dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2336                   dwAddTagChild (parent, modtp);
2337                   tp = modtp;
2338                 }
2339               if (SPEC_CONST (type))
2340                 {
2341                   modtp = dwNewTag (DW_TAG_const_type);
2342                   dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2343                   dwAddTagChild (parent, modtp);
2344                   tp = modtp;
2345                 }
2346             }
2347           else
2348             {
2349               switch (SPEC_NOUN (type))
2350                 {
2351                 case V_INT:
2352                   tp = dwNewTag (DW_TAG_base_type);
2353                   if (SPEC_USIGN (type))
2354                     {
2355                       dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2356                                                         DW_ATE_unsigned));
2357                       if (SPEC_LONG (type))
2358                         dwAddTagAttr (tp, dwNewAttrString (DW_AT_name,
2359                                                            "unsigned long"));
2360                       else
2361                         dwAddTagAttr (tp, dwNewAttrString (DW_AT_name,
2362                                                            "unsigned int"));
2363                     }
2364                   else
2365                     {
2366                       dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2367                                                         DW_ATE_signed));
2368                       if (SPEC_LONG (type))
2369                         dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "long"));
2370                       else
2371                         dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "int"));
2372                     }
2373                   dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2374                                                     getSize (type)));
2375                   dwAddTagChild (dwRootTag, tp);
2376                   break;
2377                   
2378                 case V_FLOAT:
2379                   tp = dwNewTag (DW_TAG_base_type);
2380                   dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2381                                                     DW_ATE_float));
2382                   dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "float"));
2383                   dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2384                                                     getSize (type)));
2385                   dwAddTagChild (dwRootTag, tp);
2386                   break;
2387                 
2388                 case V_CHAR:
2389                   tp = dwNewTag (DW_TAG_base_type);
2390                   if (SPEC_USIGN (type))
2391                     {
2392                       dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2393                                                         DW_ATE_unsigned_char));
2394                       dwAddTagAttr (tp, dwNewAttrString (DW_AT_name,
2395                                                          "unsigned char"));
2396                     }
2397                   else
2398                     {
2399                       dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2400                                                         DW_ATE_signed));
2401                       dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "char"));
2402                     }
2403                   dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2404                                                     getSize (type)));
2405                   dwAddTagChild (dwRootTag, tp);
2406                   break;
2407                 
2408                 case V_VOID:
2409                 case V_BIT:
2410                 case V_BITFIELD:
2411                 case V_SBIT:
2412                 case V_DOUBLE:
2413                 default:
2414                   
2415                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2416                       "unhandled base type");
2417                   printTypeChain (type, NULL);
2418                   exit (1);
2419   
2420                 }
2421             }
2422         }
2423     }
2424   
2425   if (!tableUpdated)
2426     hTabAddItemLong (&dwTypeTagTable, key, type, tp);
2427   if (!tp->parent)
2428     dwAddTagChild (parent, tp);
2429   return tp;
2430 }
2431 /*------------------------------------------------------------------------*/
2432
2433
2434 /*-----------------------------------------------------------------------*/
2435 /* dwOpenFile - opens a temporary file for debugging information         */
2436 /*-----------------------------------------------------------------------*/
2437 int dwOpenFile(char *file)
2438 {
2439   dwarf2FilePtr = tempfile();
2440   if(!dwarf2FilePtr) return 0;
2441   
2442   dwTypeTagTable = newHashTable (128);
2443   
2444   return 1;
2445 }
2446
2447 /*-----------------------------------------------------------------------*/
2448 /* dwCloseFile - close (and deletes) the temporary file for debugging    */
2449 /*               information                                             */
2450 /*-----------------------------------------------------------------------*/
2451 int dwCloseFile(void)
2452 {
2453   if(!dwarf2FilePtr) return 0;
2454   
2455   /* Don't explicitly close the file; this will be done automatically */
2456   dwarf2FilePtr = NULL;
2457   
2458   return 1;
2459 }
2460   
2461
2462 /*-----------------------------------------------------------------------*/
2463 /* dwGenerateScopes - recursively traverse an ast, generating lexical    */
2464 /*                    block tags for block scopes found                  */
2465 /*-----------------------------------------------------------------------*/
2466 static void  
2467 dwGenerateScopes (dwtag *tp, ast * tree)
2468 {
2469   dwtag *subtp;
2470
2471   if (!tree)
2472     return;
2473   
2474   if (!IS_AST_OP (tree))
2475     return;
2476       
2477   if (tree->opval.op == BLOCK)
2478     {
2479       subtp = dwNewTag (DW_TAG_lexical_block);
2480       if (tree->right)
2481         {
2482           dwAddTagAttr (subtp, dwNewAttrConst (DW_AT_user_block, tree->right->block));
2483           dwAddTagAttr (subtp, dwNewAttrConst (DW_AT_user_level, tree->right->level));
2484       
2485           dwAddTagChild (tp, subtp);
2486         }
2487       dwGenerateScopes (subtp, tree->right);
2488     }
2489   else
2490     {
2491       dwGenerateScopes (tp, tree->left);
2492       dwGenerateScopes (tp, tree->right);
2493     }
2494 }
2495
2496 /*-----------------------------------------------------------------------*/
2497 /* dwFindScope - return the lexical block tag for a particular block     */
2498 /*               scope, or NULL if not found                             */
2499 /*-----------------------------------------------------------------------*/
2500 static dwtag *
2501 dwFindScope (dwtag * tp, int block)
2502 {
2503   dwtag * rettp;
2504   dwattr * ap;
2505   
2506   if (!tp)
2507     return NULL;
2508   
2509   while (tp)
2510     {
2511       if (tp->tag == DW_TAG_lexical_block)
2512         {
2513           ap = tp->attribs;
2514           while (ap)
2515             {
2516               if (ap->attr == DW_AT_user_block)
2517                 {
2518                   if (ap->val.data == block)
2519                     return tp;
2520                 }
2521               ap = ap->next;
2522             }
2523             
2524           rettp = dwFindScope (tp->firstChild, block);
2525           if (rettp)
2526             return rettp;
2527         }
2528       tp = tp->siblings;
2529     }
2530   
2531   return NULL;  
2532 }
2533
2534 /*------------------------------------------------------------------------*/
2535 /* dwWriteSymbolInternal - create tag information for a variable or       */
2536 /*                         parameter and place it in the correct position */
2537 /*                         within the tag tree                            */
2538 /*------------------------------------------------------------------------*/
2539 static int
2540 dwWriteSymbolInternal (symbol *sym)
2541 {
2542   dwtag * tp;
2543   dwtag * subtp;
2544   dwloc * lp;
2545   dwtag * scopetp;
2546   symbol * symloc;
2547   dwtag * functp;
2548   dwattr * funcap;
2549   int inregs = 0;
2550
2551   if (!sym->level || IS_EXTERN (sym->etype))
2552     scopetp = dwRootTag;
2553   else
2554     {
2555       assert(sym->localof);
2556       if (!sym->localof)
2557         return 0;
2558         
2559       /* Find the tag for the function this symbol is defined in */
2560       functp = dwRootTag->firstChild;
2561       while (functp)
2562         {
2563           if (functp->tag == DW_TAG_subprogram)
2564             {
2565               funcap = dwFindAttr (functp, DW_AT_name);
2566               if (funcap && !strcmp (funcap->val.string, sym->localof->name))
2567                 break;
2568             }
2569           functp = functp->siblings;
2570         }
2571       assert (functp);
2572       if (!functp)
2573         return 0;
2574         
2575       /* Find the correct scope within this function */
2576       scopetp = dwFindScope (functp->firstChild, sym->block);
2577       if (!scopetp)
2578         scopetp = functp;
2579     }
2580   
2581   tp = dwNewTag (sym->_isparm ? DW_TAG_formal_parameter : DW_TAG_variable);
2582   
2583   dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, sym->name));
2584   
2585   /* Find the ultimate symbol holding the value. */
2586   /* Might be:                                   */
2587   /*   a) original symbol,                       */
2588   /*   b) register equivalent,                   */
2589   /*   c) spill location                         */
2590   symloc = sym;
2591   if (!sym->allocreq && sym->reqv)
2592     {
2593       symloc = OP_SYMBOL (symloc->reqv);
2594       if (symloc->isspilt && !symloc->remat)
2595         symloc = symloc->usl.spillLoc;
2596       else
2597         inregs = 1;
2598     }
2599   
2600   lp = NULL;
2601   if (inregs && symloc->regs[0])
2602     {
2603       dwloc * reglp;
2604       dwloc * lastlp = NULL;
2605       int regNum;
2606       int i;
2607       
2608       /* register allocation */
2609       for (i = (port->little_endian ? 0 : symloc->nRegs-1);
2610            (port->little_endian ? (i < symloc->nRegs) : (i >= 0));
2611            (port->little_endian ? i++ : i--))
2612         {
2613           regNum = port->debugger.dwarf.regNum (symloc->regs[i]);
2614           if (regNum >= 0 && regNum <= 31)
2615             reglp = dwNewLoc (DW_OP_reg0 + regNum, NULL, 0);
2616           else if (regNum >= 0)
2617             reglp = dwNewLoc (DW_OP_regx, NULL, regNum);
2618           else
2619             {
2620               /* We are forced to give up if the ABI for this port */
2621               /* does not define a number for this register        */
2622               lp = NULL;
2623               break;
2624             }
2625           
2626           if (lastlp)
2627             lastlp->next = reglp;
2628           else
2629             lp = reglp;
2630           lastlp = reglp;
2631           
2632           if (symloc->nRegs != 1)
2633             {
2634               reglp = dwNewLoc (DW_OP_piece, NULL, 1);
2635               lastlp->next = reglp;
2636               lastlp = reglp;
2637             }
2638         }
2639     }
2640   else if (symloc->onStack)
2641     {
2642       /* stack allocation */
2643       lp = dwNewLoc (DW_OP_fbreg, NULL, symloc->stack);
2644     }
2645   else
2646     {
2647       /* global allocation */
2648       if (sym->level && !sym->allocreq)
2649         lp = NULL;
2650       else
2651         lp = dwNewLoc (DW_OP_addr, symloc->rname, 0);
2652     }
2653
2654   /* Only create the DW_AT_location if a known location exists.   */
2655   /* It might not exist if the variable has been optimized away   */
2656   /* or if the compiler has lost track of it (not good, but still */
2657   /* happens sometimes -- need to improve induction)              */
2658   if (lp)
2659     dwAddTagAttr (tp, dwNewAttrLoc (DW_AT_location, lp));
2660   
2661   if (!IS_STATIC (sym->etype) && !sym->level)
2662     dwAddTagAttr (tp, dwNewAttrFlag (DW_AT_external, 1));
2663   if (IS_EXTERN (sym->etype))
2664     dwAddTagAttr (tp, dwNewAttrFlag (DW_AT_declaration, 1));
2665   
2666   subtp = dwTagFromType (sym->type, scopetp);
2667   dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2668   if (!subtp->parent)
2669     dwAddTagChild (scopetp, subtp);
2670   
2671   dwAddTagChild (scopetp, tp);
2672   return 1;
2673 }
2674  
2675
2676 /*-----------------------------------------------------------------------*/
2677 /* dwWriteFunction - generate a tag for a function.                      */
2678 /*-----------------------------------------------------------------------*/
2679 int dwWriteFunction(symbol *sym, iCode *ic)
2680 {
2681   dwtag * tp;
2682   value * args;
2683     
2684   if(!dwarf2FilePtr) return 0;
2685   
2686   dwFuncTag = tp = dwNewTag (DW_TAG_subprogram);
2687   
2688   dwAddTagAttr (dwFuncTag, dwNewAttrString (DW_AT_name, sym->name));
2689   
2690   dwAddTagAttr (dwFuncTag, dwNewAttrAddrSymbol (DW_AT_low_pc, sym, 0));
2691   
2692   if (FUNC_ISISR (sym->type))
2693     dwAddTagAttr (dwFuncTag, dwNewAttrConst (DW_AT_calling_convention,
2694                                               DW_CC_nocall));
2695   
2696   dwAddTagAttr (dwFuncTag, dwNewAttrFlag (DW_AT_external, 
2697                                            !IS_STATIC (sym->etype)));
2698
2699   if (sym->type->next && !IS_VOID (sym->type->next))
2700     {
2701       dwtag * subtp;
2702
2703       subtp = dwTagFromType (sym->type->next, dwRootTag);
2704       dwAddTagAttr (dwFuncTag, dwNewAttrTagRef (DW_AT_type, subtp));
2705     }
2706   dwAddTagChild (dwRootTag, dwFuncTag);
2707   
2708   args = FUNC_ARGS(sym->type);
2709   while (args)
2710     {
2711       dwWriteSymbolInternal (args->sym);
2712       args = args->next;
2713     }
2714   if (FUNC_HASVARARGS (sym->type))
2715     {
2716       dwAddTagChild (dwFuncTag, dwNewTag (DW_TAG_unspecified_parameters));
2717     }
2718   
2719   while (ic && ic->op != FUNCTION)
2720     ic = ic->next;
2721   if (ic && ic->op == FUNCTION && ic->tree && ic->tree->right)
2722     {
2723       dwGenerateScopes (dwFuncTag, ic->tree->right->left);
2724       dwGenerateScopes (dwFuncTag, ic->tree->right->right);
2725     }
2726   
2727   dwScopeTag = NULL;
2728   dwScopeLevel = 0;
2729   
2730   return 1;
2731 }
2732
2733
2734 /*-----------------------------------------------------------------------*/
2735 /* dwWriteEndFunction - write attributes to the current function tag     */
2736 /*                      that are only known after code generation is     */
2737 /*                      complete                                         */
2738 /*-----------------------------------------------------------------------*/
2739 int dwWriteEndFunction(symbol *sym, iCode *ic, int offset)
2740 {
2741   char debugSym[SDCC_NAME_MAX];
2742   
2743   if (ic)
2744     {
2745       dwWriteCLine (ic);
2746       dwLineLast->offset += offset;
2747       dwLineLast->end_sequence = 1;
2748     }
2749
2750   if (IS_STATIC (sym->etype))
2751     sprintf (debugSym, "XF%s$%s$0$0", dwModuleName, sym->name);
2752   else
2753     sprintf (debugSym, "XG$%s$0$0", sym->name);
2754   emitDebuggerSymbol (debugSym);
2755       
2756   dwAddTagAttr (dwFuncTag, dwNewAttrAddrLabel (DW_AT_high_pc,
2757                                                Safe_strdup(debugSym),
2758                                                offset));
2759   
2760   if (dwFrameLocList)
2761     {
2762       dwAddTagAttr (dwFuncTag, dwNewAttrLocRef (DW_AT_frame_base,
2763                                                 dwFrameLocList));
2764       
2765       dwFrameLocList->next = dwRootLocList;
2766       dwRootLocList = dwFrameLocList;
2767       dwFrameLocList = NULL;
2768     }
2769     
2770   return 1;
2771 }
2772
2773
2774 /*-----------------------------------------------------------------------*/
2775 /* dwWriteLabel - generate a tag for a source level label                */
2776 /*-----------------------------------------------------------------------*/
2777 int dwWriteLabel(symbol *sym, iCode *ic)
2778 {
2779   char debugSym[SDCC_NAME_MAX];
2780   dwtag * tp;
2781   
2782   /* ignore the compiler generated labels */
2783   if (sym->isitmp)
2784     return 1;
2785
2786   sprintf (debugSym, "L%s$%s$%s", dwModuleName, currFunc->name, sym->name);
2787   emitDebuggerSymbol (debugSym);
2788
2789   tp = dwNewTag (DW_TAG_label);
2790   dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, sym->name));
2791   dwAddTagAttr (tp, dwNewAttrAddrLabel (DW_AT_low_pc,
2792                                         Safe_strdup (debugSym), 0));
2793
2794   dwAddTagChild (dwFuncTag, tp);
2795   
2796   return 1;
2797 }
2798
2799
2800 /*-----------------------------------------------------------------------*/
2801 /* dwWriteScope - add the starting and ending address attributes to a    */
2802 /*                a lexical block tag (created during dwWriteFunction)   */
2803 /*-----------------------------------------------------------------------*/
2804 int dwWriteScope(iCode *ic)
2805 {
2806   char * debugSym = NULL;
2807   dwtag * scopetp;
2808   dwattr * ap;
2809   
2810   scopetp = dwFindScope (dwFuncTag->firstChild, ic->block);
2811   
2812   if (dwScopeTag && ic->level <= dwScopeLevel)
2813     {
2814       debugSym = dwNewDebugSymbol ();
2815       emitDebuggerSymbol (debugSym);
2816       dwSetTagAttr (dwScopeTag, dwNewAttrAddrLabel (DW_AT_high_pc, debugSym, 0));
2817                                                     
2818       dwScopeTag = scopetp;
2819       dwScopeLevel = ic->level;
2820     }
2821   if (scopetp)
2822     {
2823       ap = dwFindAttr (scopetp, DW_AT_low_pc);
2824       if (ap)
2825         return 1;
2826       
2827       if (!debugSym)
2828         debugSym = dwNewDebugSymbol ();
2829       emitDebuggerSymbol (debugSym);
2830       dwAddTagAttr (scopetp, dwNewAttrAddrLabel (DW_AT_low_pc, debugSym, 0));
2831                                                  
2832       dwScopeTag = scopetp;
2833       dwScopeLevel = ic->level;
2834     }
2835   
2836   return 1;
2837 }
2838
2839 /*-----------------------------------------------------------------------*/
2840 /* dwWriteSymbol - generate tags for global variables. This is actually  */
2841 /*                 called for all variables and parameters, but we       */
2842 /*                 process the non-global variables elsewhere.           */
2843 /*-----------------------------------------------------------------------*/
2844 int dwWriteSymbol(symbol *sym)
2845 {
2846   if (IS_FUNC (sym->type))
2847     return 1;
2848
2849   /* If it is an iTemp, then it is not a C source symbol; ignore it */
2850   if (sym->isitmp)
2851     return 1;
2852
2853   /* Ignore parameters; they must be handled specially so that they will */
2854   /* appear in the correct order */
2855   if (sym->_isparm)
2856     return 1;
2857     
2858   return dwWriteSymbolInternal (sym);
2859 }
2860
2861
2862 /*-----------------------------------------------------------------------*/
2863 /* dwWriteType                                                           */
2864 /*-----------------------------------------------------------------------*/
2865 int dwWriteType(structdef *sdef, int block, int inStruct, char *tag)
2866 {
2867   /* FIXME: needs implementation */
2868   return 1;
2869 }
2870
2871
2872 /*-----------------------------------------------------------------------*/
2873 /* dwWriteModule - generates the root tag for this compilation unit      */
2874 /*-----------------------------------------------------------------------*/
2875 int dwWriteModule(char *name)
2876 {
2877   dwtag * tp;
2878   char * s;
2879   
2880   if(!dwarf2FilePtr) return 0;
2881   
2882   dwModuleName = Safe_strdup (name);
2883   for (s = dwModuleName; *s; s++)
2884     if (ispunct (*s) || isspace (*s))
2885       *s = '_';
2886     
2887   tp = dwNewTag (DW_TAG_compile_unit);
2888   dwAddTagAttr (tp, dwNewAttrString (DW_AT_producer, "SDCC version "
2889                                              SDCC_VERSION_STR));
2890   dwAddTagAttr (tp, dwNewAttrConst (DW_AT_language, DW_LANG_C89));
2891
2892   dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, fullSrcFileName));
2893
2894   dwAddTagAttr (tp, dwNewAttrLabelRef (DW_AT_stmt_list,
2895                                        "Ldebug_line_start", -4));
2896
2897   dwRootTag = tp;
2898   
2899   return 1;
2900 }
2901
2902
2903 /*-----------------------------------------------------------------------*/
2904 /* dwWriteCLine - generates a line number/position to address record for */
2905 /*                C source                                               */
2906 /*-----------------------------------------------------------------------*/
2907 int dwWriteCLine(iCode *ic)
2908 {
2909   dwline * lp;
2910   char * debugSym;
2911   
2912   if(!dwarf2FilePtr) return 0;
2913
2914   lp = Safe_alloc (sizeof (dwline));
2915
2916   lp->line = ic->lineno;
2917   
2918   debugSym = dwNewDebugSymbol ();
2919   emitDebuggerSymbol (debugSym);
2920   lp->label = debugSym;
2921   lp->offset = 0;
2922
2923   lp->fileIndex = dwFindFileIndex (ic->filename);
2924
2925   if (!dwLineFirst)
2926     dwLineFirst = lp;
2927   else
2928     dwLineLast->next = lp;
2929   dwLineLast = lp;
2930   
2931   return 1;
2932 }
2933
2934
2935 /*-----------------------------------------------------------------------*/
2936 /* dwWriteFrameAddress - note the current position of the frame pointer  */
2937 /*                       address. The base address can be specified by   */
2938 /*                       either a register or pointer variable, leaving  */
2939 /*                       the other as NULL. If both are NULL, there is   */
2940 /*                       no current frame pointer address defined.       */
2941 /*-----------------------------------------------------------------------*/
2942 int
2943 dwWriteFrameAddress(char *variable, struct regs *reg, int offset)
2944 {
2945   char * debugSym = NULL;
2946   dwlocregion * lrp;
2947   dwloc * lp;
2948   int regNum;
2949     
2950   if(!dwarf2FilePtr) return 0;
2951
2952   /* If there was a region open, close it */
2953   if (dwFrameLastLoc)
2954     {
2955       debugSym = dwNewDebugSymbol ();
2956       emitDebuggerSymbol (debugSym);
2957       
2958       dwFrameLastLoc->endLabel = debugSym;
2959       dwFrameLastLoc = NULL;
2960     }
2961
2962   if (!variable && !reg)
2963     return 1;
2964
2965   /* Create a new debugger symbol for the start of the region if */
2966   /* we can't recycle the symbol at the end of the previous      */
2967   if (!debugSym)
2968     {
2969       debugSym = dwNewDebugSymbol ();
2970       emitDebuggerSymbol (debugSym);
2971     }
2972
2973   lrp = Safe_alloc (sizeof (dwlocregion));
2974   lrp->startLabel = debugSym;
2975
2976   if (variable)         /* frame pointer based from a global variable */
2977     {
2978       dwloc * lp;
2979
2980       lrp->loc = dwNewLoc (DW_OP_addr, variable, 0);
2981       lrp->loc->next = lp = dwNewLoc (DW_OP_deref_size, NULL, PTRSIZE);
2982       if (offset)
2983         {
2984           lp->next = dwNewLoc (DW_OP_consts, NULL, offset);
2985           lp->next->next = dwNewLoc (DW_OP_plus, NULL, 0);
2986         }
2987     }
2988   else if (reg)         /* frame pointer based from a register */
2989     {
2990       regNum = port->debugger.dwarf.regNum (reg);
2991       assert (regNum>=0);
2992       
2993       if (regNum>=0 && regNum<=31)
2994         {
2995           if (offset)
2996             lrp->loc = dwNewLoc (DW_OP_breg0 + regNum, NULL, offset);
2997           else
2998             lrp->loc = dwNewLoc (DW_OP_reg0 + regNum, NULL, 0);
2999         }
3000       else
3001         {
3002           lrp->loc = lp = dwNewLoc (DW_OP_regx, NULL, regNum);
3003           if (offset)
3004             {
3005               lp->next = dwNewLoc (DW_OP_consts, NULL, offset);
3006               lp->next->next = dwNewLoc (DW_OP_plus, NULL, 0);
3007             }
3008         }
3009     }
3010   dwFrameLastLoc = lrp;
3011   
3012   if (!dwFrameLocList)
3013     dwFrameLocList = dwNewLocList();
3014   lrp->next = dwFrameLocList->region;
3015   dwFrameLocList->region = lrp;
3016   
3017   return 1;
3018 }
3019
3020
3021 /*-----------------------------------------------------------------------*/
3022 /* dwWriteALine - generates a line number/position to address record for */
3023 /*                assembly source                                        */
3024 /*-----------------------------------------------------------------------*/
3025 int dwWriteALine(char *module, int Line)
3026 {
3027   if(!dwarf2FilePtr) return 0;
3028   
3029   return 1;
3030 }
3031
3032
3033
3034
3035 /*-----------------------------------------------------------------------*/
3036 /* dwarf2FinalizeFile - write all of the DWARF debugging data to the     */
3037 /*                      debug file                                       */
3038 /*-----------------------------------------------------------------------*/
3039 int
3040 dwarf2FinalizeFile(void)
3041 {
3042   int tagAddress = 11;
3043   int abbrevNum = 0;
3044   int attr;
3045   
3046   if(!dwarf2FilePtr) return 1;
3047
3048   /* Write the .debug_line section */
3049   dwWriteLineNumbers ();
3050  
3051   /* Assign the location list addresses (for cross references) */
3052   dwAssignLocListAddresses ();
3053   
3054   /* Write the .debug_loc section */
3055   dwWriteLocLists ();
3056
3057   /* Delete our scope related user attributes; they were only needed to help */
3058   /* build the tag tree and have no meaning to (and may confuse) debuggers   */
3059   attr = DW_AT_user_block;
3060   dwTraverseTag (dwRootTag, dwDeleteTagAttr, &attr);
3061   attr = DW_AT_user_level;
3062   dwTraverseTag (dwRootTag, dwDeleteTagAttr, &attr);
3063   
3064   /* Add a DW_AT_sibling attribute to all tags with children and siblings */
3065   dwTraverseTag (dwRootTag, dwAddSibAttr, NULL);
3066
3067   /* Assign the tag abbreviations. The tags, attributes, and forms must   */
3068   /* not change after this point. The attribute values may change as long */
3069   /* as the size of the value does not.                                   */
3070   dwAbbrevTable = newHashTable (128);
3071   dwTraverseTag (dwRootTag, dwAssignAbbrev, &abbrevNum);
3072   
3073   /* Assign the tag addresses (for cross references) */
3074   dwTraverseTag (dwRootTag, dwAssignTagAddress, &tagAddress);
3075   
3076   /* Write the .debug_abbrev section */
3077   dwWriteAbbrevs ();  
3078   
3079   /* Write the .debug_info section */
3080   dwWriteTags ();
3081
3082   /* Write the .debug_pubnames section */
3083   dwWritePubnames ();
3084   
3085   return 1;
3086 }