Update copyright to LGPL on all files
[dyninst.git] / symtabAPI / src / parseDwarf.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31 #include <map>
32
33 #include "elf.h"
34 #include "libelf.h"
35 #include "dwarf.h"
36 #include "libdwarf.h"
37
38 #include "Symtab.h"
39 #include "Type.h"
40 #include "Function.h"
41 #include "Module.h"
42 #include "symtabAPI/src/Object.h"
43 #include "Collections.h"
44 #include "common/h/pathName.h"
45 #include "Variable.h"
46 #include "Type-mem.h"
47 #include <stdarg.h>
48 #include "dynutil/h/Annotatable.h"
49 #include "annotations.h"
50
51 #ifndef DW_FRAME_CFA_COL3
52 //  This is a newer feature of libdwarf (which has been causing some other 
53 //  compilation problems locally) -- so we just fudge it for the moment
54 #define DW_FRAME_CFA_COL3               1036
55 /* Use this to get the cfa. */
56 extern "C" {
57 int dwarf_get_fde_info_for_cfa_reg3(
58                 Dwarf_Fde /*fde*/,
59                 Dwarf_Addr       /*pc_requested*/, 
60                 Dwarf_Small  *   /*value_type*/, 
61                 Dwarf_Signed *   /*offset_relevant*/,
62                 Dwarf_Signed *    /*register*/,  
63                 Dwarf_Signed *    /*offset_or_block_len*/,
64                 Dwarf_Ptr   *    /*block_ptr */,
65                 Dwarf_Addr*      /*row_pc_out*/,
66                 Dwarf_Error*     /*error*/)
67 {
68         fprintf(stderr, "%s[%d]:  WARNING:  inside dummy dwarf functions\n", FILE__, __LINE__);
69         return 0;
70 }
71 }
72 #endif
73
74 std::map<Dwarf_Off, fieldListType*> enclosureMap;
75
76 int dwarf_printf(const char *format, ...);
77
78 using namespace Dyninst;
79 using namespace Dyninst::SymtabAPI;
80
81 void setSymtabError(SymtabError new_err);
82
83 /* For location decode. */
84 #include <stack>
85
86 // on 64-bit x86_64 targets, the DWARF register number does not
87 // correspond to the machine encoding. See the AMD-64 ABI.
88
89
90 #if defined(arch_x86_64)
91 // We can only safely map the general purpose registers (0-7 on ia-32,
92 // 0-15 on amd-64)
93 #define IA32_MAX_MAP 7
94 #define AMD64_MAX_MAP 15
95 static int const amd64_register_map[] =
96   {
97     0,  // RAX
98     2,  // RDX
99     1,  // RCX
100     3,  // RBX
101     6,  // RSI
102     7,  // RDI
103     5,  // RBP
104     4,  // RSP
105     8, 9, 10, 11, 12, 13, 14, 15    // gp 8 - 15
106     /* This is incomplete. The x86_64 ABI specifies a mapping from
107        dwarf numbers (0-66) to ("architecture number"). Without a
108        corresponding mapping for the SVR4 dwarf-machine encoding for
109        IA-32, however, it is not meaningful to provide this mapping. */
110   };
111
112 int Register_DWARFtoMachineEnc32(int n)
113 {
114   if (n > IA32_MAX_MAP) {
115     dwarf_printf("%s[%d]: unexpected map lookup for DWARF register %d\n",
116                  __FILE__,__LINE__,n);
117   }
118   return n;
119 }
120
121
122 int Register_DWARFtoMachineEnc64(int n)
123 {
124   if (n <= AMD64_MAX_MAP)
125     return amd64_register_map[n];
126   else {
127     dwarf_printf("%s[%d]: unexpected map lookup for DWARF register %d\n",
128                  __FILE__,__LINE__,n);
129     return n;
130   }
131 }
132
133 #define DWARF_TO_MACHINE_ENC(n, proc)                                   \
134   ((proc->getAddressWidth() == 4) ? Register_DWARFtoMachineEnc32((int) n) : Register_DWARFtoMachineEnc64((int) n))
135 #else
136 #define DWARF_TO_MACHINE_ENC(n, proc) (n)
137 #endif
138
139 /*
140   #define DWARF_FALSE_IF(condition,...) \
141   if ( condition ) { //bpwarn ( __VA_ARGS__ ); return false; }
142   #define DWARF_RETURN_IF(condition,...) \
143   if ( condition ) { //bpwarn ( __VA_ARGS__ ); return; }
144   #define DWARF_NULL_IF(condition,...) \
145   if ( condition ) { //bpwarn ( __VA_ARGS__ ); return NULL; }
146 */
147
148 #define DWARF_FALSE_IF(condition,...)           \
149   if ( condition ) { return false; }
150 #define DWARF_RETURN_IF(condition,...)          \
151   if ( condition ) { return; }
152 #define DWARF_NULL_IF(condition,...)            \
153   if ( condition ) { return NULL; }
154 #define DWARF_NEXT_IF(condition, ...)                                   \
155   if (condition) { if (depth != 1) { return false; } else {walk_error = true; break; } }
156
157 std::string convertCharToString(char *ptr)
158 {
159   std::string str;
160   if (ptr)
161     str = ptr;
162   else
163     str = "";
164   return str;   
165 }
166
167 /* A bound attribute can be either (a constant) or (a reference
168    to a DIE which (describes an object containing the bound value) or
169    (a constant value itself)). */
170
171 bool decipherBound( Dwarf_Debug & dbg, Dwarf_Attribute boundAttribute, std::string &boundString ) {
172   Dwarf_Half boundForm;
173   int status = dwarf_whatform( boundAttribute, & boundForm, NULL );
174   DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: unable to decode form of bounds attribute.\n", __FILE__, __LINE__ );
175
176   switch( boundForm ) {
177   case DW_FORM_data1:
178   case DW_FORM_data2:
179   case DW_FORM_data4:
180   case DW_FORM_data8:
181   case DW_FORM_sdata:
182   case DW_FORM_udata: 
183     {
184       Dwarf_Unsigned constantBound;
185       status = dwarf_formudata( boundAttribute, & constantBound, NULL );
186       DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: unable decode unsigned data in bounds attribute.\n", __FILE__, __LINE__ );
187       char bString[40];
188       sprintf(bString, "%lu", (unsigned long)constantBound);
189       boundString = bString;
190       return true;
191     } break;
192
193   case DW_FORM_ref_addr:
194   case DW_FORM_ref1:
195   case DW_FORM_ref2:
196   case DW_FORM_ref4:
197   case DW_FORM_ref8:
198   case DW_FORM_ref_udata: 
199     {
200       /* Acquire the referenced DIE. */
201       Dwarf_Off boundOffset;
202       status = dwarf_global_formref( boundAttribute, & boundOffset, NULL );
203       DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: unable decode reference in bounds attribute.\n", __FILE__, __LINE__ );
204
205       Dwarf_Die boundEntry;
206       status = dwarf_offdie( dbg, boundOffset, & boundEntry, NULL );
207       DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: unable dereference DWARF pointer in bounds attribute.\n", __FILE__, __LINE__ );
208
209       /* Does it have a name? */
210       char * boundName = NULL;
211       status = dwarf_diename( boundEntry, & boundName, NULL );
212       DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error checking for name of bounds attribute.\n", __FILE__, __LINE__ );
213
214       if ( status == DW_DLV_OK ) {
215         boundString = boundName;
216
217         dwarf_dealloc( dbg, boundName, DW_DLA_STRING );
218         return true;
219       }
220
221       /* Does it describe a nameless constant? */
222       Dwarf_Attribute constBoundAttribute;
223       status = dwarf_attr( boundEntry, DW_AT_const_value, & constBoundAttribute, NULL );
224       DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error checking for constant value of bounds attribute.\n", __FILE__, __LINE__ );
225
226       if ( status == DW_DLV_OK ) {
227         Dwarf_Unsigned constBoundValue;
228         status = dwarf_formudata( constBoundAttribute, & constBoundValue, NULL );
229         DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error decoding unsigned data of bounds constant value attribute.\n", __FILE__, __LINE__ );
230
231         char bString[40];
232         sprintf(bString, "%lu", (unsigned long)constBoundValue);
233         boundString = bString;
234
235         dwarf_dealloc( dbg, boundEntry, DW_DLA_DIE );
236         dwarf_dealloc( dbg, constBoundAttribute, DW_DLA_ATTR );
237         return true;
238       }
239
240       return false;
241     } break;
242   case DW_FORM_block:
243   case DW_FORM_block1:
244     {
245       /* PGI extends DWARF to allow some bounds to be location lists.  Since we can't
246          do anything sane with them, ignore them. */
247       // Dwarf_Locdesc * locationList;
248       // Dwarf_Signed listLength;
249       // status = dwarf_loclist( boundAttribute, & locationList, & listLength, NULL );
250       boundString = "{PGI extension}";
251       return false;
252     } break;
253
254   default:
255     //bperr ( "Invalid bound form 0x%x\n", boundForm );
256     boundString = "{invalid bound form}";
257     return false;
258     break;
259   } /* end boundForm switch */
260 } /* end decipherBound() */
261
262 /* We don't have a sane way of dealing with DW_TAG_enumeration bounds, so
263    just put the name of the enumeration, or {enum} if none, in the string. */
264 void parseSubRangeDIE( Dwarf_Debug & dbg, Dwarf_Die subrangeDIE, 
265                        std::string & loBound, std::string & hiBound, Module * module, typeCollection *tc ) 
266 {
267   loBound = "{unknown or default}";
268   hiBound = "{unknown or default}";
269
270   /* Set the default lower bound, if we know it. */
271   switch ( module->language() ) {
272   case lang_Fortran:
273   case lang_Fortran_with_pretty_debug:
274   case lang_CMFortran:
275     loBound = "1";
276     break;
277   case lang_C:
278   case lang_CPlusPlus:
279     loBound = "0";
280     break;
281   default:
282     break;
283   } /* end default lower bound switch */
284
285   Dwarf_Half subrangeTag;
286   int status = dwarf_tag( subrangeDIE, & subrangeTag, NULL );
287   DWARF_RETURN_IF( status != DW_DLV_OK, "%s[%d]: unable to obtain tag of subrange DIE.\n", __FILE__, __LINE__ );
288
289   /* Could be an enumerated range. */
290   if ( subrangeTag == DW_TAG_enumeration_type ) {
291     /* FIXME? First child of enumeration type is lowest, last is highest. */
292     char * enumerationName = NULL;
293     status = dwarf_diename( subrangeDIE, & enumerationName, NULL );
294     DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error cehcking for name of enumeration.\n", __FILE__, __LINE__ );
295
296     if ( enumerationName != NULL ) {
297       loBound = enumerationName;
298       hiBound = enumerationName;
299     } else {
300       loBound = "{nameless enum lo}";
301       hiBound = "{nameless enum hi}";
302     }
303     dwarf_dealloc( dbg, enumerationName, DW_DLA_STRING );
304     return;
305   } /* end if an enumeration type */
306
307   /* Is a subrange type. */
308   DWARF_RETURN_IF( subrangeTag != DW_TAG_subrange_type, "%s[%d]: unknown tag while parsing subrange\n", __FILE__, __LINE__ );
309
310   /* Look for the lower bound. */
311   Dwarf_Attribute lowerBoundAttribute;
312   status = dwarf_attr( subrangeDIE, DW_AT_lower_bound, & lowerBoundAttribute, NULL );
313   DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error while checking for lower bound of subrange\n", __FILE__, __LINE__ );
314
315   if ( status == DW_DLV_OK ) {
316     decipherBound( dbg, lowerBoundAttribute, loBound );
317     dwarf_dealloc( dbg, lowerBoundAttribute, DW_DLA_ATTR );
318   } /* end if we found a lower bound. */
319
320   /* Look for the upper bound. */
321   Dwarf_Attribute upperBoundAttribute;
322   status = dwarf_attr( subrangeDIE, DW_AT_upper_bound, & upperBoundAttribute, NULL );
323   DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error while checking for upper bound of subrange\n", __FILE__, __LINE__ );
324   if ( status == DW_DLV_NO_ENTRY ) {
325     status = dwarf_attr( subrangeDIE, DW_AT_count, & upperBoundAttribute, NULL );
326     DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error while checking for count of subrange\n", __FILE__, __LINE__ );
327   }
328   if ( status == DW_DLV_OK ) {
329     decipherBound( dbg, upperBoundAttribute, hiBound );
330     dwarf_dealloc( dbg, upperBoundAttribute, DW_DLA_ATTR );
331   } /* end if we found an upper bound or count. */
332
333   /* Construct the range type. */
334   static char * subrangeName = NULL;
335   if (!subrangeName)
336     subrangeName = strdup("{anonymous range}");
337   status = dwarf_diename( subrangeDIE, & subrangeName, NULL );
338   DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error while checking for name of subrange\n", __FILE__, __LINE__ );
339   int dwarvenName = status;
340
341   Dwarf_Off subrangeOffset;
342   status = dwarf_dieoffset( subrangeDIE, & subrangeOffset, NULL );
343   DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error dereferencing DWARF pointer\n", __FILE__, __LINE__ );
344
345   errno = 0;
346   long low_conv = strtol(loBound.c_str(), NULL, 10);
347   if (errno)
348   {
349           fprintf(stderr, "%s[%d]:  error converting range limit '%s' to long: %s\n",
350                           FILE__, __LINE__, loBound.c_str(), strerror(errno));
351           low_conv = LONG_MIN;
352   }
353
354   errno = 0;
355   long hi_conv = strtol(hiBound.c_str(), NULL, 10);
356   if (errno) 
357   {
358           fprintf(stderr, "%s[%d]:  error converting range limit '%s' to long: %s\n",
359                           FILE__, __LINE__, hiBound.c_str(), strerror(errno));
360           hi_conv = LONG_MAX;
361   }  
362
363   std::string srName = subrangeName;
364   typeSubrange * rangeType = new typeSubrange( (int) subrangeOffset, 0, low_conv, hi_conv, srName );
365   assert( rangeType != NULL );
366   rangeType = tc->addOrUpdateType( rangeType );
367   if ( dwarvenName == DW_DLV_OK ) { dwarf_dealloc( dbg, subrangeName, DW_DLA_STRING ); }        
368 } /* end parseSubRangeDIE() */
369
370 typeArray *parseMultiDimensionalArray( Dwarf_Debug & dbg, Dwarf_Die range, 
371                                        Type * elementType, Module * module, typeCollection *tc) 
372 {
373   char buf[32];
374   /* Get the (negative) typeID for this range/subarray. */
375   Dwarf_Off dieOffset;
376   int status = dwarf_dieoffset( range, & dieOffset, NULL );
377   DWARF_NULL_IF( status != DW_DLV_OK, "%s[%d]: error while parsing multidimensional array.\n", __FILE__, __LINE__ );
378
379   /* Determine the range. */
380   std::string loBound;
381   std::string hiBound;
382   parseSubRangeDIE( dbg, range, loBound, hiBound, module, tc);
383
384   /* Does the recursion continue? */
385   Dwarf_Die nextSibling;
386   status = dwarf_siblingof( dbg, range, & nextSibling, NULL );
387   DWARF_NULL_IF( status == DW_DLV_ERROR, "%s[%d]: error checking for second dimension in array.\n", __FILE__, __LINE__ );
388
389   snprintf(buf, 31, "__array%d", (int) dieOffset);
390
391   if ( status == DW_DLV_NO_ENTRY ) {
392     /* Terminate the recursion by building an array type out of the elemental type.
393        Use the negative dieOffset to avoid conflicts with the range type created
394        by parseSubRangeDIE(). */
395     // N.B.  I'm going to ignore the type id, and just create an anonymous type here
396     std::string aName = convertCharToString(buf);
397     typeArray* innermostType = new typeArray( elementType, atoi( loBound.c_str() ), atoi( hiBound.c_str() ), aName );
398     assert( innermostType != NULL );
399     Type * typ = tc->addOrUpdateType( innermostType );
400     innermostType = dynamic_cast<typeArray *>(typ);
401     return innermostType;
402   } /* end base-case of recursion. */
403
404   /* If it does, build this array type out of the array type returned from the next recusion. */
405   typeArray * innerType = parseMultiDimensionalArray( dbg, nextSibling, elementType, module, tc);
406   assert( innerType != NULL );
407   // same here - type id ignored    jmo
408   std::string aName = convertCharToString(buf);
409   typeArray * outerType = new typeArray( innerType, atoi(loBound.c_str()), atoi(hiBound.c_str()), aName);
410   assert( outerType != NULL );
411   Type *typ = tc->addOrUpdateType( outerType );
412   outerType = dynamic_cast<typeArray *>(typ);
413
414   dwarf_dealloc( dbg, nextSibling, DW_DLA_DIE );
415   return outerType;
416 } /* end parseMultiDimensionalArray() */
417
418 void deallocateLocationList( Dwarf_Debug & dbg, Dwarf_Locdesc * locationList, 
419                              Dwarf_Signed listLength ) 
420 {
421   for( int i = 0; i < listLength; i++ ) {
422     dwarf_dealloc( dbg, locationList[i].ld_s, DW_DLA_LOC_BLOCK );
423   }
424   dwarf_dealloc( dbg, locationList, DW_DLA_LOCDESC );
425 } /* end deallocateLocationList() */
426
427 void deallocateLocationList( Dwarf_Debug & dbg, Dwarf_Locdesc ** locationList, 
428                              Dwarf_Signed listLength ) 
429 {
430   for( int i = 0; i < listLength; i++ ) {
431     dwarf_dealloc( dbg, locationList[i]->ld_s, DW_DLA_LOC_BLOCK );
432     dwarf_dealloc( dbg, locationList[i], DW_DLA_LOCDESC );
433   }
434   dwarf_dealloc( dbg, locationList, DW_DLA_LIST );
435 } /* end deallocateLocationList() */
436
437 /* An investigative function. */
438 void dumpLocListAddrRanges( Dwarf_Locdesc * locationList, Dwarf_Signed listLength ) 
439 {
440   for( int i = 0; i < listLength; i++ ) {
441     Dwarf_Locdesc location = locationList[i];
442     fprintf( stderr, "0x%lx to 0x%lx; ", (Offset)location.ld_lopc, (Offset)location.ld_hipc );
443   }
444   fprintf( stderr, "\n" );
445 } /* end dumpLocListAddrRanges */
446
447 #if defined(arch_x86_64)
448 int convertFrameBaseToAST( Dwarf_Locdesc * locationList, Dwarf_Signed listLength, 
449                            Symtab *proc /* process parameter only needed on x86_64*/) 
450 #else
451   int convertFrameBaseToAST( Dwarf_Locdesc * locationList, Dwarf_Signed listLength, 
452                              Symtab * /* process parameter only needed on x86_64*/) 
453 #endif
454 {
455   /* Until such time as we see more-complicated location lists, assume single entries
456      consisting of a register name.  Using an AST for this is massive overkill, but if
457      we need to handle more complicated frame base calculations later, the infastructure
458      will be in place. */
459
460   /* There is only one location. */
461   if (listLength != 1) {
462     //bpwarn("%s[%d]: unable to handle location lists of more than one element in frame base.\n", __FILE__, __LINE__);
463     return -1 ;
464   }
465
466   Dwarf_Locdesc locationDescriptor = locationList[0];
467
468   /* It is defined by a single operation. */
469   if (locationDescriptor.ld_cents != 1) {
470     //bpwarn("%s[%d]: unable to handle multioperation locations in frame base.\n", __FILE__, __LINE__ );
471     return -1;
472   }
473   Dwarf_Loc location = locationDescriptor.ld_s[0];
474
475   /* That operation is naming a register. */
476   int registerNumber = 0;       
477   if ( DW_OP_reg0 <= location.lr_atom && location.lr_atom <= DW_OP_reg31 ) {
478     registerNumber = DWARF_TO_MACHINE_ENC(location.lr_atom - DW_OP_reg0,
479                                           proc);
480   }
481   else if ( DW_OP_breg0 <= location.lr_atom && location.lr_atom <= DW_OP_breg31 ) {
482     registerNumber = DWARF_TO_MACHINE_ENC(location.lr_atom - DW_OP_breg0,
483                                           proc);
484     if ( location.lr_number != 0 ) {
485       /* Actually, we should be able whip up an AST node for this. */
486       return -1;
487     }
488   }
489   else if ( location.lr_atom == DW_OP_regx ) {
490     registerNumber = (int) DWARF_TO_MACHINE_ENC(location.lr_number,
491                                                 proc);
492   }
493   else if ( location.lr_atom == DW_OP_bregx ) {
494     registerNumber = (int) DWARF_TO_MACHINE_ENC(location.lr_number,
495                                                 proc);
496     if ( location.lr_number2 != 0 ) {
497       /* Actually, we should be able whip up an AST node for this. */
498       return -1;
499     }
500   }
501   else {
502     return -1;
503   }
504
505   return registerNumber;
506
507   /* We have to make sure no arithmetic is actually done to the frame pointer,
508      so add zero to it and shove it in some other register. */
509   /*    AstNodePtr constantZero = AstNode::operandNode(AstNode::Constant, (void *)0);
510     AstNodePtr framePointer = AstNode::operandNode(AstNode::DataReg, (void *)(long unsigned int)registerNumber);
511     AstNodePtr moveFPtoDestination = AstNode::operatorNode(plusOp,
512     constantZero,
513     framePointer);
514
515     return moveFPtoDestination;
516   */
517 } /* end convertFrameBaseToAST(). */
518
519
520 #if defined(arch_x86_64)
521 bool decodeLocationListForStaticOffsetOrAddress( Dwarf_Locdesc **locationList, 
522                                                  Dwarf_Signed listLength, 
523                                                  Symtab * objFile, 
524                                                  vector<VariableLocation>& locs, Address lowpc,
525                                                  long int * initialStackValue = NULL)
526 #else
527   bool decodeLocationListForStaticOffsetOrAddress( Dwarf_Locdesc **locationList, 
528                                                    Dwarf_Signed listLength, 
529                                                    Symtab *,
530                                                    vector<VariableLocation>& locs, Address lowpc, 
531                                                    long int * initialStackValue = NULL)
532 #endif
533 {
534   /* We make a few heroic assumptions about locations in this decoder.
535
536   We assume that all locations are either frame base-relative offsets,
537   encoded with DW_OP_fbreg, or are absolute addresses.  We assume these
538   locations are invariant with respect to the PC, which implies that all
539   location lists have a single entry.  We assume that no location is
540   calculated at run-time.
541
542   We make these assumptions to match the assumptions of the rest of
543   Dyninst, which makes no provision for pc-variant or run-time calculated
544   locations, aside from the frame pointer.  However, it assumes that a frame
545   pointer is readily available, which, on IA-64, it is not.  For that reason,
546   when we encounter a function with a DW_AT_frame_base (effectively all of them),
547   we do NOT use this decoder; we decode the location into an AST, which we
548   will use to calculate the frame pointer when asked to do frame-relative operations.
549   (These calculations will be invalid until the frame pointer is established,
550   which may require some fiddling with the location of the 'entry' instpoint.) */
551
552   /* We now parse the complete location list for variables and parameters within a
553    * function. We still ignore the location list defined for DW_AT_frame_base of the
554    * function as the frame pointer is readily available on all platforms(except for IA64)
555    * May be we would need to parse the location list for IA64 functions to store the 
556    * register numbers and offsets and use it based on the pc value. 
557    */
558   /*
559     DWARF_FALSE_IF( listLength != 1, "%s[%d]: unable to decode location lists of non-unit length.\n", __FILE__, __LINE__ );
560     if ( listLength != 1)
561     printf("%s[%d]: unable to decode location lists of non-unit length.\n", __FILE__, __LINE__ );
562   */
563         for (unsigned locIndex = 0 ; locIndex < listLength; locIndex++) 
564         {
565                 bool isLocSet = false;
566                 VariableLocation loc;
567                 // Initialize location values.
568                 loc.stClass = storageAddr;
569                 loc.refClass = storageNoRef;
570                 loc.reg = -1;
571
572                 /* Initialize the stack. */
573                 std::stack< long int > opStack = std::stack<long int>();
574                 if ( initialStackValue != NULL ) { opStack.push( * initialStackValue ); }
575
576                 /* There is only one location. */
577                 Dwarf_Locdesc *location = locationList[locIndex];
578
579                 loc.lowPC = (Offset)location->ld_lopc;
580                 loc.hiPC = (Offset)location->ld_hipc;
581
582                 // if range of the variable is the entire address space, do not add lowpc
583                 if (loc.lowPC != (unsigned long) 0 || loc.hiPC != (unsigned long) ~0) 
584                 {
585                         loc.lowPC = (Offset)location->ld_lopc + lowpc;
586                         loc.hiPC = (Offset)location->ld_hipc + lowpc;
587                 }
588                 dwarf_printf( "CU lowpc %lx setting lowPC %lx hiPC %lx \n", lowpc, loc.lowPC, loc.hiPC );
589
590                 Dwarf_Loc * locations = location->ld_s;
591
592                 for ( unsigned int i = 0; i < location->ld_cents; i++ ) 
593                 {
594                         /* Handle the literals w/o 32 case statements. */
595                         if ( DW_OP_lit0 <= locations[i].lr_atom && locations[i].lr_atom <= DW_OP_lit31 ) 
596                         {
597                                 dwarf_printf( "pushing named constant: %d\n", locations[i].lr_atom - DW_OP_lit0 );
598                                 opStack.push( locations[i].lr_atom - DW_OP_lit0 );
599                                 continue;
600                         }
601
602                         /* Haandle registers w/o 32 case statements. */
603                         if ( DW_OP_reg0 <= locations[i].lr_atom && locations[i].lr_atom <= DW_OP_reg31 ) 
604                         {
605                                 /* storageReg is unimplemented, so do an offset of 0 from the named register instead. */
606                                 dwarf_printf( "location is named register %d\n", 
607                                                 DWARF_TO_MACHINE_ENC(locations[i].lr_atom - DW_OP_reg0, objFile) );
608                                 //loc->stClass = storageRegOffset;
609                                 loc.stClass = storageReg;
610                                 loc.refClass = storageNoRef;
611                                 loc.frameOffset = 0;
612                                 loc.reg = DWARF_TO_MACHINE_ENC(locations[i].lr_atom - DW_OP_reg0, objFile);
613                                 //loc->frameOffset = 0;
614                                 isLocSet = true;
615                                 break;
616                         }       
617
618                         /* Haandle registers w/o 32 case statements. */
619                         if ( DW_OP_breg0 <= locations[i].lr_atom && locations[i].lr_atom <= DW_OP_breg31 ) 
620                         {
621                                 dwarf_printf( "setting storage class to named register, regNum to %d, offset %d\n", DWARF_TO_MACHINE_ENC(locations[i].lr_atom - DW_OP_breg0, objFile), locations[i].lr_number );
622                                 loc.stClass = storageRegOffset;
623                                 loc.refClass = storageNoRef;
624                                 loc.frameOffset = locations[i].lr_number ;
625                                 loc.reg = DWARF_TO_MACHINE_ENC(locations[i].lr_atom - DW_OP_breg0, objFile);
626                                 opStack.push(static_cast<long int>(locations[i].lr_number)); 
627                                 break;
628                         }
629
630                         switch( locations[i].lr_atom ) 
631                         {
632                                 case DW_OP_addr:
633                                 case DW_OP_const1u:
634                                 case DW_OP_const2u:
635                                 case DW_OP_const4u:
636                                 case DW_OP_const8u:
637                                 case DW_OP_constu:
638                                         dwarf_printf( "pushing unsigned constant %lu\n", 
639                                                         (unsigned long)locations[i].lr_number );
640                                         opStack.push(static_cast<long int>(locations[i].lr_number));
641                                         break;
642
643                                 case DW_OP_const1s:
644                                 case DW_OP_const2s:
645                                 case DW_OP_const4s:
646                                 case DW_OP_const8s:
647                                 case DW_OP_consts:
648                                         dwarf_printf( "pushing signed constant %ld\n", 
649                                                         (signed long)(locations[i].lr_number) );
650                                         opStack.push(static_cast<long int>(locations[i].lr_number));
651                                         break;
652
653                                 case DW_OP_regx:
654                                         /* storageReg is unimplemented, so do an offset of 0 from the named register instead. */
655                                         dwarf_printf( "location is register %d\n", 
656                                                         DWARF_TO_MACHINE_ENC(locations[i].lr_number, objFile) );
657                                         //loc->stClass = storageRegOffset;
658                                         loc.stClass = storageReg;
659                                         loc.refClass = storageNoRef;
660                                         loc.reg = (int) DWARF_TO_MACHINE_ENC(locations[i].lr_number, objFile); 
661                                         loc.frameOffset = 0;
662                                         isLocSet = true;
663                                         break;
664
665                                 case DW_OP_fbreg:
666                                         dwarf_printf( "setting storage class to frame base\n" );
667                                         //if ( storageClass != NULL ) { * storageClass = storageFrameOffset; }
668                                         loc.stClass = storageRegOffset;
669                                         loc.refClass = storageNoRef;
670                                         loc.frameOffset = 0;
671                                         opStack.push(static_cast<long int>(locations[i].lr_number));
672                                         break;
673
674                                 case DW_OP_bregx:
675                                         dwarf_printf( "setting storage class to register, regNum to %d\n", 
676                                                         locations[i].lr_number );
677                                         loc.stClass = storageRegOffset;
678                                         loc.refClass = storageNoRef;
679                                         loc.reg = (int) DWARF_TO_MACHINE_ENC( locations[i].lr_number, objFile );
680                                         loc.frameOffset = 0;
681                                         opStack.push(static_cast<long int>(locations[i].lr_number2));
682                                         break;
683
684                                 case DW_OP_dup:
685                                         DWARF_FALSE_IF( opStack.size() < 1, 
686                                                         "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
687                                         opStack.push( opStack.top() );
688                                         break;
689
690                                 case DW_OP_drop:
691                                         DWARF_FALSE_IF( opStack.size() < 1, 
692                                                         "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
693                                         opStack.pop();
694                                         break;
695
696                                 case DW_OP_pick: 
697                                         {
698                                                 /* Duplicate the entry at index locations[i].lr_number. */
699                                                 std::stack< long int > temp = std::stack< long int >();
700
701                                                 for ( unsigned int j = 0; j < locations[i].lr_number; j++ ) 
702                                                 {
703                                                         temp.push( opStack.top() ); opStack.pop();
704                                                 }
705
706                                                 long int dup = opStack.top();
707
708                                                 for ( unsigned int j = 0; j < locations[i].lr_number; j++ ) 
709                                                 {
710                                                         opStack.push( temp.top() ); temp.pop();
711                                                 }
712
713                                                 opStack.push( dup );
714                                         } break;
715
716                                 case DW_OP_over: 
717                                         {
718                                                 DWARF_FALSE_IF( opStack.size() < 2, 
719                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
720                                                 long int first = opStack.top(); opStack.pop();
721                                                 long int second = opStack.top(); opStack.pop();
722                                                 opStack.push( second ); opStack.push( first ); opStack.push( second );
723                                         } break;
724
725                                 case DW_OP_swap: 
726                                         {
727                                                 DWARF_FALSE_IF( opStack.size() < 2, 
728                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
729                                                 long int first = opStack.top(); opStack.pop();
730                                                 long int second = opStack.top(); opStack.pop();
731                                                 opStack.push( first ); opStack.push( second );
732                                         } break;
733
734                                 case DW_OP_rot: 
735                                         {
736                                                 DWARF_FALSE_IF( opStack.size() < 3, 
737                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
738                                                 long int first = opStack.top(); opStack.pop();
739                                                 long int second = opStack.top(); opStack.pop();
740                                                 long int third = opStack.top(); opStack.pop();
741                                                 opStack.push( first ); opStack.push( third ); opStack.push( second );
742                                         } break;
743
744                                 case DW_OP_abs: 
745                                         {
746                                                 DWARF_FALSE_IF( opStack.size() < 1, 
747                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
748                                                 long int top = opStack.top(); opStack.pop();
749                                                 opStack.push( abs( top ) );
750                                         } break;
751
752                                 case DW_OP_and: 
753                                         {
754                                                 DWARF_FALSE_IF( opStack.size() < 2, 
755                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
756                                                 long int first = opStack.top(); opStack.pop();
757                                                 long int second = opStack.top(); opStack.pop();
758                                                 opStack.push( second & first );
759                                         } break;
760
761                                 case DW_OP_div: 
762                                         {
763                                                 DWARF_FALSE_IF( opStack.size() < 2, 
764                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
765                                                 long int first = opStack.top(); opStack.pop();
766                                                 long int second = opStack.top(); opStack.pop();
767                                                 opStack.push( second / first );
768                                         } break;
769
770                                 case DW_OP_minus: 
771                                         {
772                                                 DWARF_FALSE_IF( opStack.size() < 2, 
773                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
774                                                 long int first = opStack.top(); opStack.pop();
775                                                 long int second = opStack.top(); opStack.pop();
776                                                 opStack.push( second - first );
777                                         } break;
778
779                                 case DW_OP_mod: 
780                                         {
781                                                 DWARF_FALSE_IF( opStack.size() < 2, 
782                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
783                                                 long int first = opStack.top(); opStack.pop();
784                                                 long int second = opStack.top(); opStack.pop();
785                                                 opStack.push( second % first );
786                                         } break;
787
788                                 case DW_OP_mul: 
789                                         {
790                                                 DWARF_FALSE_IF( opStack.size() < 2, 
791                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
792                                                 long int first = opStack.top(); opStack.pop();
793                                                 long int second = opStack.top(); opStack.pop();
794                                                 opStack.push( second * first );
795                                         } break;
796
797                                 case DW_OP_neg: 
798                                         {
799                                                 DWARF_FALSE_IF( opStack.size() < 1, 
800                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
801                                                 long int first = opStack.top(); opStack.pop();
802                                                 opStack.push( first * (-1) );
803                                         } break;
804
805                                 case DW_OP_not: 
806                                         {
807                                                 DWARF_FALSE_IF( opStack.size() < 1, 
808                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
809                                                 long int first = opStack.top(); opStack.pop();
810                                                 opStack.push( ~ first );
811                                         } break;
812
813                                 case DW_OP_or: 
814                                         {
815                                                 DWARF_FALSE_IF( opStack.size() < 2, 
816                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
817                                                 long int first = opStack.top(); opStack.pop();
818                                                 long int second = opStack.top(); opStack.pop();
819                                                 opStack.push( second | first );
820                                         } break;
821
822                                 case DW_OP_plus: 
823                                         {
824                                                 DWARF_FALSE_IF( opStack.size() < 2, 
825                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
826                                                 long int first = opStack.top(); opStack.pop();
827                                                 long int second = opStack.top(); opStack.pop();
828                                                 opStack.push( second + first );
829                                         } break;
830
831                                 case DW_OP_plus_uconst: 
832                                         {
833                                                 DWARF_FALSE_IF( opStack.size() < 1, 
834                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
835                                                 long int first = opStack.top(); opStack.pop();
836                                                 opStack.push(static_cast<long int>(first + locations[i].lr_number));
837                                         } break;
838
839                                 case DW_OP_shl: 
840                                         {
841                                                 DWARF_FALSE_IF( opStack.size() < 2, 
842                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
843                                                 long int first = opStack.top(); opStack.pop();
844                                                 long int second = opStack.top(); opStack.pop();
845                                                 opStack.push( second << first );
846                                         } break;
847
848                                 case DW_OP_shr: 
849                                         {
850                                                 DWARF_FALSE_IF( opStack.size() < 2, 
851                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
852                                                 long int first = opStack.top(); opStack.pop();
853                                                 long int second = opStack.top(); opStack.pop();
854
855                                                 opStack.push( (long int)((unsigned long)second >> (unsigned long)first) );
856                                         } break;
857
858                                 case DW_OP_shra: 
859                                         {
860                                                 DWARF_FALSE_IF( opStack.size() < 2, 
861                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
862                                                 long int first = opStack.top(); opStack.pop();
863                                                 long int second = opStack.top(); opStack.pop();
864                                                 opStack.push( second >> first );
865                                         } break;
866
867                                 case DW_OP_xor: 
868                                         {
869                                                 DWARF_FALSE_IF( opStack.size() < 2, 
870                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
871                                                 long int first = opStack.top(); opStack.pop();
872                                                 long int second = opStack.top(); opStack.pop();
873                                                 opStack.push( second ^ first );
874                                         } break;
875
876                                 case DW_OP_le: 
877                                         {
878                                                 DWARF_FALSE_IF( opStack.size() < 2, 
879                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
880                                                 long int first = opStack.top(); opStack.pop();
881                                                 long int second = opStack.top(); opStack.pop();
882                                                 opStack.push( first <= second ? 1 : 0 );
883                                         } break;
884
885                                 case DW_OP_ge: 
886                                         {
887                                                 DWARF_FALSE_IF( opStack.size() < 2, 
888                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
889                                                 long int first = opStack.top(); opStack.pop();
890                                                 long int second = opStack.top(); opStack.pop();
891                                                 opStack.push( first >= second ? 1 : 0 );
892                                         } break;
893
894                                 case DW_OP_eq: 
895                                         {
896                                                 DWARF_FALSE_IF( opStack.size() < 2, 
897                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
898                                                 long int first = opStack.top(); opStack.pop();
899                                                 long int second = opStack.top(); opStack.pop();
900                                                 opStack.push( first == second ? 1 : 0 );
901                                         } break;
902
903                                 case DW_OP_lt: 
904                                         {
905                                                 DWARF_FALSE_IF( opStack.size() < 2, 
906                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
907                                                 long int first = opStack.top(); opStack.pop();
908                                                 long int second = opStack.top(); opStack.pop();
909                                                 opStack.push( first < second ? 1 : 0 );
910                                         } break;
911
912                                 case DW_OP_gt: 
913                                         {
914                                                 DWARF_FALSE_IF( opStack.size() < 2, 
915                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
916                                                 long int first = opStack.top(); opStack.pop();
917                                                 long int second = opStack.top(); opStack.pop();
918                                                 opStack.push( first > second ? 1 : 0 );
919                                         } break;
920
921                                 case DW_OP_ne: 
922                                         {
923                                                 DWARF_FALSE_IF( opStack.size() < 2, 
924                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
925                                                 long int first = opStack.top(); opStack.pop();
926                                                 long int second = opStack.top(); opStack.pop();
927                                                 opStack.push( first != second ? 1 : 0 );
928                                         } break;
929
930                                 case DW_OP_bra:
931                                         {
932                                                 DWARF_FALSE_IF( opStack.size() < 1, 
933                                                                 "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
934                                                 if ( opStack.top() == 0 ) { break; }
935                                                 opStack.pop();
936                                         }
937                                 case DW_OP_skip: 
938                                         {
939                                                 int bytes = (int)(Dwarf_Signed)locations[i].lr_number;
940                                                 unsigned int target = (unsigned int) locations[i].lr_offset + bytes;
941
942                                                 int j = i;
943                                                 if ( bytes < 0 ) {
944                                                         for ( j = i - 1; j >= 0; j-- ) {
945                                                                 if ( locations[j].lr_offset == target ) { break; }
946                                                         } /* end search backward */
947                                                 } else {
948                                                         for ( j = i + 1; j < location->ld_cents; j ++ ) {
949                                                                 if ( locations[j].lr_offset == target ) { break; }
950                                                         } /* end search forward */
951                                                 } /* end if positive offset */
952
953                                                 /* Because i will be incremented the next time around the loop. */
954                                                 i = j - 1;
955                                         } break;
956
957                                 case DW_OP_piece:
958                                         /* For multi-part variables, which we don't handle. */
959                                         //bperr ( "Warning: dyninst does not handle multi-part variables.\n" );
960                                         break;
961
962                                 case DW_OP_nop:
963                                         break;
964
965                                 default:
966                                         dwarf_printf( "Unrecognized or non-static location opcode 0x%x, aborting.\n", locations[i].lr_atom );
967                                         return false;
968                                         break;
969                         } /* end operand switch */
970                 } /* end iteration over Dwarf_Loc entries. */
971
972                 if (!isLocSet)
973                 {
974                         /* The top of the stack is the computed location. */
975                         if ( opStack.empty() ) 
976                         {
977                                 dwarf_printf( "ignoring malformed location list (stack empty at end of list).\n" );
978                                 return false;
979                         }
980                         else {
981                                 dwarf_printf( "setting offset to %d\n", opStack.top() );
982                                 loc.frameOffset = opStack.top();
983                                 locs.push_back(loc);
984                         }
985                 }
986                 else
987                         locs.push_back(loc);
988         }
989
990         /* decode successful */
991         return true;
992 } /* end decodeLocationListForStaticOffsetOrAddress() */
993
994 void convertFileNoToName( Dwarf_Debug & dbg, Dwarf_Signed fileNo, 
995                 char ** returnFileName, char ** newFileNames = NULL, Dwarf_Signed newFileNamesCount = 0 ) 
996 {
997         static char ** fileNames = NULL;
998         static Dwarf_Signed fileNamesCount = 0;
999
1000         /* Initialize? */
1001         if ( returnFileName == NULL && newFileNames != NULL ) {
1002                 /* FIXME?  Did we want to normalize these filenames? */
1003                 fileNames = newFileNames;
1004                 fileNamesCount = newFileNamesCount;
1005                 return;
1006         } /* end initialization. */
1007
1008         /* Destroy? */
1009   if ( returnFileName == NULL && newFileNames == NULL ) {
1010     for( int i = 0; i < fileNamesCount; i++ ) {
1011       dwarf_dealloc( dbg, fileNames[i], DW_DLA_STRING );
1012     } /* end deallocation loop */
1013     dwarf_dealloc( dbg, fileNames, DW_DLA_LIST );
1014     fileNamesCount = 0;
1015     return;
1016   } /* end destruction. */
1017
1018   /* Do lookup. */
1019   if ( fileNo <= fileNamesCount ) { * returnFileName = fileNames[fileNo - 1]; }
1020   else { * returnFileName = NULL; }
1021 } /* end convertFileNoToName() */
1022
1023 /* Utility function. */
1024 unsigned long tvDifference( struct timeval lhs, struct timeval rhs ) 
1025 {
1026   unsigned long seconds = lhs.tv_sec - rhs.tv_sec;
1027   if ( seconds == 0 ) { return lhs.tv_usec - rhs.tv_usec; }
1028   else {
1029     seconds *= 1000000;
1030     seconds += lhs.tv_usec - rhs.tv_usec;
1031   }
1032   return seconds;
1033 } /* end tvDifference() */
1034
1035 /* For debugging. */
1036 void dumpAttributeList( Dwarf_Die dieEntry, Dwarf_Debug & dbg ) 
1037 {
1038   char * entryName = NULL;
1039   int status = dwarf_diename( dieEntry, & entryName, NULL );
1040   DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error dumping attribute list.\n", __FILE__, __LINE__ );
1041
1042   Dwarf_Attribute * attributeList;
1043   Dwarf_Signed attributeCount;
1044   status = dwarf_attrlist( dieEntry, & attributeList, & attributeCount, NULL );
1045   DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error dumping attribute list.\n", __FILE__, __LINE__ );
1046
1047   //bperr ( "DIE %s has attributes:", entryName );
1048   for( int i = 0; i < attributeCount; i++ ) {
1049     Dwarf_Half whatAttr = 0;
1050     status = dwarf_whatattr( attributeList[i], & whatAttr, NULL );
1051     DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error dumping attribute list.\n", __FILE__, __LINE__ );
1052     fprintf( stderr, " 0x%x", whatAttr );
1053
1054     dwarf_dealloc( dbg, attributeList[i], DW_DLA_ATTR );
1055   } /* end iteration over attributes */
1056   fprintf( stderr, "\n" );
1057
1058   dwarf_dealloc( dbg, attributeList, DW_DLA_LIST );
1059   dwarf_dealloc( dbg, entryName, DW_DLA_STRING );
1060 } /* end dumpAttributeList() */
1061
1062
1063 bool walkDwarvenTree(Dwarf_Debug & dbg, Dwarf_Die dieEntry,
1064                      Module * module,
1065                      Symtab * objFile,
1066                      Dwarf_Off cuOffset,
1067                      char **srcFiles,
1068                      Address lowpc,
1069                      Function * currentFunction = NULL,
1070                      typeCommon * currentCommonBlock = NULL,
1071                      typeEnum *currentEnum = NULL,
1072                      fieldListType * currentEnclosure = NULL,
1073                      bool parseSibling = true,
1074                      int depth = 0
1075                      )
1076 {
1077   /* optimization */ tail_recursion:
1078         typeCollection *tc = typeCollection::getModTypeCollection(module);
1079   bool walk_error = false;
1080   Dwarf_Half dieTag;
1081   int status = dwarf_tag( dieEntry, & dieTag, NULL );
1082   DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1083
1084   Dwarf_Off dieOffset;
1085   status = dwarf_dieoffset( dieEntry, & dieOffset, NULL );
1086   DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1087
1088   Dwarf_Off dieCUOffset;
1089   status = dwarf_die_CU_offset( dieEntry, & dieCUOffset, NULL );
1090   DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1091
1092   dwarf_printf( "Considering DIE at %lu (%lu CU-relative) with tag 0x%x at depth %d \n", (unsigned long)dieOffset, (unsigned long)dieCUOffset, dieTag, depth );
1093
1094   // Map Insert is successful only the first time a dieEntry is encountered.
1095   enclosureMap.insert(pair <Dwarf_Off, fieldListType*> (dieOffset, currentEnclosure)); 
1096
1097   /* If this entry is a function, common block, or structure (class),
1098      its children will be in its scope, rather than its
1099      enclosing scope. */
1100
1101   Function * newFunction = currentFunction;
1102
1103   typeCommon * newCommonBlock = currentCommonBlock;
1104   typeEnum *newEnum = currentEnum;
1105   fieldListType * newEnclosure = currentEnclosure;
1106
1107   Object *elfobj = objFile->getObject();
1108   if (!elfobj)
1109   {
1110           fprintf(stderr, "%s[%d]:  requested object does not exist!\n", FILE__, __LINE__);
1111           return false;
1112   }
1113
1114   bool parsedChild = false;
1115
1116   /* Is this is an entry we're interested in? */
1117   switch( dieTag ) 
1118   {
1119     /* case DW_TAG_inline_subroutine: we don't care about these */
1120   case DW_TAG_subprogram:
1121   case DW_TAG_entry_point:
1122     {
1123                 dwarf_printf(" DW_TAG_subprogram or DW_TAG_entry_point \n");
1124
1125                 /* Our goal is three-fold: First, we want to set the return type
1126                    of the function.  Second, we want to set the newFunction variable
1127                    so subsequent entries are handled correctly.  Third, we want to
1128                    record (the location of, or how to calculate) the frame base of 
1129                    this function for use by our instrumentation code later. */
1130
1131                 /* If we are revisiting this dieEntry by parsing Parent of specification entry or
1132                    abstract origin entry, get the original enclosure saved in the map to identify 
1133                    member functions correctly */
1134
1135                 fieldListType * dieEnclosure = enclosureMap.find(dieOffset)->second;
1136
1137                 char * functionName = NULL;
1138
1139                 Dwarf_Die abstractEntry = dieEntry;
1140
1141                 Dwarf_Bool isAbstractOrigin;
1142                 status = dwarf_hasattr( dieEntry, DW_AT_abstract_origin, & isAbstractOrigin, NULL );
1143
1144                 DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", 
1145                                 __FILE__, __LINE__ );
1146
1147                 if ( isAbstractOrigin ) 
1148                 {
1149                         dwarf_printf(" has DW_TAG_abstract_origin \n");
1150
1151                         Dwarf_Attribute abstractAttribute;
1152                         status = dwarf_attr( dieEntry, DW_AT_abstract_origin, & abstractAttribute, NULL );
1153
1154                         DWARF_NEXT_IF( status != DW_DLV_OK, 
1155                                         "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1156
1157                         Dwarf_Off abstractOffset;
1158                         status = dwarf_global_formref( abstractAttribute, & abstractOffset, NULL );
1159
1160                         DWARF_NEXT_IF( status != DW_DLV_OK, 
1161                                         "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1162
1163                         status = dwarf_offdie( dbg, abstractOffset, & abstractEntry, NULL );
1164
1165                         DWARF_NEXT_IF( status != DW_DLV_OK, 
1166                                         "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1167
1168                         dwarf_dealloc( dbg, abstractAttribute, DW_DLA_ATTR );
1169                 } /* end if the function has a specification */
1170
1171                 /* Is this entry specified elsewhere?  We may need to look there for its name. */
1172
1173                 Dwarf_Die specEntry = isAbstractOrigin? abstractEntry : dieEntry;
1174
1175                 Dwarf_Bool hasSpecification;
1176                 status = dwarf_hasattr( specEntry, DW_AT_specification, & hasSpecification, NULL );
1177
1178                 DWARF_NEXT_IF( status != DW_DLV_OK, 
1179                                 "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1180
1181                 /* In order to do this, we need to find the function's (mangled) name.
1182                    If a function has a specification, its specification will have its
1183                    name. */
1184
1185                 if ( hasSpecification ) 
1186                 {
1187                         dwarf_printf(" has DW_TAG_specification \n");
1188
1189                         Dwarf_Attribute specAttribute;
1190                         status = dwarf_attr( specEntry, DW_AT_specification, & specAttribute, NULL );
1191
1192                         DWARF_NEXT_IF( status != DW_DLV_OK, 
1193                                         "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1194
1195                         Dwarf_Off specOffset;
1196                         status = dwarf_global_formref( specAttribute, & specOffset, NULL );
1197
1198                         DWARF_NEXT_IF( status != DW_DLV_OK, 
1199                                         "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1200
1201                         status = dwarf_offdie( dbg, specOffset, & specEntry, NULL );
1202
1203                         DWARF_NEXT_IF( status != DW_DLV_OK, 
1204                                         "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1205
1206                         dwarf_dealloc( dbg, specAttribute, DW_DLA_ATTR );
1207                 } /* end if the function has a specification */
1208
1209                 /* Prefer linkage names. */
1210
1211                 Dwarf_Attribute linkageNameAttr;
1212                 status = dwarf_attr( specEntry, DW_AT_MIPS_linkage_name, & linkageNameAttr, NULL );
1213
1214                 DWARF_NEXT_IF( status == DW_DLV_ERROR, 
1215                                 "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1216
1217                 bool hasLinkageName;
1218
1219                 if ( status == DW_DLV_OK ) 
1220                 {
1221                         hasLinkageName = true;
1222                         status = dwarf_formstring( linkageNameAttr, & functionName, NULL );
1223
1224                         DWARF_NEXT_IF( status != DW_DLV_OK, 
1225                                         "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1226
1227                         dwarf_dealloc( dbg, linkageNameAttr, DW_DLA_ATTR );
1228                 } /* end if there's a linkage name. */
1229                 else 
1230                 {
1231                         hasLinkageName = false;
1232
1233                         status = dwarf_diename( specEntry, & functionName, NULL );
1234
1235                         DWARF_NEXT_IF( status == DW_DLV_ERROR, 
1236                                         "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1237                 } /* end if there isn't a linkage name. */
1238
1239                 if ( functionName == NULL ) 
1240                 {
1241                         /* I'm not even sure what an anonymous function _means_,
1242                            but we sure can't do anything with it. */
1243
1244                         dwarf_printf( "Warning: anonymous function (type %lu).\n", (unsigned long)dieOffset );
1245
1246                         /* Don't parse the children, since we can't add them. */
1247                         parsedChild = true;
1248
1249                         dwarf_dealloc( dbg, functionName, DW_DLA_STRING );
1250                         break;
1251                 } /* end if there's no name at all. */
1252
1253                 dwarf_printf(" Function name %s \n", functionName);
1254
1255                 Function * thisFunction = NULL;
1256                 vector<Function *> ret_funcs;
1257
1258                 // newFunction is scoped at the function level...
1259
1260             Dwarf_Addr baseAddr = 0;
1261             Offset func_lowpc = 0;
1262             bool hasLowPC = false;
1263             status = dwarf_lowpc( dieEntry, & baseAddr, NULL );
1264             
1265             if (status == DW_DLV_OK) 
1266             {
1267                bool result = elfobj->convertDebugOffset(baseAddr, func_lowpc);
1268                hasLowPC = result;
1269             }
1270
1271                 if (objFile->findFunctionsByName(ret_funcs, functionName)) 
1272                 {
1273                         // Assert a single one?
1274                         thisFunction = ret_funcs[0];
1275                         dwarf_printf(" findFunction by name \n");
1276                 }
1277                 else 
1278                 {
1279                         // Didn't find by name (???), try to look up by address...
1280                if (!hasLowPC || !objFile->findFuncByEntryOffset(newFunction, func_lowpc)) 
1281                         {
1282                   dwarf_printf( "Failed to find function at %lx -> %lx\n", func_lowpc, func_lowpc);
1283                                         break;
1284                                 }
1285                         }
1286
1287
1288                 if (thisFunction == NULL && parseSibling== true) 
1289                 {
1290                         dwarf_printf( "Failed to find function '%s'\n", functionName );
1291                         break;
1292                 } 
1293                 else if (thisFunction != NULL && parseSibling == true) 
1294                 {
1295                         newFunction = thisFunction;
1296                 } 
1297                 else if (thisFunction != NULL && parseSibling == false ) 
1298                 {
1299                         // Parsing parents of specEntry or abstractOriginEntry - but the parent aleady has Function associated with it
1300                         // Do not redundantly parse. break
1301                         break;
1302                 }
1303
1304                 /* Once we've found the Symbol pointer corresponding to this
1305                    DIE, record its frame base.  A declaration entry may not have a 
1306                    frame base, and some functions do not have frames. */
1307
1308                 Dwarf_Attribute frameBaseAttribute;
1309                 status = dwarf_attr( dieEntry, DW_AT_frame_base, & frameBaseAttribute, NULL );
1310                 
1311                 DWARF_NEXT_IF( status == DW_DLV_ERROR, 
1312                                 "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1313
1314                 if ( status == DW_DLV_OK ) 
1315                 {
1316                         dwarf_printf(" Frame Pointer available \n");
1317                         Dwarf_Locdesc ** locationList;
1318                         Dwarf_Signed listLength;
1319
1320                         status = dwarf_loclist_n( frameBaseAttribute, & locationList, & listLength, NULL );
1321                         
1322                         if ( status != DW_DLV_OK ) 
1323                         {
1324                                 /* I think DWARF 3 generically allows this abomination of empty loclists. */
1325                                 break;
1326                         }
1327
1328                         DWARF_NEXT_IF( status != DW_DLV_OK, 
1329                                         "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1330
1331                         dwarf_dealloc( dbg, frameBaseAttribute, DW_DLA_ATTR );
1332
1333 #if defined(ia64_unknown_linux2_4)
1334                         /* Convert location list to an AST for later code generation. */
1335                         newFunction->setFramePtrRegnum(convertFrameBaseToAST( locationList[0], 
1336                                                 listLength, objFile ));
1337 #endif
1338
1339                         dwarf_printf(" Frame Pointer Variable decodeLocationListForStaticOffsetOrAddress \n");
1340                         vector<VariableLocation> *funlocs = new vector<VariableLocation>();
1341                         bool decodedAddressOrOffset = decodeLocationListForStaticOffsetOrAddress( locationList, 
1342                                                                                          listLength, objFile, *funlocs, 
1343                                                                                          lowpc, NULL);
1344
1345                         DWARF_NEXT_IF(!decodedAddressOrOffset, " Frame Pointer Variable - No location list \n");
1346
1347
1348                         status = newFunction->setFramePtr(funlocs);
1349
1350                         DWARF_NEXT_IF ( !status, "%s[%d]: Frame pointer not set successfully.\n", __FILE__, __LINE__ );
1351
1352                         deallocateLocationList( dbg, locationList, listLength );
1353                 } /* end if this DIE has a frame base attribute */
1354
1355                 /* Find its return type. */
1356
1357                 Dwarf_Attribute typeAttribute;
1358                 if (hasSpecification) {
1359                         status = dwarf_attr( specEntry, DW_AT_type, & typeAttribute, NULL );
1360                 }
1361
1362                 if ((!hasSpecification) || (status == DW_DLV_NO_ENTRY)) {
1363                         status = dwarf_attr( dieEntry, DW_AT_type, & typeAttribute, NULL );
1364                 }
1365
1366                 DWARF_NEXT_IF( status == DW_DLV_ERROR, 
1367                                 "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1368
1369                 Type * returnType = NULL;
1370                 Type *voidType = tc->findType("void");
1371
1372                 if ( status == DW_DLV_NO_ENTRY ) 
1373                 {
1374                         if (parseSibling == true) 
1375                         {
1376                                 // If return type is void, specEntry or abstractOriginEntry would have set it
1377                                 dwarf_printf(" Return type void \n");
1378                                 newFunction->setReturnType( voidType );
1379                         }
1380                 } /* end if the return type is void */
1381                 else 
1382                 {
1383                         /* There's a return type attribute. */
1384                         dwarf_printf(" Return type is not void \n");
1385                         Dwarf_Off typeOffset;
1386
1387                         status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
1388
1389                         DWARF_NEXT_IF( status != DW_DLV_OK, 
1390                                         "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1391
1392                         //parsing_printf("%s/%d: ret type %d\n",
1393                         //                         __FILE__, __LINE__, typeOffset);
1394
1395                         returnType = tc->findOrCreateType( (int) typeOffset );
1396                         newFunction->setReturnType( returnType );
1397
1398                         dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
1399                 } /* end if not a void return type */
1400
1401                 /* If this is a member function, add it as a field, for backward compatibility */
1402                 
1403                 if ( dieEnclosure != NULL ) 
1404                 {
1405                         /* Using the mangled name allows us to distinguish between overridden
1406                            functions, but confuses the tests.  Since Type uses vectors
1407                            to hold field names, however, duplicate -- demangled names -- are OK. */
1408
1409                         char * demangledName = P_cplus_demangle( functionName, objFile->isNativeCompiler() );
1410
1411                         char * leftMost = NULL;
1412                         if ( demangledName == NULL ) 
1413                         {
1414                                 dwarf_printf( "%s[%d]: unable to demangle '%s', using mangled name.\n", 
1415                                                 __FILE__, __LINE__, functionName );
1416
1417                                 demangledName = strdup( functionName );
1418                                 assert( demangledName != NULL );
1419                                 leftMost = demangledName;
1420                         }
1421                         else 
1422                         {
1423                                 /* Strip everything left of the rightmost ':' off; see above. */
1424                                 leftMost = demangledName;
1425                                 if ( strrchr( demangledName, ':' ) )
1426                                         leftMost = strrchr( demangledName, ':' ) + 1;
1427                         }
1428
1429                         std::string fName = convertCharToString(leftMost);
1430                         typeFunction *funcType = new typeFunction( (typeId_t) dieOffset, returnType, fName);
1431
1432                         dieEnclosure->addField( fName, funcType);
1433                         dwarf_printf(" Adding function %s to class \n", leftMost);
1434                         free( demangledName );
1435                 }
1436
1437                 // Parse parent nodes and their children but not their sibling
1438
1439                 if ( isAbstractOrigin ) 
1440                 {
1441                         dwarf_printf( "parseParent : abstract entry  %lu with tag 0x%x \n", 
1442                                         (unsigned long)dieOffset, dieTag );
1443
1444                         bool result = walkDwarvenTree( dbg, abstractEntry, module, objFile, 
1445                                         cuOffset, srcFiles, lowpc, newFunction, 
1446                                         newCommonBlock, newEnum, newEnclosure, 
1447                                         false, depth+1 );
1448
1449                         DWARF_NEXT_IF(!result, "Failed walking Dwarven tree");
1450
1451                 } 
1452                 else if ( hasSpecification ) 
1453                 { 
1454                         dwarf_printf( "parseParent : spec entry  %lu with tag 0x%x \n",  
1455                                         (unsigned long)dieOffset, dieTag);
1456
1457                         bool result = walkDwarvenTree( dbg, specEntry, module, objFile, 
1458                                         cuOffset, srcFiles, lowpc, newFunction, 
1459                                         newCommonBlock, newEnum, newEnclosure, 
1460                                         false, depth+1 );
1461
1462                         DWARF_NEXT_IF(!result, "Failed walking Dwarven tree");
1463                 }
1464
1465                 if ( isAbstractOrigin ) dwarf_dealloc( dbg, abstractEntry, DW_DLA_DIE ); 
1466                 if ( hasSpecification ) dwarf_dealloc( dbg, specEntry, DW_DLA_DIE ); 
1467                 dwarf_dealloc( dbg, functionName, DW_DLA_STRING );
1468         } break;
1469
1470
1471   case DW_TAG_common_block: 
1472         {
1473                 dwarf_printf(" DW_TAG_common_block \n");
1474                 char * commonBlockName;
1475                 status = dwarf_diename( dieEntry, & commonBlockName, NULL );
1476                 DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1477
1478                 Symbol *commonBlockVar;
1479                 std::vector<Symbol *> commonBlockVars;
1480                 if (!objFile->findSymbolByType(commonBlockVars, 
1481                                         commonBlockName, 
1482                                         Symbol::ST_OBJECT,
1483                                         mangledName))
1484                 {
1485                         if (!objFile->findSymbolByType(commonBlockVars, 
1486                                                 commonBlockName, 
1487                                                 Symbol::ST_OBJECT, 
1488                                                 mangledName, 
1489                                                 true))
1490                         {
1491                                 //pgcc 6 is naming common blocks with a trailing underscore
1492                                 std::string cbvname = std::string(commonBlockName) + std::string("_");
1493                                 if (!objFile->findSymbolByType(commonBlockVars, 
1494                                                         cbvname, 
1495                                                         Symbol::ST_OBJECT,
1496                                                         mangledName)){
1497                                         objFile->findSymbolByType(commonBlockVars,
1498                                                         cbvname, 
1499                                                         Symbol::ST_OBJECT, 
1500                                                         mangledName,
1501                                                         true);
1502                                 }
1503                         }       
1504                 }
1505
1506                 commonBlockVar = commonBlockVars[0];
1507
1508                 DWARF_NEXT_IF( !commonBlockVar, "%s[%d]: Couldn't find variable for common block\n", __FILE__, __LINE__);
1509
1510                 Type * commonBlockType = NULL;
1511
1512                 std::string cBName = commonBlockName;
1513                 if (!commonBlockVar) {
1514                         //bperr("unable to find variable %s\n", commonBlockName);
1515                 } else {
1516                         commonBlockType = dynamic_cast<typeCommon *>(tc->findVariableType(cBName));
1517                         if (commonBlockType == NULL) {
1518                                 commonBlockType = new typeCommon( (typeId_t) dieOffset, cBName );
1519                                 assert( commonBlockType != NULL );
1520                                 tc->addGlobalVariable( cBName, commonBlockType );
1521                         }       
1522                 }
1523                 dwarf_dealloc( dbg, commonBlockName, DW_DLA_STRING );
1524
1525                 /* This node's children are in the common block. */
1526                 newCommonBlock = dynamic_cast<typeCommon*>(commonBlockType);
1527                 if (newCommonBlock)
1528                         newCommonBlock->beginCommonBlock();
1529         } break;
1530
1531   case DW_TAG_constant: 
1532         {
1533                 dwarf_printf(" DW_TAG_constant \n");
1534                 //bperr ( "Warning: dyninst ignores named constant entries.\n" );
1535         } break;
1536
1537         /* It's worth noting that a variable may have a constant value.  Since,
1538            AFAIK, Dyninst does nothing with this information, neither will we.
1539            (It will, however, explain why certain variables that otherwise would
1540            don't have locations.) */
1541   case DW_TAG_variable: 
1542         {
1543                 dwarf_printf(" DW_TAG_variable \n");
1544             /* Acquire the name, type, and line number. */
1545                 /* A variable may occur inside a function, as either static or local.
1546                    A variable may occur inside a container, as C++ static member.
1547                    A variable may not occur in either, as a global. 
1548          
1549                    For the first two cases, we need the variable's name, its type,
1550                    its line number, and its offset or address in order to tell
1551                    Dyninst about it.  Dyninst only needs to know the name and type
1552                    of a global.  (Actually, it already knows the names of the globals;
1553                    we're really just telling it the types.)
1554          
1555                    Variables may have two entries, the second, with a _specification,
1556                    being the only one with the location. */
1557       
1558                 /* We'll start with the location, since that's most likely to
1559                    require the _specification. */
1560                 Dwarf_Attribute locationAttribute;
1561                 status = dwarf_attr( dieEntry, DW_AT_location, & locationAttribute, NULL );
1562                 DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1563       
1564                 if ( status == DW_DLV_NO_ENTRY ) { break; }
1565                 DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1566       
1567       Dwarf_Locdesc **locationList;
1568       Dwarf_Signed listLength;
1569       status = dwarf_loclist_n( locationAttribute, & locationList, & listLength, NULL );
1570       dwarf_dealloc( dbg, locationAttribute, DW_DLA_ATTR );
1571       if ( status != DW_DLV_OK ) {
1572          /* I think this is OK if the local variable was optimized away. */
1573          break;
1574       }
1575       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1576          
1577       vector<VariableLocation> locs;
1578       bool decodedAddressOrOffset = decodeLocationListForStaticOffsetOrAddress( locationList, listLength, objFile, locs, lowpc, NULL);
1579       deallocateLocationList( dbg, locationList, listLength );            
1580       if ( ! decodedAddressOrOffset ) 
1581       { 
1582          fprintf(stderr, "%s[%d]:  DW_TAG_variable: failed to decode loc list\n", FILE__, __LINE__);
1583          break; 
1584       }
1585       
1586       for (unsigned i=0; i<locs.size(); i++) {
1587                //if (locs[i].stClass != storageAddr) 
1588                //continue;
1589          if (locs[i].lowPC) {
1590             Offset newlowpc = locs[i].lowPC;
1591             bool result = elfobj->convertDebugOffset(locs[i].lowPC, newlowpc);
1592             if (result)
1593                locs[i].lowPC = newlowpc;
1594          }
1595          if (locs[i].hiPC) {
1596             Offset newhipc = locs[i].hiPC;
1597             bool result = elfobj->convertDebugOffset(locs[i].hiPC, newhipc);
1598             if (result)
1599                locs[i].hiPC = newhipc;
1600          }
1601       }
1602       
1603       /* If this DIE has a _specification, use that for the rest of our inquiries. */
1604       Dwarf_Die specEntry = dieEntry;
1605       
1606       Dwarf_Attribute specAttribute;
1607       status = dwarf_attr( dieEntry, DW_AT_specification, & specAttribute, NULL );
1608       DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1609       
1610       if ( status == DW_DLV_OK ) {
1611          Dwarf_Off specOffset;
1612          status = dwarf_global_formref( specAttribute, & specOffset, NULL );
1613          DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1614          
1615          status = dwarf_offdie( dbg, specOffset, & specEntry, NULL );
1616          DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1617          
1618          dwarf_dealloc( dbg, specAttribute, DW_DLA_ATTR );
1619       } /* end if dieEntry has a _specification */
1620       
1621       /* Acquire the name, type, and line number. */
1622       char * variableName = NULL;
1623       status = dwarf_diename( specEntry, & variableName, NULL );
1624       DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1625       
1626       /* If we're fortran, get rid of the trailing _ */
1627       if (variableName && (currentFunction || currentEnclosure)) {
1628          supportedLanguages lang = module->language();
1629          if ( ( lang == lang_Fortran ||
1630                 lang == lang_CMFortran ||
1631                 lang == lang_Fortran_with_pretty_debug ) &&
1632               variableName[strlen(variableName)-1]=='_') 
1633             variableName[strlen(variableName)-1]='\0';
1634       }
1635       
1636       /* Acquire the parameter's type. */
1637       Dwarf_Attribute typeAttribute;
1638       status = dwarf_attr( specEntry, DW_AT_type, & typeAttribute, NULL );
1639       DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1640       
1641       if ( status == DW_DLV_NO_ENTRY ) { break; }
1642       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1643       
1644       Dwarf_Off typeOffset;
1645       status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
1646       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1647          
1648       /* The typeOffset forms a module-unique type identifier,
1649          so the Type look-ups by it rather than name. */
1650       Type * variableType = tc->findOrCreateType( (int) typeOffset );
1651       dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
1652       
1653       Dwarf_Unsigned variableLineNo;
1654       bool hasLineNumber = false;
1655       std::string fileName;
1656       Dwarf_Unsigned fileNameDeclVal;
1657       if (currentEnclosure || currentFunction) {
1658          /* Acquire the variable's lineNo. We don't use this for globals */
1659             
1660          Dwarf_Attribute fileDeclAttribute;
1661          status = dwarf_attr( specEntry, DW_AT_decl_file, & fileDeclAttribute, NULL );
1662          DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1663          if ( status == DW_DLV_OK ) {
1664             status = dwarf_formudata(fileDeclAttribute, &fileNameDeclVal, NULL);
1665             DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1666             dwarf_dealloc( dbg, fileDeclAttribute, DW_DLA_ATTR );                       
1667          }
1668          if ( status == DW_DLV_NO_ENTRY )
1669             fileName = "";
1670          else   
1671             fileName = convertCharToString(srcFiles[fileNameDeclVal-1]);
1672          
1673          Dwarf_Attribute lineNoAttribute;
1674          status = dwarf_attr( specEntry, DW_AT_decl_line, & lineNoAttribute, NULL );
1675          DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1676          
1677          /* We don't need to tell Dyninst a line number for C++ static variables,
1678             so it's OK if there isn't one. */
1679          if ( status == DW_DLV_OK ) {
1680             hasLineNumber = true;
1681             status = dwarf_formudata( lineNoAttribute, & variableLineNo, NULL );
1682             DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1683             dwarf_dealloc( dbg, lineNoAttribute, DW_DLA_ATTR );                 
1684          } /* end if there is a line number */
1685       }
1686       
1687       std::string vName;
1688       if (variableName)
1689          vName = convertCharToString(variableName);
1690       
1691       if ( currentFunction == NULL && currentEnclosure == NULL ) {
1692          /* The typeOffset forms a module-unique type identifier,
1693             so the Type look-ups by it rather than name. */
1694          dwarf_printf( "%s/%d: %s/%d\n", __FILE__, __LINE__, variableName ? variableName : "{NONAME}", typeOffset );
1695          Dyninst::Offset addr = 0;
1696          if (locs.size() && locs[0].stClass == storageAddr)
1697             addr = locs[0].frameOffset;
1698          Variable *var;
1699          bool result = module->exec()->findVariableByOffset(var, addr);
1700          if (result) {
1701             var->setType(variableType);
1702          }
1703             
1704          tc->addGlobalVariable( vName, variableType);
1705       } /* end if this variable is a global */
1706       else if (currentFunction) {
1707          /* We now have the variable name, type, offset, and line number.
1708             Tell Dyninst about it. */
1709          if (!variableName)
1710             break;
1711          dwarf_printf( "localVariable '%s', currentFunction %p\n", variableName, currentFunction );
1712          if (!hasLineNumber){
1713             variableLineNo = 0;
1714             fileName = "";
1715          }
1716          else {
1717             fileName = srcFiles[fileNameDeclVal-1];
1718          }
1719                localVar * newVariable = new localVar( vName, variableType, fileName, (int) variableLineNo, currentFunction);
1720          for (unsigned int i = 0; i < locs.size(); ++i)
1721          {
1722             newVariable->addLocation(locs[i]);
1723          }
1724          
1725          localVarCollection *lvs = NULL; 
1726          if (!currentFunction->getAnnotation(lvs, FunctionLocalVariablesAnno))
1727          {
1728             lvs = new localVarCollection();
1729             if (!currentFunction->addAnnotation(lvs, FunctionLocalVariablesAnno))
1730             {
1731                fprintf(stderr, "%s[%d]:  failed to add annotations here\n", 
1732                        FILE__, __LINE__);
1733                break;
1734             }
1735          }
1736          if (!lvs)
1737          {
1738             fprintf(stderr, "%s[%d]:  failed to getAnnotation here\n", 
1739                     FILE__, __LINE__);
1740             break;
1741          }
1742          lvs->addLocalVar(newVariable);
1743       } /* end if a local or static variable. */
1744       else if ( currentEnclosure != NULL ) {
1745          if (!variableName)
1746             break;
1747          assert( locs[0].stClass != storageRegOffset );
1748          currentEnclosure->addField( vName, variableType, locs[0].frameOffset);
1749       } /* end if this variable is not global */
1750    } 
1751    break;
1752
1753   case DW_TAG_formal_parameter: 
1754     {
1755                 dwarf_printf(" DW_TAG_formal_parameter \n");
1756       /* A formal parameter must occur in the context of a function.
1757          (That is, we can't do anything with a formal parameter to a
1758          function we don't know about.) */
1759     /* It's probably worth noting that a formal parameter may have a
1760        default value.  Since, AFAIK, Dyninst does nothing with this information,
1761        neither will we. */
1762       if ( currentFunction == NULL ) {
1763         dwarf_printf( "%s[%d]: ignoring formal parameter without corresponding function.\n", __FILE__, __LINE__ );
1764         break;
1765       }
1766          
1767       /* We need the formal parameter's name, its type, its line number,
1768          and its offset from the frame base in order to tell the 
1769          rest of Dyninst about it.  A single _formal_parameter
1770          DIE may not have all of this information; if it does not,
1771          we will ignore it, hoping to catch it when it is later
1772          referenced as an _abstract_origin from another _formal_parameter
1773          DIE.  If we never find such a DIE, than there is not enough
1774          information to introduce it to Dyninst. */
1775          
1776       /* We begin with the location, since this is the attribute
1777          most likely to require using the _abstract_origin. */
1778       Dwarf_Bool hasLocation = false;
1779       status = dwarf_hasattr( dieEntry, DW_AT_location, & hasLocation, NULL );
1780       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1781          
1782       if ( !hasLocation ) {
1783         dwarf_printf( "%s[%d]: ignoring formal parameter without location.\n", __FILE__, __LINE__ );
1784         break;
1785       }
1786          
1787       /* Acquire the location of this formal parameter. */
1788       Dwarf_Attribute locationAttribute;
1789       status = dwarf_attr( dieEntry, DW_AT_location, & locationAttribute, NULL );
1790       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1791          
1792       Dwarf_Locdesc **locationList;
1793       Dwarf_Signed listLength;
1794       status = dwarf_loclist_n( locationAttribute, & locationList, & listLength, NULL );
1795       dwarf_dealloc( dbg, locationAttribute, DW_DLA_ATTR );
1796       if ( status != DW_DLV_OK ) {
1797         /* I think this is legal if the parameter was optimized away. */
1798         dwarf_printf( "%s[%d]: ignoring formal parameter with bogus location.\n", __FILE__, __LINE__ );
1799         break;
1800       }
1801       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1802          
1803       vector<VariableLocation> locs;
1804       bool decodedOffset = decodeLocationListForStaticOffsetOrAddress( locationList, listLength, objFile, locs, lowpc, NULL);
1805       deallocateLocationList( dbg, locationList, listLength );
1806          
1807       if ( ! decodedOffset ) {
1808         dwarf_printf( "%s[%d]: ignoring formal parameter with undecodable location.\n", __FILE__, __LINE__ );
1809         break;
1810       }
1811          
1812       assert( locs[0].stClass != storageAddr );
1813          
1814       /* If the DIE has an _abstract_origin, we'll use that for the
1815          remainder of our inquiries. */
1816       Dwarf_Die originEntry = dieEntry;
1817          
1818       Dwarf_Attribute originAttribute;
1819       status = dwarf_attr( dieEntry, DW_AT_abstract_origin, & originAttribute, NULL );
1820       DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1821          
1822       if ( status == DW_DLV_OK ) {
1823         Dwarf_Off originOffset;
1824         status = dwarf_global_formref( originAttribute, & originOffset, NULL );
1825         DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1826             
1827         status = dwarf_offdie( dbg, originOffset, & originEntry, NULL );
1828         DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1829             
1830         dwarf_dealloc( dbg, originAttribute, DW_DLA_ATTR );
1831       } /* end if the DIE has an _abstract_origin */
1832          
1833       /* Acquire the parameter's name. */
1834       char * parameterName;
1835       status = dwarf_diename( originEntry, & parameterName, NULL );
1836       DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1837          
1838       /* We can't do anything with anonymous parameters. */
1839       if ( status == DW_DLV_NO_ENTRY ) { break; }
1840       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1841          
1842       /* Acquire the parameter's type. */
1843       Dwarf_Attribute typeAttribute;
1844       status = dwarf_attr( originEntry, DW_AT_type, & typeAttribute, NULL );
1845       DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1846          
1847       if ( status == DW_DLV_NO_ENTRY ) { break; }
1848       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1849          
1850       Dwarf_Off typeOffset;
1851       status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
1852       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1853          
1854       /* The typeOffset forms a module-unique type identifier,
1855          so the Type look-ups by it rather than name. */
1856       dwarf_printf( "%s[%d]: found formal parameter %s with type %ld\n", __FILE__, __LINE__, parameterName, typeOffset );
1857       Type * parameterType = tc->findOrCreateType( (int) typeOffset );
1858          
1859       dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
1860          
1861          
1862       Dwarf_Attribute fileDeclAttribute;
1863       std::string fileName;
1864       status = dwarf_attr( originEntry, DW_AT_decl_file, & fileDeclAttribute, NULL );
1865       DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1866       Dwarf_Unsigned fileNameDeclVal;
1867       if ( status == DW_DLV_OK ) {
1868         status = dwarf_formudata(fileDeclAttribute, &fileNameDeclVal, NULL);
1869         DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1870         dwarf_dealloc( dbg, fileDeclAttribute, DW_DLA_ATTR );
1871       }
1872       if ( status == DW_DLV_NO_ENTRY )
1873         fileName = "";
1874       else      
1875         fileName = convertCharToString(srcFiles[fileNameDeclVal-1]);
1876          
1877       /* Acquire the parameter's lineNo. */
1878       Dwarf_Attribute lineNoAttribute;
1879       Dwarf_Unsigned parameterLineNo;
1880       status = dwarf_attr( originEntry, DW_AT_decl_line, & lineNoAttribute, NULL );
1881       DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1882          
1883       if ( status == DW_DLV_NO_ENTRY ) {
1884         dwarf_printf( "%s[%d]: ignoring formal parameter without line number.\n", __FILE__, __LINE__ );
1885         parameterLineNo = 0;
1886       }
1887       else{
1888         status = dwarf_formudata( lineNoAttribute, & parameterLineNo, NULL );
1889         DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1890         dwarf_dealloc( dbg, lineNoAttribute, DW_DLA_ATTR );
1891       } 
1892          
1893          
1894       /* We now have the parameter's location, name, type, and line number.
1895          Tell Dyninst about it. */
1896       std::string pName = convertCharToString(parameterName);
1897             localVar * newParameter = new localVar( pName, parameterType, fileName, (int) parameterLineNo, currentFunction);
1898       assert( newParameter != NULL );
1899           for (unsigned int i = 0; i < locs.size(); ++i)
1900           {
1901                   newParameter->addLocation(locs[i]);
1902           }
1903
1904       /* This is just brutally ugly.  Why don't we take care of this invariant automatically? */
1905       localVarCollection *lvs = NULL;
1906       if (!currentFunction->getAnnotation(lvs, FunctionParametersAnno))
1907         {
1908           lvs = new localVarCollection();
1909           if (!currentFunction->addAnnotation(lvs, FunctionParametersAnno)) 
1910             {
1911               fprintf(stderr, "%s[%d]:  failed to add annotation here\n", 
1912                       FILE__, __LINE__);
1913               break;
1914             }
1915         }
1916          
1917       if (!lvs)
1918         {
1919           fprintf(stderr, "%s[%d]:  failed to add annotation here\n", 
1920                   FILE__, __LINE__);
1921           break;
1922         }
1923          
1924       lvs->addLocalVar(newParameter);
1925          
1926       //TODO ??NOT REQUIRED??
1927       //currentFunction->addParam( parameterName, parameterType, parameterLineNo, parameterOffset );
1928          
1929       dwarf_printf( "%s[%d]: added formal parameter '%s' of type %p from line %lu.\n", __FILE__, __LINE__, parameterName, parameterType, (unsigned long)parameterLineNo );
1930     } break;
1931
1932   case DW_TAG_base_type: 
1933     {
1934                 dwarf_printf(" DW_TAG_base_type \n");
1935       /* What's the type's name? */
1936       char * typeName;
1937       status = dwarf_diename( dieEntry, & typeName, NULL );
1938       if(status == DW_DLV_OK){
1939         //DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1940
1941         /* How big is it? */
1942         Dwarf_Attribute byteSizeAttr;
1943         Dwarf_Unsigned byteSize;
1944         status = dwarf_attr( dieEntry, DW_AT_byte_size, & byteSizeAttr, NULL );
1945         DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1946         status = dwarf_formudata( byteSizeAttr, & byteSize, NULL );
1947         DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1948
1949         dwarf_dealloc( dbg, byteSizeAttr, DW_DLA_ATTR );
1950
1951         /* Generate the appropriate built-in type; since there's no
1952            reliable way to distinguish between a built-in and a scalar,
1953            we don't bother to try. */
1954         std::string tName = convertCharToString(typeName);   
1955         typeScalar * baseType = new typeScalar( (typeId_t) dieOffset, (unsigned int) byteSize, tName );
1956         assert( baseType != NULL );
1957
1958         /* Add the basic type to our collection. */
1959         dwarf_printf( "Adding base type '%s' (%lu) of size %lu to type collection %p\n", typeName, (unsigned long)dieOffset, (unsigned long)byteSize, tc );
1960         baseType = tc->addOrUpdateType( baseType );
1961
1962         dwarf_dealloc( dbg, typeName, DW_DLA_STRING );
1963       }
1964     } break;
1965
1966   case DW_TAG_typedef: 
1967     {
1968                 dwarf_printf(" DW_TAG_typedef \n");
1969       char * definedName = NULL;
1970       status = dwarf_diename( dieEntry, & definedName, NULL );
1971       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1972
1973       Type * referencedType = NULL;
1974       Dwarf_Attribute typeAttribute;
1975       status = dwarf_attr( dieEntry, DW_AT_type, & typeAttribute, NULL );
1976       DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1977       if ( status == DW_DLV_NO_ENTRY ) {
1978         /* According to the DWARF spec, "A declaration of the type that is not also a definition."
1979            This includes constructions like "typedef void _IO_lock_t", from libio.h, which
1980            cause us to issue a lot of true but spurious-looking warnings about incomplete types.
1981            So instead of ignoring this entry, point it to the void type.  (This is also more
1982            in line with our handling of absent DW_AT_type tags everywhere else.) */
1983         referencedType = tc->findType( "void" );
1984       }
1985       else {
1986         Dwarf_Off typeOffset;
1987         status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
1988         DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1989
1990         dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
1991
1992         if (!module) 
1993           {
1994             fprintf(stderr, "%s[%d]:  FIXME\n", FILE__, __LINE__);
1995             break;
1996           }
1997         if (!tc) 
1998           {
1999             fprintf(stderr, "%s[%d]:  FIXME\n", FILE__, __LINE__);
2000             break;
2001           }
2002         referencedType = tc->findOrCreateType( (int) typeOffset );
2003       }
2004       string tName;
2005       if(!definedName) {
2006         switch(dieTag){
2007         case DW_TAG_const_type:
2008           tName = "const " + referencedType->getName();
2009           break;
2010         case DW_TAG_packed_type:
2011           tName = "packed " + referencedType->getName();
2012           break;
2013         case DW_TAG_volatile_type:
2014           tName = "volatile " + referencedType->getName();
2015           break;
2016         }
2017       }
2018       else {
2019         tName = convertCharToString(definedName);
2020       }
2021
2022       typeTypedef * typedefType = new typeTypedef( (typeId_t) dieOffset, referencedType, tName);
2023       typedefType = tc->addOrUpdateType( typedefType );
2024
2025       /* Sanity check: typedefs should not have children. */
2026       Dwarf_Die childDwarf;
2027       status = dwarf_child( dieEntry, & childDwarf, NULL );
2028       assert( status == DW_DLV_NO_ENTRY );
2029
2030       dwarf_dealloc( dbg, definedName, DW_DLA_STRING );
2031     } break;
2032
2033   case DW_TAG_array_type: 
2034     {
2035                 dwarf_printf(" DW_TAG_array \n");
2036       /* Two words about pgf90 arrays.
2037
2038       Primus: the PGI extensions to DWARF are documented in 
2039       '/p/paradyn/doc/External/manuals/pgf90-dwarf-arrays.txt'.
2040
2041       Secundus: we ignore DW_AT_PGI_lbase, DW_AT_PGI_loffset, and DW_AT_PGI_lstride,
2042       even though libdwarf recognizes them, because our type modelling doesn't allow
2043       us to make use of this information.  Similarly, in virtually every place where
2044       the Portland Group extends DWARF to allow _form_block attributes encoding location
2045       lists, we ignore them.  We should, however, recognize these cases and ignore them
2046       gracefully, that is, without an error. :)
2047       */
2048
2049       char * arrayName = NULL;
2050       status = dwarf_diename( dieEntry, & arrayName, NULL );
2051       DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2052
2053       /* Find the type of the elements. */
2054       Dwarf_Attribute typeAttribute;
2055       status = dwarf_attr( dieEntry, DW_AT_type, & typeAttribute, NULL );
2056       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2057
2058       Dwarf_Off typeOffset;
2059       status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
2060       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2061
2062       dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
2063
2064       //parsing_printf("%s/%d: %s/%d\n",
2065       //                           __FILE__, __LINE__, arrayName, typeOffset);
2066       Type * elementType = tc->findOrCreateType( (int) typeOffset );
2067
2068       /* Find the range(s) of the elements. */
2069       Dwarf_Die firstRange;
2070       status = dwarf_child( dieEntry, & firstRange, NULL );
2071       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2072       typeArray * baseArrayType = parseMultiDimensionalArray( dbg, firstRange, elementType, module, tc);
2073       assert( baseArrayType != NULL );
2074
2075       /* The baseArrayType is an anonymous type with its own typeID.  Extract
2076          the information and add an array type for this DIE. */
2077       std::string aName = convertCharToString(arrayName);
2078       typeArray *arrayType = new typeArray( (typeId_t) dieOffset, baseArrayType->getBaseType(), baseArrayType->getLow(),
2079                                             baseArrayType->getHigh(), aName);
2080       assert( arrayType != NULL );
2081       //setArraySize( arrayType, baseArrayType->getLow(), baseArrayType->getHigh() );
2082       arrayType = tc->addOrUpdateType( arrayType );
2083
2084       /* Don't parse the children again. */
2085       parsedChild = true;
2086
2087       dwarf_dealloc( dbg, firstRange, DW_DLA_DIE );
2088       dwarf_dealloc( dbg, arrayName, DW_DLA_STRING );
2089     } break;
2090
2091   case DW_TAG_subrange_type: 
2092     {
2093                 dwarf_printf(" DW_TAG_subrange \n");
2094       std::string loBound;
2095       std::string hiBound;
2096       parseSubRangeDIE( dbg, dieEntry, loBound, hiBound, module, tc);
2097     } break;
2098
2099   case DW_TAG_enumeration_type: 
2100     {
2101                 dwarf_printf(" DW_TAG_enumeration \n");
2102       char * typeName = NULL;
2103       status = dwarf_diename( dieEntry, & typeName, NULL );
2104       DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2105
2106       std::string tName = convertCharToString(typeName);
2107       typeEnum* enumerationType = new typeEnum( (typeId_t) dieOffset, tName);
2108       assert( enumerationType != NULL );
2109       enumerationType = dynamic_cast<typeEnum *>(tc->addOrUpdateType( enumerationType ));
2110       newEnum = enumerationType;
2111
2112       dwarf_dealloc( dbg, typeName, DW_DLA_STRING );
2113     } break;
2114
2115   case DW_TAG_inheritance: 
2116     {
2117                 dwarf_printf(" DW_TAG_inheritance \n");
2118       /* Acquire the super class's type. */
2119       Dwarf_Attribute scAttr;
2120       status = dwarf_attr( dieEntry, DW_AT_type, & scAttr, NULL );
2121       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2122
2123       Dwarf_Off scOffset;
2124       status = dwarf_global_formref( scAttr, & scOffset, NULL );
2125       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2126
2127       dwarf_dealloc( dbg, scAttr, DW_DLA_ATTR );
2128
2129       //parsing_printf("%s/%d: inherited %d\n",
2130       //                           __FILE__, __LINE__, scOffset);
2131       Type * superClass = tc->findOrCreateType( (int) scOffset );
2132
2133       /* Acquire the visibility, if any.  DWARF calls it accessibility
2134          to distinguish it from symbol table visibility. */
2135       Dwarf_Attribute visAttr;
2136       status = dwarf_attr( dieEntry, DW_AT_accessibility, & visAttr, NULL );
2137       DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2138
2139       visibility_t visibility = visPrivate;
2140       if ( status == DW_DLV_OK ) {
2141         Dwarf_Unsigned visValue;
2142         status = dwarf_formudata( visAttr, & visValue, NULL );
2143         DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2144
2145         switch( visValue ) {
2146         case DW_ACCESS_public: visibility = visPublic; break;
2147         case DW_ACCESS_protected: visibility = visProtected; break;
2148         case DW_ACCESS_private: visibility = visPrivate; break;
2149         default:
2150           //bperr ( "Uknown visibility, ignoring.\n" );
2151           break;
2152         } /* end visibility switch */
2153
2154         dwarf_dealloc( dbg, visAttr, DW_DLA_ATTR );
2155       } /* end if the visibility is specified. */
2156
2157       /* Add a readily-recognizable 'bad' field to represent the superclass.
2158          Type::getComponents() will Do the Right Thing. */
2159       std::string fName = "{superclass}";
2160       currentEnclosure->addField( fName, superClass, -1, visibility );
2161     } break;
2162
2163   case DW_TAG_structure_type:
2164   case DW_TAG_union_type:
2165   case DW_TAG_class_type: 
2166     {
2167                 dwarf_printf(" DW_TAG_structure or DW_TAG_union DW_TAG_class \n");
2168       char * typeName = NULL;
2169       status = dwarf_diename( dieEntry, & typeName, NULL );
2170       DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2171       Dwarf_Attribute sizeAttr;
2172       Dwarf_Unsigned typeSize = 0;
2173       status = dwarf_attr( dieEntry, DW_AT_byte_size, & sizeAttr, NULL );
2174       DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2175
2176       if ( status == DW_DLV_OK ) {
2177         status = dwarf_formudata( sizeAttr, & typeSize, NULL );
2178         DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2179
2180         dwarf_dealloc( dbg, sizeAttr, DW_DLA_ATTR );
2181       }
2182
2183       fieldListType * containingType = NULL;
2184       std::string tName = convertCharToString(typeName);
2185       switch ( dieTag ) {
2186       case DW_TAG_structure_type: 
2187       case DW_TAG_class_type: {
2188         typeStruct *ts = new typeStruct( (typeId_t) dieOffset, tName);
2189         containingType = dynamic_cast<fieldListType *>(tc->addOrUpdateType(ts));
2190         break;
2191       }
2192           case DW_TAG_union_type: 
2193           {
2194                   typeUnion *tu = new typeUnion( (typeId_t) dieOffset, tName);
2195                   containingType = dynamic_cast<fieldListType *>(tc->addOrUpdateType(tu));
2196                   dwarf_printf("%s[%d]:  new union %s\n", FILE__, __LINE__, tName.c_str());
2197                   break;
2198           }
2199           }
2200           newEnclosure = containingType;
2201
2202       dwarf_dealloc( dbg, typeName, DW_DLA_STRING );
2203     } break;
2204
2205   case DW_TAG_enumerator: 
2206     {
2207                 dwarf_printf(" DW_TAG_enumerator \n");
2208       /* An entry in an enumeration. */
2209       char * enumName = NULL;
2210       status = dwarf_diename( dieEntry, & enumName, NULL );
2211       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2212
2213       Dwarf_Attribute valueAttr;
2214       status = dwarf_attr( dieEntry, DW_AT_const_value, & valueAttr, NULL );
2215       DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2216
2217       Dwarf_Signed enumValue = 0;
2218       if ( status == DW_DLV_OK ) {
2219         status = dwarf_formsdata( valueAttr, & enumValue, NULL );
2220         DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2221
2222         dwarf_dealloc( dbg, valueAttr, DW_DLA_ATTR );
2223       }
2224
2225       // //bperr ( "Adding enum '%s' (%ld) to enumeration '%s' (%d)\n", enumName, (signed long)enumValue, currentEnclosure->getName(), currentEnclosure->getID() );
2226       currentEnum->addConstant( enumName, (int) enumValue );
2227
2228       dwarf_dealloc( dbg, enumName, DW_DLA_STRING );
2229     } break;
2230
2231   case DW_TAG_member: 
2232         {
2233                 dwarf_printf(" DW_TAG_member \n");
2234                 char * memberName = NULL;
2235                 status = dwarf_diename( dieEntry, & memberName, NULL );
2236                 DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", 
2237                                 FILE__, __LINE__ );
2238
2239                 if (!memberName)
2240                 {
2241                         //fprintf(stderr, "%s[%d]:  weird, dwarf_diename returned NULL w/out error\n", 
2242                 //      FILE__, __LINE__);
2243                 }
2244                 Dwarf_Attribute typeAttribute;
2245                 status = dwarf_attr( dieEntry, DW_AT_type, & typeAttribute, NULL );
2246
2247                 if ( status == DW_DLV_NO_ENTRY ) 
2248                 {
2249                         dwarf_printf("%s[%d]:  parse member: no entry\n", FILE__, __LINE__);
2250                         break;
2251                 }
2252
2253                 DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", 
2254                                 __FILE__, __LINE__ );
2255
2256                 Dwarf_Off typeOffset;
2257                 status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
2258
2259                 dwarf_printf("%s[%d]:  type id '%d' for type '%s'\n", FILE__, __LINE__, 
2260                                 typeOffset, memberName ? memberName : "no_name");
2261
2262                 DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", 
2263                                 FILE__, __LINE__ );
2264
2265                 dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
2266
2267                 vector<VariableLocation> locs;
2268
2269                 //parsing_printf("%s/%d: %s/%d\n",
2270                 //                         __FILE__, __LINE__, memberName, typeOffset);
2271
2272                 Type *memberType = tc->findOrCreateType((int) typeOffset );
2273
2274                 Dwarf_Attribute locationAttr;
2275                 status = dwarf_attr( dieEntry, DW_AT_data_member_location, & locationAttr, NULL );
2276
2277                 DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", 
2278                                 FILE__, __LINE__ );
2279
2280                 if ( status == DW_DLV_NO_ENTRY ) 
2281                 {
2282                         dwarf_printf("%s[%d]:  parse member %s: no location\n", FILE__, __LINE__, memberName ? memberName : "nameless_member");
2283                         //break;
2284                         //  some members do not have locations???  (see unions)
2285                 }
2286                 else
2287                 {
2288
2289                 DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", 
2290                                 FILE__, __LINE__ );
2291
2292                 Dwarf_Locdesc **locationList;
2293                 Dwarf_Signed listLength;
2294                 status = dwarf_loclist_n( locationAttr, & locationList, & listLength, NULL );
2295                 DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", 
2296                                 FILE__, __LINE__ );
2297
2298                 dwarf_dealloc( dbg, locationAttr, DW_DLA_ATTR );
2299
2300                 dwarf_printf(" Tag member %s decodeLocationListForStaticOffsetOrAddress \n", memberName);
2301                 long int baseAddress = 0;
2302                 bool decodedAddress = decodeLocationListForStaticOffsetOrAddress( locationList, listLength, objFile, locs, lowpc, & baseAddress );
2303                 deallocateLocationList( dbg, locationList, listLength );
2304
2305                 if ( ! decodedAddress ) 
2306                 { 
2307                         dwarf_printf("%s[%d]:  failed to decode member address\n", FILE__, __LINE__);
2308                         break; 
2309                 }
2310
2311                 assert( decodedAddress );
2312
2313                 assert( locs[0].stClass == storageAddr );
2314                 }
2315
2316                 /* DWARF stores offsets in bytes unless the member is a bit field.
2317                    Correct memberOffset as indicated.  Also, memberSize is in bytes
2318                    from the underlying type, not the # of bits used from it, so
2319                    correct that as necessary as well. */
2320                 long int memberSize = memberType->getSize();
2321
2322                 Dwarf_Attribute bitOffset;
2323                 status = dwarf_attr( dieEntry, DW_AT_bit_offset, & bitOffset, NULL );
2324                 DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", 
2325                                 FILE__, __LINE__ );
2326
2327                 if ( status == DW_DLV_OK ) 
2328                 {
2329                         Dwarf_Unsigned memberOffset_du = locs[0].frameOffset;
2330                         status = dwarf_formudata( bitOffset, &memberOffset_du, NULL );
2331                         DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", 
2332                                         FILE__, __LINE__ );
2333
2334                         dwarf_dealloc( dbg, bitOffset, DW_DLA_ATTR );
2335
2336                         Dwarf_Attribute bitSize;
2337                         status = dwarf_attr( dieEntry, DW_AT_bit_size, & bitSize, NULL );
2338                         DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", 
2339                                         FILE__, __LINE__ );
2340
2341                         Dwarf_Unsigned memberSize_du = memberSize;
2342                         status = dwarf_formudata( bitSize, &memberSize_du, NULL );
2343                         DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", 
2344                                         FILE__, __LINE__ );
2345
2346                         dwarf_dealloc( dbg, bitSize, DW_DLA_ATTR );
2347
2348                         /* If the DW_AT_byte_size field exists, there's some padding.
2349                            FIXME?  We ignore padding for now.  (We also don't seem to handle
2350                            bitfields right in getComponents() anyway...) */
2351                 }
2352                 else 
2353                 {
2354                         dwarf_printf("%s[%d]:  got status != OK\n", FILE__, __LINE__);
2355                         if (locs.size())
2356                                 locs[0].frameOffset *= 8;
2357                         memberSize *= 8;
2358                 } /* end if not a bit field member. */
2359
2360                 if ( memberName != NULL ) 
2361                 {
2362                         std::string fName = convertCharToString(memberName);
2363                         int offset_to_use = locs.size() ? locs[0].frameOffset : -1;
2364                         currentEnclosure->addField( fName, memberType, offset_to_use);
2365                         dwarf_dealloc( dbg, memberName, DW_DLA_STRING );
2366                         dwarf_printf("%s[%d]:  new field: [%s] %s\n", FILE__, __LINE__, 
2367                                         memberType ? memberType->getName().c_str() : "no_type", fName.c_str());
2368                 } 
2369                 else 
2370                 {
2371                         /* An anonymous union [in a struct]. */
2372                         std::string fName = "[anonymous union]";
2373                         int offset_to_use = locs.size() ? locs[0].frameOffset : -1;
2374                         currentEnclosure->addField( fName, memberType, offset_to_use);
2375                         dwarf_printf("%s[%d]:  new field: [%s] %s\n", FILE__, __LINE__, 
2376                                         memberType ? memberType->getName().c_str() : "no_type", fName.c_str());
2377                 }
2378         } 
2379         break;
2380
2381   case DW_TAG_const_type:
2382   case DW_TAG_packed_type:
2383   case DW_TAG_volatile_type: 
2384         {
2385                 dwarf_printf(" DW_TAG_const or DW_TAG_packed or DW_TAG_volatile \n");
2386     char * typeName = NULL;
2387     status = dwarf_diename( dieEntry, & typeName, NULL );
2388     DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2389
2390     /* Which type does it modify? */
2391     Dwarf_Attribute typeAttribute;
2392     status = dwarf_attr( dieEntry, DW_AT_type, & typeAttribute, NULL );
2393
2394     int typeSize = 0;
2395     Dwarf_Off typeOffset;
2396     Type * typeModified = NULL;
2397     if( status == DW_DLV_NO_ENTRY ) {
2398       /* Presumably, a pointer or reference to void. */
2399       typeModified = tc->findType( "void" );
2400     } else {                    
2401       status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
2402       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2403       //parsing_printf("%s/%d: %s/%d\n",
2404       //                           __FILE__, __LINE__, typeName, typeOffset);
2405       typeModified = tc->findOrCreateType( (int) typeOffset );
2406       typeSize = typeModified->getSize();
2407
2408       dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
2409     } /* end if typeModified is not void */
2410
2411     string tName;
2412     if(!typeName){
2413       switch(dieTag){
2414       case DW_TAG_const_type:
2415         tName = "const " + typeModified->getName();
2416         break;
2417       case DW_TAG_packed_type:
2418         tName = "packed " + typeModified->getName();
2419         break;
2420       case DW_TAG_volatile_type:
2421         tName = "volatile " + typeModified->getName();
2422         break;
2423       }
2424     }
2425     else
2426       // I'm taking out the type qualifiers for right now
2427       tName = convertCharToString(typeName);
2428
2429     typeTypedef * modifierType = new typeTypedef((typeId_t) dieOffset, typeModified, tName);
2430     assert( modifierType != NULL );
2431     // //bperr ( "Adding modifier type '%s' (%lu) modifying (%lu)\n", typeName, (unsigned long)dieOffset, (unsigned long)typeOffset );
2432     modifierType = tc->addOrUpdateType( modifierType );
2433     dwarf_dealloc( dbg, typeName, DW_DLA_STRING );
2434   } break;
2435
2436   case DW_TAG_subroutine_type:
2437     /* If the pointer specifies argument types, this DIE has
2438        children of those types. */
2439   case DW_TAG_ptr_to_member_type:
2440   case DW_TAG_pointer_type:
2441   case DW_TAG_reference_type: 
2442         {
2443                 dwarf_printf(" DW_TAG_subroutine or DW_TAG_ptr_to_member or DW_TAG_pointer or DW_TAG_reference \n");
2444     char * typeName = NULL;
2445     status = dwarf_diename( dieEntry, & typeName, NULL );
2446     DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2447
2448     /* To which type does it point? */
2449     Dwarf_Attribute typeAttribute;
2450     status = dwarf_attr( dieEntry, DW_AT_type, & typeAttribute, NULL );
2451     DWARF_NEXT_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2452
2453     Dwarf_Off typeOffset = 0;
2454     Type * typePointedTo = NULL;
2455     if( status == DW_DLV_NO_ENTRY ) {
2456       /* Presumably, a pointer or reference to void. */
2457       typePointedTo = tc->findType("void");
2458     } else {                    
2459       status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
2460       DWARF_NEXT_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2461       //parsing_printf("%s/%d: %s/%d\n",
2462       //                           __FILE__, __LINE__, typeName, typeOffset);
2463       typePointedTo = tc->findOrCreateType( (int) typeOffset );
2464
2465       dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
2466     } /* end if typePointedTo is not void */
2467
2468     Type * indirectType = NULL;
2469     std::string tName = convertCharToString(typeName);
2470     switch ( dieTag ) {
2471     case DW_TAG_subroutine_type:
2472       indirectType = new typeFunction((typeId_t) dieOffset, typePointedTo, tName);
2473       indirectType = tc->addOrUpdateType((typeFunction *) indirectType );
2474       break;
2475     case DW_TAG_ptr_to_member_type:
2476     case DW_TAG_pointer_type:
2477       indirectType = new typePointer((typeId_t) dieOffset, typePointedTo, tName);
2478       indirectType = tc->addOrUpdateType((typePointer *) indirectType );
2479       break;
2480     case DW_TAG_reference_type:
2481       indirectType = new typeRef((typeId_t) dieOffset, typePointedTo, tName);
2482       indirectType = tc->addOrUpdateType((typeRef *) indirectType );
2483       break;
2484     }
2485
2486     assert( indirectType != NULL );
2487     dwarf_printf( "Added indirect type '%s' (%lu) pointing to (%lu)\n", typeName, (unsigned long)dieOffset, (unsigned long)typeOffset );
2488
2489     dwarf_dealloc( dbg, typeName, DW_DLA_STRING );
2490   } break;
2491
2492   case DW_TAG_variant_part:
2493     /* We don't support this (Pascal) type. */
2494                 dwarf_printf(" DW_TAG_variant_part \n");
2495                 break;
2496   case DW_TAG_string_type:
2497                 dwarf_printf(" DW_TAG_string \n");
2498                 break;
2499     /* We don't support this (FORTRAN) type. */
2500   default:
2501     /* Nothing of interest. */
2502     // //bperr ( "Entry %lu with tag 0x%x ignored.\n", (unsigned long)dieOffset, dieTag );
2503     dwarf_printf( "Entry %lu with tag 0x%x ignored.\n", (unsigned long)dieOffset, dieTag );
2504
2505     break;
2506   } /* end dieTag switch */
2507
2508   if (!walk_error)
2509   {
2510           /* Recurse to its child, if any. */
2511           Dwarf_Die childDwarf;
2512           status = dwarf_child( dieEntry, & childDwarf, NULL );
2513           DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2514
2515           if ( status == DW_DLV_OK && parsedChild == false ) 
2516           {
2517                   dwarf_printf( "Start walkDwarvenTree to child of  %lu with tag 0x%x \n", (unsigned long)dieOffset, dieTag );
2518                   bool result = walkDwarvenTree( dbg, childDwarf, module, objFile, cuOffset, 
2519                                   srcFiles, lowpc, newFunction, newCommonBlock, 
2520                                   newEnum, newEnclosure, true, depth+1 );
2521                   if (!result) 
2522                   {
2523                           dwarf_printf("[%s:%u] - Failed to walk dwarven tree\n", 
2524                                           __FILE__, __LINE__);
2525                           if (depth != 1)
2526                                   return false;
2527                   }
2528           }
2529   }
2530
2531   if (parseSibling == true) 
2532   {
2533           /* Recurse to its first sibling, if any. */
2534           Dwarf_Die siblingDwarf;
2535           status = dwarf_siblingof( dbg, dieEntry, & siblingDwarf, NULL );
2536           DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2537
2538           /* Deallocate the entry we just parsed. */
2539           dwarf_dealloc( dbg, dieEntry, DW_DLA_DIE );
2540
2541           if ( status == DW_DLV_OK ) 
2542           {
2543                   /* Do the tail-call optimization by hand. */
2544                   dieEntry = siblingDwarf;
2545                   dwarf_printf( "Start walkDwarvenTree to sibling of  %lu with tag 0x%x  - tail recursion \n", (unsigned long)dieOffset, dieTag);
2546                   goto tail_recursion;
2547           }
2548   }
2549
2550   /* When would we return false? :) */
2551   return true;
2552 } /* end walkDwarvenTree() */
2553
2554 extern void pd_dwarf_handler( Dwarf_Error, Dwarf_Ptr );
2555
2556 void Object::parseDwarfTypes( Symtab *objFile) 
2557 {
2558         // Man do we do to a lot of trouble for this...
2559         /*      
2560                 assert( moduleTypes );
2561
2562                 if ( moduleTypes->dwarfParsed() ) {
2563                 dwarf_printf( "%s[%d]: already parsed %s, moduleTypes = %p\n", __FILE__, __LINE__, fileName, moduleTypes );
2564                 std::vector<Symbol *> * bpfuncs = getProcedures( true );
2565                 assert( bpfuncs );
2566                 for( unsigned int i = 0; i < bpfuncs->size(); i++ ) {
2567                 (*bpfuncs)[i]->fixupUnknown( this );
2568                 }
2569                 return;
2570                 }
2571          */             
2572         dwarf_printf( "%s[%d]: parsing %s...\n", __FILE__, __LINE__, objFile->file().c_str() );
2573
2574         /* Start the dwarven debugging. */
2575         Module *mod = NULL, *fixUnknownMod = NULL;
2576
2577         Dwarf_Debug *dbg_ptr = dwarf.dbg();
2578         DWARF_RETURN_IF( !dbg_ptr, "%s[%d]: error initializing libdwarf.\n", 
2579                         __FILE__, __LINE__ );
2580         Dwarf_Debug &dbg = *dbg_ptr;
2581
2582         /* Iterate over the compilation-unit headers. */
2583         Dwarf_Unsigned hdr;
2584
2585         while ( dwarf_next_cu_header( dbg, NULL, NULL, NULL, NULL, & hdr, NULL ) == DW_DLV_OK ) 
2586         {
2587                 /* Obtain the module DIE. */
2588                 Dwarf_Die moduleDIE;
2589                 int status = dwarf_siblingof( dbg, NULL, &moduleDIE, NULL );
2590                 DWARF_RETURN_IF( status != DW_DLV_OK, 
2591                                 "%s[%d]: error finding next CU header.\n", __FILE__, __LINE__ );
2592
2593                 /* Make sure we've got the right one. */
2594                 Dwarf_Half moduleTag;
2595                 status = dwarf_tag( moduleDIE, & moduleTag, NULL );
2596                 DWARF_RETURN_IF( status != DW_DLV_OK, 
2597                                 "%s[%d]: error acquiring CU header tag.\n", __FILE__, __LINE__ );
2598                 assert( moduleTag == DW_TAG_compile_unit );
2599
2600                 /* We may need this later. */
2601                 Dwarf_Off cuOffset;
2602                 status = dwarf_dieoffset( moduleDIE, & cuOffset, NULL );
2603                 DWARF_RETURN_IF( status != DW_DLV_OK, 
2604                                 "%s[%d]: error acquiring CU header offset.\n", __FILE__, __LINE__ );
2605
2606                 /* Extract the name of this module. */
2607                 char * moduleName;
2608                 status = dwarf_diename( moduleDIE, & moduleName, NULL );
2609
2610                 if ( status == DW_DLV_NO_ENTRY ) 
2611                 {
2612                         moduleName = strdup( "{ANONYMOUS}" );
2613                         assert( moduleName != NULL );
2614                 }
2615
2616                 DWARF_RETURN_IF( status == DW_DLV_ERROR, 
2617                                 "%s[%d]: error acquiring module name.\n", __FILE__, __LINE__ );
2618
2619                 dwarf_printf( "%s[%d]: considering compilation unit '%s'\n", 
2620                                 __FILE__, __LINE__, moduleName );
2621
2622                 /* Set the language, if any. */
2623                 Dwarf_Attribute languageAttribute;
2624                 status = dwarf_attr( moduleDIE, DW_AT_language, & languageAttribute, NULL );
2625
2626                 DWARF_RETURN_IF( status == DW_DLV_ERROR, 
2627                                 "%s[%d]: error acquiring language attribute.\n", __FILE__, __LINE__ );
2628
2629                 //      /* Set the lowPC, if any. */
2630                 //      Dwarf_Attribute lowPCAttribute;
2631                 //      status = dwarf_attr( moduleDIE, DW_AT_low_pc, & lowPCAttribute, NULL );
2632                 //      DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error acquiring language attribute.\n", __FILE__, __LINE__ );
2633
2634                 Dwarf_Addr lowPCdwarf = 0;
2635                 Address lowpc = 0;
2636                 status = dwarf_lowpc( moduleDIE, &lowPCdwarf, NULL );
2637                 if ( status == DW_DLV_OK)
2638                 {
2639                         lowpc = (Address)lowPCdwarf;
2640                 }
2641
2642                 //      status = dwarf_formaddr( lowPCAttribute, &lowPCdwarf, NULL );
2643                 //      if(status == DW_DLV_OK)
2644                 //          lowpc = (Address)lowPCdwarf;
2645
2646                 /* Iterate over the tree rooted here; walkDwarvenTree() deallocates the passed-in DIE. */
2647                 if (!objFile->findModuleByName(mod, moduleName))
2648                 {
2649                         std::string modName = moduleName;
2650                         std::string fName = extract_pathname_tail(modName);
2651
2652                         if (!objFile->findModuleByName(mod, fName))
2653                         {
2654                                 modName = objFile->file();
2655
2656                                 if (!objFile->findModuleByName(mod, modName)) 
2657                                 {
2658                mod = objFile->getDefaultModule();
2659                                 }
2660                         }
2661                 }
2662
2663                 if (!fixUnknownMod)
2664                         fixUnknownMod = mod;
2665
2666                 Dwarf_Signed cnt;
2667                 char **srcfiles;
2668                 status = dwarf_srcfiles(moduleDIE, &srcfiles,&cnt, NULL);
2669                 DWARF_RETURN_IF( status == DW_DLV_ERROR, 
2670                                 "%s[%d]: error acquiring source file names.\n", __FILE__, __LINE__ );
2671
2672                 dwarf_printf( "%s[%d]: Start walkDwarvenTree for module '%s' \n", 
2673                                 __FILE__, __LINE__, moduleName );
2674
2675                 if ( !walkDwarvenTree( dbg, moduleDIE, mod, objFile, cuOffset, srcfiles, lowpc) ) 
2676                 {
2677                         enclosureMap.clear();
2678                         //bpwarn ( "Error while parsing DWARF info for module '%s'.\n", moduleName );
2679                         dwarf_printf( "%s[%d]: Error while parsing DWARF info for module '%s' \n", 
2680                                         __FILE__, __LINE__, moduleName );
2681                         return;
2682                 }
2683
2684                 enclosureMap.clear();
2685                 dwarf_printf( "%s[%d]: Done walkDwarvenTree for module '%s' \n", 
2686                                 __FILE__, __LINE__, moduleName );
2687
2688                 if (status == DW_DLV_OK)
2689                 {
2690                         for (unsigned i = 0; i < cnt; ++i) 
2691                         {
2692                                 /* use srcfiles[i] */
2693                                 dwarf_dealloc(dbg, srcfiles[i], DW_DLA_STRING);
2694                         }
2695                         dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST);
2696                 }
2697
2698                 dwarf_dealloc( dbg, moduleName, DW_DLA_STRING );
2699         } /* end iteration over compilation-unit headers. */
2700
2701         if (!fixUnknownMod)
2702                 return;
2703
2704         /* Fix type list. */
2705         typeCollection *moduleTypes = typeCollection::getModTypeCollection(fixUnknownMod);
2706         assert(moduleTypes);
2707         dyn_hash_map< int, Type * >::iterator typeIter =  moduleTypes->typesByID.begin();
2708         for (;typeIter!=moduleTypes->typesByID.end();typeIter++)
2709         {
2710                 typeIter->second->fixupUnknowns(fixUnknownMod);
2711         } /* end iteratation over types. */
2712
2713         /* Fix the types of variabls. */   
2714         std::string variableName;
2715         dyn_hash_map< std::string, Type * >::iterator variableIter = moduleTypes->globalVarsByName.begin();
2716         for (;variableIter!=moduleTypes->globalVarsByName.end();variableIter++)
2717         { 
2718                 if (variableIter->second->getDataClass() == dataUnknownType && 
2719                                 moduleTypes->findType( variableIter->second->getID() ) != NULL ) 
2720                 {
2721                         moduleTypes->globalVarsByName[ variableIter->first ] 
2722                                 = moduleTypes->findType( variableIter->second->getID() );
2723                 } /* end if data class is unknown but the type exists. */
2724         } /* end iteration over variables. */
2725
2726
2727         moduleTypes->setDwarfParsed();
2728 } /* end parseDwarfTypes() */
2729
2730 #if defined(arch_x86) || defined(arch_x86_64)
2731 Dyninst::MachRegister DwarfToDynReg(Dwarf_Signed reg, int word_size = 4)
2732 {
2733
2734    if (word_size == 4) {
2735       //They match.  Yea!
2736       return (Dyninst::MachRegister) reg;
2737    }
2738    switch (reg) {
2739       case 0: return x86_64::RAX;
2740       case 1: return x86_64::RDX;
2741       case 2: return x86_64::RCX;
2742       case 3: return x86_64::RBX;
2743       case 4: return x86_64::RSI;
2744       case 5: return x86_64::RDI;
2745       case 6: return x86_64::RBP;
2746       case 7: return x86_64::RSP;
2747       default:
2748          //The rest match
2749          return (Dyninst::MachRegister) reg;
2750    }
2751 }
2752
2753 Dwarf_Signed DynToDwarfReg(Dyninst::MachRegister reg, int word_size = 4)
2754 {
2755
2756    if (word_size == 4) {
2757       return (Dwarf_Signed) (reg & 0xf);
2758    }
2759    switch (reg & 0xf) {
2760       case x86_64::RAX: return (Dwarf_Signed) 0;
2761       case x86_64::RCX: return (Dwarf_Signed) 2;
2762       case x86_64::RDX: return (Dwarf_Signed) 1;
2763       case x86_64::RBX: return (Dwarf_Signed) 3;
2764       case x86_64::RSP: return (Dwarf_Signed) 7;
2765       case x86_64::RBP: return (Dwarf_Signed) 6;
2766       case x86_64::RSI: return (Dwarf_Signed) 4;
2767       case x86_64::RDI: return (Dwarf_Signed) 5;
2768       default:
2769          //The rest match
2770          return (Dwarf_Signed) (reg & 0xf);
2771    }
2772 }
2773 #else
2774 Dyninst::MachRegister DwarfToDynReg(Dwarf_Signed, int word_size = 4)
2775 {
2776   assert(0);
2777   return (Dyninst::MachRegister) word_size;
2778 }
2779
2780 Dwarf_Signed DynToDwarfReg(Dyninst::MachRegister, int word_size = 4)
2781 {
2782   assert(0);  
2783   return (Dwarf_Signed) word_size;
2784 }
2785 #endif
2786
2787 bool Object::hasFrameDebugInfo()
2788 {
2789         dwarf.setupFdeData();
2790         return (dwarf.fde_data.size() != 0);
2791 }
2792
2793 bool Object::getRegValueAtFrame(Address pc, 
2794                 Dyninst::MachRegister reg, 
2795                 Dyninst::MachRegisterVal &reg_result,
2796                 MemRegReader *reader)
2797 {
2798         int result;
2799         Dwarf_Fde fde;
2800         Dwarf_Addr lowpc, hipc;
2801         Dwarf_Error err;
2802
2803         /**
2804          * Initialize the FDE and CIE data.  This is only really done once, 
2805          * after which setupFdeData will immediately return.
2806     **/
2807    dwarf.setupFdeData();
2808    if (!dwarf.fde_data.size()) {
2809       setSymtabError(Bad_Frame_Data);
2810       return false;
2811    }
2812
2813
2814    /**
2815     * Get the FDE at this PC.  The FDE contains the rules for getting
2816     * registers at the given PC in this frame.
2817     **/
2818    bool found = false;
2819    unsigned cur_fde;
2820    for (cur_fde=0; cur_fde<dwarf.fde_data.size(); cur_fde++)
2821    {
2822       result = dwarf_get_fde_at_pc(dwarf.fde_data[cur_fde].fde_data, 
2823                                    (Dwarf_Addr) pc, &fde, &lowpc, &hipc, &err);
2824       if (result == DW_DLV_ERROR)
2825       {
2826          setSymtabError(Bad_Frame_Data);
2827          return false;
2828       }
2829       else if (result == DW_DLV_OK) {
2830          found = true;
2831          break;
2832       }
2833    }
2834    if (!found)
2835    {
2836       setSymtabError(No_Frame_Entry);
2837       return false;
2838    }
2839
2840    Dwarf_Half dwarf_reg;
2841    if (reg == Dyninst::MachRegReturn) {
2842       /**
2843        * We should be getting the return address for the stack frame.  
2844        * This is treated as a virtual register in the
2845        * FDE.  We can look up the virtual register in the CIE.
2846        **/
2847       Dwarf_Cie cie;
2848       result = dwarf_get_cie_of_fde(fde, &cie, &err);
2849       if (result != DW_DLV_OK) {
2850          setSymtabError(Bad_Frame_Data);
2851          return false;
2852       }
2853
2854       Dwarf_Unsigned bytes_in_cie;
2855       result = dwarf_get_cie_info(cie, &bytes_in_cie, NULL, NULL, NULL, NULL, 
2856                                   &dwarf_reg, NULL, NULL, &err);
2857       if (result != DW_DLV_OK) {
2858          setSymtabError(Bad_Frame_Data);
2859          return false;
2860       }
2861    }
2862    else if (reg == Dyninst::MachRegFrameBase) {
2863       dwarf_reg = DW_FRAME_CFA_COL3;
2864    }
2865    else {
2866       dwarf_reg = DynToDwarfReg(reg, getAddressWidth());
2867    }
2868
2869    Dwarf_Small value_type;
2870    Dwarf_Signed offset_relevant, register_num, offset_or_block_len;
2871    Dwarf_Ptr block_ptr;
2872    Dwarf_Addr row_pc;
2873
2874    /**
2875     * Decode the rule that describes how to get dwarf_reg at pc.
2876     **/
2877    if (dwarf_reg != DW_FRAME_CFA_COL3) {
2878       result = dwarf_get_fde_info_for_reg3(fde, dwarf_reg, pc, &value_type, 
2879                                            &offset_relevant, &register_num,
2880                                            &offset_or_block_len,
2881                                            &block_ptr, &row_pc, &err);
2882    }
2883    else {
2884       result = dwarf_get_fde_info_for_cfa_reg3(fde, pc, &value_type, 
2885                                                &offset_relevant, &register_num,
2886                                                &offset_or_block_len,
2887                                                &block_ptr, &row_pc, &err);
2888    }
2889    if (result == DW_DLV_ERROR) {
2890       setSymtabError(Bad_Frame_Data);
2891       return false;
2892    }
2893
2894    /**
2895     * Interpret the rule and turn it into a real value.
2896     **/
2897    unsigned word_size = addressWidth_nbytes;
2898
2899    Dyninst::Address res_addr = 0;
2900    Dyninst::MachRegisterVal register_val;
2901    
2902    if (value_type == DW_EXPR_OFFSET || value_type == DW_EXPR_VAL_OFFSET)
2903    {
2904       if (register_num == DW_FRAME_CFA_COL3) {
2905          bool bresult = getRegValueAtFrame(pc, Dyninst::MachRegFrameBase, 
2906                                            register_val, reader);
2907          if (!bresult) 
2908             return false;
2909       }
2910       else if (register_num == DW_FRAME_SAME_VAL) {
2911          bool bresult = reader->GetReg(reg, register_val);
2912          if (!bresult) {
2913             setSymtabError(Frame_Read_Error);
2914             return false;
2915          }
2916          reg_result = register_val;
2917          return true;
2918       }
2919       else {
2920          Dyninst::MachRegister dyn_registr = DwarfToDynReg(register_num, 
2921                                                            getAddressWidth());
2922          bool bresult = reader->GetReg(dyn_registr, register_val);
2923          if (!bresult) {
2924             setSymtabError(Frame_Read_Error);
2925             return false;
2926          }
2927       }
2928    }
2929
2930    if ((value_type == DW_EXPR_VAL_OFFSET) || 
2931        (value_type == DW_EXPR_OFFSET && dwarf_reg == DW_FRAME_CFA_COL3)) {
2932       assert(offset_relevant);
2933       reg_result = (Dyninst::MachRegisterVal) (register_val + offset_or_block_len);
2934       return true;
2935    }
2936    else if (value_type == DW_EXPR_OFFSET && offset_relevant) {
2937       res_addr = (Dyninst::Address) (register_val + offset_or_block_len);
2938    }
2939    else if (value_type == DW_EXPR_OFFSET && !offset_relevant)
2940    {
2941       reg_result = register_val;
2942       return true;
2943    } 
2944    else if (value_type == DW_EXPR_EXPRESSION || value_type == DW_EXPR_EXPRESSION)
2945    {
2946       //TODO: Handle expressions
2947       return false;
2948    }
2949    else
2950    {
2951       setSymtabError(Bad_Frame_Data);
2952       return false;
2953    }
2954    
2955    assert(res_addr);
2956    bool bresult = false;
2957    if (word_size == 4) {
2958       uint32_t i;
2959       bresult = reader->ReadMem(res_addr, &i, word_size);
2960       reg_result = (Dyninst::MachRegisterVal) i;
2961    }
2962    else if (word_size == 8) {
2963       uint64_t i;
2964       bresult = reader->ReadMem(res_addr, &i, word_size);
2965       reg_result = (Dyninst::MachRegisterVal) i;
2966    }
2967    if (!bresult) {
2968       setSymtabError(Frame_Read_Error);
2969       return false;
2970    }
2971
2972    return true;
2973 }
2974
2975 DwarfHandle::DwarfHandle(Object *obj_) :
2976    fde_dwarf_status(dwarf_status_uninitialized),
2977    init_dwarf_status(dwarf_status_uninitialized),
2978    obj(obj_)
2979 {
2980    assert(obj);
2981 }
2982
2983 Dwarf_Debug *DwarfHandle::dbg()
2984 {
2985    int status;
2986    Dwarf_Error err;
2987    if (init_dwarf_status == dwarf_status_ok) {
2988       return &dbg_data;
2989    }
2990
2991    if (init_dwarf_status == dwarf_status_error) {
2992       return NULL;
2993    }
2994    
2995    status = dwarf_elf_init(obj->elfHdrForDebugInfo.e_elfp(), DW_DLC_READ, 
2996                            &pd_dwarf_handler, obj->getErrFunc(), &dbg_data, &err);
2997    if (status != DW_DLV_OK) {
2998       init_dwarf_status = dwarf_status_error;
2999       return NULL;
3000    }
3001
3002    init_dwarf_status = dwarf_status_ok;
3003    return &dbg_data;
3004 }
3005
3006 void DwarfHandle::setupFdeData()
3007 {
3008    Dwarf_Error err;
3009
3010    if (fde_dwarf_status == dwarf_status_ok || 
3011        fde_dwarf_status == dwarf_status_error)
3012       return;
3013
3014    if (!dbg()) {
3015       fde_dwarf_status = dwarf_status_error;
3016       return;
3017    }
3018
3019    fde_cie_data fc;
3020    int result = dwarf_get_fde_list(dbg_data, 
3021                                    &fc.cie_data, &fc.cie_count,
3022                                    &fc.fde_data, &fc.fde_count,
3023                                    &err);
3024    if (result == DW_DLV_OK) {
3025       fde_data.push_back(fc);
3026    }
3027
3028    result = dwarf_get_fde_list_eh(dbg_data, 
3029                                   &fc.cie_data, &fc.cie_count,
3030                                   &fc.fde_data, &fc.fde_count,
3031                                   &err);
3032    if (result == DW_DLV_OK) {
3033       fde_data.push_back(fc);
3034    }
3035
3036    if (!fde_data.size()) {
3037       fde_dwarf_status = dwarf_status_error;
3038    }
3039
3040    fde_dwarf_status = dwarf_status_ok;
3041 }
3042
3043 DwarfHandle::~DwarfHandle()
3044 {
3045    Dwarf_Error err;
3046
3047    for (unsigned i=0; i<fde_data.size(); i++)
3048    {
3049       if (fde_dwarf_status == dwarf_status_ok) {
3050          dwarf_fde_cie_list_dealloc(dbg_data, 
3051                                     fde_data[i].cie_data, fde_data[i].cie_count, 
3052                                     fde_data[i].fde_data, fde_data[i].fde_count);
3053       }
3054    }
3055    if (init_dwarf_status == dwarf_status_ok) {
3056       dwarf_finish(dbg_data, &err);
3057    }
3058 }