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