* src/SDCCdwarf2.c (dwMatchTypes): structs must have matching
[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       dwWriteULEB128 (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           dwWriteULEB128 (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                   memtp = dwNewTag (DW_TAG_member);
2277                   if (*(field->name))
2278                     dwAddTagAttr (memtp, dwNewAttrString (DW_AT_name,
2279                                                           field->name));
2280                   subtp = dwTagFromType (field->type, tp);
2281                   dwAddTagAttr (memtp, dwNewAttrTagRef (DW_AT_type, subtp));
2282                   if (!subtp->parent)
2283                     dwAddTagChild (parent, subtp);
2284
2285                   lp = dwNewLoc (DW_OP_plus_uconst, NULL, field->offset);
2286                   dwAddTagAttr (memtp,
2287                                 dwNewAttrLoc (DW_AT_data_member_location, lp));
2288
2289                   dwAddTagChild (tp, memtp);
2290                   
2291                   field = field->next;
2292                 }
2293             }
2294           else if (SPEC_VOLATILE (type) || SPEC_CONST (type))
2295             {
2296               sym_link temptype = *type;
2297               
2298               SPEC_VOLATILE (&temptype) = 0;
2299               SPEC_CONST (&temptype) = 0;
2300               tp = dwTagFromType (&temptype, parent);
2301               if (SPEC_VOLATILE (type))
2302                 {
2303                   modtp = dwNewTag (DW_TAG_volatile_type);
2304                   dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2305                   dwAddTagChild (parent, modtp);
2306                   tp = modtp;
2307                 }
2308               if (SPEC_CONST (type))
2309                 {
2310                   modtp = dwNewTag (DW_TAG_const_type);
2311                   dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2312                   dwAddTagChild (parent, modtp);
2313                   tp = modtp;
2314                 }
2315             }
2316           else
2317             {
2318               switch (SPEC_NOUN (type))
2319                 {
2320                 case V_INT:
2321                   tp = dwNewTag (DW_TAG_base_type);
2322                   if (SPEC_USIGN (type))
2323                     {
2324                       dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2325                                                         DW_ATE_unsigned));
2326                       if (SPEC_LONG (type))
2327                         dwAddTagAttr (tp, dwNewAttrString (DW_AT_name,
2328                                                            "unsigned long"));
2329                       else
2330                         dwAddTagAttr (tp, dwNewAttrString (DW_AT_name,
2331                                                            "unsigned int"));
2332                     }
2333                   else
2334                     {
2335                       dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2336                                                         DW_ATE_signed));
2337                       if (SPEC_LONG (type))
2338                         dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "long"));
2339                       else
2340                         dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "int"));
2341                     }
2342                   dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2343                                                     getSize (type)));
2344                   dwAddTagChild (dwRootTag, tp);
2345                   break;
2346                   
2347                 case V_FLOAT:
2348                   tp = dwNewTag (DW_TAG_base_type);
2349                   dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2350                                                     DW_ATE_float));
2351                   dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "float"));
2352                   dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2353                                                     getSize (type)));
2354                   dwAddTagChild (dwRootTag, tp);
2355                   break;
2356                 
2357                 case V_CHAR:
2358                   tp = dwNewTag (DW_TAG_base_type);
2359                   if (SPEC_USIGN (type))
2360                     {
2361                       dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2362                                                         DW_ATE_unsigned_char));
2363                       dwAddTagAttr (tp, dwNewAttrString (DW_AT_name,
2364                                                          "unsigned char"));
2365                     }
2366                   else
2367                     {
2368                       dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2369                                                         DW_ATE_signed));
2370                       dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "char"));
2371                     }
2372                   dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2373                                                     getSize (type)));
2374                   dwAddTagChild (dwRootTag, tp);
2375                   break;
2376                 
2377                 case V_VOID:
2378                 case V_BIT:
2379                 case V_BITFIELD:
2380                 case V_SBIT:
2381                 case V_DOUBLE:
2382                 default:
2383                   
2384                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2385                       "unhandled base type");
2386                   printTypeChain (type, NULL);
2387                   exit (1);
2388   
2389                 }
2390             }
2391         }
2392     }
2393   
2394   if (!tableUpdated)
2395     hTabAddItemLong (&dwTypeTagTable, key, type, tp);
2396   if (!tp->parent)
2397     dwAddTagChild (parent, tp);
2398   return tp;
2399 }
2400 /*------------------------------------------------------------------------*/
2401
2402
2403 /*-----------------------------------------------------------------------*/
2404 /* dwOpenFile - opens a temporary file for debugging information         */
2405 /*-----------------------------------------------------------------------*/
2406 int dwOpenFile(char *file)
2407 {
2408   dwarf2FilePtr = tempfile();
2409   if(!dwarf2FilePtr) return 0;
2410   
2411   dwTypeTagTable = newHashTable (128);
2412   
2413   return 1;
2414 }
2415
2416 /*-----------------------------------------------------------------------*/
2417 /* dwCloseFile - close (and deletes) the temporary file for debugging    */
2418 /*               information                                             */
2419 /*-----------------------------------------------------------------------*/
2420 int dwCloseFile(void)
2421 {
2422   if(!dwarf2FilePtr) return 0;
2423   
2424   fclose(dwarf2FilePtr);
2425   
2426   return 1;
2427 }
2428   
2429
2430 /*-----------------------------------------------------------------------*/
2431 /* dwGenerateScopes - recursively traverse an ast, generating lexical    */
2432 /*                    block tags for block scopes found                  */
2433 /*-----------------------------------------------------------------------*/
2434 static void  
2435 dwGenerateScopes (dwtag *tp, ast * tree)
2436 {
2437   dwtag *subtp;
2438
2439   if (!tree)
2440     return;
2441   
2442   if (!IS_AST_OP (tree))
2443     return;
2444       
2445   if (tree->opval.op == BLOCK)
2446     {
2447       subtp = dwNewTag (DW_TAG_lexical_block);
2448       if (tree->right)
2449         {
2450           dwAddTagAttr (subtp, dwNewAttrConst (DW_AT_user_block, tree->right->block));
2451           dwAddTagAttr (subtp, dwNewAttrConst (DW_AT_user_level, tree->right->level));
2452       
2453           dwAddTagChild (tp, subtp);
2454         }
2455       dwGenerateScopes (subtp, tree->right);
2456     }
2457   else
2458     {
2459       dwGenerateScopes (tp, tree->left);
2460       dwGenerateScopes (tp, tree->right);
2461     }
2462 }
2463
2464 /*-----------------------------------------------------------------------*/
2465 /* dwFindScope - return the lexical block tag for a particular block     */
2466 /*               scope, or NULL if not found                             */
2467 /*-----------------------------------------------------------------------*/
2468 static dwtag *
2469 dwFindScope (dwtag * tp, int block)
2470 {
2471   dwtag * rettp;
2472   dwattr * ap;
2473   
2474   if (!tp)
2475     return NULL;
2476   
2477   while (tp)
2478     {
2479       if (tp->tag == DW_TAG_lexical_block)
2480         {
2481           ap = tp->attribs;
2482           while (ap)
2483             {
2484               if (ap->attr == DW_AT_user_block)
2485                 {
2486                   if (ap->val.data == block)
2487                     return tp;
2488                 }
2489               ap = ap->next;
2490             }
2491             
2492           rettp = dwFindScope (tp->firstChild, block);
2493           if (rettp)
2494             return rettp;
2495         }
2496       tp = tp->siblings;
2497     }
2498   
2499   return NULL;  
2500 }
2501
2502 /*------------------------------------------------------------------------*/
2503 /* dwWriteSymbolInternal - create tag information for a variable or       */
2504 /*                         parameter and place it in the correct position */
2505 /*                         within the tag tree                            */
2506 /*------------------------------------------------------------------------*/
2507 static int
2508 dwWriteSymbolInternal (symbol *sym)
2509 {
2510   dwtag * tp;
2511   dwtag * subtp;
2512   dwloc * lp;
2513   dwtag * scopetp;
2514   symbol * symloc;
2515   dwtag * functp;
2516   dwattr * funcap;
2517   int inregs = 0;
2518
2519   if (!sym->level)
2520     scopetp = dwRootTag;
2521   else
2522     {
2523       assert(sym->localof);
2524       if (!sym->localof)
2525         return 0;
2526         
2527       /* Find the tag for the function this symbol is defined in */
2528       functp = dwRootTag->firstChild;
2529       while (functp)
2530         {
2531           if (functp->tag == DW_TAG_subprogram)
2532             {
2533               funcap = dwFindAttr (functp, DW_AT_name);
2534               if (funcap && !strcmp (funcap->val.string, sym->localof->name))
2535                 break;
2536             }
2537           functp = functp->siblings;
2538         }
2539       assert (functp);
2540       if (!functp)
2541         return 0;
2542         
2543       /* Find the correct scope within this function */
2544       scopetp = dwFindScope (functp->firstChild, sym->block);
2545       if (!scopetp)
2546         scopetp = functp;
2547     }
2548   
2549   tp = dwNewTag (sym->_isparm ? DW_TAG_formal_parameter : DW_TAG_variable);
2550   
2551   dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, sym->name));
2552   
2553   /* Find the ultimate symbol holding the value. */
2554   /* Might be:                                   */
2555   /*   a) original symbol,                       */
2556   /*   b) register equivalent,                   */
2557   /*   c) spill location                         */
2558   symloc = sym;
2559   if (!sym->allocreq && sym->reqv)
2560     {
2561       symloc = OP_SYMBOL (symloc->reqv);
2562       if (symloc->isspilt && !symloc->remat)
2563         symloc = symloc->usl.spillLoc;
2564       else
2565         inregs = 1;
2566     }
2567   
2568   lp = NULL;
2569   if (inregs && symloc->regs[0])
2570     {
2571       dwloc * reglp;
2572       dwloc * lastlp = NULL;
2573       int regNum;
2574       int i;
2575       
2576       /* register allocation */
2577       for (i = (port->little_endian ? 0 : symloc->nRegs-1);
2578            (port->little_endian ? (i < symloc->nRegs) : (i >= 0));
2579            (port->little_endian ? i++ : i--))
2580         {
2581           regNum = port->debugger.dwarf.regNum (symloc->regs[i]);
2582           if (regNum >= 0 && regNum <= 31)
2583             reglp = dwNewLoc (DW_OP_reg0 + regNum, NULL, 0);
2584           else if (regNum >= 0)
2585             reglp = dwNewLoc (DW_OP_regx, NULL, regNum);
2586           else
2587             {
2588               /* We are forced to give up if the ABI for this port */
2589               /* does not define a number for this register        */
2590               lp = NULL;
2591               break;
2592             }
2593           
2594           if (lastlp)
2595             lastlp->next = reglp;
2596           else
2597             lp = reglp;
2598           lastlp = reglp;
2599           
2600           if (symloc->nRegs != 1)
2601             {
2602               reglp = dwNewLoc (DW_OP_piece, NULL, 1);
2603               lastlp->next = reglp;
2604               lastlp = reglp;
2605             }
2606         }
2607     }
2608   else if (symloc->onStack)
2609     {
2610       /* stack allocation */
2611       lp = dwNewLoc (DW_OP_fbreg, NULL, symloc->stack);
2612     }
2613   else
2614     {
2615       /* global allocation */
2616       if (sym->level && !sym->allocreq)
2617         lp = NULL;
2618       else
2619         lp = dwNewLoc (DW_OP_addr, symloc->rname, 0);
2620     }
2621
2622   /* Only create the DW_AT_location if a known location exists.   */
2623   /* It might not exist if the variable has been optimized away   */
2624   /* or if the compiler has lost track of it (not good, but still */
2625   /* happens sometimes -- need to improve induction)              */
2626   if (lp)
2627     dwAddTagAttr (tp, dwNewAttrLoc (DW_AT_location, lp));
2628   
2629   if (!IS_STATIC (sym->etype) && !sym->level)
2630     dwAddTagAttr (tp, dwNewAttrFlag (DW_AT_external, 1));
2631   if (IS_EXTERN (sym->etype))
2632     dwAddTagAttr (tp, dwNewAttrFlag (DW_AT_declaration, 1));
2633   
2634   subtp = dwTagFromType (sym->type, scopetp);
2635   dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2636   if (!subtp->parent)
2637     dwAddTagChild (scopetp, subtp);
2638   
2639   dwAddTagChild (scopetp, tp);
2640   return 1;
2641 }
2642  
2643
2644 /*-----------------------------------------------------------------------*/
2645 /* dwWriteFunction - generate a tag for a function.                      */
2646 /*-----------------------------------------------------------------------*/
2647 int dwWriteFunction(symbol *sym, iCode *ic)
2648 {
2649   dwtag * tp;
2650   value * args;
2651     
2652   if(!dwarf2FilePtr) return 0;
2653   
2654   dwFuncTag = tp = dwNewTag (DW_TAG_subprogram);
2655   
2656   dwAddTagAttr (dwFuncTag, dwNewAttrString (DW_AT_name, sym->name));
2657   
2658   dwAddTagAttr (dwFuncTag, dwNewAttrAddrSymbol (DW_AT_low_pc, sym, 0));
2659   
2660   if (FUNC_ISISR (sym->type))
2661     dwAddTagAttr (dwFuncTag, dwNewAttrConst (DW_AT_calling_convention,
2662                                               DW_CC_nocall));
2663   
2664   dwAddTagAttr (dwFuncTag, dwNewAttrFlag (DW_AT_external, 
2665                                            !IS_STATIC (sym->etype)));
2666
2667   if (sym->type->next && !IS_VOID (sym->type->next))
2668     {
2669       dwtag * subtp;
2670
2671       subtp = dwTagFromType (sym->type->next, dwRootTag);
2672       dwAddTagAttr (dwFuncTag, dwNewAttrTagRef (DW_AT_type, subtp));
2673     }
2674   dwAddTagChild (dwRootTag, dwFuncTag);
2675   
2676   args = FUNC_ARGS(sym->type);
2677   while (args)
2678     {
2679       dwWriteSymbolInternal (args->sym);
2680       args = args->next;
2681     }
2682   if (FUNC_HASVARARGS (sym->type))
2683     {
2684       dwAddTagChild (dwFuncTag, dwNewTag (DW_TAG_unspecified_parameters));
2685     }
2686   
2687   while (ic && ic->op != FUNCTION)
2688     ic = ic->next;
2689   if (ic && ic->op == FUNCTION && ic->tree && ic->tree->right)
2690     {
2691       dwGenerateScopes (dwFuncTag, ic->tree->right->left);
2692       dwGenerateScopes (dwFuncTag, ic->tree->right->right);
2693     }
2694   
2695   dwScopeTag = NULL;
2696   dwScopeLevel = 0;
2697   
2698   return 1;
2699 }
2700
2701
2702 /*-----------------------------------------------------------------------*/
2703 /* dwWriteEndFunction - write attributes to the current function tag     */
2704 /*                      that are only known after code generation is     */
2705 /*                      complete                                         */
2706 /*-----------------------------------------------------------------------*/
2707 int dwWriteEndFunction(symbol *sym, iCode *ic, int offset)
2708 {
2709   char debugSym[SDCC_NAME_MAX];
2710   
2711   if (ic)
2712     {
2713       dwWriteCLine (ic);
2714       dwLineLast->offset += offset;
2715       dwLineLast->end_sequence = 1;
2716     }
2717
2718   if (IS_STATIC (sym->etype))
2719     sprintf (debugSym, "XF%s$%s$0$0", dwModuleName, sym->name);
2720   else
2721     sprintf (debugSym, "XG$%s$0$0", sym->name);
2722   emitDebuggerSymbol (debugSym);
2723       
2724   dwAddTagAttr (dwFuncTag, dwNewAttrAddrLabel (DW_AT_high_pc,
2725                                                Safe_strdup(debugSym),
2726                                                offset));
2727   
2728   if (dwFrameLocList)
2729     {
2730       dwAddTagAttr (dwFuncTag, dwNewAttrLocRef (DW_AT_frame_base,
2731                                                 dwFrameLocList));
2732       
2733       dwFrameLocList->next = dwRootLocList;
2734       dwRootLocList = dwFrameLocList;
2735       dwFrameLocList = NULL;
2736     }
2737     
2738   return 1;
2739 }
2740
2741
2742 /*-----------------------------------------------------------------------*/
2743 /* dwWriteLabel - generate a tag for a source level label                */
2744 /*-----------------------------------------------------------------------*/
2745 int dwWriteLabel(symbol *sym, iCode *ic)
2746 {
2747   char debugSym[SDCC_NAME_MAX];
2748   dwtag * tp;
2749   
2750   /* ignore the compiler generated labels */
2751   if (sym->isitmp)
2752     return 1;
2753
2754   sprintf (debugSym, "L%s$%s$%s", dwModuleName, currFunc->name, sym->name);
2755   emitDebuggerSymbol (debugSym);
2756
2757   tp = dwNewTag (DW_TAG_label);
2758   dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, sym->name));
2759   dwAddTagAttr (tp, dwNewAttrAddrLabel (DW_AT_low_pc,
2760                                         Safe_strdup (debugSym), 0));
2761
2762   dwAddTagChild (dwFuncTag, tp);
2763   
2764   return 1;
2765 }
2766
2767
2768 /*-----------------------------------------------------------------------*/
2769 /* dwWriteScope - add the starting and ending address attributes to a    */
2770 /*                a lexical block tag (created during dwWriteFunction)   */
2771 /*-----------------------------------------------------------------------*/
2772 int dwWriteScope(iCode *ic)
2773 {
2774   char * debugSym = NULL;
2775   dwtag * scopetp;
2776   dwattr * ap;
2777   
2778   scopetp = dwFindScope (dwFuncTag->firstChild, ic->block);
2779   
2780   if (dwScopeTag && ic->level <= dwScopeLevel)
2781     {
2782       debugSym = dwNewDebugSymbol ();
2783       emitDebuggerSymbol (debugSym);
2784       dwSetTagAttr (dwScopeTag, dwNewAttrAddrLabel (DW_AT_high_pc, debugSym, 0));
2785                                                     
2786       dwScopeTag = scopetp;
2787       dwScopeLevel = ic->level;
2788     }
2789   if (scopetp)
2790     {
2791       ap = dwFindAttr (scopetp, DW_AT_low_pc);
2792       if (ap)
2793         return 1;
2794       
2795       if (!debugSym)
2796         debugSym = dwNewDebugSymbol ();
2797       emitDebuggerSymbol (debugSym);
2798       dwAddTagAttr (scopetp, dwNewAttrAddrLabel (DW_AT_low_pc, debugSym, 0));
2799                                                  
2800       dwScopeTag = scopetp;
2801       dwScopeLevel = ic->level;
2802     }
2803   
2804   return 1;
2805 }
2806
2807 /*-----------------------------------------------------------------------*/
2808 /* dwWriteSymbol - generate tags for global variables. This is actually  */
2809 /*                 called for all variables and parameters, but we       */
2810 /*                 process the non-global variables elsewhere.           */
2811 /*-----------------------------------------------------------------------*/
2812 int dwWriteSymbol(symbol *sym)
2813 {
2814   if (IS_FUNC (sym->type))
2815     return 1;
2816
2817   /* If it is an iTemp, then it is not a C source symbol; ignore it */
2818   if (sym->isitmp)
2819     return 1;
2820
2821   /* Ignore parameters; they must be handled specially so that they will */
2822   /* appear in the correct order */
2823   if (sym->_isparm)
2824     return 1;
2825     
2826   return dwWriteSymbolInternal (sym);
2827 }
2828
2829
2830 /*-----------------------------------------------------------------------*/
2831 /* dwWriteType                                                           */
2832 /*-----------------------------------------------------------------------*/
2833 int dwWriteType(structdef *sdef, int block, int inStruct, char *tag)
2834 {
2835   /* FIXME: needs implementation */
2836   return 1;
2837 }
2838
2839
2840 /*-----------------------------------------------------------------------*/
2841 /* dwWriteModule - generates the root tag for this compilation unit      */
2842 /*-----------------------------------------------------------------------*/
2843 int dwWriteModule(char *name)
2844 {
2845   dwtag * tp;
2846   char * s;
2847   
2848   if(!dwarf2FilePtr) return 0;
2849   
2850   dwModuleName = Safe_strdup (name);
2851   for (s = dwModuleName; *s; s++)
2852     if (ispunct (*s) || isspace (*s))
2853       *s = '_';
2854     
2855   tp = dwNewTag (DW_TAG_compile_unit);
2856   dwAddTagAttr (tp, dwNewAttrString (DW_AT_producer, "SDCC version "
2857                                              SDCC_VERSION_STR));
2858   dwAddTagAttr (tp, dwNewAttrConst (DW_AT_language, DW_LANG_C89));
2859
2860   dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, fullSrcFileName));
2861
2862   dwAddTagAttr (tp, dwNewAttrLabelRef (DW_AT_stmt_list,
2863                                        "Ldebug_line_start", -4));
2864
2865   dwRootTag = tp;
2866   
2867   return 1;
2868 }
2869
2870
2871 /*-----------------------------------------------------------------------*/
2872 /* dwWriteCLine - generates a line number/position to address record for */
2873 /*                C source                                               */
2874 /*-----------------------------------------------------------------------*/
2875 int dwWriteCLine(iCode *ic)
2876 {
2877   dwline * lp;
2878   char * debugSym;
2879   
2880   if(!dwarf2FilePtr) return 0;
2881
2882   lp = Safe_alloc (sizeof (dwline));
2883
2884   lp->line = ic->lineno;
2885   
2886   debugSym = dwNewDebugSymbol ();
2887   emitDebuggerSymbol (debugSym);
2888   lp->label = debugSym;
2889   lp->offset = 0;
2890
2891   lp->fileIndex = dwFindFileIndex (ic->filename);
2892
2893   if (!dwLineFirst)
2894     dwLineFirst = lp;
2895   else
2896     dwLineLast->next = lp;
2897   dwLineLast = lp;
2898   
2899   return 1;
2900 }
2901
2902
2903 /*-----------------------------------------------------------------------*/
2904 /* dwWriteFrameAddress - note the current position of the frame pointer  */
2905 /*                       address. The base address can be specified by   */
2906 /*                       either a register or pointer variable, leaving  */
2907 /*                       the other as NULL. If both are NULL, there is   */
2908 /*                       no current frame pointer address defined.       */
2909 /*-----------------------------------------------------------------------*/
2910 int
2911 dwWriteFrameAddress(char *variable, struct regs *reg, int offset)
2912 {
2913   char * debugSym = NULL;
2914   dwlocregion * lrp;
2915   dwloc * lp;
2916   int regNum;
2917     
2918   if(!dwarf2FilePtr) return 0;
2919
2920   /* If there was a region open, close it */
2921   if (dwFrameLastLoc)
2922     {
2923       debugSym = dwNewDebugSymbol ();
2924       emitDebuggerSymbol (debugSym);
2925       
2926       dwFrameLastLoc->endLabel = debugSym;
2927       dwFrameLastLoc = NULL;
2928     }
2929
2930   if (!variable && !reg)
2931     return 1;
2932
2933   /* Create a new debugger symbol for the start of the region if */
2934   /* we can't recycle the symbol at the end of the previous      */
2935   if (!debugSym)
2936     {
2937       debugSym = dwNewDebugSymbol ();
2938       emitDebuggerSymbol (debugSym);
2939     }
2940
2941   lrp = Safe_alloc (sizeof (dwlocregion));
2942   lrp->startLabel = debugSym;
2943
2944   if (variable)         /* frame pointer based from a global variable */
2945     {
2946       dwloc * lp;
2947
2948       lrp->loc = dwNewLoc (DW_OP_addr, variable, 0);
2949       lrp->loc->next = lp = dwNewLoc (DW_OP_deref_size, NULL, PTRSIZE);
2950       if (offset)
2951         {
2952           lp->next = dwNewLoc (DW_OP_consts, NULL, offset);
2953           lp->next->next = dwNewLoc (DW_OP_plus, NULL, 0);
2954         }
2955     }
2956   else if (reg)         /* frame pointer based from a register */
2957     {
2958       regNum = port->debugger.dwarf.regNum (reg);
2959       assert (regNum>=0);
2960       
2961       if (regNum>=0 && regNum<=31)
2962         {
2963           if (offset)
2964             lrp->loc = dwNewLoc (DW_OP_breg0 + regNum, NULL, offset);
2965           else
2966             lrp->loc = dwNewLoc (DW_OP_reg0 + regNum, NULL, 0);
2967         }
2968       else
2969         {
2970           lrp->loc = lp = dwNewLoc (DW_OP_regx, NULL, regNum);
2971           if (offset)
2972             {
2973               lp->next = dwNewLoc (DW_OP_consts, NULL, offset);
2974               lp->next->next = dwNewLoc (DW_OP_plus, NULL, 0);
2975             }
2976         }
2977     }
2978   dwFrameLastLoc = lrp;
2979   
2980   if (!dwFrameLocList)
2981     dwFrameLocList = dwNewLocList();
2982   lrp->next = dwFrameLocList->region;
2983   dwFrameLocList->region = lrp;
2984   
2985   return 1;
2986 }
2987
2988
2989 /*-----------------------------------------------------------------------*/
2990 /* dwWriteALine - generates a line number/position to address record for */
2991 /*                assembly source                                        */
2992 /*-----------------------------------------------------------------------*/
2993 int dwWriteALine(char *module, int Line)
2994 {
2995   if(!dwarf2FilePtr) return 0;
2996   
2997   return 1;
2998 }
2999
3000
3001
3002
3003 /*-----------------------------------------------------------------------*/
3004 /* dwarf2FinalizeFile - write all of the DWARF debugging data to the     */
3005 /*                      debug file                                       */
3006 /*-----------------------------------------------------------------------*/
3007 int
3008 dwarf2FinalizeFile(void)
3009 {
3010   int tagAddress = 11;
3011   int abbrevNum = 0;
3012   int attr;
3013   
3014   if(!dwarf2FilePtr) return 1;
3015
3016   /* Write the .debug_line section */
3017   dwWriteLineNumbers ();
3018  
3019   /* Assign the location list addresses (for cross references) */
3020   dwAssignLocListAddresses ();
3021   
3022   /* Write the .debug_loc section */
3023   dwWriteLocLists ();
3024
3025   /* Delete our scope related user attributes; they were only needed to help */
3026   /* build the tag tree and have no meaning to (and may confuse) debuggers   */
3027   attr = DW_AT_user_block;
3028   dwTraverseTag (dwRootTag, dwDeleteTagAttr, &attr);
3029   attr = DW_AT_user_level;
3030   dwTraverseTag (dwRootTag, dwDeleteTagAttr, &attr);
3031   
3032   /* Add a DW_AT_sibling attribute to all tags with children and siblings */
3033   dwTraverseTag (dwRootTag, dwAddSibAttr, NULL);
3034
3035   /* Assign the tag abbreviations. The tags, attributes, and forms must   */
3036   /* not change after this point. The attribute values may change as long */
3037   /* as the size of the value does not.                                   */
3038   dwAbbrevTable = newHashTable (128);
3039   dwTraverseTag (dwRootTag, dwAssignAbbrev, &abbrevNum);
3040   
3041   /* Assign the tag addresses (for cross references) */
3042   dwTraverseTag (dwRootTag, dwAssignTagAddress, &tagAddress);
3043   
3044   /* Write the .debug_abbrev section */
3045   dwWriteAbbrevs ();  
3046   
3047   /* Write the .debug_info section */
3048   dwWriteTags ();
3049
3050   /* Write the .debug_pubnames section */
3051   dwWritePubnames ();
3052   
3053   return 1;
3054 }