Update svn merge history.
[sdcc.git] / sdcc / src / SDCCdwarf2.c
blobb209d3904c0c1ac4d7b677d193ca30a2f8a60357
1 /*-------------------------------------------------------------------------
2 SDCCdwarf2.c - generate DWARF2 debug information
4 Written By - Erik Petrich . epetrich@users.sourceforge.net (2004)
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.
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.
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.
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 -------------------------------------------------------------------------*/
26 #include "common.h"
27 #include "SDCCdwarf2.h"
29 /*************************************************************
34 *************************************************************/
36 extern set *includeDirsSet;
38 int dwOpenFile (const 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, const iCode *ic);
43 int dwWriteScope (iCode *ic);
44 int dwWriteSymbol (symbol *pSym);
45 int dwWriteType (structdef *sdef, int block, int inStruct, const char *tag);
46 int dwWriteModule (const char *name);
47 int dwWriteCLine (iCode *ic);
48 int dwWriteALine (const char *module, int Line);
49 int dwWriteFrameAddress (const char *variable, struct reg_info *reg, int offset);
50 int dwWriteBasicSymbol (symbol *sym, int isStructSym, int isFunc);
53 DEBUGFILE dwarf2DebugFile =
55 &dwOpenFile,
56 &dwCloseFile,
57 &dwWriteModule,
58 &dwWriteFunction,
59 &dwWriteEndFunction,
60 &dwWriteLabel,
61 &dwWriteScope,
62 &dwWriteSymbol,
63 &dwWriteType,
64 &dwWriteCLine,
65 &dwWriteALine,
66 &dwWriteFrameAddress
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 long 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 dwlocregion * dwCFILastLoc = NULL;
92 dwcfilist * dwCFIRoot = NULL;
95 /*----------------------------------------------------------------------*/
96 /* dwNewDebugSymbol - returns the name for a new debug symbol */
97 /*----------------------------------------------------------------------*/
98 static char *
99 dwNewDebugSymbol (void)
101 char debugSym[SDCC_NAME_MAX];
103 sprintf (debugSym, "S%s$%s$%d", dwModuleName, currFunc->name, dwDebugSymbol);
104 dwDebugSymbol++;
105 return Safe_strdup (debugSym);
109 /*----------------------------------------------------------------------*/
110 /* dwWriteByte - generate a single byte assembler constant in the form: */
111 /* */
112 /* .db label+offset ; comment */
113 /* */
114 /* The label and comment parameters are optional */
115 /*----------------------------------------------------------------------*/
116 static void
117 dwWriteByte (const char * label, int offset, const char * comment)
119 tfprintf (dwarf2FilePtr, "\t!db\t");
120 if (label)
122 if (offset)
123 fprintf (dwarf2FilePtr, "%s+%d", label, offset);
124 else
125 fprintf (dwarf2FilePtr, "%s", label);
127 else
128 fprintf (dwarf2FilePtr, "%d", offset);
130 if (comment)
131 fprintf (dwarf2FilePtr, "\t;%s\n", comment);
132 else
133 fprintf (dwarf2FilePtr, "\n");
136 /*----------------------------------------------------------------------*/
137 /* dwWriteHalf - generate a two byte assembler constant in the form: */
138 /* */
139 /* .dw label+offset ; comment */
140 /* */
141 /* The label and comment parameters are optional */
142 /*----------------------------------------------------------------------*/
143 static void
144 dwWriteHalf (const char * label, int offset, char * comment)
146 tfprintf (dwarf2FilePtr, "\t!dw\t");
147 if (label)
149 if (offset)
150 fprintf (dwarf2FilePtr, "%s+%d", label, offset);
151 else
152 fprintf (dwarf2FilePtr, "%s", label);
154 else
155 fprintf (dwarf2FilePtr, "%d", offset);
157 if (comment)
158 fprintf (dwarf2FilePtr, "\t;%s\n", comment);
159 else
160 fprintf (dwarf2FilePtr, "\n");
163 /*----------------------------------------------------------------------*/
164 /* dwWriteWord - generate a four byte assembler constant in the form: */
165 /* */
166 /* .dd label+offset ; comment */
167 /* */
168 /* The label and comment parameters are optional */
169 /*----------------------------------------------------------------------*/
170 static void
171 dwWriteWord (const char * label, int offset, char * comment)
173 /* FIXME: need to implement !dd pseudo-op in the assembler. In the */
174 /* meantime, we use dw with zero padding and hope the values fit */
175 /* in only 16 bits. */
176 #if 0
177 tfprintf (dwarf2FilePtr, "\t!dd\t");
178 if (label)
180 if (offset)
181 fprintf (dwarf2FilePtr, "%s+%d", label, offset);
182 else
183 fprintf (dwarf2FilePtr, "%s", label);
185 else
186 fprintf (dwarf2FilePtr, "%d", offset);
187 #else
188 tfprintf (dwarf2FilePtr, "\t!dw\t");
189 if (port->little_endian)
191 if (label)
193 if (offset)
194 fprintf (dwarf2FilePtr, "(%s+%d),0", label, offset);
195 else
196 fprintf (dwarf2FilePtr, "(%s),0", label);
198 else
199 fprintf (dwarf2FilePtr, "%d,%d", offset, offset >> 16);
201 else
203 if (label)
205 if (offset)
206 fprintf (dwarf2FilePtr, "0,(%s+%d)", label, offset);
207 else
208 fprintf (dwarf2FilePtr, "0,(%s)", label);
210 else
211 fprintf (dwarf2FilePtr, "%d,%d", offset >> 16, offset);
213 #endif
215 if (comment)
216 fprintf (dwarf2FilePtr, "\t;%s\n", comment);
217 else
218 fprintf (dwarf2FilePtr, "\n");
222 /*----------------------------------------------------------------------*/
223 /* dwWriteULEB128 - generate an unsigned variable length assembler */
224 /* constant in the form: */
225 /* */
226 /* .uleb128 label+offset ; comment */
227 /* */
228 /* The label and comment parameters are optional */
229 /*----------------------------------------------------------------------*/
230 static void
231 dwWriteULEB128 (char * label, int offset, char * comment)
233 tfprintf (dwarf2FilePtr, "\t.uleb128\t");
234 if (label)
236 if (offset)
237 fprintf (dwarf2FilePtr, "%s+%d", label, offset);
238 else
239 fprintf (dwarf2FilePtr, "%s", label);
241 else
242 fprintf (dwarf2FilePtr, "%d", offset);
244 if (comment)
245 fprintf (dwarf2FilePtr, "\t;%s\n", comment);
246 else
247 fprintf (dwarf2FilePtr, "\n");
250 /*----------------------------------------------------------------------*/
251 /* dwWriteSLEB128 - generate a signed variable length assembler */
252 /* constant in the form: */
253 /* */
254 /* .sleb128 label+offset ; comment */
255 /* */
256 /* The label and comment parameters are optional */
257 /*----------------------------------------------------------------------*/
258 static void
259 dwWriteSLEB128 (char * label, int offset, char * comment)
261 tfprintf (dwarf2FilePtr, "\t.sleb128\t");
262 if (label)
264 if (offset)
265 fprintf (dwarf2FilePtr, "%s+%d", label, offset);
266 else
267 fprintf (dwarf2FilePtr, "%s", label);
269 else
270 fprintf (dwarf2FilePtr, "%d", offset);
272 if (comment)
273 fprintf (dwarf2FilePtr, "\t;%s\n", comment);
274 else
275 fprintf (dwarf2FilePtr, "\n");
279 /*----------------------------------------------------------------------*/
280 /* dwSizeofULEB128 - return the size (in bytes) of an unsigned variable */
281 /* length constant */
282 /*----------------------------------------------------------------------*/
283 static int
284 dwSizeofULEB128 (int unsigned value)
286 int size = 0;
290 value >>= 7;
291 size++;
293 while (value);
295 return size;
298 /*----------------------------------------------------------------------*/
299 /* dwSizeofSLEB128 - return the size (in bytes) of a signed variable */
300 /* length constant */
301 /*----------------------------------------------------------------------*/
302 static int
303 dwSizeofSLEB128 (int value)
305 int size = 0;
306 int negative = (value < 0);
307 int sign;
309 while (1)
311 size++;
312 sign = value & 0x40;
313 value >>= 7;
314 if (negative)
315 value |= (0x7f << (sizeof(int)*8 - 7));
316 if ((value == 0 && !sign) || (value == -1 && sign))
317 break;
320 return size;
323 /*----------------------------------------------------------------------*/
324 /* dwWriteString - generate a string constant in the form: */
325 /* */
326 /* .ascii /string/ ; comment */
327 /* */
328 /* The comment parameter is optional. The string may contain any */
329 /* non-null characters */
330 /*----------------------------------------------------------------------*/
331 static void
332 dwWriteString (const char * string, const char * comment)
334 char * escaped = string_escape (string);
335 tfprintf (dwarf2FilePtr, "\t!ascii\n", escaped);
336 Safe_free (escaped);
337 dwWriteByte (NULL, 0, comment);
341 /*----------------------------------------------------------------------*/
342 /* dwWriteAddress - generate an assembler constant in the form: */
343 /* */
344 /* .dw label+offset ; comment */
345 /* or .dd label+offset ; comment */
346 /* */
347 /* depending on how the relevant ABI defines the address size (may be */
348 /* larger than the CPU's actual address size). The label and comment */
349 /* parameters are optional */
350 /*----------------------------------------------------------------------*/
351 static void
352 dwWriteAddress (const char * label, int offset, char * comment)
354 switch (port->debugger.dwarf.addressSize)
356 case 2:
357 dwWriteHalf (label, offset, comment);
358 break;
359 case 4:
360 dwWriteWord (label, offset, comment);
361 break;
362 default:
363 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
364 "unsupported port->debugger.dwarf.addressSize");
369 /*----------------------------------------------------------------------*/
370 /* dwWriteHalfDelta - generate a two byte assembler constant in the */
371 /* form: */
372 /* */
373 /* .dw offset+label1-label2 */
374 /* */
375 /* The offset parameter is optional */
376 /*----------------------------------------------------------------------*/
377 static void
378 dwWriteHalfDelta (char * label1, char * label2, int offset)
380 if (offset)
381 tfprintf (dwarf2FilePtr, "\t!dw\t%d+%s-%s\n", offset, label1, label2);
382 else
383 tfprintf (dwarf2FilePtr, "\t!dw\t%s-%s\n", label1, label2);
386 /*----------------------------------------------------------------------*/
387 /* dwWriteWordDelta - generate a four byte assembler constant in the */
388 /* form: */
389 /* */
390 /* .dd label1-label2 */
391 /*----------------------------------------------------------------------*/
392 static void
393 dwWriteWordDelta (char * label1, char * label2)
395 /* FIXME: need to implement !dd pseudo-op; this hack only */
396 /* works for positive offsets of less than 64k */
397 #if 0
398 tfprintf (dwarf2FilePtr, "\t!dd\t%s-%s\n", label1,label2);
399 #else
400 if (port->little_endian)
402 tfprintf (dwarf2FilePtr, "\t!dw\t%s-%s,%d\n", label1, label2, 0);
404 else
406 tfprintf (dwarf2FilePtr, "\t!dw\t%d,%s-%s\n", 0, label1, label2);
408 #endif
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)
424 switch (port->debugger.dwarf.addressSize)
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");
438 #if 0
439 /*----------------------------------------------------------------------*/
440 /* dwWriteULEB128Delta - generate an unsigned variable byte assembler */
441 /* constant in the form: */
442 /* */
443 /* .uleb128 offset+label1-label2 */
444 /* */
445 /* The offset parameter is optional */
446 /*----------------------------------------------------------------------*/
447 static void
448 dwWriteULEB128Delta (char * label1, char * label2, int offset)
450 if (offset)
451 tfprintf (dwarf2FilePtr, "\t.uleb128\t%d+%s-%s\n", offset, label1, label2);
452 else
453 tfprintf (dwarf2FilePtr, "\t.uleb128\t%s-%s\n", label1, label2);
455 #endif
457 /*------------------------------------------------------------------------*/
459 /*----------------------------------------------------------------------*/
460 /* dwNewCFIlist - allocates a new CFI list node */
461 /*----------------------------------------------------------------------*/
462 dwcfilist *
463 dwNewCFIlist ()
465 dwcfilist * p;
467 p = Safe_alloc (sizeof (dwcfilist));
469 return p;
472 /*----------------------------------------------------------------------*/
473 /* dwNewLoc - allocates a new location expression node */
474 /*----------------------------------------------------------------------*/
475 dwloc *
476 dwNewLoc (int opcode, const char * label, int offset)
478 dwloc * lp;
480 lp = Safe_alloc (sizeof (dwloc));
482 lp->opcode = opcode;
483 lp->operand.label = label;
484 lp->operand.offset = offset;
486 return lp;
489 /*-------------------------------------------------------------------------*/
490 /* dwSizeofLoc - returns the size (in bytes) of a chain of location */
491 /* expression nodes as they would be encoded by dwWriteLoc() */
492 /*-------------------------------------------------------------------------*/
493 static int
494 dwSizeofLoc (dwloc * lp)
496 int size = 0;
498 while (lp)
500 size++;
501 switch (lp->opcode)
503 case DW_OP_addr:
504 size += port->debugger.dwarf.addressSize;
505 break;
507 case DW_OP_deref_size:
508 case DW_OP_xderef_size:
509 case DW_OP_pick:
510 case DW_OP_const1u:
511 case DW_OP_const1s:
512 size += 1;
513 break;
515 case DW_OP_skip:
516 case DW_OP_bra:
517 case DW_OP_const2u:
518 case DW_OP_const2s:
519 size += 2;
520 break;
522 case DW_OP_const4u:
523 case DW_OP_const4s:
524 size += 4;
525 break;
527 case DW_OP_const8u:
528 case DW_OP_const8s:
529 size += 8;
530 break;
532 case DW_OP_piece:
533 case DW_OP_regx:
534 case DW_OP_plus_uconst:
535 size += dwSizeofULEB128 (lp->operand.offset);
536 break;
538 case DW_OP_breg0:
539 case DW_OP_breg1:
540 case DW_OP_breg2:
541 case DW_OP_breg3:
542 case DW_OP_breg4:
543 case DW_OP_breg5:
544 case DW_OP_breg6:
545 case DW_OP_breg7:
546 case DW_OP_breg8:
547 case DW_OP_breg9:
548 case DW_OP_breg10:
549 case DW_OP_breg11:
550 case DW_OP_breg12:
551 case DW_OP_breg13:
552 case DW_OP_breg14:
553 case DW_OP_breg15:
554 case DW_OP_breg16:
555 case DW_OP_breg17:
556 case DW_OP_breg18:
557 case DW_OP_breg19:
558 case DW_OP_breg20:
559 case DW_OP_breg21:
560 case DW_OP_breg22:
561 case DW_OP_breg23:
562 case DW_OP_breg24:
563 case DW_OP_breg25:
564 case DW_OP_breg26:
565 case DW_OP_breg27:
566 case DW_OP_breg28:
567 case DW_OP_breg29:
568 case DW_OP_breg30:
569 case DW_OP_breg31:
570 case DW_OP_fbreg:
571 size += dwSizeofSLEB128 (lp->operand.offset);
572 break;
575 lp = lp->next;
578 return size;
581 /*------------------------------------------------------------------------*/
582 /* dwWriteLoc - writes a chain of location expression nodes */
583 /*------------------------------------------------------------------------*/
584 static void
585 dwWriteLoc (dwloc *lp)
587 while (lp)
589 dwWriteByte (NULL, lp->opcode, NULL);
590 switch (lp->opcode)
592 case DW_OP_addr:
593 dwWriteAddress (lp->operand.label, lp->operand.offset, NULL);
594 break;
596 case DW_OP_deref_size:
597 case DW_OP_xderef_size:
598 case DW_OP_pick:
599 case DW_OP_const1u:
600 case DW_OP_const1s:
601 dwWriteByte (NULL, lp->operand.offset, NULL);
602 break;
604 case DW_OP_skip:
605 case DW_OP_bra:
606 case DW_OP_const2u:
607 case DW_OP_const2s:
608 dwWriteHalf (NULL, lp->operand.offset, NULL);
609 break;
611 case DW_OP_const4u:
612 case DW_OP_const4s:
613 dwWriteWord (NULL, lp->operand.offset, NULL);
614 break;
616 case DW_OP_piece:
617 case DW_OP_regx:
618 case DW_OP_plus_uconst:
619 dwWriteULEB128 (NULL, lp->operand.offset, NULL);
620 break;
622 case DW_OP_breg0:
623 case DW_OP_breg1:
624 case DW_OP_breg2:
625 case DW_OP_breg3:
626 case DW_OP_breg4:
627 case DW_OP_breg5:
628 case DW_OP_breg6:
629 case DW_OP_breg7:
630 case DW_OP_breg8:
631 case DW_OP_breg9:
632 case DW_OP_breg10:
633 case DW_OP_breg11:
634 case DW_OP_breg12:
635 case DW_OP_breg13:
636 case DW_OP_breg14:
637 case DW_OP_breg15:
638 case DW_OP_breg16:
639 case DW_OP_breg17:
640 case DW_OP_breg18:
641 case DW_OP_breg19:
642 case DW_OP_breg20:
643 case DW_OP_breg21:
644 case DW_OP_breg22:
645 case DW_OP_breg23:
646 case DW_OP_breg24:
647 case DW_OP_breg25:
648 case DW_OP_breg26:
649 case DW_OP_breg27:
650 case DW_OP_breg28:
651 case DW_OP_breg29:
652 case DW_OP_breg30:
653 case DW_OP_breg31:
654 case DW_OP_fbreg:
655 dwWriteSLEB128 (NULL, lp->operand.offset, NULL);
656 break;
659 lp = lp->next;
663 /*----------------------------------------------------------------------*/
664 /* dwNewLocList - allocates a new list of location expression node */
665 /*----------------------------------------------------------------------*/
666 static dwloclist *
667 dwNewLocList (void)
669 dwloclist * llp;
671 llp = Safe_alloc (sizeof (dwloclist));
673 return llp;
676 /*----------------------------------------------------------------------*/
677 /* dwSizeofLocRegion - returns the size (in bytes) of a chain of */
678 /* location regions (inluding their location */
679 /* expression nodes) as encoded by dwWriteLocLists */
680 /*----------------------------------------------------------------------*/
681 static int
682 dwSizeofLocRegion (dwlocregion * lrp)
684 int size = 0;
686 while (lrp)
688 size += 2 * port->debugger.dwarf.addressSize;
689 size += 2 + dwSizeofLoc (lrp->loc);
690 lrp = lrp->next;
693 size += 2 * port->debugger.dwarf.addressSize;
694 return size;
697 /*-----------------------------------------------------------------------*/
698 /* dwAssignLocListAddresses - assign the address offsets of the location */
699 /* lists so that they can be referenced from */
700 /* the tag structure */
701 /*-----------------------------------------------------------------------*/
702 static void
703 dwAssignLocListAddresses (void)
705 dwloclist * llp;
706 int address = 0;
708 llp = dwRootLocList;
709 while (llp)
711 llp->baseOffset = address;
712 address += dwSizeofLocRegion (llp->region);
714 llp = llp->next;
718 /*-----------------------------------------------------------------------*/
719 /* dwWriteLocLists - write all of the location lists in dwRootLocList to */
720 /* the .debug_loc section */
721 /*-----------------------------------------------------------------------*/
722 static void
723 dwWriteLocLists (void)
725 dwlocregion * lrp;
726 dwloclist * llp;
728 tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_loc (NOLOAD)");
729 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_loc_start");
731 llp = dwRootLocList;
732 while (llp)
734 //fprintf (dwarf2FilePtr, "; baseOffset = 0x%x\n", llp->baseOffset);
735 lrp = llp->region;
736 while (lrp)
738 dwWriteAddress (lrp->startLabel, 0, NULL);
739 dwWriteAddress (lrp->endLabel, 0, NULL);
740 dwWriteHalf (NULL, dwSizeofLoc (lrp->loc), NULL);
741 dwWriteLoc (lrp->loc);
742 lrp = lrp ->next;
745 dwWriteAddress (NULL, 0, NULL);
746 dwWriteAddress (NULL, 0, NULL);
748 llp = llp->next;
754 /*------------------------------------------------------------------------*/
757 /*----------------------------------------------------------------------*/
758 /* dwNewAttr - allocate a new tag attribute node */
759 /*----------------------------------------------------------------------*/
760 static dwattr *
761 dwNewAttr (int attr)
763 dwattr * ap;
765 ap = Safe_alloc ( sizeof (dwattr));
766 ap->attr = attr;
768 return ap;
771 /*----------------------------------------------------------------------*/
772 /* dwFreeAttr - deallocate a tag attribute node */
773 /*----------------------------------------------------------------------*/
774 static void
775 dwFreeAttr (dwattr * ap)
777 Safe_free (ap);
781 /*-------------------------------------------------------------------------*/
782 /* dwNewAttrString - allocate a new tag attribute node with a string value */
783 /*-------------------------------------------------------------------------*/
784 static dwattr *
785 dwNewAttrString (int attr, const char * string)
787 dwattr * ap;
789 ap = dwNewAttr (attr);
790 ap->form = DW_FORM_string;
791 ap->val.string = string;
792 return ap;
796 /*---------------------------------------------------------------------*/
797 /* dwNewAttrConst - allocate a new tag attribute node with an unsigned */
798 /* numeric constant value */
799 /*---------------------------------------------------------------------*/
800 static dwattr *
801 dwNewAttrConst (int attr, unsigned int data)
803 dwattr * ap;
805 ap = dwNewAttr (attr);
806 if (data <= 0xffu)
807 ap->form = DW_FORM_data1;
808 else if (data <= 0xffffu)
809 ap->form = DW_FORM_data2;
810 else
811 ap->form = DW_FORM_data4;
813 ap->val.data = data;
814 return ap;
817 /* disabled to eliminiate unused function warning */
818 #if 0
819 /*---------------------------------------------------------------------*/
820 /* dwNewAttrSignedConst - allocate a new tag attribute node with a */
821 /* signed numeric constant value */
822 /*---------------------------------------------------------------------*/
823 static dwattr *
824 dwNewAttrSignedConst (int attr, int data)
826 dwattr * ap;
828 ap = dwNewAttr (attr);
829 if (data <= 0x7f && data >= -0x80)
830 ap->form = DW_FORM_data1;
831 else if (data <= 0xffff && data >= -0x8000)
832 ap->form = DW_FORM_data2;
833 else
834 ap->form = DW_FORM_data4;
836 ap->val.data = data;
837 return ap;
839 #endif
841 /*---------------------------------------------------------------------*/
842 /* dwNewAttrFlag - allocate a new tag attribute node with a boolean */
843 /* flag value (zero/non-zero) */
844 /*---------------------------------------------------------------------*/
845 static dwattr *
846 dwNewAttrFlag (int attr, int data)
848 dwattr * ap;
850 ap = dwNewAttr (attr);
851 ap->form = DW_FORM_flag;
853 ap->val.data = data;
854 return ap;
857 /*---------------------------------------------------------------------*/
858 /* dwNewAttrAddrSymbol - allocate a new tag attribute node with the */
859 /* address of a C symbol plus an offset */
860 /*---------------------------------------------------------------------*/
861 static dwattr *
862 dwNewAttrAddrSymbol (int attr, symbol * sym, int offset)
864 dwattr * ap;
866 ap = dwNewAttr (attr);
867 ap->form = DW_FORM_addr;
869 ap->val.symaddr.label = sym->rname;
870 ap->val.symaddr.offset = offset;
871 return ap;
874 /*---------------------------------------------------------------------*/
875 /* dwNewAttrAddrLabel - allocate a new tag attribute node with the */
876 /* address of an assembler label plus an offset */
877 /*---------------------------------------------------------------------*/
878 static dwattr *
879 dwNewAttrAddrLabel (int attr, char * label, int offset)
881 dwattr * ap;
883 ap = dwNewAttr (attr);
884 ap->form = DW_FORM_addr;
886 ap->val.symaddr.label = label;
887 ap->val.symaddr.offset = offset;
888 return ap;
891 /*---------------------------------------------------------------------*/
892 /* dwNewAttrTagRef - allocate a new tag attribute node that references */
893 /* a tag node */
894 /*---------------------------------------------------------------------*/
895 static dwattr *
896 dwNewAttrTagRef (int attr, dwtag * tp)
898 dwattr * ap;
900 ap = dwNewAttr (attr);
901 ap->form = DW_FORM_ref4;
903 ap->val.ref = tp;
904 return ap;
907 /*---------------------------------------------------------------------*/
908 /* dwNewAttrLocRef - allocate a new tag attribute node that references */
909 /* a location list */
910 /*---------------------------------------------------------------------*/
911 static dwattr *
912 dwNewAttrLocRef (int attr, dwloclist * llp)
914 dwattr * ap;
916 ap = dwNewAttr (attr);
917 ap->form = DW_FORM_data4;
919 ap->val.loclist = llp;
920 return ap;
923 /*-----------------------------------------------------------------------*/
924 /* dwNewAttrLabelRef - allocate a new tag attribute node that references */
925 /* the address of an assembler label plus an offset */
926 /*-----------------------------------------------------------------------*/
927 static dwattr *
928 dwNewAttrLabelRef (int attr, char * label, int offset)
930 dwattr * ap;
932 ap = dwNewAttr (attr);
933 ap->form = DW_FORM_data4;
935 ap->val.symaddr.label = label;
936 ap->val.symaddr.offset = offset;
937 return ap;
940 /*---------------------------------------------------------------------*/
941 /* dwNewAttrLoc - allocate a new tag attribute node for a chain of */
942 /* location expression nodes */
943 /*---------------------------------------------------------------------*/
944 dwattr *
945 dwNewAttrLoc (int attr, dwloc * lp)
947 dwattr * ap;
949 ap = dwNewAttr (attr);
950 ap->form = DW_FORM_block1;
951 ap->val.loc = lp;
953 return ap;
956 /*---------------------------------------------------------------------*/
957 /* dwWriteAttr - write a tag attribute node */
958 /*---------------------------------------------------------------------*/
959 static void
960 dwWriteAttr (dwattr * ap)
963 switch (ap->form)
965 case DW_FORM_addr:
966 dwWriteAddress (ap->val.symaddr.label, ap->val.symaddr.offset, NULL);
967 break;
969 case DW_FORM_block:
970 dwWriteULEB128 (NULL, dwSizeofLoc (ap->val.loc), NULL);
971 dwWriteLoc (ap->val.loc);
972 break;
974 case DW_FORM_block1:
975 dwWriteByte (NULL, dwSizeofLoc (ap->val.loc), NULL);
976 dwWriteLoc (ap->val.loc);
977 break;
979 case DW_FORM_block2:
980 dwWriteHalf (NULL, dwSizeofLoc (ap->val.loc), NULL);
981 dwWriteLoc (ap->val.loc);
982 break;
984 case DW_FORM_block4:
985 dwWriteWord (NULL, dwSizeofLoc (ap->val.loc), NULL);
986 dwWriteLoc (ap->val.loc);
987 break;
989 case DW_FORM_data1:
990 case DW_FORM_flag:
991 dwWriteByte (NULL, ap->val.data, NULL);
992 break;
994 case DW_FORM_data2:
995 dwWriteHalf (NULL, ap->val.data, NULL);
996 break;
998 case DW_FORM_data4:
999 switch (ap->attr)
1001 case DW_AT_stmt_list:
1002 dwWriteWord (ap->val.symaddr.label, ap->val.symaddr.offset, NULL);
1003 break;
1004 case DW_AT_location:
1005 case DW_AT_frame_base:
1006 dwWriteWord ("Ldebug_loc_start", ap->val.loclist->baseOffset, NULL);
1007 break;
1008 default:
1009 dwWriteWord (NULL, ap->val.data, NULL);
1011 break;
1013 case DW_FORM_udata:
1014 dwWriteULEB128 (NULL, ap->val.data, NULL);
1015 break;
1017 case DW_FORM_sdata:
1018 dwWriteSLEB128 (NULL, ap->val.data, NULL);
1019 break;
1021 case DW_FORM_string:
1022 dwWriteString (ap->val.string, NULL);
1023 break;
1025 case DW_FORM_ref1:
1026 dwWriteByte (NULL, ap->val.ref->baseOffset, NULL);
1027 break;
1029 case DW_FORM_ref2:
1030 dwWriteHalf (NULL, ap->val.ref->baseOffset, NULL);
1031 break;
1033 case DW_FORM_ref4:
1034 dwWriteWord (NULL, ap->val.ref->baseOffset, NULL);
1035 break;
1037 default:
1038 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1039 "unsupported DWARF form");
1040 exit (1);
1044 /*---------------------------------------------------------------------*/
1045 /* dwSizeofAttr - returns the size (in bytes) of a tag attribute node */
1046 /* as encoded by dwWriteAttr */
1047 /*---------------------------------------------------------------------*/
1048 static int
1049 dwSizeofAttr (dwattr * ap)
1051 int size;
1053 switch (ap->form)
1055 case DW_FORM_addr:
1056 return port->debugger.dwarf.addressSize;
1058 case DW_FORM_block:
1059 size = dwSizeofLoc (ap->val.loc);
1060 return size + dwSizeofULEB128 (size);
1062 case DW_FORM_block1:
1063 size = dwSizeofLoc (ap->val.loc);
1064 return size + 1;
1066 case DW_FORM_block2:
1067 size = dwSizeofLoc (ap->val.loc);
1068 return size + 2;
1070 case DW_FORM_block4:
1071 size = dwSizeofLoc (ap->val.loc);
1072 return size + 4;
1074 case DW_FORM_data1:
1075 case DW_FORM_flag:
1076 return 1;
1078 case DW_FORM_data2:
1079 return 2;
1081 case DW_FORM_data4:
1082 return 4;
1084 case DW_FORM_udata:
1085 return dwSizeofULEB128 (ap->val.data);
1087 case DW_FORM_sdata:
1088 return dwSizeofSLEB128 (ap->val.data);
1090 case DW_FORM_string:
1091 return 1 + strlen (ap->val.string);
1093 case DW_FORM_ref1:
1094 return 1;
1096 case DW_FORM_ref2:
1097 return 2;
1099 case DW_FORM_ref4:
1100 return 4;
1102 default:
1103 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1104 "unsupported DWARF form");
1105 exit (1);
1111 /*---------------------------------------------------------------------*/
1112 /* dwFindAttr - for a tag node, return a pointer to a particular */
1113 /* attribute node, or NULL if not found */
1114 /*---------------------------------------------------------------------*/
1115 static dwattr *
1116 dwFindAttr (dwtag * tp, int attr)
1118 dwattr * ap;
1120 ap = tp->attribs;
1121 while (ap)
1123 if (ap->attr == attr)
1124 return ap;
1125 ap = ap->next;
1128 return NULL;
1133 /*------------------------------------------------------------------------*/
1136 /*----------------------------------------------------------------------*/
1137 /* dwNewTag - allocate a new tag node */
1138 /*----------------------------------------------------------------------*/
1139 static dwtag *
1140 dwNewTag (int tag)
1142 dwtag * tp;
1144 tp = Safe_alloc ( sizeof (dwtag));
1145 tp->tag = tag;
1147 return tp;
1150 /*----------------------------------------------------------------------*/
1151 /* dwAddTagAttr - add an attribute to a tag */
1152 /*----------------------------------------------------------------------*/
1153 static void
1154 dwAddTagAttr (dwtag * tp, dwattr * ap)
1156 dwattr * curap;
1158 if (!tp->attribs)
1159 tp->attribs = ap;
1160 else if (ap->attr < tp->attribs->attr)
1162 ap->next = tp->attribs;
1163 tp->attribs = ap;
1165 else
1167 curap = tp->attribs;
1168 while (curap->next && curap->next->attr < ap->attr)
1169 curap = curap->next;
1170 ap->next = curap->next;
1171 curap->next = ap;
1175 /*----------------------------------------------------------------------*/
1176 /* dwSetTagAttr - repleace an existing attribute of a tag with a new */
1177 /* attribute or add if non-existent */
1178 /*----------------------------------------------------------------------*/
1179 static void
1180 dwSetTagAttr (dwtag *tp, dwattr * ap)
1182 dwattr * curap;
1184 curap = dwFindAttr (tp, ap->attr);
1185 if (curap)
1187 ap->next = curap->next;
1188 *curap = *ap;
1189 dwFreeAttr (ap);
1191 else
1192 dwAddTagAttr (tp, ap);
1196 /*----------------------------------------------------------------------*/
1197 /* dwAddTagChild - add a tag as a child of another tag */
1198 /*----------------------------------------------------------------------*/
1199 static dwtag *
1200 dwAddTagChild (dwtag * parent, dwtag * child)
1202 child->parent = parent;
1203 if (parent->lastChild)
1205 parent->lastChild->siblings = child;
1206 parent->lastChild = child;
1208 else
1210 parent->firstChild = child;
1211 parent->lastChild = child;
1213 return parent;
1216 /*----------------------------------------------------------------------*/
1217 /* dwMatchTagAttr - returns true if two tags are equal in value, */
1218 /* attributes, and offspring status (the child tags */
1219 /* need not match, but they must both have children or */
1220 /* both not have children) */
1221 /*----------------------------------------------------------------------*/
1222 static int
1223 dwMatchTagAttr (const void * tp1v, const void * tp2v)
1225 const dwtag * tp1 = tp1v;
1226 const dwtag * tp2 = tp2v;
1227 dwattr * ap1;
1228 dwattr * ap2;
1230 if (!tp1 || !tp2)
1231 return 0;
1233 ap1 = tp1->attribs;
1234 ap2 = tp2->attribs;
1236 if (tp1->tag != tp2->tag)
1237 return 0;
1239 if (tp1->firstChild && !tp2->lastChild)
1240 return 0;
1241 if (!tp1->firstChild && tp2->lastChild)
1242 return 0;
1244 while (ap1 && ap2)
1246 if (ap1->attr != ap2->attr)
1247 return 0;
1248 if (ap1->form != ap2->form)
1249 return 0;
1251 ap1 = ap1->next;
1252 ap2 = ap2->next;
1255 return 1;
1258 /*----------------------------------------------------------------------*/
1259 /* dwHashTag - return a hash code for a tag based on its value and */
1260 /* attributes */
1261 /*----------------------------------------------------------------------*/
1262 static int
1263 dwHashTag (dwtag * tp)
1265 dwattr * ap = tp->attribs;
1266 int hash = tp->tag;
1268 while (ap)
1270 hash = (hash << 6) ^ ((hash >> 11) & 0xff);
1271 hash ^= (ap->attr) | (ap->form << 8);
1273 ap = ap->next;
1275 if (hash<0)
1276 return -hash;
1277 else
1278 return hash;
1281 /*----------------------------------------------------------------------*/
1282 /* dwTraverseTag - perform a depth-first preorder traversal of a tag */
1283 /* tree, calling the user function at each node. The */
1284 /* user function is also called with a NULL tag pointer */
1285 /* after the last sibling of each immediate family is */
1286 /* processed. */
1287 /*----------------------------------------------------------------------*/
1288 static int
1289 dwTraverseTag (dwtag *tp, int (*somefunc)(dwtag *tp, void * info), void * info)
1291 int rvalue = 0;
1293 while (tp)
1295 rvalue += (*somefunc)(tp, info);
1296 if (tp->firstChild)
1297 rvalue += dwTraverseTag (tp->firstChild, somefunc, info);
1298 tp = tp->siblings;
1300 rvalue += (*somefunc)(NULL, info);
1302 return rvalue;
1305 /*----------------------------------------------------------------------*/
1306 /* dwAssignAbbrev - find a matching abbreviation for a tag or create a */
1307 /* a new one and assign it */
1308 /*----------------------------------------------------------------------*/
1309 static int
1310 dwAssignAbbrev (dwtag *tp, void *info)
1312 dwtag * oldtp;
1313 int * anp = info; /* pointer to current abbreviation number */
1314 int key;
1316 if (!tp)
1317 return 0;
1319 key = dwHashTag (tp) % dwAbbrevTable->size;
1320 oldtp = hTabFindByKey (dwAbbrevTable, key, tp, dwMatchTagAttr);
1321 if (oldtp)
1323 tp->abbrev = oldtp->abbrev;
1324 return 0;
1326 else
1328 tp->abbrev = ++(*anp);
1329 hTabAddItemLong (&dwAbbrevTable, key, tp, tp);
1330 return 1;
1334 /*-----------------------------------------------------------------------*/
1335 /* dwWriteAbbrevs - write the abbreviations to the .debug_abbrev section */
1336 /*-----------------------------------------------------------------------*/
1337 static void
1338 dwWriteAbbrevs (int abbrevNum)
1340 dwtag * tp;
1341 dwattr * ap;
1342 int key;
1343 dwtag ** tptable = NULL;
1344 int abbrev;
1346 tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_abbrev (NOLOAD)");
1347 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_abbrev");
1349 /* Sort the abbreviations by their abbreviation number so that */
1350 /* we can output them in this order. I don't see any requirement */
1351 /* in the standard for this, but some things seem to assume it. */
1352 tptable = Safe_calloc (1+abbrevNum, sizeof(dwtag *));
1353 tp = hTabFirstItem (dwAbbrevTable, &key);
1354 for (; tp; tp = hTabNextItem (dwAbbrevTable, &key))
1355 tptable[tp->abbrev] = tp;
1357 for (abbrev=1; abbrev<=abbrevNum; abbrev++)
1359 tp = tptable[abbrev];
1360 if (!tp) continue;
1362 dwWriteULEB128 (NULL, tp->abbrev, NULL);
1363 dwWriteULEB128 (NULL, tp->tag, NULL);
1364 dwWriteByte (NULL, tp->firstChild ? DW_CHILDREN_yes : DW_CHILDREN_no,
1365 NULL);
1366 ap = tp->attribs;
1367 while (ap)
1369 dwWriteULEB128 (NULL, ap->attr, NULL);
1370 dwWriteULEB128 (NULL, ap->form, NULL);
1371 ap = ap->next;
1373 dwWriteULEB128 (NULL, 0, NULL);
1374 dwWriteULEB128 (NULL, 0, NULL);
1377 dwWriteULEB128 (NULL, 0, NULL);
1379 Safe_free (tptable);
1380 hTabDeleteAll (dwAbbrevTable);
1385 /*-----------------------------------------------------------------------*/
1386 /* dwWriteTag - write the encoded tag information */
1387 /*-----------------------------------------------------------------------*/
1388 static int
1389 dwWriteTag (dwtag *tp, void *info)
1391 dwattr * ap;
1393 if (!tp)
1395 /* mark the end of this series of siblings */
1396 dwWriteULEB128 (NULL, 0, NULL);
1397 return 0;
1400 //fprintf (dwarf2FilePtr, "; baseOffset = 0x%x\n", tp->baseOffset);
1402 /* write the tag abbreviation */
1403 dwWriteULEB128 (NULL, tp->abbrev, NULL);
1405 /* write the values of the attributes */
1406 ap = tp->attribs;
1407 while (ap)
1409 dwWriteAttr (ap);
1410 ap = ap->next;
1413 return 1;
1417 /*-----------------------------------------------------------------------*/
1418 /* dwWriteTags - write all the tags to the .debug_info section */
1419 /*-----------------------------------------------------------------------*/
1420 static void
1421 dwWriteTags (void)
1423 if (!dwRootTag)
1424 return;
1426 tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_info (NOLOAD)");
1428 dwWriteWordDelta ("Ldebug_info_end", "Ldebug_info_start");
1430 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_info_start");
1432 dwWriteHalf (NULL, 2, NULL); /* DWARF version */
1434 dwWriteWord ("Ldebug_abbrev", 0, NULL);
1436 dwWriteByte (NULL, port->debugger.dwarf.addressSize, NULL);
1438 // The root tag has no siblings and must not have an end-of-sibling-
1439 // chain marker, so handle it separately and start the traversal with
1440 // its children.
1441 dwWriteTag (dwRootTag, NULL);
1442 if (dwRootTag->firstChild)
1443 dwTraverseTag (dwRootTag->firstChild, dwWriteTag, NULL);
1445 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_info_end");
1449 /*-----------------------------------------------------------------------*/
1450 /* dwAssignTagAddress - assign the current address to the current tag. */
1451 /* Compute the next address based on the tag size */
1452 /*-----------------------------------------------------------------------*/
1453 static int
1454 dwAssignTagAddress (dwtag *tp, void *info)
1456 int * tap = info;
1457 dwattr * ap;
1459 if (!tp)
1461 *tap += 1;
1462 return 0;
1465 tp->baseOffset = *tap;
1467 *tap += dwSizeofULEB128 (tp->abbrev);
1469 ap = tp->attribs;
1470 while (ap)
1472 *tap += dwSizeofAttr (ap);
1473 ap = ap->next;
1476 return 0;
1479 /*-----------------------------------------------------------------------*/
1480 /* dwAddSibAttr - if a tag has children and a sibling, add a sibling */
1481 /* attribute (it allows debuggers to jump to the sibling */
1482 /* and skip the child data) */
1483 /*-----------------------------------------------------------------------*/
1484 static int
1485 dwAddSibAttr (dwtag *tp, void *info)
1487 if (!tp)
1488 return 0;
1489 if (tp == dwRootTag)
1490 return 0;
1492 if (tp->firstChild && tp->siblings)
1493 dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_sibling, tp->siblings));
1495 return 0;
1498 /*-----------------------------------------------------------------------*/
1499 /* dwDeleteTagAttr - given a pointer to an attribute type, delete any */
1500 /* matching attribute */
1501 /*-----------------------------------------------------------------------*/
1502 static int
1503 dwDeleteTagAttr (dwtag *tp, void *info)
1505 int attr = *((int *) info);
1506 dwattr * ap;
1508 if (!tp)
1509 return 0;
1511 ap = tp->attribs;
1512 if (ap && ap->attr == attr)
1514 tp->attribs = ap->next;
1515 return 1;
1518 while (ap)
1520 if (ap->next && ap->next->attr == attr)
1522 ap->next = ap->next->next;
1523 return 1;
1525 ap = ap->next;
1528 return 0;
1532 /*------------------------------------------------------------------------*/
1534 /*-----------------------------------------------------------------------*/
1535 /* dwWritePubnames - write all the public names to the .debug_pubnames */
1536 /* section. Externally visible functions and variables */
1537 /* are considered to have public names. */
1538 /*-----------------------------------------------------------------------*/
1539 static void
1540 dwWritePubnames (void)
1542 dwtag * tp;
1543 dwattr * ap1;
1544 dwattr * ap2;
1546 tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_pubnames (NOLOAD)");
1548 dwWriteWordDelta ("Ldebug_pubnames_end", "Ldebug_pubnames_start");
1550 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_pubnames_start");
1552 dwWriteHalf (NULL, 2, NULL); /* DWARF version */
1554 dwWriteWord ("Ldebug_info_start-4", 0, NULL);
1555 dwWriteWordDelta ("4+Ldebug_info_end", "Ldebug_info_start");
1557 if (dwRootTag && dwRootTag->firstChild)
1559 tp = dwRootTag->firstChild;
1560 while (tp)
1562 if (tp->tag == DW_TAG_variable || tp->tag == DW_TAG_subprogram)
1564 /* If it has a name and is externally visible, it's a pubname */
1565 ap1 = dwFindAttr (tp, DW_AT_external);
1566 ap2 = dwFindAttr (tp, DW_AT_name);
1567 if (ap1 && ap1->val.data && ap2)
1569 dwWriteWord (NULL, tp->baseOffset, NULL);
1570 dwWriteString (ap2->val.string, NULL);
1574 tp = tp->siblings;
1577 dwWriteWord (NULL, 0, NULL);
1578 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_pubnames_end");
1581 /*------------------------------------------------------------------------*/
1583 /*-----------------------------------------------------------------------*/
1584 /* dwFindFileIndex - find the index of a filename in dwFilenameSet; if */
1585 /* it does not exist, it is added */
1586 /*-----------------------------------------------------------------------*/
1587 static int
1588 dwFindFileIndex (char * filename)
1590 char * includeDir;
1591 dwfile * srcfile;
1592 int fileIndex = 1;
1593 int dirIndex = 1;
1595 /* Just do a linear search for the file. There should be hardly */
1596 /* a penalty since 1) most calls search for the first file, and */
1597 /* 2) the file set is usually small (often just 1 item) */
1598 for (srcfile = setFirstItem (dwFilenameSet);
1599 srcfile;
1600 srcfile = setNextItem(dwFilenameSet), fileIndex++ )
1602 if (!strcmp (srcfile->name, filename))
1603 return fileIndex;
1606 for (includeDir = setFirstItem (includeDirsSet);
1607 includeDir;
1608 includeDir = setNextItem(includeDirsSet), dirIndex++ )
1610 if (!strncmp (includeDir, filename, strlen (includeDir))
1611 && strlen (filename) > strlen (includeDir))
1613 if (IS_DIR_SEPARATOR(filename[strlen (includeDir)]))
1614 break;
1617 if (!includeDir)
1618 dirIndex = 0;
1620 srcfile = Safe_alloc (sizeof (dwfile));
1621 srcfile->name = filename;
1622 srcfile->dirIndex = dirIndex;
1623 srcfile->timestamp = 0;
1624 srcfile->length = 0;
1626 addSet (&dwFilenameSet, srcfile);
1627 return fileIndex;
1630 /*-----------------------------------------------------------------------*/
1631 /* dwWriteLineNumber - write line number (and related position info) to */
1632 /* address corespondence data for a single node */
1633 /*-----------------------------------------------------------------------*/
1634 static void
1635 dwWriteLineNumber (dwline * lp)
1637 static int curFileIndex = 1;
1638 static int curLine = 1;
1639 static char * curLabel = NULL;
1640 static int curOffset = 0;
1641 int deltaLine = lp->line - curLine;
1642 int deltaAddr = lp->offset - curOffset;
1643 int deltaAddrValid = curLabel && lp->label && !strcmp (lp->label, curLabel);
1645 //fprintf (dwarf2FilePtr, "; line %d\n", lp->line);
1646 if (lp->begin_sequence)
1648 curFileIndex = 1;
1649 curLine = 1;
1650 curLabel = NULL;
1651 curOffset = 0;
1653 if (lp->end_sequence)
1654 return;
1657 if (lp->fileIndex != curFileIndex)
1659 dwWriteByte (NULL, DW_LNS_set_file, NULL);
1660 dwWriteULEB128 (NULL, lp->fileIndex, NULL);
1661 curFileIndex = lp->fileIndex;
1664 if (lp->basic_block)
1666 dwWriteByte (NULL, DW_LNS_set_basic_block, NULL);
1669 if (lp->begin_sequence)
1671 dwWriteByte (NULL, 0, NULL);
1672 dwWriteULEB128 (NULL, 1+port->debugger.dwarf.addressSize, NULL);
1673 dwWriteByte (NULL, DW_LNE_set_address, NULL);
1674 dwWriteAddress (lp->label, lp->offset, NULL);
1675 curLabel = lp->label;
1676 curOffset = lp->offset;
1678 dwWriteByte (NULL, DW_LNS_advance_line, NULL);
1679 dwWriteSLEB128 (NULL, lp->line - 1, NULL);
1680 curLine = lp->line;
1682 dwWriteByte (NULL, DW_LNS_copy, NULL);
1684 else if (lp->end_sequence)
1686 if (deltaAddrValid)
1688 dwWriteByte (NULL, DW_LNS_advance_pc, NULL);
1689 dwWriteULEB128 (NULL, deltaAddr, NULL);
1691 else
1693 dwWriteByte (NULL, DW_LNS_fixed_advance_pc, NULL);
1694 dwWriteHalfDelta (lp->label, curLabel, lp->offset-curOffset);
1695 curLabel = lp->label;
1696 curOffset = lp->offset;
1699 dwWriteByte (NULL, 0, NULL);
1700 dwWriteULEB128 (NULL, 1, NULL);
1701 dwWriteByte (NULL, DW_LNE_end_sequence, NULL);
1703 else
1705 int usedSpecial = 0;
1707 /* Metrowerks CW08 V3.0 gets confused by this. Just use the long */
1708 /* encoding until we can find a more compatible phrasing. */
1709 #if 0
1710 if (deltaLine >= dwLineBase && deltaLine < (dwLineBase+dwLineRange))
1712 int opcode;
1714 /* try to build a "special" opcode */
1715 opcode = dwLineOpcodeBase + (deltaLine - dwLineBase);
1716 if (deltaAddrValid)
1717 opcode += deltaAddr*dwLineRange;
1719 if (opcode >= dwLineOpcodeBase && opcode <= 255)
1721 /* ok, we can use a "special" opcode */
1723 /* If the deltaAddr value was symbolic, it can't be part */
1724 /* of the "special" opcode, so encode it separately */
1725 if (!deltaAddrValid)
1727 dwWriteByte (NULL, DW_LNS_advance_pc, NULL);
1728 dwWriteULEB128Delta (lp->label, curLabel, lp->offset-curOffset);
1729 curLabel = lp->label;
1730 curOffset = lp->offset;
1733 /* Write the "special" opcode */
1734 dwWriteByte (NULL, opcode, NULL);
1735 curLine = lp->line;
1736 usedSpecial = 1;
1739 #endif
1741 /* If we couldn't use the "special" opcode, we will have to */
1742 /* encode this the long way. */
1743 if (!usedSpecial)
1745 #if 0 // Fails to assemble for initializations of local static variables. TODO: Use this, when possible, as DW_LNS_fixed_advance_pc is much shorter than DW_LNE_set_address below.
1746 dwWriteByte (NULL, DW_LNS_fixed_advance_pc, NULL);
1747 dwWriteHalfDelta (lp->label, curLabel, lp->offset-curOffset);
1748 #else // Todo: This was implemented to make initializations of local static variables compile, but stepping through those initializations in gdb reports "Cannot find bounds of current function".
1749 dwWriteByte (NULL, 0, NULL);
1750 dwWriteULEB128 (NULL, 1+port->debugger.dwarf.addressSize, NULL);
1751 dwWriteByte (NULL, DW_LNE_set_address, NULL);
1752 dwWriteAddress (lp->label, lp->offset, NULL);
1753 #endif
1754 curLabel = lp->label;
1755 curOffset = lp->offset;
1757 dwWriteByte (NULL, DW_LNS_advance_line, NULL);
1758 dwWriteSLEB128 (NULL, deltaLine, NULL);
1759 curLine = lp->line;
1761 dwWriteByte (NULL, DW_LNS_copy, NULL);
1768 /*-----------------------------------------------------------------------*/
1769 /* dwWriteLineNumbers - write all the source line number position data */
1770 /* to the .debug_line section */
1771 /*-----------------------------------------------------------------------*/
1772 static void
1773 dwWriteLineNumbers (void)
1775 char * includeDir;
1776 dwfile * srcfile;
1777 dwline * lp;
1779 tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_line (NOLOAD)");
1781 dwWriteWordDelta ("Ldebug_line_end", "Ldebug_line_start");
1783 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_line_start");
1785 dwWriteHalf (NULL, 2, NULL); /* DWARF version */
1787 dwWriteWordDelta ("Ldebug_line_stmt-6", "Ldebug_line_start");
1789 dwWriteByte (NULL, 1, NULL); /* we track everything in 1 byte increments */
1791 dwWriteByte (NULL, 1, NULL); /* assume every line is a new statement */
1793 dwWriteByte (NULL, dwLineBase, NULL);
1794 dwWriteByte (NULL, dwLineRange, NULL);
1796 dwWriteByte (NULL, 9+1, NULL); /* there are 9 standard opcodes */
1798 dwWriteByte (NULL, 0, NULL); /* number of DW_LNS_copy arguments */
1799 dwWriteByte (NULL, 1, NULL); /* number of DW_LNS_advance_pc arguments */
1800 dwWriteByte (NULL, 1, NULL); /* number of DW_LNS_advance_line arguments */
1801 dwWriteByte (NULL, 1, NULL); /* number of DW_LNS_set_file arguments */
1802 dwWriteByte (NULL, 1, NULL); /* number of DW_LNS_set_column arguments */
1803 dwWriteByte (NULL, 0, NULL); /* number of DW_LNS_negate_stmt arguments */
1804 dwWriteByte (NULL, 0, NULL); /* number of DW_LNS_set_basic_block arguments */
1805 dwWriteByte (NULL, 0, NULL); /* number of DW_LNS_const_add_pc arguments */
1806 dwWriteByte (NULL, 1, NULL); /* number of DW_LNS_fixed_advance_pc arguments */
1808 /* Write the list of source directories searched */
1809 for (includeDir = setFirstItem (includeDirsSet);
1810 includeDir;
1811 includeDir = setNextItem(includeDirsSet) )
1812 dwWriteString (includeDir, NULL);
1813 dwWriteByte (NULL, 0, NULL);
1815 /* Write the list of source files used */
1816 for (srcfile = setFirstItem (dwFilenameSet);
1817 srcfile;
1818 srcfile = setNextItem(dwFilenameSet) )
1820 dwWriteString (srcfile->name, NULL);
1821 dwWriteULEB128 (NULL, srcfile->dirIndex, NULL);
1822 dwWriteULEB128 (NULL, srcfile->timestamp, NULL);
1823 dwWriteULEB128 (NULL, srcfile->length, NULL);
1825 dwWriteByte (NULL, 0, NULL);
1827 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_line_stmt");
1829 lp = dwLineFirst;
1830 if (lp)
1831 lp->begin_sequence = 1;
1832 while (lp)
1834 dwWriteLineNumber (lp);
1835 if (lp->end_sequence && lp->next)
1836 lp->next->begin_sequence = 1;
1837 lp = lp->next;
1840 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_line_end");
1843 /*------------------------------------------------------------------------*/
1846 static void
1847 dwWriteCFAinstructions (dwcfins *ip)
1849 dwcfop * op = ip->first;
1851 while (op)
1853 dwWriteByte (NULL, op->opcode, NULL);
1854 switch (op->opcode >> 6)
1856 case 0:
1857 switch (op->opcode)
1859 case DW_CFA_set_loc:
1860 dwWriteAddress (op->label, op->operand1, NULL);
1861 break;
1863 case DW_CFA_advance_loc1:
1864 dwWriteByte (NULL, op->operand1, NULL);
1865 break;
1867 case DW_CFA_advance_loc2:
1868 dwWriteHalf (NULL, op->operand1, NULL);
1869 break;
1871 case DW_CFA_advance_loc4:
1872 dwWriteWord (NULL, op->operand1, NULL);
1873 break;
1875 case DW_CFA_def_cfa:
1876 case DW_CFA_register:
1877 case DW_CFA_offset_extended:
1878 dwWriteULEB128 (NULL, op->operand1, NULL);
1879 dwWriteULEB128 (NULL, op->operand2, NULL);
1880 break;
1882 case DW_CFA_undefined:
1883 case DW_CFA_same_value:
1884 case DW_CFA_def_cfa_register:
1885 case DW_CFA_def_cfa_offset:
1886 case DW_CFA_restore_extended:
1887 dwWriteULEB128 (NULL, op->operand1, NULL);
1888 break;
1890 break;
1892 case DW_CFA_restore >> 6:
1893 case DW_CFA_advance_loc >> 6:
1894 break;
1896 case DW_CFA_offset >> 6:
1897 dwWriteULEB128 (NULL, op->operand1, NULL);
1898 break;
1900 op = op->next;
1904 static int
1905 dwSizeofCFAinstructions (dwcfins *ip)
1907 int size = 0;
1908 dwcfop * op = ip->first;
1910 while (op)
1912 size++;
1913 switch (op->opcode >> 6)
1915 case 0:
1916 switch (op->opcode)
1918 case DW_CFA_set_loc:
1919 size += port->debugger.dwarf.addressSize;
1920 break;
1922 case DW_CFA_advance_loc1:
1923 size += 1;
1924 break;
1926 case DW_CFA_advance_loc2:
1927 size += 2;
1928 break;
1930 case DW_CFA_advance_loc4:
1931 size += 4;
1932 break;
1934 case DW_CFA_def_cfa:
1935 case DW_CFA_register:
1936 case DW_CFA_offset_extended:
1937 size += dwSizeofULEB128 (op->operand1);
1938 size += dwSizeofULEB128 (op->operand2);
1939 break;
1941 case DW_CFA_undefined:
1942 case DW_CFA_same_value:
1943 case DW_CFA_def_cfa_register:
1944 case DW_CFA_def_cfa_offset:
1945 case DW_CFA_restore_extended:
1946 size += dwSizeofULEB128 (op->operand1);
1947 break;
1949 break;
1951 case DW_CFA_restore >> 6:
1952 case DW_CFA_advance_loc >> 6:
1953 break;
1955 case DW_CFA_offset >> 6:
1956 size += dwSizeofULEB128 (op->operand1);
1957 break;
1959 op = op->next;
1961 return size;
1964 static dwcfop *
1965 dwNewCFop (int opcode)
1967 dwcfop * op;
1969 op = Safe_alloc (sizeof (dwcfop));
1970 op->opcode = opcode;
1972 return op;
1975 static dwcfins *
1976 dwNewCFins (void)
1978 return (dwcfins *) Safe_alloc (sizeof (dwcfins));
1981 static void
1982 dwAddCFinsOp (dwcfins * ip, dwcfop *op)
1984 if (ip->last)
1985 ip->last->next = op;
1986 else
1987 ip->first = op;
1988 ip->last = op;
1991 static void
1992 dwGenCFIins (int callsize, int id)
1994 dwcfins * ip;
1995 dwcfop * op;
1996 int i;
1997 char s[32];
1998 int padding;
2000 tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_frame (NOLOAD)");
2002 /* FIXME: these two dw should be combined into a dd */
2003 tfprintf (dwarf2FilePtr, "\t!dw\t0\n");
2004 tfprintf (dwarf2FilePtr, "\t!dw\t");
2005 tfprintf (dwarf2FilePtr, "Ldebug_CIE%d_end-Ldebug_CIE%d_start\n", id, id);
2007 snprintf(s, sizeof(s), "Ldebug_CIE%d_start", id);
2008 tfprintf (dwarf2FilePtr, "!slabeldef\n", s);
2010 tfprintf (dwarf2FilePtr, "\t!dw\t0xffff\n");
2011 tfprintf (dwarf2FilePtr, "\t!dw\t0xffff\n"); /* CIE_id */
2013 tfprintf (dwarf2FilePtr, "\t!db\t%d\n",1); /* CIE version number */
2015 tfprintf (dwarf2FilePtr, "\t!db\t%d\n",0); /* augmentation (none) */
2017 dwWriteULEB128 (NULL, 1, NULL); /* code alignment factor */
2019 dwWriteSLEB128 (NULL, (port->stack.direction > 0) ? 1 : -1, NULL); /* data alignment factor */
2021 dwWriteByte (NULL, port->debugger.dwarf.regNumRet, NULL);
2023 ip = dwNewCFins ();
2025 /* Define the CFA as the SP at the previous frame (call site) */
2026 /* The return address is then at CFA-1 (for stm8) */
2027 op = dwNewCFop (DW_CFA_def_cfa);
2028 op->operand1 = port->debugger.dwarf.regNumSP;
2029 op->operand2 = port->debugger.dwarf.offsetSP;
2030 if (callsize == 3)
2031 op->operand2 = port->debugger.dwarf.offsetSP + port->stack.isr_overhead;
2032 dwAddCFinsOp (ip, op);
2034 op = dwNewCFop (DW_CFA_offset + port->debugger.dwarf.regNumRet);
2035 op->operand1 = 1; /* perhaps we need a way to configure this relative position for the ret pos? ARE*/
2036 dwAddCFinsOp (ip, op);
2038 if (port->debugger.dwarf.cfiUndef)
2039 for (i=0; i < port->debugger.dwarf.cfiUndef->size; i++)
2041 if (bitVectBitValue (port->debugger.dwarf.cfiUndef, i))
2043 op = dwNewCFop (DW_CFA_undefined);
2044 op->operand1 = i;
2045 dwAddCFinsOp (ip, op);
2049 if (port->debugger.dwarf.cfiSame)
2050 for (i=0; i < port->debugger.dwarf.cfiSame->size; i++)
2052 if (bitVectBitValue (port->debugger.dwarf.cfiSame, i))
2054 op = dwNewCFop (DW_CFA_same_value);
2055 op->operand1 = i;
2056 dwAddCFinsOp (ip, op);
2060 dwWriteCFAinstructions (ip);
2062 //pad with NOPs if needed to maintain 32-bit alignment
2063 padding = (4 - ((5 + dwSizeofCFAinstructions (ip)) & 3)) & 3;
2064 while (padding)
2066 dwWriteByte (NULL, DW_CFA_nop, NULL);
2067 padding--;
2070 op = ip->first;
2071 while (op)
2073 dwcfop * next;
2074 next = op->next;
2075 Safe_free(op);
2076 op = next;
2078 Safe_free(ip);
2080 snprintf(s, sizeof(s), "Ldebug_CIE%d_end", id);
2081 tfprintf (dwarf2FilePtr, "!slabeldef\n",s);
2085 static void
2086 dwWriteFDE (dwfde * fp, int id)
2088 int length = dwSizeofCFAinstructions(fp->ins) + 4
2089 + port->debugger.dwarf.addressSize * 2;
2090 int padding = (4 - (length & 3)) & 3;
2092 //length
2093 dwWriteWord (NULL, length + padding , NULL);
2095 //CIE ptr
2096 char s[32];
2097 snprintf(s, sizeof(s), "Ldebug_CIE%d_start-4", id);
2098 dwWriteWord (s, 0, NULL);
2100 //initial loc
2101 dwWriteAddress(fp->startLabel, 0, "initial loc");
2103 //address range
2104 dwWriteAddressDelta (fp->endLabel, fp->startLabel);
2106 //instructions
2107 dwWriteCFAinstructions (fp->ins);
2109 //pad with NOPs if needed to maintain 32-bit alignment
2110 while (padding)
2112 dwWriteByte (NULL, DW_CFA_nop, NULL);
2113 padding--;
2117 static void
2118 dwWriteFrames (void)
2120 dwfde fp;
2121 dwcfop * op;
2122 dwcfilist * cfip;
2123 dwlocregion * lrp;
2125 int id = 0;
2126 for (cfip = dwCFIRoot; cfip; cfip = cfip->next)
2128 if (!cfip->startLabel || !cfip->endLabel)
2129 continue;
2131 fp.startLabel=cfip->startLabel;
2132 fp.endLabel=cfip->endLabel;
2134 fp.ins = dwNewCFins();
2136 lrp = cfip->region;
2138 /* emit fde records */
2139 while (lrp)
2141 op = dwNewCFop (DW_CFA_set_loc);
2142 op->label = lrp->startLabel;
2143 op->operand1 = 0;
2144 dwAddCFinsOp (fp.ins, op);
2145 op = dwNewCFop (DW_CFA_def_cfa_offset);
2146 if (cfip->callsize == 3)
2147 op->operand1 = lrp->loc->operand.offset + port->debugger.dwarf.offsetSP - 1 + port->stack.isr_overhead;
2148 else
2149 op->operand1 = lrp->loc->operand.offset + port->debugger.dwarf.offsetSP - 1; /* another -1 constant that needs attention ARE*/
2150 dwAddCFinsOp (fp.ins, op);
2152 lrp = lrp ->next;
2155 dwGenCFIins(cfip->callsize, id);
2156 dwWriteFDE(&fp, id++);
2158 op = fp.ins->first;
2159 while (op)
2161 dwcfop * next;
2162 next = op->next;
2163 Safe_free(op);
2164 op = next;
2171 /*------------------------------------------------------------------------*/
2176 /*-----------------------------------------------------------------------*/
2177 /* dwHashType - return a hash code for a type chain */
2178 /*-----------------------------------------------------------------------*/
2179 static int
2180 dwHashType (sym_link * type)
2182 int hash = 0;
2184 while (type)
2186 hash = (hash << 5) ^ ((hash >> 8) & 0xff);
2187 if (IS_DECL (type))
2189 hash ^= DCL_TYPE (type);
2191 else
2193 hash ^= SPEC_NOUN (type)
2194 | (SPEC_CONST (type) << 4)
2195 | (SPEC_VOLATILE (type) << 5)
2196 | (SPEC_LONG (type) << 6)
2197 | (SPEC_LONGLONG (type) << 7);
2200 type = type->next;
2203 if (hash<0)
2204 return -hash;
2205 else
2206 return hash;
2209 /*-----------------------------------------------------------------------*/
2210 /* dwMatchType - returns true if two types match exactly (including type */
2211 /* qualifiers) */
2212 /*-----------------------------------------------------------------------*/
2213 static int
2214 dwMatchTypes (const void * type1v, const void * type2v)
2216 sym_link * type1 = (sym_link *)type1v;
2217 sym_link * type2 = (sym_link *)type2v;
2219 if (!type1 || !type2)
2220 return 0;
2222 while (type1 && type2)
2224 if (IS_SPEC(type1))
2226 if (IS_SPEC (type2))
2228 if (SPEC_NOUN (type1) != SPEC_NOUN (type2))
2229 return 0;
2230 if (SPEC_NOUN (type1) == V_STRUCT
2231 && SPEC_STRUCT (type1) != SPEC_STRUCT (type2))
2232 return 0;
2233 if (SPEC_CONST (type1) != SPEC_CONST (type2))
2234 return 0;
2235 if (SPEC_VOLATILE (type1) != SPEC_VOLATILE (type2))
2236 return 0;
2237 if (SPEC_SHORT (type1) != SPEC_SHORT (type2))
2238 return 0;
2239 if (SPEC_LONG (type1) != SPEC_LONG (type2))
2240 return 0;
2241 if (SPEC_LONGLONG (type1) != SPEC_LONGLONG (type2))
2242 return 0;
2243 if (SPEC_USIGN (type1) != SPEC_USIGN (type2))
2244 return 0;
2246 else
2247 return 0;
2249 else
2251 if (IS_DECL (type2))
2253 if (DCL_TYPE (type1) != DCL_TYPE (type2))
2254 return 0;
2255 if (DCL_PTR_CONST (type1) != DCL_PTR_CONST (type2))
2256 return 0;
2257 if (DCL_PTR_VOLATILE (type1) != DCL_PTR_VOLATILE (type2))
2258 return 0;
2259 if (DCL_TYPE (type1) == ARRAY
2260 && DCL_ELEM (type1) != DCL_ELEM (type2))
2261 return 0;
2262 /* FIXME: need to match function pointer parameters */
2264 else
2265 return 0;
2268 type1 = type1->next;
2269 type2 = type2->next;
2272 if (!type1 && !type2)
2273 return 1;
2274 else
2275 return 0;
2278 /*-----------------------------------------------------------------------*/
2279 /* dwTagFromType - returns the tag describing a type. If new tags need */
2280 /* to be created, they will be added under the specified */
2281 /* parent tag */
2282 /*-----------------------------------------------------------------------*/
2283 static dwtag *
2284 dwTagFromType (sym_link * type, dwtag * parent)
2286 dwtag * oldtp;
2287 dwtag * tp = NULL;
2288 dwtag * modtp;
2289 dwtag * subtp;
2290 int key;
2291 int tableUpdated = 0;
2293 key = dwHashType (type) % dwTypeTagTable->size;
2294 oldtp = hTabFindByKey (dwTypeTagTable, key, type, dwMatchTypes);
2295 if (oldtp)
2296 return oldtp;
2297 else
2299 if (IS_DECL (type))
2301 switch (DCL_TYPE (type))
2303 case POINTER:
2304 case FPOINTER:
2305 case CPOINTER:
2306 case GPOINTER:
2307 case PPOINTER:
2308 case IPOINTER:
2309 case EEPPOINTER:
2310 case UPOINTER:
2311 tp = dwNewTag (DW_TAG_pointer_type);
2312 if (type->next && !IS_VOID (type->next))
2314 subtp = dwTagFromType (type->next, parent);
2315 dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2317 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2318 getSize (type)));
2319 dwAddTagChild (parent, tp);
2320 if (DCL_PTR_VOLATILE (type))
2322 modtp = dwNewTag (DW_TAG_volatile_type);
2323 dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2324 dwAddTagChild (parent, modtp);
2325 tp = modtp;
2327 if (DCL_PTR_CONST (type))
2329 modtp = dwNewTag (DW_TAG_const_type);
2330 dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2331 dwAddTagChild (parent, modtp);
2332 tp = modtp;
2334 break;
2336 case ARRAY:
2337 tp = dwNewTag (DW_TAG_array_type);
2338 subtp = dwTagFromType (type->next, parent);
2339 dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2340 if (!subtp->parent)
2341 dwAddTagChild (tp, subtp);
2342 if (DCL_ELEM (type))
2344 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2345 getSize (type)));
2346 subtp = dwNewTag (DW_TAG_subrange_type);
2347 dwAddTagAttr (subtp, dwNewAttrConst (DW_AT_upper_bound,
2348 DCL_ELEM (type)-1));
2349 dwAddTagChild (tp, subtp);
2352 break;
2354 case FUNCTION:
2355 tp = dwNewTag (DW_TAG_subroutine_type);
2356 if (type->next && !IS_VOID (type->next))
2358 subtp = dwTagFromType (type->next, parent);
2359 dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2361 /* FIXME: need to handle function parameters */
2362 break;
2364 default:
2365 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2366 "unknown DCL_TYPE");
2367 exit (1);
2370 else
2372 if (IS_STRUCT (type))
2374 struct structdef * sdp = SPEC_STRUCT (type);
2375 symbol * field;
2377 tp = dwNewTag (sdp->type == STRUCT ? DW_TAG_structure_type
2378 : DW_TAG_union_type);
2379 if (*(sdp->tag))
2380 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, sdp->tag));
2382 /* FIXME: should only specify the size if we know this */
2383 /* is a complete type */
2384 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2385 getSize (type)));
2387 /* Must add this before processing the struct fields */
2388 /* in case there is a recursive definition. */
2389 hTabAddItemLong (&dwTypeTagTable, key, type, tp);
2390 tableUpdated = 1;
2392 field = sdp->fields;
2393 while (field)
2395 dwtag * memtp;
2396 dwloc * lp;
2398 if (IS_BITFIELD (field->type) && !SPEC_BLEN(field->type))
2400 field = field->next;
2401 continue;
2404 memtp = dwNewTag (DW_TAG_member);
2405 if (*(field->name))
2406 dwAddTagAttr (memtp, dwNewAttrString (DW_AT_name,
2407 field->name));
2408 if (IS_BITFIELD (field->type))
2410 unsigned blen = SPEC_BLEN (field->type);
2411 unsigned bstr = SPEC_BSTR (field->type);
2412 sym_link * type;
2414 dwAddTagAttr (memtp,
2415 dwNewAttrConst (DW_AT_byte_size,
2416 (blen+7)/8));
2417 dwAddTagAttr (memtp,
2418 dwNewAttrConst (DW_AT_bit_size, blen));
2419 dwAddTagAttr (memtp,
2420 dwNewAttrConst (DW_AT_bit_offset,
2421 ((blen+7) & ~7)
2422 - (blen+bstr)));
2423 if (blen < 8)
2424 type = typeFromStr ("Uc");
2425 else
2426 type = typeFromStr ("Ui");
2427 subtp = dwTagFromType (type, tp);
2428 dwAddTagAttr (memtp, dwNewAttrTagRef (DW_AT_type, subtp));
2430 else
2432 subtp = dwTagFromType (field->type, tp);
2433 dwAddTagAttr (memtp, dwNewAttrTagRef (DW_AT_type, subtp));
2434 if (!subtp->parent)
2435 dwAddTagChild (parent, subtp);
2438 lp = dwNewLoc (DW_OP_plus_uconst, NULL, field->offset);
2439 dwAddTagAttr (memtp,
2440 dwNewAttrLoc (DW_AT_data_member_location, lp));
2442 dwAddTagChild (tp, memtp);
2444 field = field->next;
2447 else if (SPEC_VOLATILE (type) || SPEC_CONST (type))
2449 sym_link temptype = *type;
2451 SPEC_VOLATILE (&temptype) = 0;
2452 SPEC_CONST (&temptype) = 0;
2453 tp = dwTagFromType (&temptype, parent);
2454 if (SPEC_VOLATILE (type))
2456 modtp = dwNewTag (DW_TAG_volatile_type);
2457 dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2458 dwAddTagChild (parent, modtp);
2459 tp = modtp;
2461 if (SPEC_CONST (type))
2463 modtp = dwNewTag (DW_TAG_const_type);
2464 dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2465 dwAddTagChild (parent, modtp);
2466 tp = modtp;
2469 else
2471 switch (SPEC_NOUN (type))
2473 case V_INT:
2474 tp = dwNewTag (DW_TAG_base_type);
2475 if (SPEC_USIGN (type))
2477 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2478 DW_ATE_unsigned));
2479 if (SPEC_LONGLONG (type))
2480 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name,
2481 "unsigned long long"));
2482 else if (SPEC_LONG (type))
2483 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name,
2484 "unsigned long"));
2485 else
2486 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name,
2487 "unsigned int"));
2489 else
2491 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2492 DW_ATE_signed));
2493 if (SPEC_LONGLONG (type))
2494 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "long long"));
2495 else if (SPEC_LONG (type))
2496 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "long"));
2497 else
2498 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "int"));
2500 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2501 getSize (type)));
2502 dwAddTagChild (dwRootTag, tp);
2503 break;
2505 case V_FLOAT:
2506 tp = dwNewTag (DW_TAG_base_type);
2507 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2508 DW_ATE_float));
2509 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "float"));
2510 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2511 getSize (type)));
2512 dwAddTagChild (dwRootTag, tp);
2513 break;
2515 case V_FIXED16X16:
2516 tp = dwNewTag (DW_TAG_base_type);
2517 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2518 DW_ATE_float));
2519 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "fixed16x16"));
2520 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2521 getSize (type)));
2522 dwAddTagChild (dwRootTag, tp);
2523 break;
2525 case V_BOOL:
2526 tp = dwNewTag (DW_TAG_base_type);
2527 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2528 DW_ATE_boolean));
2529 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "_Bool"));
2530 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2531 getSize (type)));
2532 dwAddTagChild (dwRootTag, tp);
2533 break;
2535 case V_CHAR:
2536 tp = dwNewTag (DW_TAG_base_type);
2537 if (SPEC_USIGN (type))
2539 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2540 DW_ATE_unsigned_char));
2541 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name,
2542 "unsigned char"));
2544 else
2546 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2547 DW_ATE_signed));
2548 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "signed char"));
2550 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2551 getSize (type)));
2552 dwAddTagChild (dwRootTag, tp);
2553 break;
2555 case V_VOID:
2556 case V_BIT:
2557 case V_BITFIELD:
2558 case V_SBIT:
2559 case V_DOUBLE:
2560 default:
2562 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2563 "unhandled base type");
2564 printTypeChain (type, NULL);
2565 exit (1);
2572 if (!tableUpdated)
2573 hTabAddItemLong (&dwTypeTagTable, key, type, tp);
2574 if (!tp->parent)
2575 dwAddTagChild (parent, tp);
2576 return tp;
2578 /*------------------------------------------------------------------------*/
2581 /*-----------------------------------------------------------------------*/
2582 /* dwOpenFile - open the debugging file (just initialize, since all */
2583 /* DWARF data goes into the assembly output file) */
2584 /*-----------------------------------------------------------------------*/
2586 dwOpenFile(const char *file)
2588 dwTypeTagTable = newHashTable (128);
2590 return 1;
2593 /*-----------------------------------------------------------------------*/
2594 /* dwCloseFile - close the debugging file (do nothing, since all DWARF */
2595 /* data goes into the assembly output file) */
2596 /*-----------------------------------------------------------------------*/
2598 dwCloseFile (void)
2600 return 1;
2604 /*-----------------------------------------------------------------------*/
2605 /* dwGenerateScopes - recursively traverse an ast, generating lexical */
2606 /* block tags for block scopes found */
2607 /*-----------------------------------------------------------------------*/
2608 static void
2609 dwGenerateScopes (dwtag *tp, ast * tree)
2611 dwtag *subtp;
2613 if (!tree)
2614 return;
2616 if (!IS_AST_OP (tree))
2617 return;
2619 if (tree->opval.op == BLOCK)
2621 subtp = dwNewTag (DW_TAG_lexical_block);
2622 if (tree->right)
2624 dwAddTagAttr (subtp, dwNewAttrConst (DW_AT_user_block, tree->right->block));
2625 dwAddTagAttr (subtp, dwNewAttrConst (DW_AT_user_level, tree->right->level));
2627 dwAddTagChild (tp, subtp);
2629 dwGenerateScopes (subtp, tree->right);
2631 else
2633 dwGenerateScopes (tp, tree->left);
2634 dwGenerateScopes (tp, tree->right);
2638 /*-----------------------------------------------------------------------*/
2639 /* dwFindScope - return the lexical block tag for a particular block */
2640 /* scope, or NULL if not found */
2641 /*-----------------------------------------------------------------------*/
2642 static dwtag *
2643 dwFindScope (dwtag * tp, int block)
2645 dwtag * rettp;
2646 dwattr * ap;
2648 if (!tp)
2649 return NULL;
2651 while (tp)
2653 if (tp->tag == DW_TAG_lexical_block)
2655 ap = tp->attribs;
2656 while (ap)
2658 if (ap->attr == DW_AT_user_block)
2660 if (ap->val.data == block)
2661 return tp;
2663 ap = ap->next;
2666 rettp = dwFindScope (tp->firstChild, block);
2667 if (rettp)
2668 return rettp;
2670 tp = tp->siblings;
2673 return NULL;
2676 /*------------------------------------------------------------------------*/
2677 /* dwWriteSymbolInternal - create tag information for a variable or */
2678 /* parameter and place it in the correct position */
2679 /* within the tag tree */
2680 /*------------------------------------------------------------------------*/
2681 static int
2682 dwWriteSymbolInternal (symbol *sym)
2684 dwtag *tp;
2685 dwtag *subtp;
2686 dwloc *lp;
2687 dwtag *scopetp;
2688 symbol *symloc;
2689 dwtag *functp;
2690 dwattr *funcap;
2691 bool inregs = FALSE;
2693 if (!sym->level || IS_EXTERN (sym->etype))
2694 scopetp = dwRootTag;
2695 else
2697 assert(sym->localof);
2698 if (!sym->localof)
2699 return 0;
2701 /* Find the tag for the function this symbol is defined in */
2702 functp = dwRootTag->firstChild;
2703 while (functp)
2705 if (functp->tag == DW_TAG_subprogram)
2707 funcap = dwFindAttr (functp, DW_AT_name);
2708 if (funcap && !strcmp (funcap->val.string, sym->localof->name))
2709 break;
2711 functp = functp->siblings;
2714 /* There might be no function found if it was only inlined and */
2715 /* not generated as a stand-alone function. In that case, */
2716 /* dwWriteSymbolInternal will be called again later in another */
2717 /* context where the function will be found. */
2718 if (!functp)
2719 return 0;
2721 /* Find the correct scope within this function */
2722 scopetp = dwFindScope (functp->firstChild, sym->block);
2723 if (!scopetp)
2724 scopetp = functp;
2727 tp = dwNewTag (sym->_isparm ? DW_TAG_formal_parameter : DW_TAG_variable);
2729 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, sym->name));
2731 /* Find the ultimate symbol holding the value. */
2732 /* Might be: */
2733 /* a) original symbol, */
2734 /* b) register equivalent, */
2735 /* c) spill location */
2736 symloc = sym;
2737 if (/*!sym->allocreq &&*/ sym->reqv)
2739 symloc = OP_SYMBOL (symloc->reqv);
2741 for (int i = 0; i < symloc->nRegs; i++)
2742 if (symloc->regs[i])
2744 inregs = TRUE;
2745 break;
2748 if (!inregs && symloc->isspilt && !symloc->remat)
2749 symloc = symloc->usl.spillLoc;
2752 lp = NULL;
2753 if (inregs) /* Variable (partially) in registers*/
2755 dwloc *reglp;
2756 dwloc *lastlp = NULL;
2757 symbol *spillloc = NULL;
2758 int regNum, i, stack = 0;
2759 int stackchange = port->little_endian ? port->stack.direction : -port->stack.direction;
2761 if ((spillloc = symloc->usl.spillLoc) && spillloc->onStack)
2762 stack = (port->little_endian ? spillloc->stack + symloc->nRegs - 1 : spillloc->stack);
2764 /* register allocation */
2765 for (i = (port->little_endian ? 0 : symloc->nRegs-1);
2766 (port->little_endian ? (i < symloc->nRegs) : (i >= 0));
2767 (port->little_endian ? i++ : i--), stack += stackchange)
2769 if (!symloc->regs[i]) /* Spilt byte of variable */
2771 if (!(spillloc && spillloc->onStack))
2773 lp = NULL;
2774 break;
2776 reglp = dwNewLoc (DW_OP_fbreg, NULL, stack);
2778 else /* Byte in registers */
2780 regNum = port->debugger.dwarf.regNum (symloc->regs[i]);
2781 if (regNum >= 0 && regNum <= 31)
2782 reglp = dwNewLoc (DW_OP_reg0 + regNum, NULL, 0);
2783 else if (regNum >= 0)
2784 reglp = dwNewLoc (DW_OP_regx, NULL, regNum);
2785 else
2787 /* We are forced to give up if the ABI for this port */
2788 /* does not define a number for this register */
2789 lp = NULL;
2790 break;
2794 if (lastlp)
2795 lastlp->next = reglp;
2796 else
2797 lp = reglp;
2798 lastlp = reglp;
2800 if (symloc->nRegs != 1)
2802 reglp = dwNewLoc (DW_OP_piece, NULL, 1);
2803 lastlp->next = reglp;
2804 lastlp = reglp;
2808 else if (symloc->onStack)
2810 /* stack allocation */
2811 lp = dwNewLoc (DW_OP_fbreg, NULL, symloc->stack);
2813 else
2815 /* global allocation */
2816 if (sym->level && !sym->allocreq)
2817 lp = NULL;
2818 else
2819 lp = dwNewLoc (DW_OP_addr, symloc->rname, 0);
2822 /* Only create the DW_AT_location if a known location exists. */
2823 /* It might not exist if the variable has been optimized away */
2824 /* or if the compiler has lost track of it (not good, but still */
2825 /* happens sometimes -- need to improve induction) */
2826 if (lp)
2827 dwAddTagAttr (tp, dwNewAttrLoc (DW_AT_location, lp));
2829 if (!IS_STATIC (sym->etype) && !sym->level)
2830 dwAddTagAttr (tp, dwNewAttrFlag (DW_AT_external, 1));
2831 if (IS_EXTERN (sym->etype))
2832 dwAddTagAttr (tp, dwNewAttrFlag (DW_AT_declaration, 1));
2834 subtp = dwTagFromType (sym->type, scopetp);
2835 dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2836 if (!subtp->parent)
2837 dwAddTagChild (scopetp, subtp);
2839 dwAddTagChild (scopetp, tp);
2840 return 1;
2844 /*-----------------------------------------------------------------------*/
2845 /* dwWriteFunction - generate a tag for a function. */
2846 /*-----------------------------------------------------------------------*/
2848 dwWriteFunction (symbol *sym, iCode *ic)
2850 dwtag * tp;
2851 value * args;
2853 /* Add this function to CFI list */
2854 dwcfilist * cfip;
2855 cfip = dwNewCFIlist();
2856 cfip->callsize = 1;
2857 if (FUNC_ISISR (sym->type))
2858 cfip->callsize = 3;
2859 cfip->next = dwCFIRoot;
2860 dwCFIRoot = cfip;
2861 dwCFILastLoc = NULL;
2863 dwFuncTag = tp = dwNewTag (DW_TAG_subprogram);
2865 dwAddTagAttr (dwFuncTag, dwNewAttrString (DW_AT_name, sym->name));
2867 dwAddTagAttr (dwFuncTag, dwNewAttrAddrSymbol (DW_AT_low_pc, sym, 0));
2869 if (FUNC_ISISR (sym->type))
2870 dwAddTagAttr (dwFuncTag, dwNewAttrConst (DW_AT_calling_convention,
2871 DW_CC_nocall));
2873 dwAddTagAttr (dwFuncTag, dwNewAttrFlag (DW_AT_external,
2874 !IS_STATIC (sym->etype)));
2876 if (sym->type->next && !IS_VOID (sym->type->next))
2878 dwtag * subtp;
2880 subtp = dwTagFromType (sym->type->next, dwRootTag);
2881 dwAddTagAttr (dwFuncTag, dwNewAttrTagRef (DW_AT_type, subtp));
2883 dwAddTagChild (dwRootTag, dwFuncTag);
2885 args = FUNC_ARGS(sym->type);
2886 while (args)
2888 dwWriteSymbolInternal (args->sym);
2889 args = args->next;
2891 if (FUNC_HASVARARGS (sym->type))
2893 dwAddTagChild (dwFuncTag, dwNewTag (DW_TAG_unspecified_parameters));
2896 while (ic && ic->op != FUNCTION)
2897 ic = ic->next;
2898 if (ic && ic->op == FUNCTION && ic->tree && ic->tree->right)
2900 dwGenerateScopes (dwFuncTag, ic->tree->right->left);
2901 dwGenerateScopes (dwFuncTag, ic->tree->right->right);
2904 dwScopeTag = NULL;
2905 dwScopeLevel = 0;
2907 return 1;
2911 /*-----------------------------------------------------------------------*/
2912 /* dwWriteEndFunction - write attributes to the current function tag */
2913 /* that are only known after code generation is */
2914 /* complete */
2915 /*-----------------------------------------------------------------------*/
2917 dwWriteEndFunction (symbol *sym, iCode *ic, int offset)
2919 char debugSym[SDCC_NAME_MAX + 1];
2921 if (ic)
2923 dwWriteCLine (ic);
2924 dwLineLast->offset += offset;
2925 dwLineLast->end_sequence = 1;
2928 if (IS_STATIC (sym->etype))
2929 sprintf (debugSym, "XF%s$%s$0$0", dwModuleName, sym->name);
2930 else
2931 sprintf (debugSym, "XG$%s$0$0", sym->name);
2932 emitDebuggerSymbol (debugSym);
2934 dwAddTagAttr (dwFuncTag, dwNewAttrAddrLabel (DW_AT_high_pc,
2935 Safe_strdup(debugSym),
2936 offset));
2938 if (dwFrameLocList)
2940 dwAddTagAttr (dwFuncTag, dwNewAttrLocRef (DW_AT_frame_base,
2941 dwFrameLocList));
2943 dwFrameLocList->next = dwRootLocList;
2944 dwRootLocList = dwFrameLocList;
2945 dwFrameLocList = NULL;
2948 return 1;
2952 /*-----------------------------------------------------------------------*/
2953 /* dwWriteLabel - generate a tag for a source level label */
2954 /*-----------------------------------------------------------------------*/
2956 dwWriteLabel (symbol *sym, const iCode *ic)
2958 char debugSym[SDCC_NAME_MAX + 1];
2959 dwtag * tp;
2961 /* ignore the compiler generated labels */
2962 if (sym->isitmp)
2963 return 1;
2965 sprintf (debugSym, "L%s$%s$%s", dwModuleName, currFunc->name, sym->name);
2966 emitDebuggerSymbol (debugSym);
2968 tp = dwNewTag (DW_TAG_label);
2969 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, sym->name));
2970 dwAddTagAttr (tp, dwNewAttrAddrLabel (DW_AT_low_pc,
2971 Safe_strdup (debugSym), 0));
2973 dwAddTagChild (dwFuncTag, tp);
2975 return 1;
2979 /*-----------------------------------------------------------------------*/
2980 /* dwWriteScope - add the starting and ending address attributes to a */
2981 /* a lexical block tag (created during dwWriteFunction) */
2982 /*-----------------------------------------------------------------------*/
2984 dwWriteScope (iCode *ic)
2986 char * debugSym = NULL;
2987 dwtag * scopetp;
2988 dwattr * ap;
2990 scopetp = dwFindScope (dwFuncTag->firstChild, ic->block);
2992 if (dwScopeTag && ic->level <= dwScopeLevel)
2994 debugSym = dwNewDebugSymbol ();
2995 emitDebuggerSymbol (debugSym);
2996 dwSetTagAttr (dwScopeTag, dwNewAttrAddrLabel (DW_AT_high_pc, debugSym, 0));
2998 dwScopeTag = scopetp;
2999 dwScopeLevel = ic->level;
3001 if (scopetp)
3003 ap = dwFindAttr (scopetp, DW_AT_low_pc);
3004 if (ap)
3005 return 1;
3007 if (!debugSym)
3008 debugSym = dwNewDebugSymbol ();
3009 emitDebuggerSymbol (debugSym);
3010 dwAddTagAttr (scopetp, dwNewAttrAddrLabel (DW_AT_low_pc, debugSym, 0));
3012 dwScopeTag = scopetp;
3013 dwScopeLevel = ic->level;
3016 return 1;
3019 /*-----------------------------------------------------------------------*/
3020 /* dwWriteSymbol - generate tags for global variables. This is actually */
3021 /* called for all variables and parameters, but we */
3022 /* process the non-global variables elsewhere. */
3023 /*-----------------------------------------------------------------------*/
3025 dwWriteSymbol (symbol *sym)
3027 if (IS_FUNC (sym->type))
3028 return 1;
3030 /* If it is an iTemp, then it is a local variable; ignore it */
3031 if (sym->isitmp)
3032 return 1;
3034 /* If it is an unused extern ignore it, or it might produce link failure */
3035 if (IS_EXTERN (sym->etype) && !sym->used)
3036 return 1;
3038 /* Ignore parameters; they must be handled specially so that they will */
3039 /* appear in the correct order */
3040 if (sym->_isparm)
3041 return 1;
3043 return dwWriteSymbolInternal (sym);
3047 /*-----------------------------------------------------------------------*/
3048 /* dwWriteType */
3049 /*-----------------------------------------------------------------------*/
3051 dwWriteType (structdef *sdef, int block, int inStruct, const char *tag)
3053 /* FIXME: needs implementation */
3054 return 1;
3058 /*-----------------------------------------------------------------------*/
3059 /* dwWriteModule - generates the root tag for this compilation unit */
3060 /*-----------------------------------------------------------------------*/
3062 dwWriteModule (const char *name)
3064 dwtag * tp;
3065 char *verid = (char*)Safe_alloc(125);
3067 dwModuleName = Safe_strdup (name);
3069 sprintf(verid, "SDCC version %s #%s", SDCC_VERSION_STR, getBuildNumber());
3071 tp = dwNewTag (DW_TAG_compile_unit);
3072 dwAddTagAttr (tp, dwNewAttrString (DW_AT_producer, verid));
3074 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_language, DW_LANG_C89));
3076 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, fullSrcFileName));
3078 dwAddTagAttr (tp, dwNewAttrLabelRef (DW_AT_stmt_list,
3079 "Ldebug_line_start", -4));
3081 dwRootTag = tp;
3083 return 1;
3087 /*-----------------------------------------------------------------------*/
3088 /* dwWriteCLine - generates a line number/position to address record for */
3089 /* C source */
3090 /*-----------------------------------------------------------------------*/
3092 dwWriteCLine (iCode *ic)
3094 dwline * lp;
3095 char * debugSym;
3097 if (ic->inlined)
3098 return 0;
3100 lp = Safe_alloc (sizeof (dwline));
3102 lp->line = ic->lineno;
3104 debugSym = dwNewDebugSymbol ();
3105 emitDebuggerSymbol (debugSym);
3106 lp->label = debugSym;
3107 lp->offset = 0;
3109 lp->fileIndex = dwFindFileIndex (ic->filename);
3111 if (!dwLineFirst)
3112 dwLineFirst = lp;
3113 else
3114 dwLineLast->next = lp;
3115 dwLineLast = lp;
3117 return 1;
3121 /*-----------------------------------------------------------------------*/
3122 /* dwWriteFrameAddress - note the current position of the frame pointer */
3123 /* address. The base address can be specified by */
3124 /* either a register or pointer variable, leaving */
3125 /* the other as NULL. If both are NULL, there is */
3126 /* no current frame pointer address defined. */
3127 /*-----------------------------------------------------------------------*/
3129 dwWriteFrameAddress(const char *variable, struct reg_info *reg, int offset)
3131 char * debugSym = NULL;
3132 dwlocregion * lrp;
3133 dwlocregion * cfi_lrp;
3134 dwloc * lp;
3135 int regNum;
3137 /* If there was a region open, close it */
3138 if (dwFrameLastLoc)
3140 debugSym = dwNewDebugSymbol ();
3141 emitDebuggerSymbol (debugSym);
3143 dwFrameLastLoc->endLabel = debugSym;
3144 dwFrameLastLoc = NULL;
3147 if (dwCFILastLoc)
3149 dwCFILastLoc->endLabel = debugSym;
3150 dwCFIRoot->endLabel = debugSym;
3154 if (!variable && !reg)
3155 return 1;
3157 /* Create a new debugger symbol for the start of the region if */
3158 /* we can't recycle the symbol at the end of the previous */
3159 if (!debugSym)
3161 debugSym = dwNewDebugSymbol ();
3162 emitDebuggerSymbol (debugSym);
3165 lrp = Safe_alloc (sizeof (dwlocregion));
3166 lrp->startLabel = debugSym;
3168 /*** Create a new loc region for CFI */
3169 cfi_lrp = Safe_alloc (sizeof (dwlocregion));
3170 cfi_lrp->startLabel = debugSym;
3171 cfi_lrp->loc = dwNewLoc (0, NULL, offset);
3172 if (dwCFILastLoc)
3174 dwCFILastLoc->next = cfi_lrp;
3176 else
3178 dwCFIRoot->region = cfi_lrp;
3179 dwCFIRoot->startLabel = debugSym;
3181 dwCFILastLoc = cfi_lrp;
3183 if (variable) /* frame pointer based from a global variable */
3185 dwloc * lp;
3187 lrp->loc = dwNewLoc (DW_OP_addr, variable, 0);
3188 lrp->loc->next = lp = dwNewLoc (DW_OP_deref_size, NULL, NEARPTRSIZE);
3189 if (offset)
3191 lp->next = dwNewLoc (DW_OP_consts, NULL, offset);
3192 lp->next->next = dwNewLoc (DW_OP_plus, NULL, 0);
3195 else if (reg) /* frame pointer based from a register */
3197 regNum = port->debugger.dwarf.regNum (reg);
3198 assert (regNum>=0);
3200 if (regNum>=0 && regNum<=31)
3202 if (offset)
3203 lrp->loc = dwNewLoc (DW_OP_breg0 + regNum, NULL, offset);
3204 else
3205 lrp->loc = dwNewLoc (DW_OP_reg0 + regNum, NULL, 0);
3207 else
3209 lrp->loc = lp = dwNewLoc (DW_OP_regx, NULL, regNum);
3210 if (offset)
3212 lp->next = dwNewLoc (DW_OP_consts, NULL, offset);
3213 lp->next->next = dwNewLoc (DW_OP_plus, NULL, 0);
3217 dwFrameLastLoc = lrp;
3219 if (!dwFrameLocList)
3220 dwFrameLocList = dwNewLocList();
3221 lrp->next = dwFrameLocList->region;
3222 dwFrameLocList->region = lrp;
3224 return 1;
3228 /*-----------------------------------------------------------------------*/
3229 /* dwWriteALine - generates a line number/position to address record for */
3230 /* assembly source */
3231 /*-----------------------------------------------------------------------*/
3233 dwWriteALine(const char *module, int Line)
3235 return 1;
3239 /*-----------------------------------------------------------------------*/
3240 /* dwarf2FinalizeFile - write all of the DWARF debugging data to the */
3241 /* debug file */
3242 /*-----------------------------------------------------------------------*/
3244 dwarf2FinalizeFile (FILE *of)
3246 int tagAddress = 11;
3247 int abbrevNum = 0;
3248 int attr;
3250 dwarf2FilePtr = of;
3252 /* Write the .debug_line section */
3253 dwWriteLineNumbers ();
3255 /* Assign the location list addresses (for cross references) */
3256 dwAssignLocListAddresses ();
3258 /* Write the .debug_loc section */
3259 dwWriteLocLists ();
3261 /* Delete our scope related user attributes; they were only needed to help */
3262 /* build the tag tree and have no meaning to (and may confuse) debuggers */
3263 attr = DW_AT_user_block;
3264 dwTraverseTag (dwRootTag, dwDeleteTagAttr, &attr);
3265 attr = DW_AT_user_level;
3266 dwTraverseTag (dwRootTag, dwDeleteTagAttr, &attr);
3268 /* Add a DW_AT_sibling attribute to all tags with children and siblings */
3269 dwTraverseTag (dwRootTag, dwAddSibAttr, NULL);
3271 /* Assign the tag abbreviations. The tags, attributes, and forms must */
3272 /* not change after this point. The attribute values may change as long */
3273 /* as the size of the value does not. */
3274 dwAbbrevTable = newHashTable (128);
3275 dwTraverseTag (dwRootTag, dwAssignAbbrev, &abbrevNum);
3277 /* Assign the tag addresses (for cross references) */
3278 dwTraverseTag (dwRootTag, dwAssignTagAddress, &tagAddress);
3280 /* Write the .debug_abbrev section */
3281 dwWriteAbbrevs (abbrevNum);
3283 /* Write the .debug_info section */
3284 dwWriteTags ();
3286 /* Write the .debug_pubnames section */
3287 dwWritePubnames ();
3289 dwWriteFrames ();
3291 return 1;