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", moduleName, 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 (NULL, 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 (*(filename+strlen (includeDir)) == DIR_SEPARATOR_CHAR)
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 dwWriteULEB128 (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 dwWriteULEB128 (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_CONST (type1) != SPEC_CONST (type2))
2112 if (SPEC_VOLATILE (type1) != SPEC_VOLATILE (type2))
2114 if (SPEC_SHORT (type1) != SPEC_SHORT (type2))
2116 if (SPEC_LONG (type1) != SPEC_LONG (type2))
2118 if (SPEC_USIGN (type1) != SPEC_USIGN (type2))
2126 if (IS_DECL (type2))
2128 if (DCL_TYPE (type1) != DCL_TYPE (type2))
2130 if (DCL_PTR_CONST (type1) != DCL_PTR_CONST (type2))
2132 if (DCL_PTR_VOLATILE (type1) != DCL_PTR_VOLATILE (type2))
2134 if (DCL_TYPE (type1) == ARRAY
2135 && DCL_ELEM (type1) != DCL_ELEM (type2))
2137 /* FIXME: need to match function pointer parameters */
2143 type1 = type1->next;
2144 type2 = type2->next;
2147 if (!type1 && !type2)
2153 /*-----------------------------------------------------------------------*/
2154 /* dwTagFromType - returns the tag describing a type. If new tags need */
2155 /* to be created, they will be added under the specified */
2157 /*-----------------------------------------------------------------------*/
2159 dwTagFromType (sym_link * type, dwtag * parent)
2167 key = dwHashType (type) % dwTypeTagTable->size;
2168 oldtp = hTabFindByKey (dwTypeTagTable, key, type, dwMatchTypes);
2175 switch (DCL_TYPE (type))
2185 tp = dwNewTag (DW_TAG_pointer_type);
2186 if (type->next && !IS_VOID (type->next))
2188 subtp = dwTagFromType (type->next, parent);
2189 dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2191 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2193 dwAddTagChild (parent, tp);
2194 if (DCL_PTR_VOLATILE (type))
2196 modtp = dwNewTag (DW_TAG_volatile_type);
2197 dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2198 dwAddTagChild (parent, modtp);
2201 if (DCL_PTR_CONST (type))
2203 modtp = dwNewTag (DW_TAG_const_type);
2204 dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2205 dwAddTagChild (parent, modtp);
2211 tp = dwNewTag (DW_TAG_array_type);
2212 subtp = dwTagFromType (type->next, parent);
2213 dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2215 dwAddTagChild (tp, subtp);
2216 if (DCL_ELEM (type))
2218 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2220 subtp = dwNewTag (DW_TAG_subrange_type);
2221 dwAddTagAttr (subtp, dwNewAttrConst (DW_AT_upper_bound,
2222 DCL_ELEM (type)-1));
2223 dwAddTagChild (tp, subtp);
2229 tp = dwNewTag (DW_TAG_subroutine_type);
2230 if (type->next && !IS_VOID (type->next))
2232 subtp = dwTagFromType (type->next, parent);
2233 dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2235 /* FIXME: need to handle function parameters */
2239 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2240 "unknown DCL_TYPE");
2246 if (IS_STRUCT (type))
2248 struct structdef * sdp = SPEC_STRUCT (type);
2251 tp = dwNewTag (sdp->type == STRUCT ? DW_TAG_structure_type
2252 : DW_TAG_union_type);
2254 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, sdp->tag));
2256 /* FIXME: should only specify the size if we know this */
2257 /* is a complete type */
2258 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2260 field = sdp->fields;
2266 memtp = dwNewTag (DW_TAG_member);
2268 dwAddTagAttr (memtp, dwNewAttrString (DW_AT_name,
2270 subtp = dwTagFromType (field->type, tp);
2271 dwAddTagAttr (memtp, dwNewAttrTagRef (DW_AT_type, subtp));
2273 dwAddTagChild (parent, subtp);
2275 lp = dwNewLoc (DW_OP_plus_uconst, NULL, field->offset);
2276 dwAddTagAttr (memtp,
2277 dwNewAttrLoc (DW_AT_data_member_location, lp));
2279 dwAddTagChild (tp, memtp);
2281 field = field->next;
2284 else if (SPEC_VOLATILE (type) || SPEC_CONST (type))
2286 sym_link temptype = *type;
2288 SPEC_VOLATILE (&temptype) = 0;
2289 SPEC_CONST (&temptype) = 0;
2290 tp = dwTagFromType (&temptype, parent);
2291 if (SPEC_VOLATILE (type))
2293 modtp = dwNewTag (DW_TAG_volatile_type);
2294 dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2295 dwAddTagChild (parent, modtp);
2298 if (SPEC_CONST (type))
2300 modtp = dwNewTag (DW_TAG_const_type);
2301 dwAddTagAttr (modtp, dwNewAttrTagRef (DW_AT_type, tp));
2302 dwAddTagChild (parent, modtp);
2308 switch (SPEC_NOUN (type))
2311 tp = dwNewTag (DW_TAG_base_type);
2312 if (SPEC_USIGN (type))
2314 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2316 if (SPEC_LONG (type))
2317 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name,
2320 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name,
2325 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2327 if (SPEC_LONG (type))
2328 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "long"));
2330 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "int"));
2332 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2334 dwAddTagChild (dwRootTag, tp);
2338 tp = dwNewTag (DW_TAG_base_type);
2339 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2341 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "float"));
2342 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2344 dwAddTagChild (dwRootTag, tp);
2348 tp = dwNewTag (DW_TAG_base_type);
2349 if (SPEC_USIGN (type))
2351 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2352 DW_ATE_unsigned_char));
2353 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name,
2358 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_encoding,
2360 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, "char"));
2362 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_byte_size,
2364 dwAddTagChild (dwRootTag, tp);
2374 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2375 "unhandled base type");
2376 printTypeChain (type, NULL);
2384 hTabAddItemLong (&dwTypeTagTable, key, type, tp);
2387 /*------------------------------------------------------------------------*/
2390 /*-----------------------------------------------------------------------*/
2391 /* dwOpenFile - opens a temporary file for debugging information */
2392 /*-----------------------------------------------------------------------*/
2393 int dwOpenFile(char *file)
2395 dwarf2FilePtr = tempfile();
2396 if(!dwarf2FilePtr) return 0;
2398 dwTypeTagTable = newHashTable (128);
2403 /*-----------------------------------------------------------------------*/
2404 /* dwCloseFile - close (and deletes) the temporary file for debugging */
2406 /*-----------------------------------------------------------------------*/
2407 int dwCloseFile(void)
2409 if(!dwarf2FilePtr) return 0;
2411 fclose(dwarf2FilePtr);
2417 /*-----------------------------------------------------------------------*/
2418 /* dwGenerateScopes - recursively traverse an ast, generating lexical */
2419 /* block tags for block scopes found */
2420 /*-----------------------------------------------------------------------*/
2422 dwGenerateScopes (dwtag *tp, ast * tree)
2429 if (!IS_AST_OP (tree))
2432 if (tree->opval.op == BLOCK)
2434 subtp = dwNewTag (DW_TAG_lexical_block);
2437 dwAddTagAttr (subtp, dwNewAttrConst (DW_AT_user_block, tree->right->block));
2438 dwAddTagAttr (subtp, dwNewAttrConst (DW_AT_user_level, tree->right->level));
2440 dwAddTagChild (tp, subtp);
2442 dwGenerateScopes (subtp, tree->right);
2446 dwGenerateScopes (tp, tree->left);
2447 dwGenerateScopes (tp, tree->right);
2451 /*-----------------------------------------------------------------------*/
2452 /* dwFindScope - return the lexical block tag for a particular block */
2453 /* scope, or NULL if not found */
2454 /*-----------------------------------------------------------------------*/
2456 dwFindScope (dwtag * tp, int block)
2466 if (tp->tag == DW_TAG_lexical_block)
2471 if (ap->attr == DW_AT_user_block)
2473 if (ap->val.data == block)
2479 rettp = dwFindScope (tp->firstChild, block);
2489 /*------------------------------------------------------------------------*/
2490 /* dwWriteSymbolInternal - create tag information for a variable or */
2491 /* parameter and place it in the correct position */
2492 /* within the tag tree */
2493 /*------------------------------------------------------------------------*/
2495 dwWriteSymbolInternal (symbol *sym)
2507 scopetp = dwRootTag;
2510 assert(sym->localof);
2514 /* Find the tag for the function this symbol is defined in */
2515 functp = dwRootTag->firstChild;
2518 if (functp->tag == DW_TAG_subprogram)
2520 funcap = dwFindAttr (functp, DW_AT_name);
2521 if (funcap && !strcmp (funcap->val.string, sym->localof->name))
2524 functp = functp->siblings;
2530 /* Find the correct scope within this function */
2531 scopetp = dwFindScope (functp->firstChild, sym->block);
2536 tp = dwNewTag (sym->_isparm ? DW_TAG_formal_parameter : DW_TAG_variable);
2538 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, sym->name));
2540 /* Find the ultimate symbol holding the value. */
2542 /* a) original symbol, */
2543 /* b) register equivalent, */
2544 /* c) spill location */
2546 if (!sym->allocreq && sym->reqv)
2548 symloc = OP_SYMBOL (symloc->reqv);
2549 if (symloc->isspilt && !symloc->remat)
2550 symloc = symloc->usl.spillLoc;
2556 if (inregs && symloc->regs[0])
2559 dwloc * lastlp = NULL;
2563 /* register allocation */
2564 for (i = (port->little_endian ? 0 : symloc->nRegs-1);
2565 (port->little_endian ? (i < symloc->nRegs) : (i >= 0));
2566 (port->little_endian ? i++ : i--))
2568 regNum = port->debugger.dwarf.regNum (symloc->regs[i]);
2569 if (regNum >= 0 && regNum <= 31)
2570 reglp = dwNewLoc (DW_OP_reg0 + regNum, NULL, 0);
2571 else if (regNum >= 0)
2572 reglp = dwNewLoc (DW_OP_regx, NULL, regNum);
2575 /* We are forced to give up if the ABI for this port */
2576 /* does not define a number for this register */
2582 lastlp->next = reglp;
2587 if (symloc->nRegs != 1)
2589 reglp = dwNewLoc (DW_OP_piece, NULL, 1);
2590 lastlp->next = reglp;
2595 else if (symloc->onStack)
2597 /* stack allocation */
2598 lp = dwNewLoc (DW_OP_fbreg, NULL, sym->stack);
2602 /* global allocation */
2603 lp = dwNewLoc (DW_OP_addr, sym->rname, 0);
2606 /* Only create the DW_AT_location if a known location exists. */
2607 /* It might not exist if the variable has been optimized away */
2608 /* or if the compiler has lost track of it (not good, but still */
2609 /* happens sometimes -- need to improve induction) */
2611 dwAddTagAttr (tp, dwNewAttrLoc (DW_AT_location, lp));
2613 if (!IS_STATIC (sym->etype) && !sym->level)
2614 dwAddTagAttr (tp, dwNewAttrFlag (DW_AT_external, 1));
2615 if (IS_EXTERN (sym->etype))
2616 dwAddTagAttr (tp, dwNewAttrFlag (DW_AT_declaration, 1));
2618 subtp = dwTagFromType (sym->type, scopetp);
2619 dwAddTagAttr (tp, dwNewAttrTagRef (DW_AT_type, subtp));
2621 dwAddTagChild (scopetp, subtp);
2623 dwAddTagChild (scopetp, tp);
2628 /*-----------------------------------------------------------------------*/
2629 /* dwWriteFunction - generate a tag for a function. */
2630 /*-----------------------------------------------------------------------*/
2631 int dwWriteFunction(symbol *sym, iCode *ic)
2636 if(!dwarf2FilePtr) return 0;
2638 dwFuncTag = tp = dwNewTag (DW_TAG_subprogram);
2640 dwAddTagAttr (dwFuncTag, dwNewAttrString (DW_AT_name, sym->name));
2642 dwAddTagAttr (dwFuncTag, dwNewAttrAddrSymbol (DW_AT_low_pc, sym, 0));
2644 if (FUNC_ISISR (sym->type))
2645 dwAddTagAttr (dwFuncTag, dwNewAttrConst (DW_AT_calling_convention,
2648 dwAddTagAttr (dwFuncTag, dwNewAttrFlag (DW_AT_external,
2649 !IS_STATIC (sym->etype)));
2651 if (sym->type->next && !IS_VOID (sym->type->next))
2655 subtp = dwTagFromType (sym->type->next, dwRootTag);
2656 dwAddTagAttr (dwFuncTag, dwNewAttrTagRef (DW_AT_type, subtp));
2658 dwAddTagChild (dwRootTag, dwFuncTag);
2660 args = FUNC_ARGS(sym->type);
2663 dwWriteSymbolInternal (args->sym);
2666 if (FUNC_HASVARARGS (sym->type))
2668 dwAddTagChild (dwFuncTag, dwNewTag (DW_TAG_unspecified_parameters));
2671 while (ic && ic->op != FUNCTION)
2673 if (ic && ic->op == FUNCTION && ic->tree && ic->tree->right)
2675 dwGenerateScopes (dwFuncTag, ic->tree->right->left);
2676 dwGenerateScopes (dwFuncTag, ic->tree->right->right);
2686 /*-----------------------------------------------------------------------*/
2687 /* dwWriteEndFunction - write attributes to the current function tag */
2688 /* that are only known after code generation is */
2690 /*-----------------------------------------------------------------------*/
2691 int dwWriteEndFunction(symbol *sym, iCode *ic, int offset)
2693 char debugSym[SDCC_NAME_MAX];
2698 dwLineLast->offset += offset;
2699 dwLineLast->end_sequence = 1;
2702 if (IS_STATIC (sym->etype))
2703 sprintf (debugSym, "XF%s$%s$0$0", moduleName, sym->name);
2705 sprintf (debugSym, "XG$%s$0$0", sym->name);
2706 emitDebuggerSymbol (debugSym);
2708 dwAddTagAttr (dwFuncTag, dwNewAttrAddrLabel (DW_AT_high_pc,
2709 Safe_strdup(debugSym),
2714 dwAddTagAttr (dwFuncTag, dwNewAttrLocRef (DW_AT_frame_base,
2717 dwFrameLocList->next = dwRootLocList;
2718 dwRootLocList = dwFrameLocList;
2719 dwFrameLocList = NULL;
2726 /*-----------------------------------------------------------------------*/
2727 /* dwWriteLabel - generate a tag for a source level label */
2728 /*-----------------------------------------------------------------------*/
2729 int dwWriteLabel(symbol *sym, iCode *ic)
2731 char debugSym[SDCC_NAME_MAX];
2734 /* ignore the compiler generated labels */
2738 sprintf (debugSym, "L%s$%s$%s", moduleName, currFunc->name, sym->name);
2739 emitDebuggerSymbol (debugSym);
2741 tp = dwNewTag (DW_TAG_label);
2742 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, sym->name));
2743 dwAddTagAttr (tp, dwNewAttrAddrLabel (DW_AT_low_pc,
2744 Safe_strdup (debugSym), 0));
2746 dwAddTagChild (dwFuncTag, tp);
2752 /*-----------------------------------------------------------------------*/
2753 /* dwWriteScope - add the starting and ending address attributes to a */
2754 /* a lexical block tag (created during dwWriteFunction) */
2755 /*-----------------------------------------------------------------------*/
2756 int dwWriteScope(iCode *ic)
2758 char * debugSym = NULL;
2762 scopetp = dwFindScope (dwFuncTag->firstChild, ic->block);
2764 if (dwScopeTag && ic->level <= dwScopeLevel)
2766 debugSym = dwNewDebugSymbol ();
2767 emitDebuggerSymbol (debugSym);
2768 dwSetTagAttr (dwScopeTag, dwNewAttrAddrLabel (DW_AT_high_pc, debugSym, 0));
2770 dwScopeTag = scopetp;
2771 dwScopeLevel = ic->level;
2775 ap = dwFindAttr (scopetp, DW_AT_low_pc);
2780 debugSym = dwNewDebugSymbol ();
2781 emitDebuggerSymbol (debugSym);
2782 dwAddTagAttr (scopetp, dwNewAttrAddrLabel (DW_AT_low_pc, debugSym, 0));
2784 dwScopeTag = scopetp;
2785 dwScopeLevel = ic->level;
2791 /*-----------------------------------------------------------------------*/
2792 /* dwWriteSymbol - generate tags for global variables. This is actually */
2793 /* called for all variables and parameters, but we */
2794 /* process the non-global variables elsewhere. */
2795 /*-----------------------------------------------------------------------*/
2796 int dwWriteSymbol(symbol *sym)
2798 if (IS_FUNC (sym->type))
2801 /* If it is an iTemp, then it is not a C source symbol; ignore it */
2805 /* Ignore parameters; they must be handled specially so that they will */
2806 /* appear in the correct order */
2810 return dwWriteSymbolInternal (sym);
2814 /*-----------------------------------------------------------------------*/
2816 /*-----------------------------------------------------------------------*/
2817 int dwWriteType(structdef *sdef, int block, int inStruct, char *tag)
2819 /* FIXME: needs implementation */
2824 /*-----------------------------------------------------------------------*/
2825 /* dwWriteModule - generates the root tag for this compilation unit */
2826 /*-----------------------------------------------------------------------*/
2827 int dwWriteModule(char *name)
2831 if(!dwarf2FilePtr) return 0;
2833 tp = dwNewTag (DW_TAG_compile_unit);
2834 dwAddTagAttr (tp, dwNewAttrString (DW_AT_producer, "SDCC version "
2836 dwAddTagAttr (tp, dwNewAttrConst (DW_AT_language, DW_LANG_C89));
2838 dwAddTagAttr (tp, dwNewAttrString (DW_AT_name, fullSrcFileName));
2840 dwAddTagAttr (tp, dwNewAttrLabelRef (DW_AT_stmt_list,
2841 "Ldebug_line_start", -4));
2849 /*-----------------------------------------------------------------------*/
2850 /* dwWriteCLine - generates a line number/position to address record for */
2852 /*-----------------------------------------------------------------------*/
2853 int dwWriteCLine(iCode *ic)
2858 if(!dwarf2FilePtr) return 0;
2860 lp = Safe_alloc (sizeof (dwline));
2862 lp->line = ic->lineno;
2864 debugSym = dwNewDebugSymbol ();
2865 emitDebuggerSymbol (debugSym);
2866 lp->label = debugSym;
2869 lp->fileIndex = dwFindFileIndex (ic->filename);
2874 dwLineLast->next = lp;
2881 /*-----------------------------------------------------------------------*/
2882 /* dwWriteFrameAddress - note the current position of the frame pointer */
2883 /* address. The base address can be specified by */
2884 /* either a register or pointer variable, leaving */
2885 /* the other as NULL. If both are NULL, there is */
2886 /* no current frame pointer address defined. */
2887 /*-----------------------------------------------------------------------*/
2889 dwWriteFrameAddress(char *variable, struct regs *reg, int offset)
2891 char * debugSym = NULL;
2896 if(!dwarf2FilePtr) return 0;
2898 /* If there was a region open, close it */
2901 debugSym = dwNewDebugSymbol ();
2902 emitDebuggerSymbol (debugSym);
2904 dwFrameLastLoc->endLabel = debugSym;
2905 dwFrameLastLoc = NULL;
2908 if (!variable && !reg)
2911 /* Create a new debugger symbol for the start of the region if */
2912 /* we can't recycle the symbol at the end of the previous */
2915 debugSym = dwNewDebugSymbol ();
2916 emitDebuggerSymbol (debugSym);
2919 lrp = Safe_alloc (sizeof (dwlocregion));
2920 lrp->startLabel = debugSym;
2922 if (variable) /* frame pointer based from a global variable */
2926 lrp->loc = dwNewLoc (DW_OP_addr, variable, 0);
2927 lrp->loc->next = lp = dwNewLoc (DW_OP_deref_size, NULL, PTRSIZE);
2930 lp->next = dwNewLoc (DW_OP_consts, NULL, offset);
2931 lp->next->next = dwNewLoc (DW_OP_plus, NULL, 0);
2934 else if (reg) /* frame pointer based from a register */
2936 regNum = port->debugger.dwarf.regNum (reg);
2939 if (regNum>=0 && regNum<=31)
2942 lrp->loc = dwNewLoc (DW_OP_breg0 + regNum, NULL, offset);
2944 lrp->loc = dwNewLoc (DW_OP_reg0 + regNum, NULL, 0);
2948 lrp->loc = lp = dwNewLoc (DW_OP_regx, NULL, regNum);
2951 lp->next = dwNewLoc (DW_OP_consts, NULL, offset);
2952 lp->next->next = dwNewLoc (DW_OP_plus, NULL, 0);
2956 dwFrameLastLoc = lrp;
2958 if (!dwFrameLocList)
2959 dwFrameLocList = dwNewLocList();
2960 lrp->next = dwFrameLocList->region;
2961 dwFrameLocList->region = lrp;
2967 /*-----------------------------------------------------------------------*/
2968 /* dwWriteALine - generates a line number/position to address record for */
2969 /* assembly source */
2970 /*-----------------------------------------------------------------------*/
2971 int dwWriteALine(char *module, int Line)
2973 if(!dwarf2FilePtr) return 0;
2981 /*-----------------------------------------------------------------------*/
2982 /* dwarf2FinalizeFile - write all of the DWARF debugging data to the */
2984 /*-----------------------------------------------------------------------*/
2986 dwarf2FinalizeFile(void)
2988 int tagAddress = 11;
2992 if(!dwarf2FilePtr) return 1;
2994 /* Write the .debug_line section */
2995 dwWriteLineNumbers ();
2997 /* Assign the location list addresses (for cross references) */
2998 dwAssignLocListAddresses ();
3000 /* Write the .debug_loc section */
3003 /* Delete our scope related user attributes; they were only needed to help */
3004 /* build the tag tree and have no meaning to (and may confuse) debuggers */
3005 attr = DW_AT_user_block;
3006 dwTraverseTag (dwRootTag, dwDeleteTagAttr, &attr);
3007 attr = DW_AT_user_level;
3008 dwTraverseTag (dwRootTag, dwDeleteTagAttr, &attr);
3010 /* Add a DW_AT_sibling attribute to all tags with children and siblings */
3011 dwTraverseTag (dwRootTag, dwAddSibAttr, NULL);
3013 /* Assign the tag abbreviations. The tags, attributes, and forms must */
3014 /* not change after this point. The attribute values may change as long */
3015 /* as the size of the value does not. */
3016 dwAbbrevTable = newHashTable (128);
3017 dwTraverseTag (dwRootTag, dwAssignAbbrev, &abbrevNum);
3019 /* Assign the tag addresses (for cross references) */
3020 dwTraverseTag (dwRootTag, dwAssignTagAddress, &tagAddress);
3022 /* Write the .debug_abbrev section */
3025 /* Write the .debug_info section */
3028 /* Write the .debug_pubnames section */