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