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(char *file);
39 int dwCloseFile(void);
40 int dwWriteFunction(symbol *pSym, iCode *ic);
41 int dwWriteEndFunction(symbol *pSym, iCode *ic, int offset);
42 int dwWriteLabel(symbol *pSym, iCode *ic);
43 int dwWriteScope(iCode *ic);
44 int dwWriteSymbol(symbol *pSym);
45 int dwWriteType(structdef *sdef, int block, int inStruct, char *tag);
46 int dwWriteModule(char *name);
47 int dwWriteCLine(iCode *ic);
48 int dwWriteALine(char *module, int Line);
49 int dwWriteFrameAddress(char *variable, struct regs *reg, int offset);
50 int dwWriteBasicSymbol(symbol *sym, int isStructSym, int isFunc);
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;
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;
93 /*----------------------------------------------------------------------*/
94 /* dwNewDebugSymbol - returns the name for a new debug symbol */
95 /*----------------------------------------------------------------------*/
99 char debugSym[SDCC_NAME_MAX];
101 sprintf (debugSym, "S%s$%s$%d", dwModuleName, currFunc->name, dwDebugSymbol);
103 return Safe_strdup (debugSym);
107 /*----------------------------------------------------------------------*/
108 /* dwWriteByte - generate a single byte assembler constant in the form: */
110 /* .db label+offset ; comment */
112 /* The label and comment parameters are optional */
113 /*----------------------------------------------------------------------*/
115 dwWriteByte (char * label, int offset, char * comment)
117 tfprintf (dwarf2FilePtr, "\t!db\t");
121 fprintf (dwarf2FilePtr, "%s+%d", label, offset);
123 fprintf (dwarf2FilePtr, "%s", label);
126 fprintf (dwarf2FilePtr, "%d", offset);
129 fprintf (dwarf2FilePtr, "\t;%s\n", comment);
131 fprintf (dwarf2FilePtr, "\n");
134 /*----------------------------------------------------------------------*/
135 /* dwWriteHalf - generate a two byte assembler constant in the form: */
137 /* .dw label+offset ; comment */
139 /* The label and comment parameters are optional */
140 /*----------------------------------------------------------------------*/
142 dwWriteHalf (char * label, int offset, char * comment)
144 tfprintf (dwarf2FilePtr, "\t!dw\t");
148 fprintf (dwarf2FilePtr, "%s+%d", label, offset);
150 fprintf (dwarf2FilePtr, "%s", label);
153 fprintf (dwarf2FilePtr, "%d", offset);
156 fprintf (dwarf2FilePtr, "\t;%s\n", comment);
158 fprintf (dwarf2FilePtr, "\n");
161 /*----------------------------------------------------------------------*/
162 /* dwWriteWord - generate a four byte assembler constant in the form: */
164 /* .dd label+offset ; comment */
166 /* The label and comment parameters are optional */
167 /*----------------------------------------------------------------------*/
169 dwWriteWord (char * label, int offset, char * comment)
171 /* FIXME: need to implement !dd pseudo-op in the assember. In the */
172 /* meantime, we use dw with zero padding and hope the values fit */
173 /* in only 16 bits. */
175 tfprintf (dwarf2FilePtr, "\t!dd\t");
179 fprintf (dwarf2FilePtr, "%s+%d", label, offset);
181 fprintf (dwarf2FilePtr, "%s", label);
184 fprintf (dwarf2FilePtr, "%d", offset);
186 tfprintf (dwarf2FilePtr, "\t!dw\t");
187 if (port->little_endian)
192 fprintf (dwarf2FilePtr, "(%s+%d),0", label, offset);
194 fprintf (dwarf2FilePtr, "(%s),0", label);
197 fprintf (dwarf2FilePtr, "%d,%d", offset, offset >> 16);
204 fprintf (dwarf2FilePtr, "0,(%s+%d)", label, offset);
206 fprintf (dwarf2FilePtr, "0,(%s)", label);
209 fprintf (dwarf2FilePtr, "%d,%d", offset >> 16, offset);
214 fprintf (dwarf2FilePtr, "\t;%s\n", comment);
216 fprintf (dwarf2FilePtr, "\n");
220 /*----------------------------------------------------------------------*/
221 /* dwWriteULEB128 - generate an unsigned variable length assembler */
222 /* constant in the form: */
224 /* .uleb128 label+offset ; comment */
226 /* The label and comment parameters are optional */
227 /*----------------------------------------------------------------------*/
229 dwWriteULEB128 (char * label, int offset, char * comment)
231 tfprintf (dwarf2FilePtr, "\t.uleb128\t");
235 fprintf (dwarf2FilePtr, "%s+%d", label, offset);
237 fprintf (dwarf2FilePtr, "%s", label);
240 fprintf (dwarf2FilePtr, "%d", offset);
243 fprintf (dwarf2FilePtr, "\t;%s\n", comment);
245 fprintf (dwarf2FilePtr, "\n");
248 /*----------------------------------------------------------------------*/
249 /* dwWriteSLEB128 - generate a signed variable length assembler */
250 /* constant in the form: */
252 /* .sleb128 label+offset ; comment */
254 /* The label and comment parameters are optional */
255 /*----------------------------------------------------------------------*/
257 dwWriteSLEB128 (char * label, int offset, char * comment)
259 tfprintf (dwarf2FilePtr, "\t.sleb128\t");
263 fprintf (dwarf2FilePtr, "%s+%d", label, offset);
265 fprintf (dwarf2FilePtr, "%s", label);
268 fprintf (dwarf2FilePtr, "%d", offset);
271 fprintf (dwarf2FilePtr, "\t;%s\n", comment);
273 fprintf (dwarf2FilePtr, "\n");
277 /*----------------------------------------------------------------------*/
278 /* dwSizeofULEB128 - return the size (in bytes) of an unsigned variable */
279 /* length constant */
280 /*----------------------------------------------------------------------*/
282 dwSizeofULEB128 (int unsigned value)
296 /*----------------------------------------------------------------------*/
297 /* dwSizeofSLEB128 - return the size (in bytes) of a signed variable */
298 /* length constant */
299 /*----------------------------------------------------------------------*/
301 dwSizeofSLEB128 (int value)
304 int negative = (value < 0);
313 value |= (0x7f << (sizeof(int)*8 - 7));
314 if ((value == 0 && !sign) || (value == -1 && sign))
321 /*----------------------------------------------------------------------*/
322 /* dwWriteString - generate a string constant in the form: */
324 /* .ascii /string/ ; comment */
326 /* The comment parameter is optional. The string may contain any */
327 /* non-null characters */
328 /*----------------------------------------------------------------------*/
330 dwWriteString (char * string, char * comment)
332 /* FIXME: need to safely handle nonalphanumeric data in string */
334 tfprintf (dwarf2FilePtr, "\t!ascii\n", string);
335 dwWriteByte (NULL, 0, comment);
339 /*----------------------------------------------------------------------*/
340 /* dwWriteAddress - generate an assembler constant in the form: */
342 /* .dw label+offset ; comment */
343 /* or .dd label+offset ; comment */
345 /* depending on how the relevant ABI defines the address size (may be */
346 /* larger than the CPU's actual address size). The label and comment */
347 /* parameters are optional */
348 /*----------------------------------------------------------------------*/
350 dwWriteAddress (char * label, int offset, char * comment)
352 switch (port->debugger.dwarf.addressSize)
355 dwWriteHalf (label, offset, comment);
358 dwWriteWord (label, offset, comment);
361 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
362 "unsupported port->debugger.dwarf.addressSize");
367 /*----------------------------------------------------------------------*/
368 /* dwWriteHalfDelta - generate a two byte assembler constant in the */
371 /* .dw offset+label1-label2 */
373 /* The offset parameter is optional */
374 /*----------------------------------------------------------------------*/
376 dwWriteHalfDelta (char * label1, char * label2, int offset)
379 tfprintf (dwarf2FilePtr, "\t!dw\t%d+%s-%s\n", offset, label1, label2);
381 tfprintf (dwarf2FilePtr, "\t!dw\t%s-%s\n", label1, label2);
384 /*----------------------------------------------------------------------*/
385 /* dwWriteWordDelta - generate a four byte assembler constant in the */
388 /* .dd label1-label2 */
389 /*----------------------------------------------------------------------*/
391 dwWriteWordDelta (char * label1, char * label2)
393 /* FIXME: need to implement !dd pseudo-op; this hack only */
394 /* works for positive offsets of less than 64k */
396 tfprintf (dwarf2FilePtr, "\t!dd\t%s-%s\n", label1,label2);
398 if (port->little_endian)
400 tfprintf (dwarf2FilePtr, "\t!dw\t%s-%s,%d\n", label1, label2, 0);
404 tfprintf (dwarf2FilePtr, "\t!dw\t%d,%s-%s\n", 0, label1, label2);
410 /* disabled to eliminiate unused function warning */
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");
438 /*----------------------------------------------------------------------*/
439 /* dwWriteULEB128Delta - generate an unsigned variable byte assembler */
440 /* constant in the form: */
442 /* .uleb128 offset+label1-label2 */
444 /* The offset parameter is optional */
445 /*----------------------------------------------------------------------*/
447 dwWriteULEB128Delta (char * label1, char * label2, int offset)
450 tfprintf (dwarf2FilePtr, "\t.uleb128\t%d+%s-%s\n", offset, label1, label2);
452 tfprintf (dwarf2FilePtr, "\t.uleb128\t%s-%s\n", label1, label2);
456 /*------------------------------------------------------------------------*/
458 /*----------------------------------------------------------------------*/
459 /* dwNewLoc - allocates a new location expression node */
460 /*----------------------------------------------------------------------*/
462 dwNewLoc (int opcode, char * label, int offset)
466 lp = Safe_alloc (sizeof (dwloc));
469 lp->operand.label = label;
470 lp->operand.offset = offset;
475 /*-------------------------------------------------------------------------*/
476 /* dwSizeofLoc - returns the size (in bytes) of a chain of location */
477 /* expression nodes as they would be encoded by dwWriteLoc() */
478 /*-------------------------------------------------------------------------*/
480 dwSizeofLoc (dwloc * lp)
490 size += port->debugger.dwarf.addressSize;
493 case DW_OP_deref_size:
494 case DW_OP_xderef_size:
520 case DW_OP_plus_uconst:
521 size += dwSizeofULEB128 (lp->operand.offset);
557 size += dwSizeofSLEB128 (lp->operand.offset);
567 /*------------------------------------------------------------------------*/
568 /* dwWriteLoc - writes a chain of location expression nodes */
569 /*------------------------------------------------------------------------*/
571 dwWriteLoc (dwloc *lp)
575 dwWriteByte (NULL, lp->opcode, NULL);
579 dwWriteAddress (lp->operand.label, lp->operand.offset, NULL);
582 case DW_OP_deref_size:
583 case DW_OP_xderef_size:
587 dwWriteByte (NULL, lp->operand.offset, NULL);
594 dwWriteHalf (NULL, lp->operand.offset, NULL);
599 dwWriteWord (NULL, lp->operand.offset, NULL);
604 case DW_OP_plus_uconst:
605 dwWriteULEB128 (NULL, lp->operand.offset, NULL);
641 dwWriteSLEB128 (NULL, lp->operand.offset, NULL);
649 /*----------------------------------------------------------------------*/
650 /* dwNewLocList - allocates a new list of location expression node */
651 /*----------------------------------------------------------------------*/
657 llp = Safe_alloc (sizeof (dwloclist));
662 /*----------------------------------------------------------------------*/
663 /* dwSizeofLocRegion - returns the size (in bytes) of a chain of */
664 /* location regions (inluding their location */
665 /* expression nodes) as encoded by dwWriteLocLists */
666 /*----------------------------------------------------------------------*/
668 dwSizeofLocRegion (dwlocregion * lrp)
674 size += 2 * port->debugger.dwarf.addressSize;
675 size += 2 + dwSizeofLoc (lrp->loc);
679 size += 2 * port->debugger.dwarf.addressSize;
683 /*-----------------------------------------------------------------------*/
684 /* dwAssignLocListAddresses - assign the address offsets of the location */
685 /* lists so that they can be referenced from */
686 /* the tag structure */
687 /*-----------------------------------------------------------------------*/
689 dwAssignLocListAddresses (void)
697 llp->baseOffset = address;
698 address += dwSizeofLocRegion (llp->region);
704 /*-----------------------------------------------------------------------*/
705 /* dwWriteLocLists - write all of the location lists in dwRootLocList to */
706 /* the .debug_loc section */
707 /*-----------------------------------------------------------------------*/
709 dwWriteLocLists (void)
714 tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_loc (NOLOAD)");
715 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_loc_start");
720 //fprintf (dwarf2FilePtr, "; baseOffset = 0x%x\n", llp->baseOffset);
724 dwWriteAddress (lrp->startLabel, 0, NULL);
725 dwWriteAddress (lrp->endLabel, 0, NULL);
726 dwWriteHalf (NULL, dwSizeofLoc (lrp->loc), NULL);
727 dwWriteLoc (lrp->loc);
731 dwWriteAddress (NULL, 0, NULL);
732 dwWriteAddress (NULL, 0, NULL);
740 /*------------------------------------------------------------------------*/
743 /*----------------------------------------------------------------------*/
744 /* dwNewAttr - allocate a new tag attribute node */
745 /*----------------------------------------------------------------------*/
751 ap = Safe_alloc ( sizeof (dwattr));
757 /*----------------------------------------------------------------------*/
758 /* dwFreeAttr - deallocate a tag attribute node */
759 /*----------------------------------------------------------------------*/
761 dwFreeAttr (dwattr * ap)
768 /*-------------------------------------------------------------------------*/
769 /* dwNewAttrString - allocate a new tag attribute node with a string value */
770 /*-------------------------------------------------------------------------*/
772 dwNewAttrString (int attr, char * string)
776 ap = dwNewAttr (attr);
777 ap->form = DW_FORM_string;
778 ap->val.string = string;
783 /*---------------------------------------------------------------------*/
784 /* dwNewAttrConst - allocate a new tag attribute node with an unsigned */
785 /* numeric constant value */
786 /*---------------------------------------------------------------------*/
788 dwNewAttrConst (int attr, unsigned int data)
792 ap = dwNewAttr (attr);
794 ap->form = DW_FORM_data1;
795 else if (data <= 0xffffu)
796 ap->form = DW_FORM_data2;
798 ap->form = DW_FORM_data4;
804 /* disabled to eliminiate unused function warning */
806 /*---------------------------------------------------------------------*/
807 /* dwNewAttrSignedConst - allocate a new tag attribute node with a */
808 /* signed numeric constant value */
809 /*---------------------------------------------------------------------*/
811 dwNewAttrSignedConst (int attr, int data)
815 ap = dwNewAttr (attr);
816 if (data <= 0x7f && data >= -0x80)
817 ap->form = DW_FORM_data1;
818 else if (data <= 0xffff && data >= -0x8000)
819 ap->form = DW_FORM_data2;
821 ap->form = DW_FORM_data4;
828 /*---------------------------------------------------------------------*/
829 /* dwNewAttrFlag - allocate a new tag attribute node with a boolean */
830 /* flag value (zero/non-zero) */
831 /*---------------------------------------------------------------------*/
833 dwNewAttrFlag (int attr, int data)
837 ap = dwNewAttr (attr);
838 ap->form = DW_FORM_flag;
844 /*---------------------------------------------------------------------*/
845 /* dwNewAttrAddrSymbol - allocate a new tag attribute node with the */
846 /* address of a C symbol plus an offset */
847 /*---------------------------------------------------------------------*/
849 dwNewAttrAddrSymbol (int attr, symbol * sym, int offset)
853 ap = dwNewAttr (attr);
854 ap->form = DW_FORM_addr;
856 ap->val.symaddr.label = sym->rname;
857 ap->val.symaddr.offset = offset;
861 /*---------------------------------------------------------------------*/
862 /* dwNewAttrAddrLabel - allocate a new tag attribute node with the */
863 /* address of an assembler label plus an offset */
864 /*---------------------------------------------------------------------*/
866 dwNewAttrAddrLabel (int attr, char * label, int offset)
870 ap = dwNewAttr (attr);
871 ap->form = DW_FORM_addr;
873 ap->val.symaddr.label = label;
874 ap->val.symaddr.offset = offset;
878 /*---------------------------------------------------------------------*/
879 /* dwNewAttrTagRef - allocate a new tag attribute node that references */
881 /*---------------------------------------------------------------------*/
883 dwNewAttrTagRef (int attr, dwtag * tp)
887 ap = dwNewAttr (attr);
888 ap->form = DW_FORM_ref4;
894 /*---------------------------------------------------------------------*/
895 /* dwNewAttrLocRef - allocate a new tag attribute node that references */
896 /* a location list */
897 /*---------------------------------------------------------------------*/
899 dwNewAttrLocRef (int attr, dwloclist * llp)
903 ap = dwNewAttr (attr);
904 ap->form = DW_FORM_data4;
906 ap->val.loclist = llp;
910 /*-----------------------------------------------------------------------*/
911 /* dwNewAttrLabelRef - allocate a new tag attribute node that references */
912 /* the address of an assembler label plus an offset */
913 /*-----------------------------------------------------------------------*/
915 dwNewAttrLabelRef (int attr, char * label, int offset)
919 ap = dwNewAttr (attr);
920 ap->form = DW_FORM_data4;
922 ap->val.symaddr.label = label;
923 ap->val.symaddr.offset = offset;
927 /*---------------------------------------------------------------------*/
928 /* dwNewAttrLoc - allocate a new tag attribute node for a chain of */
929 /* location expression nodes */
930 /*---------------------------------------------------------------------*/
932 dwNewAttrLoc (int attr, dwloc * lp)
936 ap = dwNewAttr (attr);
937 ap->form = DW_FORM_block1;
943 /*---------------------------------------------------------------------*/
944 /* dwWriteAttr - write a tag attribute node */
945 /*---------------------------------------------------------------------*/
947 dwWriteAttr (dwattr * ap)
953 dwWriteAddress (ap->val.symaddr.label, ap->val.symaddr.offset, NULL);
957 dwWriteULEB128 (NULL, dwSizeofLoc (ap->val.loc), NULL);
958 dwWriteLoc (ap->val.loc);
962 dwWriteByte (NULL, dwSizeofLoc (ap->val.loc), NULL);
963 dwWriteLoc (ap->val.loc);
967 dwWriteHalf (NULL, dwSizeofLoc (ap->val.loc), NULL);
968 dwWriteLoc (ap->val.loc);
972 dwWriteWord (NULL, dwSizeofLoc (ap->val.loc), NULL);
973 dwWriteLoc (ap->val.loc);
978 dwWriteByte (NULL, ap->val.data, NULL);
982 dwWriteHalf (NULL, ap->val.data, NULL);
988 case DW_AT_stmt_list:
989 dwWriteWord (ap->val.symaddr.label, ap->val.symaddr.offset, NULL);
992 case DW_AT_frame_base:
993 dwWriteWord ("Ldebug_loc_start", ap->val.loclist->baseOffset, NULL);
996 dwWriteWord (NULL, ap->val.data, NULL);
1001 dwWriteULEB128 (NULL, ap->val.data, NULL);
1005 dwWriteSLEB128 (NULL, ap->val.data, NULL);
1008 case DW_FORM_string:
1009 dwWriteString (ap->val.string, NULL);
1013 dwWriteByte (NULL, ap->val.ref->baseOffset, NULL);
1017 dwWriteHalf (NULL, ap->val.ref->baseOffset, NULL);
1021 dwWriteWord (NULL, ap->val.ref->baseOffset, NULL);
1025 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1026 "unsupported DWARF form");
1031 /*---------------------------------------------------------------------*/
1032 /* dwSizeofAttr - returns the size (in bytes) of a tag attribute node */
1033 /* as encoded by dwWriteAttr */
1034 /*---------------------------------------------------------------------*/
1036 dwSizeofAttr (dwattr * ap)
1043 return port->debugger.dwarf.addressSize;
1046 size = dwSizeofLoc (ap->val.loc);
1047 return size + dwSizeofULEB128 (size);
1049 case DW_FORM_block1:
1050 size = dwSizeofLoc (ap->val.loc);
1053 case DW_FORM_block2:
1054 size = dwSizeofLoc (ap->val.loc);
1057 case DW_FORM_block4:
1058 size = dwSizeofLoc (ap->val.loc);
1072 return dwSizeofULEB128 (ap->val.data);
1075 return dwSizeofSLEB128 (ap->val.data);
1077 case DW_FORM_string:
1078 return 1 + strlen (ap->val.string);
1090 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1091 "unsupported DWARF form");
1098 /*---------------------------------------------------------------------*/
1099 /* dwFindAttr - for a tag node, return a pointer to a particular */
1100 /* attribute node, or NULL if not found */
1101 /*---------------------------------------------------------------------*/
1103 dwFindAttr (dwtag * tp, int attr)
1110 if (ap->attr == attr)
1120 /*------------------------------------------------------------------------*/
1123 /*----------------------------------------------------------------------*/
1124 /* dwNewTag - allocate a new tag node */
1125 /*----------------------------------------------------------------------*/
1131 tp = Safe_alloc ( sizeof (dwtag));
1137 /*----------------------------------------------------------------------*/
1138 /* dwAddTagAttr - add an attribute to a tag */
1139 /*----------------------------------------------------------------------*/
1141 dwAddTagAttr (dwtag * tp, dwattr * ap)
1147 else if (ap->attr < tp->attribs->attr)
1149 ap->next = tp->attribs;
1154 curap = tp->attribs;
1155 while (curap->next && curap->next->attr < ap->attr)
1156 curap = curap->next;
1157 ap->next = curap->next;
1162 /*----------------------------------------------------------------------*/
1163 /* dwSetTagAttr - repleace an existing attribute of a tag with a new */
1164 /* attribute or add if non-existent */
1165 /*----------------------------------------------------------------------*/
1167 dwSetTagAttr (dwtag *tp, dwattr * ap)
1171 curap = dwFindAttr (tp, ap->attr);
1174 ap->next = curap->next;
1179 dwAddTagAttr (tp, ap);
1183 /*----------------------------------------------------------------------*/
1184 /* dwAddTagChild - add a tag as a child of another tag */
1185 /*----------------------------------------------------------------------*/
1187 dwAddTagChild (dwtag * parent, dwtag * child)
1189 child->parent = parent;
1190 if (parent->lastChild)
1192 parent->lastChild->siblings = child;
1193 parent->lastChild = child;
1197 parent->firstChild = child;
1198 parent->lastChild = child;
1203 /*----------------------------------------------------------------------*/
1204 /* dwMatchTagAttr - returns true if two tags are equal in value, */
1205 /* attributes, and offspring status (the child tags */
1206 /* need not match, but they must both have children or */
1207 /* both not have children) */
1208 /*----------------------------------------------------------------------*/
1210 dwMatchTagAttr (const void * tp1v, const void * tp2v)
1212 const dwtag * tp1 = tp1v;
1213 const dwtag * tp2 = tp2v;
1214 dwattr * ap1 = tp1->attribs;
1215 dwattr * ap2 = tp2->attribs;
1220 if (tp1->tag != tp2->tag)
1223 if (tp1->firstChild && !tp2->lastChild)
1225 if (!tp1->firstChild && tp2->lastChild)
1230 if (ap1->attr != ap2->attr)
1232 if (ap1->form != ap2->form)
1242 /*----------------------------------------------------------------------*/
1243 /* dwHashTag - return a hash code for a tag based on its value and */
1245 /*----------------------------------------------------------------------*/
1247 dwHashTag (dwtag * tp)
1249 dwattr * ap = tp->attribs;
1254 hash = (hash << 6) ^ ((hash >> 11) & 0xff);
1255 hash ^= (ap->attr) | (ap->form << 8);
1265 /*----------------------------------------------------------------------*/
1266 /* dwTraverseTag - perform a depth-first preorder traversal of a tag */
1267 /* tree, calling the user function at each node. The */
1268 /* user function is also called with a NULL tag pointer */
1269 /* after the last sibling of each immediate family is */
1271 /*----------------------------------------------------------------------*/
1273 dwTraverseTag (dwtag *tp, int (*somefunc)(dwtag *tp, void * info), void * info)
1279 rvalue += (*somefunc)(tp, info);
1281 rvalue += dwTraverseTag (tp->firstChild, somefunc, info);
1284 rvalue += (*somefunc)(NULL, info);
1289 /*----------------------------------------------------------------------*/
1290 /* dwAssignAbbrev - find a matching abbreviation for a tag or create a */
1291 /* a new one and assign it */
1292 /*----------------------------------------------------------------------*/
1294 dwAssignAbbrev (dwtag *tp, void *info)
1297 int * anp = info; /* pointer to current abbreviation number */
1303 key = dwHashTag (tp) % dwAbbrevTable->size;
1304 oldtp = hTabFindByKey (dwAbbrevTable, key, tp, dwMatchTagAttr);
1307 tp->abbrev = oldtp->abbrev;
1312 tp->abbrev = ++(*anp);
1313 hTabAddItemLong (&dwAbbrevTable, key, tp, tp);
1318 /*-----------------------------------------------------------------------*/
1319 /* dwWriteAbbrevs - write the abbreviations to the .debug_abbrev section */
1320 /*-----------------------------------------------------------------------*/
1322 dwWriteAbbrevs (void)
1328 tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_abbrev (NOLOAD)");
1329 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_abbrev");
1331 tp = hTabFirstItem (dwAbbrevTable, &key);
1332 for (; tp; tp = hTabNextItem (dwAbbrevTable, &key))
1334 dwWriteULEB128 (NULL, tp->abbrev, NULL);
1335 dwWriteULEB128 (NULL, tp->tag, NULL);
1336 dwWriteByte (NULL, tp->firstChild ? DW_CHILDREN_yes : DW_CHILDREN_no,
1341 dwWriteULEB128 (NULL, ap->attr, NULL);
1342 dwWriteULEB128 (NULL, ap->form, NULL);
1345 dwWriteULEB128 (NULL, 0, NULL);
1346 dwWriteULEB128 (NULL, 0, NULL);
1349 dwWriteULEB128 (NULL, 0, NULL);
1351 hTabDeleteAll (dwAbbrevTable);
1356 /*-----------------------------------------------------------------------*/
1357 /* dwWriteTag - write the encoded tag information */
1358 /*-----------------------------------------------------------------------*/
1360 dwWriteTag (dwtag *tp, void *info)
1366 /* mark the end of this series of siblings */
1367 dwWriteULEB128 (NULL, 0, NULL);
1371 //fprintf (dwarf2FilePtr, "; baseOffset = 0x%x\n", tp->baseOffset);
1373 /* write the tag abbreviation */
1374 dwWriteULEB128 (NULL, tp->abbrev, NULL);
1376 /* write the values of the attributes */
1388 /*-----------------------------------------------------------------------*/
1389 /* dwWriteTags - write all the tags to the .debug_info section */
1390 /*-----------------------------------------------------------------------*/
1394 tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_info (NOLOAD)");
1396 dwWriteWordDelta ("Ldebug_info_end", "Ldebug_info_start");
1398 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_info_start");
1400 dwWriteHalf (NULL, 2, NULL); /* DWARF version */
1402 dwWriteWord ("Ldebug_abbrev", 0, NULL);
1404 dwWriteByte (NULL, port->debugger.dwarf.addressSize, NULL);
1406 dwTraverseTag (dwRootTag, dwWriteTag, NULL);
1408 dwWriteULEB128 (NULL, 0, NULL);
1410 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_info_end");
1414 /*-----------------------------------------------------------------------*/
1415 /* dwAssignTagAddress - assign the current address to the current tag. */
1416 /* Compute the next address based on the tag size */
1417 /*-----------------------------------------------------------------------*/
1419 dwAssignTagAddress (dwtag *tp, void *info)
1430 tp->baseOffset = *tap;
1432 *tap += dwSizeofULEB128 (tp->abbrev);
1437 *tap += dwSizeofAttr (ap);
1444 /*-----------------------------------------------------------------------*/
1445 /* dwAddSibAttr - if a tag has children and a sibling, add a sibling */
1446 /* attribute (it allows debuggers to jump to the sibling */
1447 /* and skip the child data) */
1448 /*-----------------------------------------------------------------------*/
1450 dwAddSibAttr (dwtag *tp, void *info)
1454 if (tp == dwRootTag)
1457 if (tp->firstChild && tp->siblings)
1458 dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_sibling, tp->siblings));
1463 /*-----------------------------------------------------------------------*/
1464 /* dwDeleteTagAttr - given a pointer to an attribute type, delete any */
1465 /* matching attribute */
1466 /*-----------------------------------------------------------------------*/
1468 dwDeleteTagAttr (dwtag *tp, void *info)
1470 int attr = *((int *) info);
1477 if (ap && ap->attr == attr)
1479 tp->attribs = ap->next;
1485 if (ap->next && ap->next->attr == attr)
1487 ap->next = ap->next->next;
1497 /*------------------------------------------------------------------------*/
1499 /*-----------------------------------------------------------------------*/
1500 /* dwWritePubnames - write all the public names to the .debug_pubnames */
1501 /* section. Externally visible functions and variables */
1502 /* are considered to have public names. */
1503 /*-----------------------------------------------------------------------*/
1505 dwWritePubnames (void)
1511 tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_pubnames (NOLOAD)");
1513 dwWriteWordDelta ("Ldebug_pubnames_end", "Ldebug_pubnames_start");
1515 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_pubnames_start");
1517 dwWriteHalf (NULL, 2, NULL); /* DWARF version */
1519 dwWriteWord ("Ldebug_info_start-4", 0, NULL);
1520 dwWriteWordDelta ("4+Ldebug_info_end", "Ldebug_info_start");
1522 if (dwRootTag && dwRootTag->firstChild)
1524 tp = dwRootTag->firstChild;
1527 if (tp->tag == DW_TAG_variable || tp->tag == DW_TAG_subprogram)
1529 /* If it has a name and is externally visible, it's a pubname */
1530 ap1 = dwFindAttr (tp, DW_AT_external);
1531 ap2 = dwFindAttr (tp, DW_AT_name);
1532 if (ap1 && ap1->val.data && ap2)
1534 dwWriteWord (NULL, tp->baseOffset, NULL);
1535 dwWriteString (ap2->val.string, NULL);
1542 dwWriteWord (NULL, 0, NULL);
1543 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_pubnames_end");
1546 /*------------------------------------------------------------------------*/
1548 /*-----------------------------------------------------------------------*/
1549 /* dwFindFileIndex - find the index of a filename in dwFilenameSet; if */
1550 /* it does not exist, it is added */
1551 /*-----------------------------------------------------------------------*/
1553 dwFindFileIndex (char * filename)
1560 /* Just do a linear search for the file. There should be hardly */
1561 /* a penalty since 1) most calls search for the first file, and */
1562 /* 2) the file set is usually small (often just 1 item) */
1563 for (srcfile = setFirstItem (dwFilenameSet);
1565 srcfile = setNextItem(dwFilenameSet), fileIndex++ )
1567 if (!strcmp (srcfile->name, filename))
1571 for (includeDir = setFirstItem (includeDirsSet);
1573 includeDir = setNextItem(includeDirsSet), dirIndex++ )
1575 if (!strncmp (includeDir, filename, strlen (includeDir))
1576 && strlen (filename) > strlen (includeDir))
1578 if (IS_DIR_SEPARATOR(filename[strlen (includeDir)]))
1585 srcfile = Safe_alloc (sizeof (dwfile));
1586 srcfile->name = filename;
1587 srcfile->dirIndex = dirIndex;
1588 srcfile->timestamp = 0;
1589 srcfile->length = 0;
1591 addSet (&dwFilenameSet, srcfile);
1595 /*-----------------------------------------------------------------------*/
1596 /* dwWriteLineNumber - write line number (and related position info) to */
1597 /* address corespondence data for a single node */
1598 /*-----------------------------------------------------------------------*/
1600 dwWriteLineNumber (dwline * lp)
1602 static int curFileIndex = 1;
1603 static int curLine = 1;
1604 static char * curLabel = NULL;
1605 static int curOffset = 0;
1606 int deltaLine = lp->line - curLine;
1607 int deltaAddr = lp->offset - curOffset;
1608 int deltaAddrValid = curLabel && lp->label && !strcmp (lp->label, curLabel);
1610 //fprintf (dwarf2FilePtr, "; line %d\n", lp->line);
1611 if (lp->begin_sequence)
1618 if (lp->end_sequence)
1622 if (lp->fileIndex != curFileIndex)
1624 dwWriteByte (NULL, DW_LNS_set_file, NULL);
1625 dwWriteULEB128 (NULL, lp->fileIndex, NULL);
1626 curFileIndex = lp->fileIndex;
1629 if (lp->basic_block)
1631 dwWriteByte (NULL, DW_LNS_set_basic_block, NULL);
1634 if (lp->begin_sequence)
1636 dwWriteByte (NULL, 0, NULL);
1637 dwWriteULEB128 (NULL, 1+port->debugger.dwarf.addressSize, NULL);
1638 dwWriteByte (NULL, DW_LNE_set_address, NULL);
1639 dwWriteAddress (lp->label, lp->offset, NULL);
1640 curLabel = lp->label;
1641 curOffset = lp->offset;
1643 dwWriteByte (NULL, DW_LNS_advance_line, NULL);
1644 dwWriteSLEB128 (NULL, lp->line - 1, NULL);
1647 dwWriteByte (NULL, DW_LNS_copy, NULL);
1649 else if (lp->end_sequence)
1653 dwWriteByte (NULL, DW_LNS_advance_pc, NULL);
1654 dwWriteULEB128 (NULL, deltaAddr, NULL);
1658 dwWriteByte (NULL, DW_LNS_fixed_advance_pc, NULL);
1659 dwWriteHalfDelta (lp->label, curLabel, lp->offset-curOffset);
1660 curLabel = lp->label;
1661 curOffset = lp->offset;
1664 dwWriteByte (NULL, 0, NULL);
1665 dwWriteULEB128 (NULL, 1, NULL);
1666 dwWriteByte (NULL, DW_LNE_end_sequence, NULL);
1670 int usedSpecial = 0;
1672 /* Metrowerks CW08 V3.0 gets confused by this. Just use the long */
1673 /* encoding until we can find a more compatible phrasing. */
1675 if (deltaLine >= dwLineBase && deltaLine < (dwLineBase+dwLineRange))
1679 /* try to build a "special" opcode */
1680 opcode = dwLineOpcodeBase + (deltaLine - dwLineBase);
1682 opcode += deltaAddr*dwLineRange;
1684 if (opcode >= dwLineOpcodeBase && opcode <= 255)
1686 /* ok, we can use a "special" opcode */
1688 /* If the deltaAddr value was symbolic, it can't be part */
1689 /* of the "special" opcode, so encode it seperately */
1690 if (!deltaAddrValid)
1692 dwWriteByte (NULL, DW_LNS_advance_pc, NULL);
1693 dwWriteULEB128Delta (lp->label, curLabel, lp->offset-curOffset);
1694 curLabel = lp->label;
1695 curOffset = lp->offset;
1698 /* Write the "special" opcode */
1699 dwWriteByte (NULL, opcode, NULL);
1706 /* If we couldn't use the "special" opcode, we will have to */
1707 /* encode this the long way. */
1710 dwWriteByte (NULL, DW_LNS_fixed_advance_pc, NULL);
1711 dwWriteHalfDelta (lp->label, curLabel, lp->offset-curOffset);
1712 curLabel = lp->label;
1713 curOffset = lp->offset;
1715 dwWriteByte (NULL, DW_LNS_advance_line, NULL);
1716 dwWriteSLEB128 (NULL, deltaLine, NULL);
1719 dwWriteByte (NULL, DW_LNS_copy, NULL);
1726 /*-----------------------------------------------------------------------*/
1727 /* dwWriteLineNumbers - write all the source line number position data */
1728 /* to the .debug_line section */
1729 /*-----------------------------------------------------------------------*/
1731 dwWriteLineNumbers (void)
1737 tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_line (NOLOAD)");
1739 dwWriteWordDelta ("Ldebug_line_end", "Ldebug_line_start");
1741 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_line_start");
1743 dwWriteHalf (NULL, 2, NULL); /* DWARF version */
1745 dwWriteWordDelta ("Ldebug_line_stmt-6", "Ldebug_line_start");
1747 dwWriteByte (NULL, 1, NULL); /* we track everything in 1 byte increments */
1749 dwWriteByte (NULL, 1, NULL); /* assume every line is a new statement */
1751 dwWriteByte (NULL, dwLineBase, NULL);
1752 dwWriteByte (NULL, dwLineRange, NULL);
1754 dwWriteByte (NULL, 9+1, NULL); /* there are 9 standard opcodes */
1756 dwWriteByte (NULL, 0, NULL); /* number of DW_LNS_copy arguments */
1757 dwWriteByte (NULL, 1, NULL); /* number of DW_LNS_advance_pc arguments */
1758 dwWriteByte (NULL, 1, NULL); /* number of DW_LNS_advance_line arguments */
1759 dwWriteByte (NULL, 1, NULL); /* number of DW_LNS_set_file arguments */
1760 dwWriteByte (NULL, 1, NULL); /* number of DW_LNS_set_column arguments */
1761 dwWriteByte (NULL, 0, NULL); /* number of DW_LNS_negate_stmt arguments */
1762 dwWriteByte (NULL, 0, NULL); /* number of DW_LNS_set_basic_block arguments */
1763 dwWriteByte (NULL, 0, NULL); /* number of DW_LNS_const_add_pc arguments */
1764 dwWriteByte (NULL, 1, NULL); /* number of DW_LNS_fixed_advance_pc arguments */
1766 /* Write the list of source directories searched */
1767 for (includeDir = setFirstItem (includeDirsSet);
1769 includeDir = setNextItem(includeDirsSet) )
1770 dwWriteString (includeDir, NULL);
1771 dwWriteByte (NULL, 0, NULL);
1773 /* Write the list of source files used */
1774 for (srcfile = setFirstItem (dwFilenameSet);
1776 srcfile = setNextItem(dwFilenameSet) )
1778 dwWriteString (srcfile->name, NULL);
1779 dwWriteULEB128 (NULL, srcfile->dirIndex, NULL);
1780 dwWriteULEB128 (NULL, srcfile->timestamp, NULL);
1781 dwWriteULEB128 (NULL, srcfile->length, NULL);
1783 dwWriteByte (NULL, 0, NULL);
1785 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_line_stmt");
1789 lp->begin_sequence = 1;
1792 dwWriteLineNumber (lp);
1793 if (lp->end_sequence && lp->next)
1794 lp->next->begin_sequence = 1;
1798 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_line_end");
1801 /*------------------------------------------------------------------------*/
1804 /* I have disabled all of this canonical frame address related code */
1805 /* until I better understand this part of the DWARF2 spec. -- EEP */
1808 dwWriteCFAinstructions (dwcfins *ip)
1810 dwcfop * op = ip->first;
1814 dwWriteByte (NULL, op->opcode, NULL);
1815 switch (op->opcode >> 6)
1820 case DW_CFA_set_loc:
1821 dwWriteAddress (NULL, op->label, op->operand1);
1824 case DW_CFA_advance_loc1:
1825 dwWriteByte (NULL, op->operand1, NULL);
1828 case DW_CFA_advance_loc2:
1829 dwWriteHalf (NULL, op->operand1, NULL);
1832 case DW_CFA_advance_loc4:
1833 dwWriteWord (NULL, op->operand1, NULL);
1836 case DW_CFA_def_cfa:
1837 case DW_CFA_register:
1838 case DW_CFA_offset_extended:
1839 dwWriteULEB128 (NULL, op->operand1, NULL);
1840 dwWriteULEB128 (NULL, op->operand2, NULL);
1843 case DW_CFA_undefined:
1844 case DW_CFA_same_value:
1845 case DW_CFA_def_cfa_register:
1846 case DW_CFA_def_cfa_offset:
1847 case DW_CFA_restore_extended:
1848 dwWriteULEB128 (NULL, op->operand1, NULL);
1853 case DW_CFA_restore >> 6:
1854 case DW_CFA_advance_loc >> 6:
1857 case DW_CFA_offset >> 6:
1858 dwWriteULEB128 (NULL, op->operand1, NULL);
1866 dwSizeofCFAinstructions (dwcfins *ip)
1869 dwcfop * op = ip->first;
1874 switch (op->opcode >> 6)
1879 case DW_CFA_set_loc:
1880 size += port->debugger.dwarf.addressSize;
1883 case DW_CFA_advance_loc1:
1887 case DW_CFA_advance_loc2:
1891 case DW_CFA_advance_loc4:
1895 case DW_CFA_def_cfa:
1896 case DW_CFA_register:
1897 case DW_CFA_offset_extended:
1898 size += dwSizeofULEB128 (op->operand1);
1899 size += dwSizeofULEB128 (op->operand2);
1902 case DW_CFA_undefined:
1903 case DW_CFA_same_value:
1904 case DW_CFA_def_cfa_register:
1905 case DW_CFA_def_cfa_offset:
1906 case DW_CFA_restore_extended:
1907 size += dwSizeofULEB128 (op->operand1);
1912 case DW_CFA_restore >> 6:
1913 case DW_CFA_advance_loc >> 6:
1916 case DW_CFA_offset >> 6:
1917 size += dwSizeofULEB128 (op->operand1);
1926 dwNewCFop (int opcode)
1930 op = Safe_alloc (sizeof (dwcfop));
1931 op->opcode = opcode;
1939 return (dwcfins *) Safe_alloc (sizeof (dwcfins));
1943 dwAddCFinsOp (dwcfins * ip, dwcfop *op)
1946 ip->last->next = op;
1961 /* Define the CFA as the top of the stack at function start. */
1962 /* The return address is then at cfa+0 */
1963 op = dwNewCFop (DW_CFA_def_cfa);
1964 op->operand1 = port->debugger.dwarf.regNumSP;
1965 op->operand2 = port->debugger.dwarf.offsetSP;
1966 dwAddCFinsOp (ip, op);
1968 op = dwNewCFop (DW_CFA_offset + port->debugger.dwarf.regNumRet);
1970 dwAddCFinsOp (ip, op);
1972 if (port->debugger.dwarf.cfiUndef)
1973 for (i=0; i < port->debugger.dwarf.cfiUndef->size; i++)
1975 if (bitVectBitValue (port->debugger.dwarf.cfiUndef, i))
1977 op = dwNewCFop (DW_CFA_undefined);
1978 dwAddCFinsOp (ip, op);
1982 if (port->debugger.dwarf.cfiSame)
1983 for (i=0; i < port->debugger.dwarf.cfiSame->size; i++)
1985 if (bitVectBitValue (port->debugger.dwarf.cfiSame, i))
1987 op = dwNewCFop (DW_CFA_undefined);
1988 dwAddCFinsOp (ip, op);
1997 dwWriteFDE (dwfde * fp)
1999 dwWriteWord (NULL, dwSizeofCFAinstructions(fp->ins) + 4
2000 + port->debugger.dwarf.addressSize * 2, NULL);
2002 dwWriteWord ("Ldebug_CIE_start-4", 0, NULL);
2004 dwWriteAddressDelta (fp->endLabel, fp->startLabel);
2006 dwWriteCFAinstructions (fp->ins);
2011 dwWriteFrames (void)
2013 tfprintf (dwarf2FilePtr, "\n\t!area\n", ".debug_frame (NOLOAD)");
2015 /* FIXME: these two dw should be combined into a dd */
2016 tfprintf (dwarf2FilePtr, "\t!dw\t0\n");
2017 tfprintf (dwarf2FilePtr, "\t!dw\t%s\n", "Ldebug_CIE_end-Ldebug_CIE_start");
2019 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_CIE_start");
2021 tfprintf (dwarf2FilePtr, "\t!dw\t0xffff\n");
2022 tfprintf (dwarf2FilePtr, "\t!dw\t0xffff\n"); /* CIE_id */
2024 tfprintf (dwarf2FilePtr, "\t!db\t%d\n",1); /* CIE version number */
2026 tfprintf (dwarf2FilePtr, "\t!db\t%d\n",0); /* augmentation (none) */
2028 dwWriteULEB128 (NULL, 1, NULL); /* code alignment factor */
2030 dwWriteSLEB128 (NULL, (port->stack.direction > 0) ? -1 : 1, NULL); /* data alignment factor */
2032 dwWriteByte (NULL, port->debugger.dwarf.regNumRet, NULL);
2037 if (port->debugger.dwarf.genCFIins)
2038 dwCIEins = port->debugger.dwarf.genCFIins ();
2041 dwCIEins = dwGenCFIins ();
2043 dwWriteCFAinstructions (dwCIEins);
2045 tfprintf (dwarf2FilePtr, "!slabeldef\n", "Ldebug_CIE_end");
2052 /*------------------------------------------------------------------------*/
2057 /*-----------------------------------------------------------------------*/
2058 /* dwHashType - return a hash code for a type chain */
2059 /*-----------------------------------------------------------------------*/
2061 dwHashType (sym_link * type)
2067 hash = (hash << 5) ^ ((hash >> 8) & 0xff);
2070 hash ^= DCL_TYPE (type);
2074 hash ^= SPEC_NOUN (type)
2075 | (SPEC_CONST (type) << 4)
2076 | (SPEC_VOLATILE (type) << 5)
2077 | (SPEC_LONG (type) << 6);
2089 /*-----------------------------------------------------------------------*/
2090 /* dwMatchType - returns true if two types match exactly (including type */
2092 /*-----------------------------------------------------------------------*/
2094 dwMatchTypes (const void * type1v, const void * type2v)
2096 sym_link * type1 = (sym_link *)type1v;
2097 sym_link * type2 = (sym_link *)type2v;
2099 if (!type1 || !type2)
2102 while (type1 && type2)
2106 if (IS_SPEC (type2))
2108 if (SPEC_NOUN (type1) != SPEC_NOUN (type2))
2110 if (SPEC_NOUN (type1) == V_STRUCT
2111 && SPEC_STRUCT (type1) != SPEC_STRUCT (type2))
2113 if (SPEC_CONST (type1) != SPEC_CONST (type2))
2115 if (SPEC_VOLATILE (type1) != SPEC_VOLATILE (type2))
2117 if (SPEC_SHORT (type1) != SPEC_SHORT (type2))
2119 if (SPEC_LONG (type1) != SPEC_LONG (type2))
2121 if (SPEC_USIGN (type1) != SPEC_USIGN (type2))
2129 if (IS_DECL (type2))
2131 if (DCL_TYPE (type1) != DCL_TYPE (type2))
2133 if (DCL_PTR_CONST (type1) != DCL_PTR_CONST (type2))
2135 if (DCL_PTR_VOLATILE (type1) != DCL_PTR_VOLATILE (type2))
2137 if (DCL_TYPE (type1) == ARRAY
2138 && DCL_ELEM (type1) != DCL_ELEM (type2))
2140 /* FIXME: need to match function pointer parameters */
2146 type1 = type1->next;
2147 type2 = type2->next;
2150 if (!type1 && !type2)
2156 /*-----------------------------------------------------------------------*/
2157 /* dwTagFromType - returns the tag describing a type. If new tags need */
2158 /* to be created, they will be added under the specified */
2160 /*-----------------------------------------------------------------------*/
2162 dwTagFromType (sym_link * type, dwtag * parent)
2169 int tableUpdated = 0;
2171 key = dwHashType (type) % dwTypeTagTable->size;
2172 oldtp = hTabFindByKey (dwTypeTagTable, key, type, dwMatchTypes);
2179 switch (DCL_TYPE (type))
2189 tp = dwNewTag (DW_TAG_pointer_type);
2190 if (type->next && !IS_VOID (type->next))
2192 subtp = dwTagFromType (type->next, parent);
2193 dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2195 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2197 dwAddTagChild (parent, tp);
2198 if (DCL_PTR_VOLATILE (type))
2200 modtp = dwNewTag (DW_TAG_volatile_type);
2201 dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2202 dwAddTagChild (parent, modtp);
2205 if (DCL_PTR_CONST (type))
2207 modtp = dwNewTag (DW_TAG_const_type);
2208 dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2209 dwAddTagChild (parent, modtp);
2215 tp = dwNewTag (DW_TAG_array_type);
2216 subtp = dwTagFromType (type->next, parent);
2217 dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2219 dwAddTagChild (tp, subtp);
2220 if (DCL_ELEM (type))
2222 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2224 subtp = dwNewTag (DW_TAG_subrange_type);
2225 dwAddTagAttr (subtp, dwNewAttrConst (DW_AT_upper_bound,
2226 DCL_ELEM (type)-1));
2227 dwAddTagChild (tp, subtp);
2233 tp = dwNewTag (DW_TAG_subroutine_type);
2234 if (type->next && !IS_VOID (type->next))
2236 subtp = dwTagFromType (type->next, parent);
2237 dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2239 /* FIXME: need to handle function parameters */
2243 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2244 "unknown DCL_TYPE");
2250 if (IS_STRUCT (type))
2252 struct structdef * sdp = SPEC_STRUCT (type);
2255 tp = dwNewTag (sdp->type == STRUCT ? DW_TAG_structure_type
2256 : DW_TAG_union_type);
2258 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, sdp->tag));
2260 /* FIXME: should only specify the size if we know this */
2261 /* is a complete type */
2262 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2265 /* Must add this before processing the struct fields */
2266 /* in case there is a recursive definition. */
2267 hTabAddItemLong (&dwTypeTagTable, key, type, tp);
2270 field = sdp->fields;
2276 if (IS_BITFIELD (field->type) && !SPEC_BLEN(field->type))
2278 field = field->next;
2282 memtp = dwNewTag (DW_TAG_member);
2284 dwAddTagAttr (memtp, dwNewAttrString (DW_AT_name,
2286 if (IS_BITFIELD (field->type))
2288 int blen = SPEC_BLEN (field->type);
2289 int bstr = SPEC_BSTR (field->type);
2292 dwAddTagAttr (memtp,
2293 dwNewAttrConst (DW_AT_byte_size,
2295 dwAddTagAttr (memtp,
2296 dwNewAttrConst (DW_AT_bit_size, blen));
2297 dwAddTagAttr (memtp,
2298 dwNewAttrConst (DW_AT_bit_offset,
2302 type = typeFromStr ("uc");
2304 type = typeFromStr ("ui");
2305 subtp = dwTagFromType (type, tp);
2306 dwAddTagAttr (memtp, dwNewAttrTagRef (DW_AT_type, subtp));
2310 subtp = dwTagFromType (field->type, tp);
2311 dwAddTagAttr (memtp, dwNewAttrTagRef (DW_AT_type, subtp));
2313 dwAddTagChild (parent, subtp);
2316 lp = dwNewLoc (DW_OP_plus_uconst, NULL, field->offset);
2317 dwAddTagAttr (memtp,
2318 dwNewAttrLoc (DW_AT_data_member_location, lp));
2320 dwAddTagChild (tp, memtp);
2322 field = field->next;
2325 else if (SPEC_VOLATILE (type) || SPEC_CONST (type))
2327 sym_link temptype = *type;
2329 SPEC_VOLATILE (&temptype) = 0;
2330 SPEC_CONST (&temptype) = 0;
2331 tp = dwTagFromType (&temptype, parent);
2332 if (SPEC_VOLATILE (type))
2334 modtp = dwNewTag (DW_TAG_volatile_type);
2335 dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2336 dwAddTagChild (parent, modtp);
2339 if (SPEC_CONST (type))
2341 modtp = dwNewTag (DW_TAG_const_type);
2342 dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2343 dwAddTagChild (parent, modtp);
2349 switch (SPEC_NOUN (type))
2352 tp = dwNewTag (DW_TAG_base_type);
2353 if (SPEC_USIGN (type))
2355 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2357 if (SPEC_LONG (type))
2358 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name,
2361 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name,
2366 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2368 if (SPEC_LONG (type))
2369 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "long"));
2371 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "int"));
2373 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2375 dwAddTagChild (dwRootTag, tp);
2379 tp = dwNewTag (DW_TAG_base_type);
2380 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2382 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "float"));
2383 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2385 dwAddTagChild (dwRootTag, tp);
2389 tp = dwNewTag (DW_TAG_base_type);
2390 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2392 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "fixed16x16"));
2393 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2395 dwAddTagChild (dwRootTag, tp);
2399 tp = dwNewTag (DW_TAG_base_type);
2400 if (SPEC_USIGN (type))
2402 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2403 DW_ATE_unsigned_char));
2404 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name,
2409 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2411 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "char"));
2413 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2415 dwAddTagChild (dwRootTag, tp);
2425 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2426 "unhandled base type");
2427 printTypeChain (type, NULL);
2436 hTabAddItemLong (&dwTypeTagTable, key, type, tp);
2438 dwAddTagChild (parent, tp);
2441 /*------------------------------------------------------------------------*/
2444 /*-----------------------------------------------------------------------*/
2445 /* dwOpenFile - open the debugging file (just initialize, since all */
2446 /* DWARF data goes into the assembly output file) */
2447 /*-----------------------------------------------------------------------*/
2448 int dwOpenFile(char *file)
2450 dwTypeTagTable = newHashTable (128);
2455 /*-----------------------------------------------------------------------*/
2456 /* dwCloseFile - close the debugging file (do nothing, since all DWARF */
2457 /* data goes into the assembly output file) */
2458 /*-----------------------------------------------------------------------*/
2459 int dwCloseFile(void)
2465 /*-----------------------------------------------------------------------*/
2466 /* dwGenerateScopes - recursively traverse an ast, generating lexical */
2467 /* block tags for block scopes found */
2468 /*-----------------------------------------------------------------------*/
2470 dwGenerateScopes (dwtag *tp, ast * tree)
2477 if (!IS_AST_OP (tree))
2480 if (tree->opval.op == BLOCK)
2482 subtp = dwNewTag (DW_TAG_lexical_block);
2485 dwAddTagAttr (subtp, dwNewAttrConst (DW_AT_user_block, tree->right->block));
2486 dwAddTagAttr (subtp, dwNewAttrConst (DW_AT_user_level, tree->right->level));
2488 dwAddTagChild (tp, subtp);
2490 dwGenerateScopes (subtp, tree->right);
2494 dwGenerateScopes (tp, tree->left);
2495 dwGenerateScopes (tp, tree->right);
2499 /*-----------------------------------------------------------------------*/
2500 /* dwFindScope - return the lexical block tag for a particular block */
2501 /* scope, or NULL if not found */
2502 /*-----------------------------------------------------------------------*/
2504 dwFindScope (dwtag * tp, int block)
2514 if (tp->tag == DW_TAG_lexical_block)
2519 if (ap->attr == DW_AT_user_block)
2521 if (ap->val.data == block)
2527 rettp = dwFindScope (tp->firstChild, block);
2537 /*------------------------------------------------------------------------*/
2538 /* dwWriteSymbolInternal - create tag information for a variable or */
2539 /* parameter and place it in the correct position */
2540 /* within the tag tree */
2541 /*------------------------------------------------------------------------*/
2543 dwWriteSymbolInternal (symbol *sym)
2554 if (!sym->level || IS_EXTERN (sym->etype))
2555 scopetp = dwRootTag;
2558 assert(sym->localof);
2562 /* Find the tag for the function this symbol is defined in */
2563 functp = dwRootTag->firstChild;
2566 if (functp->tag == DW_TAG_subprogram)
2568 funcap = dwFindAttr (functp, DW_AT_name);
2569 if (funcap && !strcmp (funcap->val.string, sym->localof->name))
2572 functp = functp->siblings;
2578 /* Find the correct scope within this function */
2579 scopetp = dwFindScope (functp->firstChild, sym->block);
2584 tp = dwNewTag (sym->_isparm ? DW_TAG_formal_parameter : DW_TAG_variable);
2586 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, sym->name));
2588 /* Find the ultimate symbol holding the value. */
2590 /* a) original symbol, */
2591 /* b) register equivalent, */
2592 /* c) spill location */
2594 if (!sym->allocreq && sym->reqv)
2596 symloc = OP_SYMBOL (symloc->reqv);
2597 if (symloc->isspilt && !symloc->remat)
2598 symloc = symloc->usl.spillLoc;
2604 if (inregs && symloc->regs[0])
2607 dwloc * lastlp = NULL;
2611 /* register allocation */
2612 for (i = (port->little_endian ? 0 : symloc->nRegs-1);
2613 (port->little_endian ? (i < symloc->nRegs) : (i >= 0));
2614 (port->little_endian ? i++ : i--))
2616 regNum = port->debugger.dwarf.regNum (symloc->regs[i]);
2617 if (regNum >= 0 && regNum <= 31)
2618 reglp = dwNewLoc (DW_OP_reg0 + regNum, NULL, 0);
2619 else if (regNum >= 0)
2620 reglp = dwNewLoc (DW_OP_regx, NULL, regNum);
2623 /* We are forced to give up if the ABI for this port */
2624 /* does not define a number for this register */
2630 lastlp->next = reglp;
2635 if (symloc->nRegs != 1)
2637 reglp = dwNewLoc (DW_OP_piece, NULL, 1);
2638 lastlp->next = reglp;
2643 else if (symloc->onStack)
2645 /* stack allocation */
2646 lp = dwNewLoc (DW_OP_fbreg, NULL, symloc->stack);
2650 /* global allocation */
2651 if (sym->level && !sym->allocreq)
2654 lp = dwNewLoc (DW_OP_addr, symloc->rname, 0);
2657 /* Only create the DW_AT_location if a known location exists. */
2658 /* It might not exist if the variable has been optimized away */
2659 /* or if the compiler has lost track of it (not good, but still */
2660 /* happens sometimes -- need to improve induction) */
2662 dwAddTagAttr (tp, dwNewAttrLoc (DW_AT_location, lp));
2664 if (!IS_STATIC (sym->etype) && !sym->level)
2665 dwAddTagAttr (tp, dwNewAttrFlag (DW_AT_external, 1));
2666 if (IS_EXTERN (sym->etype))
2667 dwAddTagAttr (tp, dwNewAttrFlag (DW_AT_declaration, 1));
2669 subtp = dwTagFromType (sym->type, scopetp);
2670 dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2672 dwAddTagChild (scopetp, subtp);
2674 dwAddTagChild (scopetp, tp);
2679 /*-----------------------------------------------------------------------*/
2680 /* dwWriteFunction - generate a tag for a function. */
2681 /*-----------------------------------------------------------------------*/
2682 int dwWriteFunction(symbol *sym, iCode *ic)
2687 dwFuncTag = tp = dwNewTag (DW_TAG_subprogram);
2689 dwAddTagAttr (dwFuncTag, dwNewAttrString (DW_AT_name, sym->name));
2691 dwAddTagAttr (dwFuncTag, dwNewAttrAddrSymbol (DW_AT_low_pc, sym, 0));
2693 if (FUNC_ISISR (sym->type))
2694 dwAddTagAttr (dwFuncTag, dwNewAttrConst (DW_AT_calling_convention,
2697 dwAddTagAttr (dwFuncTag, dwNewAttrFlag (DW_AT_external,
2698 !IS_STATIC (sym->etype)));
2700 if (sym->type->next && !IS_VOID (sym->type->next))
2704 subtp = dwTagFromType (sym->type->next, dwRootTag);
2705 dwAddTagAttr (dwFuncTag, dwNewAttrTagRef (DW_AT_type, subtp));
2707 dwAddTagChild (dwRootTag, dwFuncTag);
2709 args = FUNC_ARGS(sym->type);
2712 dwWriteSymbolInternal (args->sym);
2715 if (FUNC_HASVARARGS (sym->type))
2717 dwAddTagChild (dwFuncTag, dwNewTag (DW_TAG_unspecified_parameters));
2720 while (ic && ic->op != FUNCTION)
2722 if (ic && ic->op == FUNCTION && ic->tree && ic->tree->right)
2724 dwGenerateScopes (dwFuncTag, ic->tree->right->left);
2725 dwGenerateScopes (dwFuncTag, ic->tree->right->right);
2735 /*-----------------------------------------------------------------------*/
2736 /* dwWriteEndFunction - write attributes to the current function tag */
2737 /* that are only known after code generation is */
2739 /*-----------------------------------------------------------------------*/
2740 int dwWriteEndFunction(symbol *sym, iCode *ic, int offset)
2742 char debugSym[SDCC_NAME_MAX + 1];
2747 dwLineLast->offset += offset;
2748 dwLineLast->end_sequence = 1;
2751 if (IS_STATIC (sym->etype))
2752 sprintf (debugSym, "XF%s$%s$0$0", dwModuleName, sym->name);
2754 sprintf (debugSym, "XG$%s$0$0", sym->name);
2755 emitDebuggerSymbol (debugSym);
2757 dwAddTagAttr (dwFuncTag, dwNewAttrAddrLabel (DW_AT_high_pc,
2758 Safe_strdup(debugSym),
2763 dwAddTagAttr (dwFuncTag, dwNewAttrLocRef (DW_AT_frame_base,
2766 dwFrameLocList->next = dwRootLocList;
2767 dwRootLocList = dwFrameLocList;
2768 dwFrameLocList = NULL;
2775 /*-----------------------------------------------------------------------*/
2776 /* dwWriteLabel - generate a tag for a source level label */
2777 /*-----------------------------------------------------------------------*/
2778 int dwWriteLabel(symbol *sym, iCode *ic)
2780 char debugSym[SDCC_NAME_MAX + 1];
2783 /* ignore the compiler generated labels */
2787 sprintf (debugSym, "L%s$%s$%s", dwModuleName, currFunc->name, sym->name);
2788 emitDebuggerSymbol (debugSym);
2790 tp = dwNewTag (DW_TAG_label);
2791 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, sym->name));
2792 dwAddTagAttr (tp, dwNewAttrAddrLabel (DW_AT_low_pc,
2793 Safe_strdup (debugSym), 0));
2795 dwAddTagChild (dwFuncTag, tp);
2801 /*-----------------------------------------------------------------------*/
2802 /* dwWriteScope - add the starting and ending address attributes to a */
2803 /* a lexical block tag (created during dwWriteFunction) */
2804 /*-----------------------------------------------------------------------*/
2805 int dwWriteScope(iCode *ic)
2807 char * debugSym = NULL;
2811 scopetp = dwFindScope (dwFuncTag->firstChild, ic->block);
2813 if (dwScopeTag && ic->level <= dwScopeLevel)
2815 debugSym = dwNewDebugSymbol ();
2816 emitDebuggerSymbol (debugSym);
2817 dwSetTagAttr (dwScopeTag, dwNewAttrAddrLabel (DW_AT_high_pc, debugSym, 0));
2819 dwScopeTag = scopetp;
2820 dwScopeLevel = ic->level;
2824 ap = dwFindAttr (scopetp, DW_AT_low_pc);
2829 debugSym = dwNewDebugSymbol ();
2830 emitDebuggerSymbol (debugSym);
2831 dwAddTagAttr (scopetp, dwNewAttrAddrLabel (DW_AT_low_pc, debugSym, 0));
2833 dwScopeTag = scopetp;
2834 dwScopeLevel = ic->level;
2840 /*-----------------------------------------------------------------------*/
2841 /* dwWriteSymbol - generate tags for global variables. This is actually */
2842 /* called for all variables and parameters, but we */
2843 /* process the non-global variables elsewhere. */
2844 /*-----------------------------------------------------------------------*/
2845 int dwWriteSymbol(symbol *sym)
2847 if (IS_FUNC (sym->type))
2850 /* If it is an iTemp, then it is not a C source symbol; ignore it */
2854 /* Ignore parameters; they must be handled specially so that they will */
2855 /* appear in the correct order */
2859 return dwWriteSymbolInternal (sym);
2863 /*-----------------------------------------------------------------------*/
2865 /*-----------------------------------------------------------------------*/
2866 int dwWriteType(structdef *sdef, int block, int inStruct, char *tag)
2868 /* FIXME: needs implementation */
2873 /*-----------------------------------------------------------------------*/
2874 /* dwWriteModule - generates the root tag for this compilation unit */
2875 /*-----------------------------------------------------------------------*/
2876 int dwWriteModule(char *name)
2881 dwModuleName = Safe_strdup (name);
2883 sprintf(verid, "SDCC version %s #%s", SDCC_VERSION_STR, getBuildNumber());
2885 tp = dwNewTag (DW_TAG_compile_unit);
2886 dwAddTagAttr (tp, dwNewAttrString (DW_AT_producer, verid));
2888 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_language, DW_LANG_C89));
2890 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, fullSrcFileName));
2892 dwAddTagAttr (tp, dwNewAttrLabelRef (DW_AT_stmt_list,
2893 "Ldebug_line_start", -4));
2901 /*-----------------------------------------------------------------------*/
2902 /* dwWriteCLine - generates a line number/position to address record for */
2904 /*-----------------------------------------------------------------------*/
2905 int dwWriteCLine(iCode *ic)
2910 lp = Safe_alloc (sizeof (dwline));
2912 lp->line = ic->lineno;
2914 debugSym = dwNewDebugSymbol ();
2915 emitDebuggerSymbol (debugSym);
2916 lp->label = debugSym;
2919 lp->fileIndex = dwFindFileIndex (ic->filename);
2924 dwLineLast->next = lp;
2931 /*-----------------------------------------------------------------------*/
2932 /* dwWriteFrameAddress - note the current position of the frame pointer */
2933 /* address. The base address can be specified by */
2934 /* either a register or pointer variable, leaving */
2935 /* the other as NULL. If both are NULL, there is */
2936 /* no current frame pointer address defined. */
2937 /*-----------------------------------------------------------------------*/
2939 dwWriteFrameAddress(char *variable, struct regs *reg, int offset)
2941 char * debugSym = NULL;
2946 /* If there was a region open, close it */
2949 debugSym = dwNewDebugSymbol ();
2950 emitDebuggerSymbol (debugSym);
2952 dwFrameLastLoc->endLabel = debugSym;
2953 dwFrameLastLoc = NULL;
2956 if (!variable && !reg)
2959 /* Create a new debugger symbol for the start of the region if */
2960 /* we can't recycle the symbol at the end of the previous */
2963 debugSym = dwNewDebugSymbol ();
2964 emitDebuggerSymbol (debugSym);
2967 lrp = Safe_alloc (sizeof (dwlocregion));
2968 lrp->startLabel = debugSym;
2970 if (variable) /* frame pointer based from a global variable */
2974 lrp->loc = dwNewLoc (DW_OP_addr, variable, 0);
2975 lrp->loc->next = lp = dwNewLoc (DW_OP_deref_size, NULL, PTRSIZE);
2978 lp->next = dwNewLoc (DW_OP_consts, NULL, offset);
2979 lp->next->next = dwNewLoc (DW_OP_plus, NULL, 0);
2982 else if (reg) /* frame pointer based from a register */
2984 regNum = port->debugger.dwarf.regNum (reg);
2987 if (regNum>=0 && regNum<=31)
2990 lrp->loc = dwNewLoc (DW_OP_breg0 + regNum, NULL, offset);
2992 lrp->loc = dwNewLoc (DW_OP_reg0 + regNum, NULL, 0);
2996 lrp->loc = lp = dwNewLoc (DW_OP_regx, NULL, regNum);
2999 lp->next = dwNewLoc (DW_OP_consts, NULL, offset);
3000 lp->next->next = dwNewLoc (DW_OP_plus, NULL, 0);
3004 dwFrameLastLoc = lrp;
3006 if (!dwFrameLocList)
3007 dwFrameLocList = dwNewLocList();
3008 lrp->next = dwFrameLocList->region;
3009 dwFrameLocList->region = lrp;
3015 /*-----------------------------------------------------------------------*/
3016 /* dwWriteALine - generates a line number/position to address record for */
3017 /* assembly source */
3018 /*-----------------------------------------------------------------------*/
3019 int dwWriteALine(char *module, int Line)
3027 /*-----------------------------------------------------------------------*/
3028 /* dwarf2FinalizeFile - write all of the DWARF debugging data to the */
3030 /*-----------------------------------------------------------------------*/
3032 dwarf2FinalizeFile(FILE *of)
3034 int tagAddress = 11;
3040 /* Write the .debug_line section */
3041 dwWriteLineNumbers ();
3043 /* Assign the location list addresses (for cross references) */
3044 dwAssignLocListAddresses ();
3046 /* Write the .debug_loc section */
3049 /* Delete our scope related user attributes; they were only needed to help */
3050 /* build the tag tree and have no meaning to (and may confuse) debuggers */
3051 attr = DW_AT_user_block;
3052 dwTraverseTag (dwRootTag, dwDeleteTagAttr, &attr);
3053 attr = DW_AT_user_level;
3054 dwTraverseTag (dwRootTag, dwDeleteTagAttr, &attr);
3056 /* Add a DW_AT_sibling attribute to all tags with children and siblings */
3057 dwTraverseTag (dwRootTag, dwAddSibAttr, NULL);
3059 /* Assign the tag abbreviations. The tags, attributes, and forms must */
3060 /* not change after this point. The attribute values may change as long */
3061 /* as the size of the value does not. */
3062 dwAbbrevTable = newHashTable (128);
3063 dwTraverseTag (dwRootTag, dwAssignAbbrev, &abbrevNum);
3065 /* Assign the tag addresses (for cross references) */
3066 dwTraverseTag (dwRootTag, dwAssignTagAddress, &tagAddress);
3068 /* Write the .debug_abbrev section */
3071 /* Write the .debug_info section */
3074 /* Write the .debug_pubnames section */