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