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
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 -------------------------------------------------------------------------*/
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
=
69 FILE *dwarf2FilePtr
= NULL
;
70 char *dwModuleName
= NULL
;
71 dwtag
*dwRootTag
= NULL
;
72 dwtag
*dwFuncTag
= NULL
;
73 dwtag
*dwScopeTag
= NULL
;
76 hTab
* dwTypeTagTable
;
79 long dwScopeLevel
= 0;
80 int dwDebugSymbol
= 0;
81 dwcfins
* dwCIEins
= NULL
;
82 dwlocregion
* dwFrameLastLoc
= NULL
;
83 dwloclist
* dwRootLocList
= NULL
;
84 dwloclist
* dwFrameLocList
= NULL
;
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 /*----------------------------------------------------------------------*/
99 dwNewDebugSymbol (void)
101 char debugSym
[SDCC_NAME_MAX
];
103 sprintf (debugSym
, "S%s$%s$%d", dwModuleName
, currFunc
->name
, dwDebugSymbol
);
105 return Safe_strdup (debugSym
);
109 /*----------------------------------------------------------------------*/
110 /* dwWriteByte - generate a single byte assembler constant in the form: */
112 /* .db label+offset ; comment */
114 /* The label and comment parameters are optional */
115 /*----------------------------------------------------------------------*/
117 dwWriteByte (const char * label
, int offset
, const char * comment
)
119 tfprintf (dwarf2FilePtr
, "\t!db\t");
123 fprintf (dwarf2FilePtr
, "%s+%d", label
, offset
);
125 fprintf (dwarf2FilePtr
, "%s", label
);
128 fprintf (dwarf2FilePtr
, "%d", offset
);
131 fprintf (dwarf2FilePtr
, "\t;%s\n", comment
);
133 fprintf (dwarf2FilePtr
, "\n");
136 /*----------------------------------------------------------------------*/
137 /* dwWriteHalf - generate a two byte assembler constant in the form: */
139 /* .dw label+offset ; comment */
141 /* The label and comment parameters are optional */
142 /*----------------------------------------------------------------------*/
144 dwWriteHalf (const char * label
, int offset
, char * comment
)
146 tfprintf (dwarf2FilePtr
, "\t!dw\t");
150 fprintf (dwarf2FilePtr
, "%s+%d", label
, offset
);
152 fprintf (dwarf2FilePtr
, "%s", label
);
155 fprintf (dwarf2FilePtr
, "%d", offset
);
158 fprintf (dwarf2FilePtr
, "\t;%s\n", comment
);
160 fprintf (dwarf2FilePtr
, "\n");
163 /*----------------------------------------------------------------------*/
164 /* dwWriteWord - generate a four byte assembler constant in the form: */
166 /* .dd label+offset ; comment */
168 /* The label and comment parameters are optional */
169 /*----------------------------------------------------------------------*/
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. */
177 tfprintf (dwarf2FilePtr
, "\t!dd\t");
181 fprintf (dwarf2FilePtr
, "%s+%d", label
, offset
);
183 fprintf (dwarf2FilePtr
, "%s", label
);
186 fprintf (dwarf2FilePtr
, "%d", offset
);
188 tfprintf (dwarf2FilePtr
, "\t!dw\t");
189 if (port
->little_endian
)
194 fprintf (dwarf2FilePtr
, "(%s+%d),0", label
, offset
);
196 fprintf (dwarf2FilePtr
, "(%s),0", label
);
199 fprintf (dwarf2FilePtr
, "%d,%d", offset
, offset
>> 16);
206 fprintf (dwarf2FilePtr
, "0,(%s+%d)", label
, offset
);
208 fprintf (dwarf2FilePtr
, "0,(%s)", label
);
211 fprintf (dwarf2FilePtr
, "%d,%d", offset
>> 16, offset
);
216 fprintf (dwarf2FilePtr
, "\t;%s\n", comment
);
218 fprintf (dwarf2FilePtr
, "\n");
222 /*----------------------------------------------------------------------*/
223 /* dwWriteULEB128 - generate an unsigned variable length assembler */
224 /* constant in the form: */
226 /* .uleb128 label+offset ; comment */
228 /* The label and comment parameters are optional */
229 /*----------------------------------------------------------------------*/
231 dwWriteULEB128 (char * label
, int offset
, char * comment
)
233 tfprintf (dwarf2FilePtr
, "\t.uleb128\t");
237 fprintf (dwarf2FilePtr
, "%s+%d", label
, offset
);
239 fprintf (dwarf2FilePtr
, "%s", label
);
242 fprintf (dwarf2FilePtr
, "%d", offset
);
245 fprintf (dwarf2FilePtr
, "\t;%s\n", comment
);
247 fprintf (dwarf2FilePtr
, "\n");
250 /*----------------------------------------------------------------------*/
251 /* dwWriteSLEB128 - generate a signed variable length assembler */
252 /* constant in the form: */
254 /* .sleb128 label+offset ; comment */
256 /* The label and comment parameters are optional */
257 /*----------------------------------------------------------------------*/
259 dwWriteSLEB128 (char * label
, int offset
, char * comment
)
261 tfprintf (dwarf2FilePtr
, "\t.sleb128\t");
265 fprintf (dwarf2FilePtr
, "%s+%d", label
, offset
);
267 fprintf (dwarf2FilePtr
, "%s", label
);
270 fprintf (dwarf2FilePtr
, "%d", offset
);
273 fprintf (dwarf2FilePtr
, "\t;%s\n", comment
);
275 fprintf (dwarf2FilePtr
, "\n");
279 /*----------------------------------------------------------------------*/
280 /* dwSizeofULEB128 - return the size (in bytes) of an unsigned variable */
281 /* length constant */
282 /*----------------------------------------------------------------------*/
284 dwSizeofULEB128 (int unsigned value
)
298 /*----------------------------------------------------------------------*/
299 /* dwSizeofSLEB128 - return the size (in bytes) of a signed variable */
300 /* length constant */
301 /*----------------------------------------------------------------------*/
303 dwSizeofSLEB128 (int value
)
306 int negative
= (value
< 0);
315 value
|= (0x7f << (sizeof(int)*8 - 7));
316 if ((value
== 0 && !sign
) || (value
== -1 && sign
))
323 /*----------------------------------------------------------------------*/
324 /* dwWriteString - generate a string constant in the form: */
326 /* .ascii /string/ ; comment */
328 /* The comment parameter is optional. The string may contain any */
329 /* non-null characters */
330 /*----------------------------------------------------------------------*/
332 dwWriteString (const char * string
, const char * comment
)
334 char * escaped
= string_escape (string
);
335 tfprintf (dwarf2FilePtr
, "\t!ascii\n", escaped
);
337 dwWriteByte (NULL
, 0, comment
);
341 /*----------------------------------------------------------------------*/
342 /* dwWriteAddress - generate an assembler constant in the form: */
344 /* .dw label+offset ; comment */
345 /* or .dd label+offset ; comment */
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 /*----------------------------------------------------------------------*/
352 dwWriteAddress (const char * label
, int offset
, char * comment
)
354 switch (port
->debugger
.dwarf
.addressSize
)
357 dwWriteHalf (label
, offset
, comment
);
360 dwWriteWord (label
, offset
, comment
);
363 werror (E_INTERNAL_ERROR
, __FILE__
, __LINE__
,
364 "unsupported port->debugger.dwarf.addressSize");
369 /*----------------------------------------------------------------------*/
370 /* dwWriteHalfDelta - generate a two byte assembler constant in the */
373 /* .dw offset+label1-label2 */
375 /* The offset parameter is optional */
376 /*----------------------------------------------------------------------*/
378 dwWriteHalfDelta (char * label1
, char * label2
, int offset
)
381 tfprintf (dwarf2FilePtr
, "\t!dw\t%d+%s-%s\n", offset
, label1
, label2
);
383 tfprintf (dwarf2FilePtr
, "\t!dw\t%s-%s\n", label1
, label2
);
386 /*----------------------------------------------------------------------*/
387 /* dwWriteWordDelta - generate a four byte assembler constant in the */
390 /* .dd label1-label2 */
391 /*----------------------------------------------------------------------*/
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 */
398 tfprintf (dwarf2FilePtr
, "\t!dd\t%s-%s\n", label1
,label2
);
400 if (port
->little_endian
)
402 tfprintf (dwarf2FilePtr
, "\t!dw\t%s-%s,%d\n", label1
, label2
, 0);
406 tfprintf (dwarf2FilePtr
, "\t!dw\t%d,%s-%s\n", 0, label1
, label2
);
412 /*----------------------------------------------------------------------*/
413 /* dwWriteAddressDelta - generate an assembler constant in the form: */
415 /* .dw label1-label2 */
416 /* or .dd label1-label2 */
418 /* depending on how the relevant ABI defines the address size (may be */
419 /* larger than the CPU's actual address size) */
420 /*----------------------------------------------------------------------*/
422 dwWriteAddressDelta (char * label1
, char * label2
)
424 switch (port
->debugger
.dwarf
.addressSize
)
427 dwWriteHalfDelta (label1
, label2
, 0);
430 dwWriteWordDelta (label1
, label2
);
433 werror (E_INTERNAL_ERROR
, __FILE__
, __LINE__
,
434 "unsupported port->debugger.dwarf.addressSize");
439 /*----------------------------------------------------------------------*/
440 /* dwWriteULEB128Delta - generate an unsigned variable byte assembler */
441 /* constant in the form: */
443 /* .uleb128 offset+label1-label2 */
445 /* The offset parameter is optional */
446 /*----------------------------------------------------------------------*/
448 dwWriteULEB128Delta (char * label1
, char * label2
, int offset
)
451 tfprintf (dwarf2FilePtr
, "\t.uleb128\t%d+%s-%s\n", offset
, label1
, label2
);
453 tfprintf (dwarf2FilePtr
, "\t.uleb128\t%s-%s\n", label1
, label2
);
457 /*------------------------------------------------------------------------*/
459 /*----------------------------------------------------------------------*/
460 /* dwNewCFIlist - allocates a new CFI list node */
461 /*----------------------------------------------------------------------*/
467 p
= Safe_alloc (sizeof (dwcfilist
));
472 /*----------------------------------------------------------------------*/
473 /* dwNewLoc - allocates a new location expression node */
474 /*----------------------------------------------------------------------*/
476 dwNewLoc (int opcode
, const char * label
, int offset
)
480 lp
= Safe_alloc (sizeof (dwloc
));
483 lp
->operand
.label
= label
;
484 lp
->operand
.offset
= offset
;
489 /*-------------------------------------------------------------------------*/
490 /* dwSizeofLoc - returns the size (in bytes) of a chain of location */
491 /* expression nodes as they would be encoded by dwWriteLoc() */
492 /*-------------------------------------------------------------------------*/
494 dwSizeofLoc (dwloc
* lp
)
504 size
+= port
->debugger
.dwarf
.addressSize
;
507 case DW_OP_deref_size
:
508 case DW_OP_xderef_size
:
534 case DW_OP_plus_uconst
:
535 size
+= dwSizeofULEB128 (lp
->operand
.offset
);
571 size
+= dwSizeofSLEB128 (lp
->operand
.offset
);
581 /*------------------------------------------------------------------------*/
582 /* dwWriteLoc - writes a chain of location expression nodes */
583 /*------------------------------------------------------------------------*/
585 dwWriteLoc (dwloc
*lp
)
589 dwWriteByte (NULL
, lp
->opcode
, NULL
);
593 dwWriteAddress (lp
->operand
.label
, lp
->operand
.offset
, NULL
);
596 case DW_OP_deref_size
:
597 case DW_OP_xderef_size
:
601 dwWriteByte (NULL
, lp
->operand
.offset
, NULL
);
608 dwWriteHalf (NULL
, lp
->operand
.offset
, NULL
);
613 dwWriteWord (NULL
, lp
->operand
.offset
, NULL
);
618 case DW_OP_plus_uconst
:
619 dwWriteULEB128 (NULL
, lp
->operand
.offset
, NULL
);
655 dwWriteSLEB128 (NULL
, lp
->operand
.offset
, NULL
);
663 /*----------------------------------------------------------------------*/
664 /* dwNewLocList - allocates a new list of location expression node */
665 /*----------------------------------------------------------------------*/
671 llp
= Safe_alloc (sizeof (dwloclist
));
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 /*----------------------------------------------------------------------*/
682 dwSizeofLocRegion (dwlocregion
* lrp
)
688 size
+= 2 * port
->debugger
.dwarf
.addressSize
;
689 size
+= 2 + dwSizeofLoc (lrp
->loc
);
693 size
+= 2 * port
->debugger
.dwarf
.addressSize
;
697 /*-----------------------------------------------------------------------*/
698 /* dwAssignLocListAddresses - assign the address offsets of the location */
699 /* lists so that they can be referenced from */
700 /* the tag structure */
701 /*-----------------------------------------------------------------------*/
703 dwAssignLocListAddresses (void)
711 llp
->baseOffset
= address
;
712 address
+= dwSizeofLocRegion (llp
->region
);
718 /*-----------------------------------------------------------------------*/
719 /* dwWriteLocLists - write all of the location lists in dwRootLocList to */
720 /* the .debug_loc section */
721 /*-----------------------------------------------------------------------*/
723 dwWriteLocLists (void)
728 tfprintf (dwarf2FilePtr
, "\n\t!area\n", ".debug_loc (NOLOAD)");
729 tfprintf (dwarf2FilePtr
, "!slabeldef\n", "Ldebug_loc_start");
734 //fprintf (dwarf2FilePtr, "; baseOffset = 0x%x\n", llp->baseOffset);
738 dwWriteAddress (lrp
->startLabel
, 0, NULL
);
739 dwWriteAddress (lrp
->endLabel
, 0, NULL
);
740 dwWriteHalf (NULL
, dwSizeofLoc (lrp
->loc
), NULL
);
741 dwWriteLoc (lrp
->loc
);
745 dwWriteAddress (NULL
, 0, NULL
);
746 dwWriteAddress (NULL
, 0, NULL
);
754 /*------------------------------------------------------------------------*/
757 /*----------------------------------------------------------------------*/
758 /* dwNewAttr - allocate a new tag attribute node */
759 /*----------------------------------------------------------------------*/
765 ap
= Safe_alloc ( sizeof (dwattr
));
771 /*----------------------------------------------------------------------*/
772 /* dwFreeAttr - deallocate a tag attribute node */
773 /*----------------------------------------------------------------------*/
775 dwFreeAttr (dwattr
* ap
)
781 /*-------------------------------------------------------------------------*/
782 /* dwNewAttrString - allocate a new tag attribute node with a string value */
783 /*-------------------------------------------------------------------------*/
785 dwNewAttrString (int attr
, const char * string
)
789 ap
= dwNewAttr (attr
);
790 ap
->form
= DW_FORM_string
;
791 ap
->val
.string
= string
;
796 /*---------------------------------------------------------------------*/
797 /* dwNewAttrConst - allocate a new tag attribute node with an unsigned */
798 /* numeric constant value */
799 /*---------------------------------------------------------------------*/
801 dwNewAttrConst (int attr
, unsigned int data
)
805 ap
= dwNewAttr (attr
);
807 ap
->form
= DW_FORM_data1
;
808 else if (data
<= 0xffffu
)
809 ap
->form
= DW_FORM_data2
;
811 ap
->form
= DW_FORM_data4
;
817 /* disabled to eliminiate unused function warning */
819 /*---------------------------------------------------------------------*/
820 /* dwNewAttrSignedConst - allocate a new tag attribute node with a */
821 /* signed numeric constant value */
822 /*---------------------------------------------------------------------*/
824 dwNewAttrSignedConst (int attr
, int data
)
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
;
834 ap
->form
= DW_FORM_data4
;
841 /*---------------------------------------------------------------------*/
842 /* dwNewAttrFlag - allocate a new tag attribute node with a boolean */
843 /* flag value (zero/non-zero) */
844 /*---------------------------------------------------------------------*/
846 dwNewAttrFlag (int attr
, int data
)
850 ap
= dwNewAttr (attr
);
851 ap
->form
= DW_FORM_flag
;
857 /*---------------------------------------------------------------------*/
858 /* dwNewAttrAddrSymbol - allocate a new tag attribute node with the */
859 /* address of a C symbol plus an offset */
860 /*---------------------------------------------------------------------*/
862 dwNewAttrAddrSymbol (int attr
, symbol
* sym
, int offset
)
866 ap
= dwNewAttr (attr
);
867 ap
->form
= DW_FORM_addr
;
869 ap
->val
.symaddr
.label
= sym
->rname
;
870 ap
->val
.symaddr
.offset
= offset
;
874 /*---------------------------------------------------------------------*/
875 /* dwNewAttrAddrLabel - allocate a new tag attribute node with the */
876 /* address of an assembler label plus an offset */
877 /*---------------------------------------------------------------------*/
879 dwNewAttrAddrLabel (int attr
, char * label
, int offset
)
883 ap
= dwNewAttr (attr
);
884 ap
->form
= DW_FORM_addr
;
886 ap
->val
.symaddr
.label
= label
;
887 ap
->val
.symaddr
.offset
= offset
;
891 /*---------------------------------------------------------------------*/
892 /* dwNewAttrTagRef - allocate a new tag attribute node that references */
894 /*---------------------------------------------------------------------*/
896 dwNewAttrTagRef (int attr
, dwtag
* tp
)
900 ap
= dwNewAttr (attr
);
901 ap
->form
= DW_FORM_ref4
;
907 /*---------------------------------------------------------------------*/
908 /* dwNewAttrLocRef - allocate a new tag attribute node that references */
909 /* a location list */
910 /*---------------------------------------------------------------------*/
912 dwNewAttrLocRef (int attr
, dwloclist
* llp
)
916 ap
= dwNewAttr (attr
);
917 ap
->form
= DW_FORM_data4
;
919 ap
->val
.loclist
= llp
;
923 /*-----------------------------------------------------------------------*/
924 /* dwNewAttrLabelRef - allocate a new tag attribute node that references */
925 /* the address of an assembler label plus an offset */
926 /*-----------------------------------------------------------------------*/
928 dwNewAttrLabelRef (int attr
, char * label
, int offset
)
932 ap
= dwNewAttr (attr
);
933 ap
->form
= DW_FORM_data4
;
935 ap
->val
.symaddr
.label
= label
;
936 ap
->val
.symaddr
.offset
= offset
;
940 /*---------------------------------------------------------------------*/
941 /* dwNewAttrLoc - allocate a new tag attribute node for a chain of */
942 /* location expression nodes */
943 /*---------------------------------------------------------------------*/
945 dwNewAttrLoc (int attr
, dwloc
* lp
)
949 ap
= dwNewAttr (attr
);
950 ap
->form
= DW_FORM_block1
;
956 /*---------------------------------------------------------------------*/
957 /* dwWriteAttr - write a tag attribute node */
958 /*---------------------------------------------------------------------*/
960 dwWriteAttr (dwattr
* ap
)
966 dwWriteAddress (ap
->val
.symaddr
.label
, ap
->val
.symaddr
.offset
, NULL
);
970 dwWriteULEB128 (NULL
, dwSizeofLoc (ap
->val
.loc
), NULL
);
971 dwWriteLoc (ap
->val
.loc
);
975 dwWriteByte (NULL
, dwSizeofLoc (ap
->val
.loc
), NULL
);
976 dwWriteLoc (ap
->val
.loc
);
980 dwWriteHalf (NULL
, dwSizeofLoc (ap
->val
.loc
), NULL
);
981 dwWriteLoc (ap
->val
.loc
);
985 dwWriteWord (NULL
, dwSizeofLoc (ap
->val
.loc
), NULL
);
986 dwWriteLoc (ap
->val
.loc
);
991 dwWriteByte (NULL
, ap
->val
.data
, NULL
);
995 dwWriteHalf (NULL
, ap
->val
.data
, NULL
);
1001 case DW_AT_stmt_list
:
1002 dwWriteWord (ap
->val
.symaddr
.label
, ap
->val
.symaddr
.offset
, NULL
);
1004 case DW_AT_location
:
1005 case DW_AT_frame_base
:
1006 dwWriteWord ("Ldebug_loc_start", ap
->val
.loclist
->baseOffset
, NULL
);
1009 dwWriteWord (NULL
, ap
->val
.data
, NULL
);
1014 dwWriteULEB128 (NULL
, ap
->val
.data
, NULL
);
1018 dwWriteSLEB128 (NULL
, ap
->val
.data
, NULL
);
1021 case DW_FORM_string
:
1022 dwWriteString (ap
->val
.string
, NULL
);
1026 dwWriteByte (NULL
, ap
->val
.ref
->baseOffset
, NULL
);
1030 dwWriteHalf (NULL
, ap
->val
.ref
->baseOffset
, NULL
);
1034 dwWriteWord (NULL
, ap
->val
.ref
->baseOffset
, NULL
);
1038 werror (E_INTERNAL_ERROR
, __FILE__
, __LINE__
,
1039 "unsupported DWARF form");
1044 /*---------------------------------------------------------------------*/
1045 /* dwSizeofAttr - returns the size (in bytes) of a tag attribute node */
1046 /* as encoded by dwWriteAttr */
1047 /*---------------------------------------------------------------------*/
1049 dwSizeofAttr (dwattr
* ap
)
1056 return port
->debugger
.dwarf
.addressSize
;
1059 size
= dwSizeofLoc (ap
->val
.loc
);
1060 return size
+ dwSizeofULEB128 (size
);
1062 case DW_FORM_block1
:
1063 size
= dwSizeofLoc (ap
->val
.loc
);
1066 case DW_FORM_block2
:
1067 size
= dwSizeofLoc (ap
->val
.loc
);
1070 case DW_FORM_block4
:
1071 size
= dwSizeofLoc (ap
->val
.loc
);
1085 return dwSizeofULEB128 (ap
->val
.data
);
1088 return dwSizeofSLEB128 (ap
->val
.data
);
1090 case DW_FORM_string
:
1091 return 1 + strlen (ap
->val
.string
);
1103 werror (E_INTERNAL_ERROR
, __FILE__
, __LINE__
,
1104 "unsupported DWARF form");
1111 /*---------------------------------------------------------------------*/
1112 /* dwFindAttr - for a tag node, return a pointer to a particular */
1113 /* attribute node, or NULL if not found */
1114 /*---------------------------------------------------------------------*/
1116 dwFindAttr (dwtag
* tp
, int attr
)
1123 if (ap
->attr
== attr
)
1133 /*------------------------------------------------------------------------*/
1136 /*----------------------------------------------------------------------*/
1137 /* dwNewTag - allocate a new tag node */
1138 /*----------------------------------------------------------------------*/
1144 tp
= Safe_alloc ( sizeof (dwtag
));
1150 /*----------------------------------------------------------------------*/
1151 /* dwAddTagAttr - add an attribute to a tag */
1152 /*----------------------------------------------------------------------*/
1154 dwAddTagAttr (dwtag
* tp
, dwattr
* ap
)
1160 else if (ap
->attr
< tp
->attribs
->attr
)
1162 ap
->next
= tp
->attribs
;
1167 curap
= tp
->attribs
;
1168 while (curap
->next
&& curap
->next
->attr
< ap
->attr
)
1169 curap
= curap
->next
;
1170 ap
->next
= curap
->next
;
1175 /*----------------------------------------------------------------------*/
1176 /* dwSetTagAttr - repleace an existing attribute of a tag with a new */
1177 /* attribute or add if non-existent */
1178 /*----------------------------------------------------------------------*/
1180 dwSetTagAttr (dwtag
*tp
, dwattr
* ap
)
1184 curap
= dwFindAttr (tp
, ap
->attr
);
1187 ap
->next
= curap
->next
;
1192 dwAddTagAttr (tp
, ap
);
1196 /*----------------------------------------------------------------------*/
1197 /* dwAddTagChild - add a tag as a child of another tag */
1198 /*----------------------------------------------------------------------*/
1200 dwAddTagChild (dwtag
* parent
, dwtag
* child
)
1202 child
->parent
= parent
;
1203 if (parent
->lastChild
)
1205 parent
->lastChild
->siblings
= child
;
1206 parent
->lastChild
= child
;
1210 parent
->firstChild
= child
;
1211 parent
->lastChild
= child
;
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 /*----------------------------------------------------------------------*/
1223 dwMatchTagAttr (const void * tp1v
, const void * tp2v
)
1225 const dwtag
* tp1
= tp1v
;
1226 const dwtag
* tp2
= tp2v
;
1236 if (tp1
->tag
!= tp2
->tag
)
1239 if (tp1
->firstChild
&& !tp2
->lastChild
)
1241 if (!tp1
->firstChild
&& tp2
->lastChild
)
1246 if (ap1
->attr
!= ap2
->attr
)
1248 if (ap1
->form
!= ap2
->form
)
1258 /*----------------------------------------------------------------------*/
1259 /* dwHashTag - return a hash code for a tag based on its value and */
1261 /*----------------------------------------------------------------------*/
1263 dwHashTag (dwtag
* tp
)
1265 dwattr
* ap
= tp
->attribs
;
1270 hash
= (hash
<< 6) ^ ((hash
>> 11) & 0xff);
1271 hash
^= (ap
->attr
) | (ap
->form
<< 8);
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 */
1287 /*----------------------------------------------------------------------*/
1289 dwTraverseTag (dwtag
*tp
, int (*somefunc
)(dwtag
*tp
, void * info
), void * info
)
1295 rvalue
+= (*somefunc
)(tp
, info
);
1297 rvalue
+= dwTraverseTag (tp
->firstChild
, somefunc
, info
);
1300 rvalue
+= (*somefunc
)(NULL
, info
);
1305 /*----------------------------------------------------------------------*/
1306 /* dwAssignAbbrev - find a matching abbreviation for a tag or create a */
1307 /* a new one and assign it */
1308 /*----------------------------------------------------------------------*/
1310 dwAssignAbbrev (dwtag
*tp
, void *info
)
1313 int * anp
= info
; /* pointer to current abbreviation number */
1319 key
= dwHashTag (tp
) % dwAbbrevTable
->size
;
1320 oldtp
= hTabFindByKey (dwAbbrevTable
, key
, tp
, dwMatchTagAttr
);
1323 tp
->abbrev
= oldtp
->abbrev
;
1328 tp
->abbrev
= ++(*anp
);
1329 hTabAddItemLong (&dwAbbrevTable
, key
, tp
, tp
);
1334 /*-----------------------------------------------------------------------*/
1335 /* dwWriteAbbrevs - write the abbreviations to the .debug_abbrev section */
1336 /*-----------------------------------------------------------------------*/
1338 dwWriteAbbrevs (int abbrevNum
)
1343 dwtag
** tptable
= NULL
;
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
];
1362 dwWriteULEB128 (NULL
, tp
->abbrev
, NULL
);
1363 dwWriteULEB128 (NULL
, tp
->tag
, NULL
);
1364 dwWriteByte (NULL
, tp
->firstChild
? DW_CHILDREN_yes
: DW_CHILDREN_no
,
1369 dwWriteULEB128 (NULL
, ap
->attr
, NULL
);
1370 dwWriteULEB128 (NULL
, ap
->form
, NULL
);
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 /*-----------------------------------------------------------------------*/
1389 dwWriteTag (dwtag
*tp
, void *info
)
1395 /* mark the end of this series of siblings */
1396 dwWriteULEB128 (NULL
, 0, NULL
);
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 */
1417 /*-----------------------------------------------------------------------*/
1418 /* dwWriteTags - write all the tags to the .debug_info section */
1419 /*-----------------------------------------------------------------------*/
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
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 /*-----------------------------------------------------------------------*/
1454 dwAssignTagAddress (dwtag
*tp
, void *info
)
1465 tp
->baseOffset
= *tap
;
1467 *tap
+= dwSizeofULEB128 (tp
->abbrev
);
1472 *tap
+= dwSizeofAttr (ap
);
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 /*-----------------------------------------------------------------------*/
1485 dwAddSibAttr (dwtag
*tp
, void *info
)
1489 if (tp
== dwRootTag
)
1492 if (tp
->firstChild
&& tp
->siblings
)
1493 dwAddTagAttr (tp
, dwNewAttrTagRef (DW_AT_sibling
, tp
->siblings
));
1498 /*-----------------------------------------------------------------------*/
1499 /* dwDeleteTagAttr - given a pointer to an attribute type, delete any */
1500 /* matching attribute */
1501 /*-----------------------------------------------------------------------*/
1503 dwDeleteTagAttr (dwtag
*tp
, void *info
)
1505 int attr
= *((int *) info
);
1512 if (ap
&& ap
->attr
== attr
)
1514 tp
->attribs
= ap
->next
;
1520 if (ap
->next
&& ap
->next
->attr
== attr
)
1522 ap
->next
= ap
->next
->next
;
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 /*-----------------------------------------------------------------------*/
1540 dwWritePubnames (void)
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
;
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
);
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 /*-----------------------------------------------------------------------*/
1588 dwFindFileIndex (char * filename
)
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
);
1600 srcfile
= setNextItem(dwFilenameSet
), fileIndex
++ )
1602 if (!strcmp (srcfile
->name
, filename
))
1606 for (includeDir
= setFirstItem (includeDirsSet
);
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
)]))
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
);
1630 /*-----------------------------------------------------------------------*/
1631 /* dwWriteLineNumber - write line number (and related position info) to */
1632 /* address corespondence data for a single node */
1633 /*-----------------------------------------------------------------------*/
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
)
1653 if (lp
->end_sequence
)
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
);
1682 dwWriteByte (NULL
, DW_LNS_copy
, NULL
);
1684 else if (lp
->end_sequence
)
1688 dwWriteByte (NULL
, DW_LNS_advance_pc
, NULL
);
1689 dwWriteULEB128 (NULL
, deltaAddr
, NULL
);
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
);
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. */
1710 if (deltaLine
>= dwLineBase
&& deltaLine
< (dwLineBase
+dwLineRange
))
1714 /* try to build a "special" opcode */
1715 opcode
= dwLineOpcodeBase
+ (deltaLine
- dwLineBase
);
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
);
1741 /* If we couldn't use the "special" opcode, we will have to */
1742 /* encode this the long way. */
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
);
1754 curLabel
= lp
->label
;
1755 curOffset
= lp
->offset
;
1757 dwWriteByte (NULL
, DW_LNS_advance_line
, NULL
);
1758 dwWriteSLEB128 (NULL
, deltaLine
, NULL
);
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 /*-----------------------------------------------------------------------*/
1773 dwWriteLineNumbers (void)
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
);
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
);
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");
1831 lp
->begin_sequence
= 1;
1834 dwWriteLineNumber (lp
);
1835 if (lp
->end_sequence
&& lp
->next
)
1836 lp
->next
->begin_sequence
= 1;
1840 tfprintf (dwarf2FilePtr
, "!slabeldef\n", "Ldebug_line_end");
1843 /*------------------------------------------------------------------------*/
1847 dwWriteCFAinstructions (dwcfins
*ip
)
1849 dwcfop
* op
= ip
->first
;
1853 dwWriteByte (NULL
, op
->opcode
, NULL
);
1854 switch (op
->opcode
>> 6)
1859 case DW_CFA_set_loc
:
1860 dwWriteAddress (op
->label
, op
->operand1
, NULL
);
1863 case DW_CFA_advance_loc1
:
1864 dwWriteByte (NULL
, op
->operand1
, NULL
);
1867 case DW_CFA_advance_loc2
:
1868 dwWriteHalf (NULL
, op
->operand1
, NULL
);
1871 case DW_CFA_advance_loc4
:
1872 dwWriteWord (NULL
, op
->operand1
, NULL
);
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
);
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
);
1892 case DW_CFA_restore
>> 6:
1893 case DW_CFA_advance_loc
>> 6:
1896 case DW_CFA_offset
>> 6:
1897 dwWriteULEB128 (NULL
, op
->operand1
, NULL
);
1905 dwSizeofCFAinstructions (dwcfins
*ip
)
1908 dwcfop
* op
= ip
->first
;
1913 switch (op
->opcode
>> 6)
1918 case DW_CFA_set_loc
:
1919 size
+= port
->debugger
.dwarf
.addressSize
;
1922 case DW_CFA_advance_loc1
:
1926 case DW_CFA_advance_loc2
:
1930 case DW_CFA_advance_loc4
:
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
);
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
);
1951 case DW_CFA_restore
>> 6:
1952 case DW_CFA_advance_loc
>> 6:
1955 case DW_CFA_offset
>> 6:
1956 size
+= dwSizeofULEB128 (op
->operand1
);
1965 dwNewCFop (int opcode
)
1969 op
= Safe_alloc (sizeof (dwcfop
));
1970 op
->opcode
= opcode
;
1978 return (dwcfins
*) Safe_alloc (sizeof (dwcfins
));
1982 dwAddCFinsOp (dwcfins
* ip
, dwcfop
*op
)
1985 ip
->last
->next
= op
;
1992 dwGenCFIins (int callsize
, int id
)
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
);
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
;
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
);
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
);
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;
2066 dwWriteByte (NULL
, DW_CFA_nop
, NULL
);
2080 snprintf(s
, sizeof(s
), "Ldebug_CIE%d_end", id
);
2081 tfprintf (dwarf2FilePtr
, "!slabeldef\n",s
);
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;
2093 dwWriteWord (NULL
, length
+ padding
, NULL
);
2097 snprintf(s
, sizeof(s
), "Ldebug_CIE%d_start-4", id
);
2098 dwWriteWord (s
, 0, NULL
);
2101 dwWriteAddress(fp
->startLabel
, 0, "initial loc");
2104 dwWriteAddressDelta (fp
->endLabel
, fp
->startLabel
);
2107 dwWriteCFAinstructions (fp
->ins
);
2109 //pad with NOPs if needed to maintain 32-bit alignment
2112 dwWriteByte (NULL
, DW_CFA_nop
, NULL
);
2118 dwWriteFrames (void)
2126 for (cfip
= dwCFIRoot
; cfip
; cfip
= cfip
->next
)
2128 if (!cfip
->startLabel
|| !cfip
->endLabel
)
2131 fp
.startLabel
=cfip
->startLabel
;
2132 fp
.endLabel
=cfip
->endLabel
;
2134 fp
.ins
= dwNewCFins();
2138 /* emit fde records */
2141 op
= dwNewCFop (DW_CFA_set_loc
);
2142 op
->label
= lrp
->startLabel
;
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
;
2149 op
->operand1
= lrp
->loc
->operand
.offset
+ port
->debugger
.dwarf
.offsetSP
- 1; /* another -1 constant that needs attention ARE*/
2150 dwAddCFinsOp (fp
.ins
, op
);
2155 dwGenCFIins(cfip
->callsize
, id
);
2156 dwWriteFDE(&fp
, id
++);
2171 /*------------------------------------------------------------------------*/
2176 /*-----------------------------------------------------------------------*/
2177 /* dwHashType - return a hash code for a type chain */
2178 /*-----------------------------------------------------------------------*/
2180 dwHashType (sym_link
* type
)
2186 hash
= (hash
<< 5) ^ ((hash
>> 8) & 0xff);
2189 hash
^= DCL_TYPE (type
);
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);
2209 /*-----------------------------------------------------------------------*/
2210 /* dwMatchType - returns true if two types match exactly (including type */
2212 /*-----------------------------------------------------------------------*/
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
)
2222 while (type1
&& type2
)
2226 if (IS_SPEC (type2
))
2228 if (SPEC_NOUN (type1
) != SPEC_NOUN (type2
))
2230 if (SPEC_NOUN (type1
) == V_STRUCT
2231 && SPEC_STRUCT (type1
) != SPEC_STRUCT (type2
))
2233 if (SPEC_CONST (type1
) != SPEC_CONST (type2
))
2235 if (SPEC_VOLATILE (type1
) != SPEC_VOLATILE (type2
))
2237 if (SPEC_SHORT (type1
) != SPEC_SHORT (type2
))
2239 if (SPEC_LONG (type1
) != SPEC_LONG (type2
))
2241 if (SPEC_LONGLONG (type1
) != SPEC_LONGLONG (type2
))
2243 if (SPEC_USIGN (type1
) != SPEC_USIGN (type2
))
2251 if (IS_DECL (type2
))
2253 if (DCL_TYPE (type1
) != DCL_TYPE (type2
))
2255 if (DCL_PTR_CONST (type1
) != DCL_PTR_CONST (type2
))
2257 if (DCL_PTR_VOLATILE (type1
) != DCL_PTR_VOLATILE (type2
))
2259 if (DCL_TYPE (type1
) == ARRAY
2260 && DCL_ELEM (type1
) != DCL_ELEM (type2
))
2262 /* FIXME: need to match function pointer parameters */
2268 type1
= type1
->next
;
2269 type2
= type2
->next
;
2272 if (!type1
&& !type2
)
2278 /*-----------------------------------------------------------------------*/
2279 /* dwTagFromType - returns the tag describing a type. If new tags need */
2280 /* to be created, they will be added under the specified */
2282 /*-----------------------------------------------------------------------*/
2284 dwTagFromType (sym_link
* type
, dwtag
* parent
)
2291 int tableUpdated
= 0;
2293 key
= dwHashType (type
) % dwTypeTagTable
->size
;
2294 oldtp
= hTabFindByKey (dwTypeTagTable
, key
, type
, dwMatchTypes
);
2301 switch (DCL_TYPE (type
))
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
,
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
);
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
);
2337 tp
= dwNewTag (DW_TAG_array_type
);
2338 subtp
= dwTagFromType (type
->next
, parent
);
2339 dwAddTagAttr (tp
, dwNewAttrTagRef (DW_AT_type
, subtp
));
2341 dwAddTagChild (tp
, subtp
);
2342 if (DCL_ELEM (type
))
2344 dwAddTagAttr (tp
, dwNewAttrConst (DW_AT_byte_size
,
2346 subtp
= dwNewTag (DW_TAG_subrange_type
);
2347 dwAddTagAttr (subtp
, dwNewAttrConst (DW_AT_upper_bound
,
2348 DCL_ELEM (type
)-1));
2349 dwAddTagChild (tp
, subtp
);
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 */
2365 werror (E_INTERNAL_ERROR
, __FILE__
, __LINE__
,
2366 "unknown DCL_TYPE");
2372 if (IS_STRUCT (type
))
2374 struct structdef
* sdp
= SPEC_STRUCT (type
);
2377 tp
= dwNewTag (sdp
->type
== STRUCT
? DW_TAG_structure_type
2378 : DW_TAG_union_type
);
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
,
2387 /* Must add this before processing the struct fields */
2388 /* in case there is a recursive definition. */
2389 hTabAddItemLong (&dwTypeTagTable
, key
, type
, tp
);
2392 field
= sdp
->fields
;
2398 if (IS_BITFIELD (field
->type
) && !SPEC_BLEN(field
->type
))
2400 field
= field
->next
;
2404 memtp
= dwNewTag (DW_TAG_member
);
2406 dwAddTagAttr (memtp
, dwNewAttrString (DW_AT_name
,
2408 if (IS_BITFIELD (field
->type
))
2410 unsigned blen
= SPEC_BLEN (field
->type
);
2411 unsigned bstr
= SPEC_BSTR (field
->type
);
2414 dwAddTagAttr (memtp
,
2415 dwNewAttrConst (DW_AT_byte_size
,
2417 dwAddTagAttr (memtp
,
2418 dwNewAttrConst (DW_AT_bit_size
, blen
));
2419 dwAddTagAttr (memtp
,
2420 dwNewAttrConst (DW_AT_bit_offset
,
2424 type
= typeFromStr ("Uc");
2426 type
= typeFromStr ("Ui");
2427 subtp
= dwTagFromType (type
, tp
);
2428 dwAddTagAttr (memtp
, dwNewAttrTagRef (DW_AT_type
, subtp
));
2432 subtp
= dwTagFromType (field
->type
, tp
);
2433 dwAddTagAttr (memtp
, dwNewAttrTagRef (DW_AT_type
, subtp
));
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
);
2461 if (SPEC_CONST (type
))
2463 modtp
= dwNewTag (DW_TAG_const_type
);
2464 dwAddTagAttr (modtp
, dwNewAttrTagRef (DW_AT_type
, tp
));
2465 dwAddTagChild (parent
, modtp
);
2471 switch (SPEC_NOUN (type
))
2474 tp
= dwNewTag (DW_TAG_base_type
);
2475 if (SPEC_USIGN (type
))
2477 dwAddTagAttr (tp
, dwNewAttrConst (DW_AT_encoding
,
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
,
2486 dwAddTagAttr (tp
, dwNewAttrString (DW_AT_name
,
2491 dwAddTagAttr (tp
, dwNewAttrConst (DW_AT_encoding
,
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"));
2498 dwAddTagAttr (tp
, dwNewAttrString (DW_AT_name
, "int"));
2500 dwAddTagAttr (tp
, dwNewAttrConst (DW_AT_byte_size
,
2502 dwAddTagChild (dwRootTag
, tp
);
2506 tp
= dwNewTag (DW_TAG_base_type
);
2507 dwAddTagAttr (tp
, dwNewAttrConst (DW_AT_encoding
,
2509 dwAddTagAttr (tp
, dwNewAttrString (DW_AT_name
, "float"));
2510 dwAddTagAttr (tp
, dwNewAttrConst (DW_AT_byte_size
,
2512 dwAddTagChild (dwRootTag
, tp
);
2516 tp
= dwNewTag (DW_TAG_base_type
);
2517 dwAddTagAttr (tp
, dwNewAttrConst (DW_AT_encoding
,
2519 dwAddTagAttr (tp
, dwNewAttrString (DW_AT_name
, "fixed16x16"));
2520 dwAddTagAttr (tp
, dwNewAttrConst (DW_AT_byte_size
,
2522 dwAddTagChild (dwRootTag
, tp
);
2526 tp
= dwNewTag (DW_TAG_base_type
);
2527 dwAddTagAttr (tp
, dwNewAttrConst (DW_AT_encoding
,
2529 dwAddTagAttr (tp
, dwNewAttrString (DW_AT_name
, "_Bool"));
2530 dwAddTagAttr (tp
, dwNewAttrConst (DW_AT_byte_size
,
2532 dwAddTagChild (dwRootTag
, tp
);
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
,
2546 dwAddTagAttr (tp
, dwNewAttrConst (DW_AT_encoding
,
2548 dwAddTagAttr (tp
, dwNewAttrString (DW_AT_name
, "signed char"));
2550 dwAddTagAttr (tp
, dwNewAttrConst (DW_AT_byte_size
,
2552 dwAddTagChild (dwRootTag
, tp
);
2562 werror (E_INTERNAL_ERROR
, __FILE__
, __LINE__
,
2563 "unhandled base type");
2564 printTypeChain (type
, NULL
);
2573 hTabAddItemLong (&dwTypeTagTable
, key
, type
, tp
);
2575 dwAddTagChild (parent
, 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);
2593 /*-----------------------------------------------------------------------*/
2594 /* dwCloseFile - close the debugging file (do nothing, since all DWARF */
2595 /* data goes into the assembly output file) */
2596 /*-----------------------------------------------------------------------*/
2604 /*-----------------------------------------------------------------------*/
2605 /* dwGenerateScopes - recursively traverse an ast, generating lexical */
2606 /* block tags for block scopes found */
2607 /*-----------------------------------------------------------------------*/
2609 dwGenerateScopes (dwtag
*tp
, ast
* tree
)
2616 if (!IS_AST_OP (tree
))
2619 if (tree
->opval
.op
== BLOCK
)
2621 subtp
= dwNewTag (DW_TAG_lexical_block
);
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
);
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 /*-----------------------------------------------------------------------*/
2643 dwFindScope (dwtag
* tp
, int block
)
2653 if (tp
->tag
== DW_TAG_lexical_block
)
2658 if (ap
->attr
== DW_AT_user_block
)
2660 if (ap
->val
.data
== block
)
2666 rettp
= dwFindScope (tp
->firstChild
, block
);
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 /*------------------------------------------------------------------------*/
2682 dwWriteSymbolInternal (symbol
*sym
)
2691 bool inregs
= FALSE
;
2693 if (!sym
->level
|| IS_EXTERN (sym
->etype
))
2694 scopetp
= dwRootTag
;
2697 assert(sym
->localof
);
2701 /* Find the tag for the function this symbol is defined in */
2702 functp
= dwRootTag
->firstChild
;
2705 if (functp
->tag
== DW_TAG_subprogram
)
2707 funcap
= dwFindAttr (functp
, DW_AT_name
);
2708 if (funcap
&& !strcmp (funcap
->val
.string
, sym
->localof
->name
))
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. */
2721 /* Find the correct scope within this function */
2722 scopetp
= dwFindScope (functp
->firstChild
, sym
->block
);
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. */
2733 /* a) original symbol, */
2734 /* b) register equivalent, */
2735 /* c) spill location */
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
])
2748 if (!inregs
&& symloc
->isspilt
&& !symloc
->remat
)
2749 symloc
= symloc
->usl
.spillLoc
;
2753 if (inregs
) /* Variable (partially) in registers*/
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
))
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
);
2787 /* We are forced to give up if the ABI for this port */
2788 /* does not define a number for this register */
2795 lastlp
->next
= reglp
;
2800 if (symloc
->nRegs
!= 1)
2802 reglp
= dwNewLoc (DW_OP_piece
, NULL
, 1);
2803 lastlp
->next
= reglp
;
2808 else if (symloc
->onStack
)
2810 /* stack allocation */
2811 lp
= dwNewLoc (DW_OP_fbreg
, NULL
, symloc
->stack
);
2815 /* global allocation */
2816 if (sym
->level
&& !sym
->allocreq
)
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) */
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
));
2837 dwAddTagChild (scopetp
, subtp
);
2839 dwAddTagChild (scopetp
, tp
);
2844 /*-----------------------------------------------------------------------*/
2845 /* dwWriteFunction - generate a tag for a function. */
2846 /*-----------------------------------------------------------------------*/
2848 dwWriteFunction (symbol
*sym
, iCode
*ic
)
2853 /* Add this function to CFI list */
2855 cfip
= dwNewCFIlist();
2857 if (FUNC_ISISR (sym
->type
))
2859 cfip
->next
= dwCFIRoot
;
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
,
2873 dwAddTagAttr (dwFuncTag
, dwNewAttrFlag (DW_AT_external
,
2874 !IS_STATIC (sym
->etype
)));
2876 if (sym
->type
->next
&& !IS_VOID (sym
->type
->next
))
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
);
2888 dwWriteSymbolInternal (args
->sym
);
2891 if (FUNC_HASVARARGS (sym
->type
))
2893 dwAddTagChild (dwFuncTag
, dwNewTag (DW_TAG_unspecified_parameters
));
2896 while (ic
&& ic
->op
!= FUNCTION
)
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
);
2911 /*-----------------------------------------------------------------------*/
2912 /* dwWriteEndFunction - write attributes to the current function tag */
2913 /* that are only known after code generation is */
2915 /*-----------------------------------------------------------------------*/
2917 dwWriteEndFunction (symbol
*sym
, iCode
*ic
, int offset
)
2919 char debugSym
[SDCC_NAME_MAX
+ 1];
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
);
2931 sprintf (debugSym
, "XG$%s$0$0", sym
->name
);
2932 emitDebuggerSymbol (debugSym
);
2934 dwAddTagAttr (dwFuncTag
, dwNewAttrAddrLabel (DW_AT_high_pc
,
2935 Safe_strdup(debugSym
),
2940 dwAddTagAttr (dwFuncTag
, dwNewAttrLocRef (DW_AT_frame_base
,
2943 dwFrameLocList
->next
= dwRootLocList
;
2944 dwRootLocList
= dwFrameLocList
;
2945 dwFrameLocList
= NULL
;
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];
2961 /* ignore the compiler generated labels */
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
);
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
;
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
;
3003 ap
= dwFindAttr (scopetp
, DW_AT_low_pc
);
3008 debugSym
= dwNewDebugSymbol ();
3009 emitDebuggerSymbol (debugSym
);
3010 dwAddTagAttr (scopetp
, dwNewAttrAddrLabel (DW_AT_low_pc
, debugSym
, 0));
3012 dwScopeTag
= scopetp
;
3013 dwScopeLevel
= ic
->level
;
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
))
3030 /* If it is an iTemp, then it is a local variable; ignore it */
3034 /* If it is an unused extern ignore it, or it might produce link failure */
3035 if (IS_EXTERN (sym
->etype
) && !sym
->used
)
3038 /* Ignore parameters; they must be handled specially so that they will */
3039 /* appear in the correct order */
3043 return dwWriteSymbolInternal (sym
);
3047 /*-----------------------------------------------------------------------*/
3049 /*-----------------------------------------------------------------------*/
3051 dwWriteType (structdef
*sdef
, int block
, int inStruct
, const char *tag
)
3053 /* FIXME: needs implementation */
3058 /*-----------------------------------------------------------------------*/
3059 /* dwWriteModule - generates the root tag for this compilation unit */
3060 /*-----------------------------------------------------------------------*/
3062 dwWriteModule (const char *name
)
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));
3087 /*-----------------------------------------------------------------------*/
3088 /* dwWriteCLine - generates a line number/position to address record for */
3090 /*-----------------------------------------------------------------------*/
3092 dwWriteCLine (iCode
*ic
)
3100 lp
= Safe_alloc (sizeof (dwline
));
3102 lp
->line
= ic
->lineno
;
3104 debugSym
= dwNewDebugSymbol ();
3105 emitDebuggerSymbol (debugSym
);
3106 lp
->label
= debugSym
;
3109 lp
->fileIndex
= dwFindFileIndex (ic
->filename
);
3114 dwLineLast
->next
= lp
;
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
;
3133 dwlocregion
* cfi_lrp
;
3137 /* If there was a region open, close it */
3140 debugSym
= dwNewDebugSymbol ();
3141 emitDebuggerSymbol (debugSym
);
3143 dwFrameLastLoc
->endLabel
= debugSym
;
3144 dwFrameLastLoc
= NULL
;
3149 dwCFILastLoc
->endLabel
= debugSym
;
3150 dwCFIRoot
->endLabel
= debugSym
;
3154 if (!variable
&& !reg
)
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 */
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
);
3174 dwCFILastLoc
->next
= cfi_lrp
;
3178 dwCFIRoot
->region
= cfi_lrp
;
3179 dwCFIRoot
->startLabel
= debugSym
;
3181 dwCFILastLoc
= cfi_lrp
;
3183 if (variable
) /* frame pointer based from a global variable */
3187 lrp
->loc
= dwNewLoc (DW_OP_addr
, variable
, 0);
3188 lrp
->loc
->next
= lp
= dwNewLoc (DW_OP_deref_size
, NULL
, NEARPTRSIZE
);
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
);
3200 if (regNum
>=0 && regNum
<=31)
3203 lrp
->loc
= dwNewLoc (DW_OP_breg0
+ regNum
, NULL
, offset
);
3205 lrp
->loc
= dwNewLoc (DW_OP_reg0
+ regNum
, NULL
, 0);
3209 lrp
->loc
= lp
= dwNewLoc (DW_OP_regx
, NULL
, regNum
);
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
;
3228 /*-----------------------------------------------------------------------*/
3229 /* dwWriteALine - generates a line number/position to address record for */
3230 /* assembly source */
3231 /*-----------------------------------------------------------------------*/
3233 dwWriteALine(const char *module
, int Line
)
3239 /*-----------------------------------------------------------------------*/
3240 /* dwarf2FinalizeFile - write all of the DWARF debugging data to the */
3242 /*-----------------------------------------------------------------------*/
3244 dwarf2FinalizeFile (FILE *of
)
3246 int tagAddress
= 11;
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 */
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 */
3286 /* Write the .debug_pubnames section */