make variable and parameter lists annotations to class Symbol instead of class members
[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                              
32 #include "elf.h"
33 #include "libelf.h"
34 #include "dwarf.h"
35 #include "libdwarf.h"
36
37 #include "Type.h"
38 #include "Symbol.h"
39 #include "Symtab.h"
40 #include "symtabAPI/src/Object.h"
41 #include "symtabAPI/src/Collections.h"
42 #include "common/h/pathName.h"
43
44 #include <stdarg.h>
45 int dwarf_printf(const char *format, ...);
46
47 using namespace Dyninst;
48 using namespace Dyninst::SymtabAPI;
49
50 /* For location decode. */
51 #include <stack>
52
53 // on 64-bit x86_64 targets, the DWARF register number does not
54 // correspond to the machine encoding. See the AMD-64 ABI.
55
56
57 #if defined(arch_x86_64)
58 // We can only safely map the general purpose registers (0-7 on ia-32,
59 // 0-15 on amd-64)
60 #define IA32_MAX_MAP 7
61 #define AMD64_MAX_MAP 15
62 static int const amd64_register_map[] =
63 {
64    0,  // RAX
65    2,  // RDX
66    1,  // RCX
67    3,  // RBX
68    6,  // RSI
69    7,  // RDI
70    5,  // RBP
71    4,  // RSP
72    8, 9, 10, 11, 12, 13, 14, 15    // gp 8 - 15
73       /* This is incomplete. The x86_64 ABI specifies a mapping from
74          dwarf numbers (0-66) to ("architecture number"). Without a
75          corresponding mapping for the SVR4 dwarf-machine encoding for
76          IA-32, however, it is not meaningful to provide this mapping. */
77 };
78
79 int Register_DWARFtoMachineEnc32(int n)
80 {
81    if (n > IA32_MAX_MAP) {
82       dwarf_printf("%s[%d]: unexpected map lookup for DWARF register %d\n",
83             __FILE__,__LINE__,n);
84    }
85    return n;
86 }
87
88
89 int Register_DWARFtoMachineEnc64(int n)
90 {
91    if (n <= AMD64_MAX_MAP)
92       return amd64_register_map[n];
93    else {
94       dwarf_printf("%s[%d]: unexpected map lookup for DWARF register %d\n",
95             __FILE__,__LINE__,n);
96       return n;
97    }
98 }
99
100 #define DWARF_TO_MACHINE_ENC(n, proc) \
101    ((proc->getAddressWidth() == 4) ? Register_DWARFtoMachineEnc32(n) : Register_DWARFtoMachineEnc64(n))
102 #else
103 #define DWARF_TO_MACHINE_ENC(n, proc) (n)
104 #endif
105
106                                                                        /*
107 #define DWARF_FALSE_IF(condition,...) \
108 if ( condition ) { //bpwarn ( __VA_ARGS__ ); return false; }
109 #define DWARF_RETURN_IF(condition,...) \
110 if ( condition ) { //bpwarn ( __VA_ARGS__ ); return; }
111 #define DWARF_NULL_IF(condition,...) \
112 if ( condition ) { //bpwarn ( __VA_ARGS__ ); return NULL; }
113                                                                         */
114
115 #define DWARF_FALSE_IF(condition,...) \
116       if ( condition ) { return false; }
117 #define DWARF_RETURN_IF(condition,...) \
118       if ( condition ) { return; }
119 #define DWARF_NULL_IF(condition,...) \
120       if ( condition ) { return NULL; }
121
122 std::string convertCharToString(char *ptr)
123 {
124    std::string str;
125    if (ptr)
126       str = ptr;
127    else
128       str = "";
129    return str;  
130 }
131
132 /* A bound attribute can be either (a constant) or (a reference
133    to a DIE which (describes an object containing the bound value) or
134    (a constant value itself)). */
135
136 bool decipherBound( Dwarf_Debug & dbg, Dwarf_Attribute boundAttribute, std::string &boundString ) {
137    Dwarf_Half boundForm;
138    int status = dwarf_whatform( boundAttribute, & boundForm, NULL );
139    DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: unable to decode form of bounds attribute.\n", __FILE__, __LINE__ );
140
141    switch( boundForm ) {
142       case DW_FORM_data1:
143       case DW_FORM_data2:
144       case DW_FORM_data4:
145       case DW_FORM_data8:
146       case DW_FORM_sdata:
147       case DW_FORM_udata: 
148          {
149             Dwarf_Unsigned constantBound;
150             status = dwarf_formudata( boundAttribute, & constantBound, NULL );
151             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: unable decode unsigned data in bounds attribute.\n", __FILE__, __LINE__ );
152             char bString[40];
153             sprintf(bString, "%lu", (unsigned long)constantBound);
154             boundString = bString;
155             return true;
156          } break;
157
158       case DW_FORM_ref_addr:
159       case DW_FORM_ref1:
160       case DW_FORM_ref2:
161       case DW_FORM_ref4:
162       case DW_FORM_ref8:
163       case DW_FORM_ref_udata: 
164          {
165             /* Acquire the referenced DIE. */
166             Dwarf_Off boundOffset;
167             status = dwarf_global_formref( boundAttribute, & boundOffset, NULL );
168             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: unable decode reference in bounds attribute.\n", __FILE__, __LINE__ );
169
170             Dwarf_Die boundEntry;
171             status = dwarf_offdie( dbg, boundOffset, & boundEntry, NULL );
172             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: unable dereference DWARF pointer in bounds attribute.\n", __FILE__, __LINE__ );
173
174             /* Does it have a name? */
175             char * boundName = NULL;
176             status = dwarf_diename( boundEntry, & boundName, NULL );
177             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error checking for name of bounds attribute.\n", __FILE__, __LINE__ );
178
179             if ( status == DW_DLV_OK ) {
180                boundString = boundName;
181
182                dwarf_dealloc( dbg, boundName, DW_DLA_STRING );
183                return true;
184             }
185
186             /* Does it describe a nameless constant? */
187             Dwarf_Attribute constBoundAttribute;
188             status = dwarf_attr( boundEntry, DW_AT_const_value, & constBoundAttribute, NULL );
189             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error checking for constant value of bounds attribute.\n", __FILE__, __LINE__ );
190
191             if ( status == DW_DLV_OK ) {
192                Dwarf_Unsigned constBoundValue;
193                status = dwarf_formudata( constBoundAttribute, & constBoundValue, NULL );
194                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error decoding unsigned data of bounds constant value attribute.\n", __FILE__, __LINE__ );
195
196                char bString[40];
197                sprintf(bString, "%lu", (unsigned long)constBoundValue);
198                boundString = bString;
199
200                dwarf_dealloc( dbg, boundEntry, DW_DLA_DIE );
201                dwarf_dealloc( dbg, constBoundAttribute, DW_DLA_ATTR );
202                return true;
203             }
204
205             return false;
206          } break;
207       case DW_FORM_block:
208       case DW_FORM_block1:
209          {
210             /* PGI extends DWARF to allow some bounds to be location lists.  Since we can't
211                do anything sane with them, ignore them. */
212             // Dwarf_Locdesc * locationList;
213             // Dwarf_Signed listLength;
214             // status = dwarf_loclist( boundAttribute, & locationList, & listLength, NULL );
215             boundString = "{PGI extension}";
216             return false;
217          } break;
218
219       default:
220          //bperr ( "Invalid bound form 0x%x\n", boundForm );
221          boundString = "{invalid bound form}";
222          return false;
223          break;
224    } /* end boundForm switch */
225 } /* end decipherBound() */
226
227 /* We don't have a sane way of dealing with DW_TAG_enumeration bounds, so
228    just put the name of the enumeration, or {enum} if none, in the string. */
229 void parseSubRangeDIE( Dwarf_Debug & dbg, Dwarf_Die subrangeDIE, 
230       std::string & loBound, std::string & hiBound, Module * module ) 
231 {
232    loBound = "{unknown or default}";
233    hiBound = "{unknown or default}";
234
235    /* Set the default lower bound, if we know it. */
236    switch ( module->language() ) {
237       case lang_Fortran:
238       case lang_Fortran_with_pretty_debug:
239       case lang_CMFortran:
240          loBound = "1";
241          break;
242       case lang_C:
243       case lang_CPlusPlus:
244          loBound = "0";
245          break;
246       default:
247          break;
248    } /* end default lower bound switch */
249
250    Dwarf_Half subrangeTag;
251    int status = dwarf_tag( subrangeDIE, & subrangeTag, NULL );
252    DWARF_RETURN_IF( status != DW_DLV_OK, "%s[%d]: unable to obtain tag of subrange DIE.\n", __FILE__, __LINE__ );
253
254    /* Could be an enumerated range. */
255    if ( subrangeTag == DW_TAG_enumeration_type ) {
256       /* FIXME? First child of enumeration type is lowest, last is highest. */
257       char * enumerationName = NULL;
258       status = dwarf_diename( subrangeDIE, & enumerationName, NULL );
259       DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error cehcking for name of enumeration.\n", __FILE__, __LINE__ );
260
261       if ( enumerationName != NULL ) {
262          loBound = enumerationName;
263          hiBound = enumerationName;
264       } else {
265          loBound = "{nameless enum lo}";
266          hiBound = "{nameless enum hi}";
267       }
268       dwarf_dealloc( dbg, enumerationName, DW_DLA_STRING );
269       return;
270    } /* end if an enumeration type */
271
272    /* Is a subrange type. */
273    DWARF_RETURN_IF( subrangeTag != DW_TAG_subrange_type, "%s[%d]: unknown tag while parsing subrange\n", __FILE__, __LINE__ );
274
275    /* Look for the lower bound. */
276    Dwarf_Attribute lowerBoundAttribute;
277    status = dwarf_attr( subrangeDIE, DW_AT_lower_bound, & lowerBoundAttribute, NULL );
278    DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error while checking for lower bound of subrange\n", __FILE__, __LINE__ );
279
280    if ( status == DW_DLV_OK ) {
281       decipherBound( dbg, lowerBoundAttribute, loBound );
282       dwarf_dealloc( dbg, lowerBoundAttribute, DW_DLA_ATTR );
283    } /* end if we found a lower bound. */
284
285    /* Look for the upper bound. */
286    Dwarf_Attribute upperBoundAttribute;
287    status = dwarf_attr( subrangeDIE, DW_AT_upper_bound, & upperBoundAttribute, NULL );
288    DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error while checking for upper bound of subrange\n", __FILE__, __LINE__ );
289    if ( status == DW_DLV_NO_ENTRY ) {
290       status = dwarf_attr( subrangeDIE, DW_AT_count, & upperBoundAttribute, NULL );
291       DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error while checking for count of subrange\n", __FILE__, __LINE__ );
292    }
293    if ( status == DW_DLV_OK ) {
294       decipherBound( dbg, upperBoundAttribute, hiBound );
295       dwarf_dealloc( dbg, upperBoundAttribute, DW_DLA_ATTR );
296    } /* end if we found an upper bound or count. */
297
298    /* Construct the range type. */
299    char * subrangeName = "{anonymous range}"; // type doesn't like NULL.
300    status = dwarf_diename( subrangeDIE, & subrangeName, NULL );
301    DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error while checking for name of subrange\n", __FILE__, __LINE__ );
302    int dwarvenName = status;
303
304    Dwarf_Off subrangeOffset;
305    status = dwarf_dieoffset( subrangeDIE, & subrangeOffset, NULL );
306    DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error dereferencing DWARF pointer\n", __FILE__, __LINE__ );
307
308    std::string srName = subrangeName;
309    Type * rangeType = new typeSubrange( (int) subrangeOffset, 0, atoi(loBound.c_str()), atoi(hiBound.c_str()), srName );
310    assert( rangeType != NULL );
311    rangeType = module->getModuleTypes()->addOrUpdateType( rangeType );
312    if ( dwarvenName == DW_DLV_OK ) { dwarf_dealloc( dbg, subrangeName, DW_DLA_STRING ); }       
313 } /* end parseSubRangeDIE() */
314
315 typeArray *parseMultiDimensionalArray( Dwarf_Debug & dbg, Dwarf_Die range, 
316       Type * elementType, Module * module ) 
317 {
318    char buf[32];
319    /* Get the (negative) typeID for this range/subarray. */
320    Dwarf_Off dieOffset;
321    int status = dwarf_dieoffset( range, & dieOffset, NULL );
322    DWARF_NULL_IF( status != DW_DLV_OK, "%s[%d]: error while parsing multidimensional array.\n", __FILE__, __LINE__ );
323
324    /* Determine the range. */
325    std::string loBound;
326    std::string hiBound;
327    parseSubRangeDIE( dbg, range, loBound, hiBound, module );
328
329    /* Does the recursion continue? */
330    Dwarf_Die nextSibling;
331    status = dwarf_siblingof( dbg, range, & nextSibling, NULL );
332    DWARF_NULL_IF( status == DW_DLV_ERROR, "%s[%d]: error checking for second dimension in array.\n", __FILE__, __LINE__ );
333
334    snprintf(buf, 31, "__array%d", (int) dieOffset);
335
336    if ( status == DW_DLV_NO_ENTRY ) {
337       /* Terminate the recursion by building an array type out of the elemental type.
338          Use the negative dieOffset to avoid conflicts with the range type created
339          by parseSubRangeDIE(). */
340       // N.B.  I'm going to ignore the type id, and just create an anonymous type here
341       std::string aName = convertCharToString(buf);
342       typeArray* innermostType = new typeArray( elementType, atoi( loBound.c_str() ), atoi( hiBound.c_str() ), aName );
343       assert( innermostType != NULL );
344       Type * typ = module->getModuleTypes()->addOrUpdateType( innermostType );
345       innermostType = dynamic_cast<typeArray *>(typ);
346       return innermostType;
347    } /* end base-case of recursion. */
348
349    /* If it does, build this array type out of the array type returned from the next recusion. */
350    typeArray * innerType = parseMultiDimensionalArray( dbg, nextSibling, elementType, module );
351    assert( innerType != NULL );
352    // same here - type id ignored    jmo
353    std::string aName = convertCharToString(buf);
354    typeArray * outerType = new typeArray( innerType, atoi(loBound.c_str()), atoi(hiBound.c_str()), aName);
355    assert( outerType != NULL );
356    Type *typ = module->getModuleTypes()->addOrUpdateType( outerType );
357    outerType = dynamic_cast<typeArray *>(typ);
358
359    dwarf_dealloc( dbg, nextSibling, DW_DLA_DIE );
360    return outerType;
361 } /* end parseMultiDimensionalArray() */
362
363 void deallocateLocationList( Dwarf_Debug & dbg, Dwarf_Locdesc * locationList, 
364       Dwarf_Signed listLength ) 
365 {
366    for( int i = 0; i < listLength; i++ ) {
367       dwarf_dealloc( dbg, locationList[i].ld_s, DW_DLA_LOC_BLOCK );
368    }
369    dwarf_dealloc( dbg, locationList, DW_DLA_LOCDESC );
370 } /* end deallocateLocationList() */
371
372 void deallocateLocationList( Dwarf_Debug & dbg, Dwarf_Locdesc ** locationList, 
373       Dwarf_Signed listLength ) 
374 {
375    for( int i = 0; i < listLength; i++ ) {
376       dwarf_dealloc( dbg, locationList[i]->ld_s, DW_DLA_LOC_BLOCK );
377       dwarf_dealloc( dbg, locationList[i], DW_DLA_LOCDESC );
378    }
379    dwarf_dealloc( dbg, locationList, DW_DLA_LIST );
380 } /* end deallocateLocationList() */
381
382 /* An investigative function. */
383 void dumpLocListAddrRanges( Dwarf_Locdesc * locationList, Dwarf_Signed listLength ) 
384 {
385    for( int i = 0; i < listLength; i++ ) {
386       Dwarf_Locdesc location = locationList[i];
387       fprintf( stderr, "0x%lx to 0x%lx; ", (Offset)location.ld_lopc, (Offset)location.ld_hipc );
388    }
389    fprintf( stderr, "\n" );
390 } /* end dumpLocListAddrRanges */
391
392 #if defined(arch_x86_64)
393 int convertFrameBaseToAST( Dwarf_Locdesc * locationList, Dwarf_Signed listLength, 
394       Symtab *proc /* process parameter only needed on x86_64*/) 
395 #else
396 int convertFrameBaseToAST( Dwarf_Locdesc * locationList, Dwarf_Signed listLength, 
397       Symtab * /* process parameter only needed on x86_64*/) 
398 #endif
399 {
400    /* Until such time as we see more-complicated location lists, assume single entries
401       consisting of a register name.  Using an AST for this is massive overkill, but if
402       we need to handle more complicated frame base calculations later, the infastructure
403       will be in place. */
404
405    /* There is only one location. */
406    if (listLength != 1) {
407       //bpwarn("%s[%d]: unable to handle location lists of more than one element in frame base.\n", __FILE__, __LINE__);
408       return -1 ;
409    }
410
411    Dwarf_Locdesc locationDescriptor = locationList[0];
412
413    /* It is defined by a single operation. */
414    if (locationDescriptor.ld_cents != 1) {
415       //bpwarn("%s[%d]: unable to handle multioperation locations in frame base.\n", __FILE__, __LINE__ );
416       return -1;
417    }
418    Dwarf_Loc location = locationDescriptor.ld_s[0];
419
420    /* That operation is naming a register. */
421    int registerNumber = 0;      
422    if ( DW_OP_reg0 <= location.lr_atom && location.lr_atom <= DW_OP_reg31 ) {
423       registerNumber = DWARF_TO_MACHINE_ENC(location.lr_atom - DW_OP_reg0,
424             proc);
425    }
426    else if ( DW_OP_breg0 <= location.lr_atom && location.lr_atom <= DW_OP_breg31 ) {
427       registerNumber = DWARF_TO_MACHINE_ENC(location.lr_atom - DW_OP_breg0,
428             proc);
429       if ( location.lr_number != 0 ) {
430          /* Actually, we should be able whip up an AST node for this. */
431          return -1;
432       }
433    }
434    else if ( location.lr_atom == DW_OP_regx ) {
435       registerNumber = DWARF_TO_MACHINE_ENC(location.lr_number,
436             proc);
437    }
438    else if ( location.lr_atom == DW_OP_bregx ) {
439       registerNumber = DWARF_TO_MACHINE_ENC(location.lr_number,
440             proc);
441       if ( location.lr_number2 != 0 ) {
442          /* Actually, we should be able whip up an AST node for this. */
443          return -1;
444       }
445    }
446    else {
447       return -1;
448    }
449
450    return registerNumber;
451
452    /* We have to make sure no arithmetic is actually done to the frame pointer,
453       so add zero to it and shove it in some other register. */
454    /*   AstNodePtr constantZero = AstNode::operandNode(AstNode::Constant, (void *)0);
455       AstNodePtr framePointer = AstNode::operandNode(AstNode::DataReg, (void *)(long unsigned int)registerNumber);
456       AstNodePtr moveFPtoDestination = AstNode::operatorNode(plusOp,
457       constantZero,
458       framePointer);
459
460       return moveFPtoDestination;
461     */
462 } /* end convertFrameBaseToAST(). */
463
464
465 #if defined(arch_x86_64)
466 bool decodeLocationListForStaticOffsetOrAddress( Dwarf_Locdesc **locationList, 
467       Dwarf_Signed listLength, 
468       Symtab * objFile, 
469       vector<loc_t *>*& locs,
470       long int * initialStackValue = NULL)
471 #else
472 bool decodeLocationListForStaticOffsetOrAddress( Dwarf_Locdesc **locationList, 
473       Dwarf_Signed listLength, 
474       Symtab *, 
475       vector<loc_t *>*& locs,  
476       long int * initialStackValue = NULL)
477 #endif
478 {
479    /* We make a few heroic assumptions about locations in this decoder.
480
481       We assume that all locations are either frame base-relative offsets,
482       encoded with DW_OP_fbreg, or are absolute addresses.  We assume these
483       locations are invariant with respect to the PC, which implies that all
484       location lists have a single entry.  We assume that no location is
485       calculated at run-time.
486
487       We make these assumptions to match the assumptions of the rest of
488       Dyninst, which makes no provision for pc-variant or run-time calculated
489       locations, aside from the frame pointer.  However, it assumes that a frame
490       pointer is readily available, which, on IA-64, it is not.  For that reason,
491       when we encounter a function with a DW_AT_frame_base (effectively all of them),
492       we do NOT use this decoder; we decode the location into an AST, which we
493       will use to calculate the frame pointer when asked to do frame-relative operations.
494       (These calculations will be invalid until the frame pointer is established,
495       which may require some fiddling with the location of the 'entry' instpoint.) */
496
497    /* We now parse the complete location list for variables and parameters within a
498     * function. We still ignore the location list defined for DW_AT_frame_base of the
499     * function as the frame pointer is readily available on all platforms(except for IA64)
500     * May be we would need to parse the location list for IA64 functions to store the 
501     * register numbers and offsets and use it based on the pc value. 
502     */
503    /*
504       DWARF_FALSE_IF( listLength != 1, "%s[%d]: unable to decode location lists of non-unit length.\n", __FILE__, __LINE__ );
505       if ( listLength != 1)
506       printf("%s[%d]: unable to decode location lists of non-unit length.\n", __FILE__, __LINE__ );
507     */
508    for(unsigned locIndex = 0 ; locIndex < listLength; locIndex++) {
509       bool isLocSet = false;
510       loc_t *loc = (loc_t *)malloc(sizeof(loc_t));
511       // Initialize location values.
512       loc->stClass = storageAddr;
513       loc->refClass = storageNoRef;
514       loc->reg = -1;
515
516       /* Initialize the stack. */
517       std::stack< long int > opStack = std::stack<long int>();
518       if ( initialStackValue != NULL ) { opStack.push( * initialStackValue ); }
519
520       /* There is only one location. */
521       Dwarf_Locdesc *location = locationList[locIndex];
522       loc->lowPC = (Offset)location->ld_lopc;
523       loc->hiPC = (Offset)location->ld_hipc;
524       Dwarf_Loc * locations = location->ld_s;
525       for( unsigned int i = 0; i < location->ld_cents; i++ ) {
526          /* Handle the literals w/o 32 case statements. */
527          if ( DW_OP_lit0 <= locations[i].lr_atom && locations[i].lr_atom <= DW_OP_lit31 ) {
528             dwarf_printf( "pushing named constant: %d\n", locations[i].lr_atom - DW_OP_lit0 );
529             opStack.push( locations[i].lr_atom - DW_OP_lit0 );
530             continue;
531          }
532
533          /* Haandle registers w/o 32 case statements. */
534          if ( DW_OP_reg0 <= locations[i].lr_atom && locations[i].lr_atom <= DW_OP_reg31 ) {
535             /* storageReg is unimplemented, so do an offset of 0 from the named register instead. */
536             dwarf_printf( "location is named register %d\n", DWARF_TO_MACHINE_ENC(locations[i].lr_atom - DW_OP_reg0, objFile) );
537             loc->stClass = storageRegOffset;
538             loc->refClass = storageNoRef;
539             loc->reg = DWARF_TO_MACHINE_ENC(locations[i].lr_atom - DW_OP_reg0, objFile);
540             loc->frameOffset = 0;
541             isLocSet = true;
542             break;
543          }      
544
545          /* Haandle registers w/o 32 case statements. */
546          if ( DW_OP_breg0 <= locations[i].lr_atom && locations[i].lr_atom <= DW_OP_breg31 ) {
547             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 );
548             loc->stClass = storageRegOffset;
549             loc->refClass = storageNoRef;
550             loc->reg = DWARF_TO_MACHINE_ENC(locations[i].lr_atom - DW_OP_breg0, objFile);
551             opStack.push( locations[i].lr_number );
552             locs->push_back(loc);
553             continue;
554          }
555
556          switch( locations[i].lr_atom ) {
557             case DW_OP_addr:
558             case DW_OP_const1u:
559             case DW_OP_const2u:
560             case DW_OP_const4u:
561             case DW_OP_const8u:
562             case DW_OP_constu:
563                dwarf_printf( "pushing unsigned constant %lu\n", (unsigned long)locations[i].lr_number );
564                opStack.push( (Dwarf_Unsigned)locations[i].lr_number );
565                break;
566
567             case DW_OP_const1s:
568             case DW_OP_const2s:
569             case DW_OP_const4s:
570             case DW_OP_const8s:
571             case DW_OP_consts:
572                dwarf_printf( "pushing signed constant %ld\n", (signed long)(locations[i].lr_number) );
573                opStack.push( (Dwarf_Signed)(locations[i].lr_number) );
574                break;
575
576             case DW_OP_regx:
577                /* storageReg is unimplemented, so do an offset of 0 from the named register instead. */
578                dwarf_printf( "location is register %d\n", DWARF_TO_MACHINE_ENC(locations[i].lr_number, objFile) );
579                loc->stClass = storageRegOffset;
580                loc->refClass = storageNoRef;
581                loc->reg = DWARF_TO_MACHINE_ENC(locations[i].lr_number, objFile); 
582                loc->frameOffset = 0;
583                isLocSet = true;
584                break;
585
586             case DW_OP_fbreg:
587                dwarf_printf( "setting storage class to frame base\n" );
588                //if ( storageClass != NULL ) { * storageClass = storageFrameOffset; }
589                loc->stClass = storageRegOffset;
590                loc->refClass = storageNoRef;
591                opStack.push( locations[i].lr_number );
592                break;
593
594             case DW_OP_bregx:
595                dwarf_printf( "setting storage class to register, regNum to %d\n", locations[i].lr_number );
596                loc->stClass = storageRegOffset;
597                loc->refClass = storageNoRef;
598                loc->reg = DWARF_TO_MACHINE_ENC( locations[i].lr_number, objFile );
599                loc->frameOffset = 0;
600                opStack.push( locations[i].lr_number2 );
601                break;
602
603             case DW_OP_dup:
604                DWARF_FALSE_IF( opStack.size() < 1, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
605                opStack.push( opStack.top() );
606                break;
607
608             case DW_OP_drop:
609                DWARF_FALSE_IF( opStack.size() < 1, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
610                opStack.pop();
611                break;
612
613             case DW_OP_pick: 
614                {
615                   /* Duplicate the entry at index locations[i].lr_number. */
616                   std::stack< long int > temp = std::stack< long int >();
617                   for( unsigned int j = 0; j < locations[i].lr_number; j++ ) {
618                      temp.push( opStack.top() ); opStack.pop();
619                   }
620                   long int dup = opStack.top();
621                   for( unsigned int j = 0; j < locations[i].lr_number; j++ ) {
622                      opStack.push( temp.top() ); temp.pop();
623                   }
624                   opStack.push( dup );
625                } break;
626
627             case DW_OP_over: 
628                {
629                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
630                   long int first = opStack.top(); opStack.pop();
631                   long int second = opStack.top(); opStack.pop();
632                   opStack.push( second ); opStack.push( first ); opStack.push( second );
633                } break;
634
635             case DW_OP_swap: 
636                {
637                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
638                   long int first = opStack.top(); opStack.pop();
639                   long int second = opStack.top(); opStack.pop();
640                   opStack.push( first ); opStack.push( second );
641                } break;
642
643             case DW_OP_rot: 
644                {
645                   DWARF_FALSE_IF( opStack.size() < 3, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
646                   long int first = opStack.top(); opStack.pop();
647                   long int second = opStack.top(); opStack.pop();
648                   long int third = opStack.top(); opStack.pop();
649                   opStack.push( first ); opStack.push( third ); opStack.push( second );
650                } break;
651
652             case DW_OP_abs: 
653                {
654                   DWARF_FALSE_IF( opStack.size() < 1, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
655                   long int top = opStack.top(); opStack.pop();
656                   opStack.push( abs( top ) );
657                } break;
658
659             case DW_OP_and: 
660                {
661                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
662                   long int first = opStack.top(); opStack.pop();
663                   long int second = opStack.top(); opStack.pop();
664                   opStack.push( second & first );
665                } break;
666
667             case DW_OP_div: 
668                {
669                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
670                   long int first = opStack.top(); opStack.pop();
671                   long int second = opStack.top(); opStack.pop();
672                   opStack.push( second / first );
673                } break;
674
675             case DW_OP_minus: 
676                {
677                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
678                   long int first = opStack.top(); opStack.pop();
679                   long int second = opStack.top(); opStack.pop();
680                   opStack.push( second - first );
681                } break;
682
683             case DW_OP_mod: 
684                {
685                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
686                   long int first = opStack.top(); opStack.pop();
687                   long int second = opStack.top(); opStack.pop();
688                   opStack.push( second % first );
689                } break;
690
691             case DW_OP_mul: 
692                {
693                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
694                   long int first = opStack.top(); opStack.pop();
695                   long int second = opStack.top(); opStack.pop();
696                   opStack.push( second * first );
697                } break;
698
699             case DW_OP_neg: 
700                {
701                   DWARF_FALSE_IF( opStack.size() < 1, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
702                   long int first = opStack.top(); opStack.pop();
703                   opStack.push( first * (-1) );
704                } break;
705
706             case DW_OP_not: 
707                {
708                   DWARF_FALSE_IF( opStack.size() < 1, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
709                   long int first = opStack.top(); opStack.pop();
710                   opStack.push( ~ first );
711                } break;
712
713             case DW_OP_or: 
714                {
715                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
716                   long int first = opStack.top(); opStack.pop();
717                   long int second = opStack.top(); opStack.pop();
718                   opStack.push( second | first );
719                } break;
720
721             case DW_OP_plus: 
722                {
723                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
724                   long int first = opStack.top(); opStack.pop();
725                   long int second = opStack.top(); opStack.pop();
726                   opStack.push( second + first );
727                } break;
728
729             case DW_OP_plus_uconst: 
730                {
731                   DWARF_FALSE_IF( opStack.size() < 1, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
732                   long int first = opStack.top(); opStack.pop();
733                   opStack.push( first + locations[i].lr_number );
734                } break;
735
736             case DW_OP_shl: 
737                {
738                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
739                   long int first = opStack.top(); opStack.pop();
740                   long int second = opStack.top(); opStack.pop();
741                   opStack.push( second << first );
742                } break;
743
744             case DW_OP_shr: 
745                {
746                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
747                   long int first = opStack.top(); opStack.pop();
748                   long int second = opStack.top(); opStack.pop();
749                   opStack.push( (long int)((unsigned long)second >> (unsigned long)first) );
750                } break;
751
752             case DW_OP_shra: 
753                {
754                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
755                   long int first = opStack.top(); opStack.pop();
756                   long int second = opStack.top(); opStack.pop();
757                   opStack.push( second >> first );
758                } break;
759
760             case DW_OP_xor: 
761                {
762                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
763                   long int first = opStack.top(); opStack.pop();
764                   long int second = opStack.top(); opStack.pop();
765                   opStack.push( second ^ first );
766                } break;
767
768             case DW_OP_le: 
769                {
770                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
771                   long int first = opStack.top(); opStack.pop();
772                   long int second = opStack.top(); opStack.pop();
773                   opStack.push( first <= second ? 1 : 0 );
774                } break;
775
776             case DW_OP_ge: 
777                {
778                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
779                   long int first = opStack.top(); opStack.pop();
780                   long int second = opStack.top(); opStack.pop();
781                   opStack.push( first >= second ? 1 : 0 );
782                } break;
783
784             case DW_OP_eq: 
785                {
786                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
787                   long int first = opStack.top(); opStack.pop();
788                   long int second = opStack.top(); opStack.pop();
789                   opStack.push( first == second ? 1 : 0 );
790                } break;
791
792             case DW_OP_lt: 
793                {
794                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
795                   long int first = opStack.top(); opStack.pop();
796                   long int second = opStack.top(); opStack.pop();
797                   opStack.push( first < second ? 1 : 0 );
798                } break;
799
800             case DW_OP_gt: 
801                {
802                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
803                   long int first = opStack.top(); opStack.pop();
804                   long int second = opStack.top(); opStack.pop();
805                   opStack.push( first > second ? 1 : 0 );
806                } break;
807
808             case DW_OP_ne: 
809                {
810                   DWARF_FALSE_IF( opStack.size() < 2, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
811                   long int first = opStack.top(); opStack.pop();
812                   long int second = opStack.top(); opStack.pop();
813                   opStack.push( first != second ? 1 : 0 );
814                } break;
815
816             case DW_OP_bra:
817                DWARF_FALSE_IF( opStack.size() < 1, "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
818                if ( opStack.top() == 0 ) { break; }
819                opStack.pop();
820             case DW_OP_skip: 
821                {
822                   int bytes = (int)(Dwarf_Signed)locations[i].lr_number;
823                   unsigned int target = locations[i].lr_offset + bytes;
824
825                   int j = i;
826                   if ( bytes < 0 ) {
827                      for( j = i - 1; j >= 0; j-- ) {
828                         if ( locations[j].lr_offset == target ) { break; }
829                      } /* end search backward */
830                   } else {
831                      for( j = i + 1; j < location->ld_cents; j ++ ) {
832                         if ( locations[j].lr_offset == target ) { break; }
833                      } /* end search forward */
834                   } /* end if positive offset */
835
836                   /* Because i will be incremented the next time around the loop. */
837                   i = j - 1;
838                } break;
839
840             case DW_OP_piece:
841                /* For multi-part variables, which we don't handle. */
842                //bperr ( "Warning: dyninst does not handle multi-part variables.\n" );
843                break;
844
845             case DW_OP_nop:
846                break;
847
848             default:
849                dwarf_printf( "Unrecognized or non-static location opcode 0x%x, aborting.\n", locations[i].lr_atom );
850                //return false;
851                break;
852          } /* end operand switch */
853       } /* end iteration over Dwarf_Loc entries. */
854
855       if (!isLocSet){
856          /* The top of the stack is the computed location. */
857          if ( opStack.empty() ) {
858             dwarf_printf( "ignoring malformed location list (stack empty at end of list).\n" );
859             //return false;
860          }
861          else {
862             dwarf_printf( "setting offset to %d\n", opStack.top() );
863             loc->frameOffset = opStack.top();
864             locs->push_back(loc);
865          }
866       }
867       else
868          locs->push_back(loc);
869    }
870
871    /* decode successful */
872    return true;
873 } /* end decodeLocationListForStaticOffsetOrAddress() */
874
875 void convertFileNoToName( Dwarf_Debug & dbg, Dwarf_Signed fileNo, 
876       char ** returnFileName, char ** newFileNames = NULL, Dwarf_Signed newFileNamesCount = 0 ) 
877 {
878    static char ** fileNames = NULL;
879    static Dwarf_Signed fileNamesCount = 0;
880
881    /* Initialize? */
882    if ( returnFileName == NULL && newFileNames != NULL ) {
883       /* FIXME?  Did we want to normalize these filenames? */
884       fileNames = newFileNames;
885       fileNamesCount = newFileNamesCount;
886       return;
887    } /* end initialization. */
888
889    /* Destroy? */
890    if ( returnFileName == NULL && newFileNames == NULL ) {
891       for( int i = 0; i < fileNamesCount; i++ ) {
892          dwarf_dealloc( dbg, fileNames[i], DW_DLA_STRING );
893       } /* end deallocation loop */
894       dwarf_dealloc( dbg, fileNames, DW_DLA_LIST );
895       fileNamesCount = 0;
896       return;
897    } /* end destruction. */
898
899    /* Do lookup. */
900    if ( fileNo <= fileNamesCount ) { * returnFileName = fileNames[fileNo - 1]; }
901    else { * returnFileName = NULL; }
902 } /* end convertFileNoToName() */
903
904 /* Utility function. */
905 unsigned long tvDifference( struct timeval lhs, struct timeval rhs ) 
906 {
907    unsigned long seconds = lhs.tv_sec - rhs.tv_sec;
908    if ( seconds == 0 ) { return lhs.tv_usec - rhs.tv_usec; }
909    else {
910       seconds *= 1000000;
911       seconds += lhs.tv_usec - rhs.tv_usec;
912    }
913    return seconds;
914 } /* end tvDifference() */
915
916 /* For debugging. */
917 void dumpAttributeList( Dwarf_Die dieEntry, Dwarf_Debug & dbg ) 
918 {
919    char * entryName = NULL;
920    int status = dwarf_diename( dieEntry, & entryName, NULL );
921    DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error dumping attribute list.\n", __FILE__, __LINE__ );
922
923    Dwarf_Attribute * attributeList;
924    Dwarf_Signed attributeCount;
925    status = dwarf_attrlist( dieEntry, & attributeList, & attributeCount, NULL );
926    DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error dumping attribute list.\n", __FILE__, __LINE__ );
927
928    //bperr ( "DIE %s has attributes:", entryName );
929    for( int i = 0; i < attributeCount; i++ ) {
930       Dwarf_Half whatAttr = 0;
931       status = dwarf_whatattr( attributeList[i], & whatAttr, NULL );
932       DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error dumping attribute list.\n", __FILE__, __LINE__ );
933       fprintf( stderr, " 0x%x", whatAttr );
934
935       dwarf_dealloc( dbg, attributeList[i], DW_DLA_ATTR );
936    } /* end iteration over attributes */
937    fprintf( stderr, "\n" );
938
939    dwarf_dealloc( dbg, attributeList, DW_DLA_LIST );
940    dwarf_dealloc( dbg, entryName, DW_DLA_STRING );
941 } /* end dumpAttributeList() */
942
943
944 bool walkDwarvenTree(Dwarf_Debug & dbg, Dwarf_Die dieEntry,
945       Module * module,
946       Symtab * objFile,
947       Dwarf_Off cuOffset,
948       char **srcFiles,
949       Symbol * currentFunction = NULL,
950       typeCommon * currentCommonBlock = NULL,
951       typeEnum *currentEnum = NULL,
952       fieldListType * currentEnclosure = NULL )
953 {
954
955 /* optimization */ tail_recursion:
956    Dwarf_Half dieTag;
957    int status = dwarf_tag( dieEntry, & dieTag, NULL );
958    DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
959
960    Dwarf_Off dieOffset;
961    status = dwarf_dieoffset( dieEntry, & dieOffset, NULL );
962    DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
963
964    Dwarf_Off dieCUOffset;
965    status = dwarf_die_CU_offset( dieEntry, & dieCUOffset, NULL );
966    DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
967
968    dwarf_printf( "Considering DIE at %lu (%lu CU-relative) with tag 0x%x\n", (unsigned long)dieOffset, (unsigned long)dieCUOffset, dieTag );
969
970    /* If this entry is a function, common block, or structure (class),
971       its children will be in its scope, rather than its
972       enclosing scope. */
973    Symbol * newFunction = currentFunction;
974    typeCommon * newCommonBlock = currentCommonBlock;
975    typeEnum *newEnum = currentEnum;
976    fieldListType * newEnclosure = currentEnclosure;
977
978    bool parsedChild = false;
979    /* Is this is an entry we're interested in? */
980    switch( dieTag ) {
981       /* case DW_TAG_inline_subroutine: we don't care about these */
982       case DW_TAG_subprogram:
983       case DW_TAG_entry_point:
984          {
985
986             /* Is this entry specified elsewhere?  We may need to look there for its name. */
987             Dwarf_Bool hasSpecification;
988             status = dwarf_hasattr( dieEntry, DW_AT_specification, & hasSpecification, NULL );
989             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
990
991             /* Our goal is three-fold: First, we want to set the return type
992                of the function.  Second, we want to set the newFunction variable
993                so subsequent entries are handled correctly.  Third, we want to
994                record (the location of, or how to calculate) the frame base of 
995                this function for use by our instrumentation code later. */
996
997             char * functionName = NULL;
998             Dwarf_Die specEntry = dieEntry;
999
1000             /* In order to do this, we need to find the function's (mangled) name.
1001                If a function has a specification, its specification will have its
1002                name. */
1003             if ( hasSpecification ) {
1004                Dwarf_Attribute specAttribute;
1005                status = dwarf_attr( dieEntry, DW_AT_specification, & specAttribute, NULL );
1006                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1007
1008                Dwarf_Off specOffset;
1009                status = dwarf_global_formref( specAttribute, & specOffset, NULL );
1010                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1011
1012                status = dwarf_offdie( dbg, specOffset, & specEntry, NULL );
1013                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1014
1015                dwarf_dealloc( dbg, specAttribute, DW_DLA_ATTR );
1016             } /* end if the function has a specification */
1017
1018             /* Prefer linkage names. */
1019             Dwarf_Attribute linkageNameAttr;
1020             status = dwarf_attr( specEntry, DW_AT_MIPS_linkage_name, & linkageNameAttr, NULL );
1021             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1022
1023             bool hasLinkageName;
1024             if ( status == DW_DLV_OK ) {
1025                hasLinkageName = true;
1026                status = dwarf_formstring( linkageNameAttr, & functionName, NULL );
1027                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1028
1029                dwarf_dealloc( dbg, linkageNameAttr, DW_DLA_ATTR );
1030             } /* end if there's a linkage name. */
1031             else {
1032                hasLinkageName = false;
1033                status = dwarf_diename( specEntry, & functionName, NULL );
1034                DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1035             } /* end if there isn't a linkage name. */
1036
1037             if ( functionName == NULL ) {
1038                /* I'm not even sure what an anonymous function _means_,
1039                   but we sure can't do anything with it. */
1040                dwarf_printf( "Warning: anonymous function (type %lu).\n", (unsigned long)dieOffset );
1041
1042                /* Don't parse the children, since we can't add them. */
1043                parsedChild = true;
1044
1045                if ( hasSpecification ) { dwarf_dealloc( dbg, specEntry, DW_DLA_DIE ); }
1046                dwarf_dealloc( dbg, functionName, DW_DLA_STRING );
1047                break;
1048             } /* end if there's no name at all. */
1049
1050             if (strcmp(functionName, "ggPoint2") == 0) {
1051                static volatile int foundit = 0;
1052                fprintf(stderr, "Found it\n");
1053                while (!foundit);
1054             }
1055
1056             /* Try to find the function by its mangled name. */
1057             Dwarf_Addr baseAddr = 0;
1058             std::vector< Symbol * > ret_funcs;
1059             std::vector<Symbol *> functions;
1060             if (objFile->findSymbolByType(ret_funcs, functionName, Symbol::ST_FUNCTION, true)) {
1061                for (unsigned foo = 0; foo < ret_funcs.size(); foo++)
1062                   functions.push_back(ret_funcs[foo]);
1063                ret_funcs.clear();       
1064             }
1065             else {
1066                /* If we can't find it by mangled name, try searching by address. */
1067                status = dwarf_lowpc( dieEntry, & baseAddr, NULL );
1068                if ( status == DW_DLV_OK ) {
1069                   /* The base addresses in DWARF appear to be image-relative. */
1070                   // Symbol * intFunction = objFile->findFuncByAddr( baseAddr );
1071                   Offset absAddr = objFile->getBaseOffset() + baseAddr;
1072                   std::vector<Symbol *>funcs;
1073                   if (objFile->findFuncByEntryOffset(funcs, absAddr)){
1074                      functions.push_back(funcs[0]);
1075                   }
1076                }
1077             }
1078             if ( functions.size() == 0 ) { // Still....
1079                /* If we can't find it by address, try searching by pretty name. */
1080                if ( baseAddr != 0 ) { dwarf_printf( "%s[%d]: unable to locate function %s by address 0x%llx\n", __FILE__, __LINE__, functionName, baseAddr ); 
1081                }
1082                std::vector<Symbol *> prettyFuncs;
1083                if (objFile->findSymbolByType(prettyFuncs, functionName, Symbol::ST_FUNCTION)) {
1084                   for (unsigned bar = 0; bar < prettyFuncs.size(); bar++) {
1085                      functions.push_back(prettyFuncs[bar]);
1086                   }
1087                }
1088             }
1089
1090             if ( functions.size() == 0 ) {
1091                /* Don't parse the children, since we can't add them. */
1092                dwarf_printf( "Failed to find function '%s'\n", functionName );
1093                parsedChild = true;
1094
1095                //Add the function to the list of functions and continue parsing the FDE ??
1096
1097                if ( hasSpecification ) { dwarf_dealloc( dbg, specEntry, DW_DLA_DIE ); }
1098                dwarf_dealloc( dbg, functionName, DW_DLA_STRING );
1099                break;
1100             }
1101             else if ( functions.size() > 1 ) {
1102                dwarf_printf( "Warning: found more than one function '%s', unable to do anything reasonable.\n", functionName );
1103
1104                /* Don't parse the children, since we can't add them. */
1105                parsedChild = true;
1106
1107                if ( hasSpecification ) { dwarf_dealloc( dbg, specEntry, DW_DLA_DIE ); }
1108                dwarf_dealloc( dbg, functionName, DW_DLA_STRING );
1109                break;           
1110             }
1111             else {
1112                Symbol * newIntFunction = functions[0];
1113                assert( newIntFunction != NULL );
1114                //newFunction = objFile->newFunctionCB( newIntFunction );
1115                newFunction = newIntFunction;
1116                assert( newFunction != NULL );
1117             } /* end findFunction() cases */
1118
1119             /* Once we've found the Symbol pointer corresponding to this
1120                DIE, record its frame base.  A declaration entry may not have a 
1121                frame base, and some functions do not have frames. */
1122             Dwarf_Attribute frameBaseAttribute;
1123             status = dwarf_attr( dieEntry, DW_AT_frame_base, & frameBaseAttribute, NULL );
1124             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1125
1126             if ( status == DW_DLV_OK ) {
1127                Dwarf_Locdesc ** locationList;
1128                Dwarf_Signed listLength;
1129                status = dwarf_loclist_n( frameBaseAttribute, & locationList, & listLength, NULL );
1130                if ( status != DW_DLV_OK ) {
1131                   /* I think DWARF 3 generically allows this abomination of empty loclists. */
1132                   break;
1133                }
1134                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1135
1136                dwarf_dealloc( dbg, frameBaseAttribute, DW_DLA_ATTR );
1137
1138 #if defined(ia64_unknown_linux2_4)
1139                /* Convert location list to an AST for later code generation. */
1140                newFunction->setFramePtrRegnum(convertFrameBaseToAST( locationList[0], listLength, objFile ));
1141                //                               newFunction->lowlevel_func()->ifunc()->framePointerCalculator = convertFrameBaseToAST( locationList[0], listLength, proc );
1142 #endif
1143
1144                deallocateLocationList( dbg, locationList, listLength );
1145             } /* end if this DIE has a frame base attribute */
1146
1147             /* Find its return type. */
1148             Dwarf_Attribute typeAttribute;
1149             status = dwarf_attr( specEntry, DW_AT_type, & typeAttribute, NULL );
1150             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1151
1152             Type * returnType = NULL;
1153             if ( status == DW_DLV_NO_ENTRY ) { 
1154                returnType = module->getModuleTypes()->findType("void");
1155                newFunction->setReturnType( returnType );
1156             } /* end if the return type is void */
1157             else {
1158                /* There's a return type attribute. */
1159                Dwarf_Off typeOffset;
1160                status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
1161                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1162
1163                //parsing_printf("%s/%d: ret type %d\n",
1164                //                          __FILE__, __LINE__, typeOffset);
1165                returnType = module->getModuleTypes()->findOrCreateType( typeOffset );
1166                newFunction->setReturnType( returnType );
1167
1168                dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
1169             } /* end if not a void return type */
1170
1171             /* If this is a member function, add it as a field, for backward compatibility */
1172             if ( currentEnclosure != NULL ) {
1173                /* Using the mangled name allows us to distinguish between overridden
1174                   functions, but confuses the tests.  Since Type uses vectors
1175                   to hold field names, however, duplicate -- demangled names -- are OK. */
1176                char * demangledName = P_cplus_demangle( functionName, objFile->isNativeCompiler() );
1177
1178                char * leftMost = NULL;
1179                if ( demangledName == NULL ) {
1180                   dwarf_printf( "%s[%d]: unable to demangle '%s', using mangled name.\n", __FILE__, __LINE__, functionName );
1181                   demangledName = strdup( functionName );
1182                   assert( demangledName != NULL );
1183                   leftMost = demangledName;
1184                }
1185                else {
1186                   /* Strip everything left of the rightmost ':' off; see above. */
1187                   leftMost = demangledName;
1188                   if ( strrchr( demangledName, ':' ) )
1189                      leftMost = strrchr( demangledName, ':' ) + 1;
1190                }
1191                std::string fName = convertCharToString(leftMost);
1192                typeFunction *funcType = new typeFunction( dieOffset, returnType, fName);
1193
1194                currentEnclosure->addField( fName, funcType);
1195                free( demangledName );
1196             }
1197
1198             if ( hasSpecification ) { dwarf_dealloc( dbg, specEntry, DW_DLA_DIE ); }
1199             dwarf_dealloc( dbg, functionName, DW_DLA_STRING );
1200          } break;
1201
1202
1203       case DW_TAG_common_block: 
1204          {
1205             char * commonBlockName;
1206             status = dwarf_diename( dieEntry, & commonBlockName, NULL );
1207             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1208
1209             Symbol *commonBlockVar;
1210             std::vector<Symbol *> commonBlockVars;
1211             if (!objFile->findSymbolByType(commonBlockVars, commonBlockName, Symbol::ST_OBJECT))
1212             {
1213                if (!objFile->findSymbolByType(commonBlockVars, commonBlockName, Symbol::ST_OBJECT, true))
1214                {
1215                   //pgcc 6 is naming common blocks with a trailing underscore
1216                   std::string cbvname = std::string(commonBlockName) + std::string("_");
1217                   if (!objFile->findSymbolByType(commonBlockVars, cbvname, Symbol::ST_OBJECT)){
1218                      objFile->findSymbolByType(commonBlockVars, cbvname, Symbol::ST_OBJECT, true);
1219                   }
1220                }        
1221             }
1222
1223             commonBlockVar = commonBlockVars[0];
1224
1225             DWARF_FALSE_IF( !commonBlockVar, "%s[%d]: Couldn't find variable for common block\n", __FILE__, __LINE__);
1226
1227             Type * commonBlockType = NULL;
1228
1229             std::string cBName = commonBlockName;
1230             if (!commonBlockVar) {
1231                //bperr("unable to find variable %s\n", commonBlockName);
1232             } else {
1233                commonBlockType = dynamic_cast<typeCommon *>(module->getModuleTypes()->findVariableType(cBName));
1234                if (commonBlockType == NULL) {
1235                   commonBlockType = new typeCommon( dieOffset, cBName );
1236                   assert( commonBlockType != NULL );
1237                   module->getModuleTypes()->addGlobalVariable( cBName, commonBlockType );
1238                }        
1239             }
1240             dwarf_dealloc( dbg, commonBlockName, DW_DLA_STRING );
1241
1242             /* This node's children are in the common block. */
1243             newCommonBlock = dynamic_cast<typeCommon*>(commonBlockType);
1244             if (newCommonBlock)
1245                newCommonBlock->beginCommonBlock();
1246          } break;
1247
1248       case DW_TAG_constant: 
1249          {
1250             //bperr ( "Warning: dyninst ignores named constant entries.\n" );
1251          } break;
1252
1253          /* It's worth noting that a variable may have a constant value.  Since,
1254             AFAIK, Dyninst does nothing with this information, neither will we.
1255             (It will, however, explain why certain variables that otherwise would
1256             don't have locations.) */
1257       case DW_TAG_variable: 
1258          {
1259             /* A variable may occur inside a function, as either static or local.
1260                A variable may occur inside a container, as C++ static member.
1261                A variable may not occur in either, as a global. 
1262
1263                For the first two cases, we need the variable's name, its type,
1264                its line number, and its offset or address in order to tell
1265                Dyninst about it.  Dyninst only needs to know the name and type
1266                of a global.  (Actually, it already knows the names of the globals;
1267                we're really just telling it the types.)
1268
1269                Variables may have two entries, the second, with a _specification,
1270                being the only one with the location. */
1271
1272             /* We will begin by determining which kind of variable we think it is,
1273                and the determining if we need to wait for the DIE with a _specification
1274                before telling Dyninst about it. */
1275
1276             if ( currentFunction == NULL && currentEnclosure == NULL ) {
1277                /* Then this variable must be a global.  Acquire its name and type. */
1278                char * variableName;
1279                status = dwarf_diename( dieEntry, & variableName, NULL );
1280                DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1281
1282                if ( status == DW_DLV_NO_ENTRY ) { break; }
1283                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1284
1285                Dwarf_Attribute typeAttribute;
1286                status = dwarf_attr( dieEntry, DW_AT_type, & typeAttribute, NULL );
1287                DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1288
1289                if ( status == DW_DLV_NO_ENTRY ) { break; }
1290                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1291
1292                Dwarf_Off typeOffset;
1293                status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
1294                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1295
1296                /* The typeOffset forms a module-unique type identifier,
1297                   so the Type look-ups by it rather than name. */
1298                dwarf_printf( "%s/%d: %s/%d\n", __FILE__, __LINE__, variableName, typeOffset );
1299                Type * variableType = module->getModuleTypes()->findOrCreateType( typeOffset );
1300                dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
1301
1302                /* Tell Dyninst what this global's type is. */
1303                std::string vName = convertCharToString(variableName);
1304                module->getModuleTypes()->addGlobalVariable( vName, variableType );
1305             } /* end if this variable is a global */
1306             else {
1307                /* We'll start with the location, since that's most likely to
1308                   require the _specification. */
1309                Dwarf_Attribute locationAttribute;
1310                status = dwarf_attr( dieEntry, DW_AT_location, & locationAttribute, NULL );
1311                DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1312
1313                if ( status == DW_DLV_NO_ENTRY ) { break; }
1314                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1315
1316                Dwarf_Locdesc **locationList;
1317                Dwarf_Signed listLength;
1318                status = dwarf_loclist_n( locationAttribute, & locationList, & listLength, NULL );
1319                dwarf_dealloc( dbg, locationAttribute, DW_DLA_ATTR );
1320                if ( status != DW_DLV_OK ) {
1321                   /* I think this is OK if the local variable was optimized away. */
1322                   break;
1323                }
1324                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1325
1326
1327                //loc_t *loc = (loc_t *)malloc(listLength * sizeof(loc_t));
1328                vector<loc_t *>* locs = new vector<loc_t *>;
1329                bool decodedAddressOrOffset = decodeLocationListForStaticOffsetOrAddress( locationList, listLength, objFile, locs, NULL);
1330                deallocateLocationList( dbg, locationList, listLength );
1331
1332                if ( ! decodedAddressOrOffset ) { break; }
1333
1334                /* If this DIE has a _specification, use that for the rest of our inquiries. */
1335                Dwarf_Die specEntry = dieEntry;
1336
1337                Dwarf_Attribute specAttribute;
1338                status = dwarf_attr( dieEntry, DW_AT_specification, & specAttribute, NULL );
1339                DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1340
1341                if ( status == DW_DLV_OK ) {
1342                   Dwarf_Off specOffset;
1343                   status = dwarf_global_formref( specAttribute, & specOffset, NULL );
1344                   DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1345
1346                   status = dwarf_offdie( dbg, specOffset, & specEntry, NULL );
1347                   DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1348
1349                   dwarf_dealloc( dbg, specAttribute, DW_DLA_ATTR );
1350                } /* end if dieEntry has a _specification */
1351
1352                /* Acquire the name, type, and line number. */
1353                char * variableName;
1354                status = dwarf_diename( specEntry, & variableName, NULL );
1355                DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1356
1357                /* We can't do anything with an anonymous variable. */
1358                if ( status == DW_DLV_NO_ENTRY ) { break; }
1359                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1360
1361                /* If we're fortran, get rid of the trailing _ */
1362                supportedLanguages lang = module->language();
1363                if ( ( lang == lang_Fortran ||
1364                         lang == lang_CMFortran ||
1365                         lang == lang_Fortran_with_pretty_debug ) &&
1366                      variableName[strlen(variableName)-1]=='_') 
1367                   variableName[strlen(variableName)-1]='\0';
1368
1369                /* Acquire the parameter's type. */
1370                Dwarf_Attribute typeAttribute;
1371                status = dwarf_attr( specEntry, DW_AT_type, & typeAttribute, NULL );
1372                DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1373
1374                if ( status == DW_DLV_NO_ENTRY ) { break; }
1375                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1376
1377                Dwarf_Off typeOffset;
1378                status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
1379                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1380
1381                /* The typeOffset forms a module-unique type identifier,
1382                   so the Type look-ups by it rather than name. */
1383                Type * variableType = module->getModuleTypes()->findOrCreateType( typeOffset );
1384
1385                dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
1386
1387                /* Acquire the variable's lineNo. */
1388                Dwarf_Unsigned variableLineNo;
1389                bool hasLineNumber = false;
1390                std::string fileName;
1391
1392                Dwarf_Attribute fileDeclAttribute;
1393                status = dwarf_attr( specEntry, DW_AT_decl_file, & fileDeclAttribute, NULL );
1394                DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1395                Dwarf_Unsigned fileNameDeclVal;
1396                if ( status == DW_DLV_OK ) {
1397                   status = dwarf_formudata(fileDeclAttribute, &fileNameDeclVal, NULL);
1398                   DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1399                   dwarf_dealloc( dbg, fileDeclAttribute, DW_DLA_ATTR );                 
1400                }
1401                if ( status == DW_DLV_NO_ENTRY )
1402                   fileName = "";
1403                else     
1404                   fileName = convertCharToString(srcFiles[fileNameDeclVal-1]);
1405
1406                Dwarf_Attribute lineNoAttribute;
1407                status = dwarf_attr( specEntry, DW_AT_decl_line, & lineNoAttribute, NULL );
1408                DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1409
1410                /* We don't need to tell Dyninst a line number for C++ static variables,
1411                   so it's OK if there isn't one. */
1412                if ( status == DW_DLV_OK ) {
1413                   hasLineNumber = true;
1414                   status = dwarf_formudata( lineNoAttribute, & variableLineNo, NULL );
1415                   DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1416
1417                   dwarf_dealloc( dbg, lineNoAttribute, DW_DLA_ATTR );                   
1418                } /* end if there is a line number */
1419
1420                /* We now have the variable name, type, offset, and line number.
1421                   Tell Dyninst about it. */
1422                dwarf_printf( "localVariable '%s', currentFunction %p\n", variableName, currentFunction );
1423                if ( currentFunction != NULL ) {
1424                   if (!hasLineNumber){
1425                      variableLineNo = 0;
1426                      fileName = "";
1427                   }
1428                   else
1429                      fileName = srcFiles[fileNameDeclVal-1];
1430                   std::string vName = convertCharToString(variableName);
1431                   localVar * newVariable = new localVar( vName, variableType, fileName, variableLineNo);
1432                   newVariable->setLocation(locs);
1433                   Annotatable<localVarCollection, symbol_variables_a, true> &varA = *currentFunction;
1434                   if (!varA.size()) {
1435                      localVarCollection newCollection;
1436                      varA.addAnnotation(newCollection);
1437                   }
1438                   localVarCollection &svars = varA[0];
1439                   svars.addLocalVar(newVariable);
1440                } /* end if a local or static variable. */
1441                else if ( currentEnclosure != NULL ) {
1442                   //assert( sClass != storageFrameOffset );
1443                   assert( (*locs)[0]->stClass != storageRegOffset );
1444                   std::string vName = convertCharToString(variableName);
1445                   currentEnclosure->addField( vName, variableType, (*locs)[0]->frameOffset);
1446                } /* end if a C++ static member. */
1447             } /* end if this variable is not global */
1448          } break;
1449
1450          /* It's probably worth noting that a formal parameter may have a
1451             default value.  Since, AFAIK, Dyninst does nothing with this information,
1452             neither will we. */
1453       case DW_TAG_formal_parameter: 
1454          {
1455             /* A formal parameter must occur in the context of a function.
1456                (That is, we can't do anything with a formal parameter to a
1457                function we don't know about.) */
1458             if ( currentFunction == NULL ) {
1459                dwarf_printf( "%s[%d]: ignoring formal parameter without corresponding function.\n", __FILE__, __LINE__ );
1460                break;
1461             }
1462
1463             /* We need the formal parameter's name, its type, its line number,
1464                and its offset from the frame base in order to tell the 
1465                rest of Dyninst about it.  A single _formal_parameter
1466                DIE may not have all of this information; if it does not,
1467                we will ignore it, hoping to catch it when it is later
1468                referenced as an _abstract_origin from another _formal_parameter
1469                DIE.  If we never find such a DIE, than there is not enough
1470                information to introduce it to Dyninst. */
1471
1472             /* We begin with the location, since this is the attribute
1473                most likely to require using the _abstract_origin. */
1474             Dwarf_Bool hasLocation = false;
1475             status = dwarf_hasattr( dieEntry, DW_AT_location, & hasLocation, NULL );
1476             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1477
1478             if ( !hasLocation ) {
1479                dwarf_printf( "%s[%d]: ignoring formal parameter without location.\n", __FILE__, __LINE__ );
1480                break;
1481             }
1482
1483             /* Acquire the location of this formal parameter. */
1484             Dwarf_Attribute locationAttribute;
1485             status = dwarf_attr( dieEntry, DW_AT_location, & locationAttribute, NULL );
1486             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1487
1488             Dwarf_Locdesc **locationList;
1489             Dwarf_Signed listLength;
1490             status = dwarf_loclist_n( locationAttribute, & locationList, & listLength, NULL );
1491             dwarf_dealloc( dbg, locationAttribute, DW_DLA_ATTR );
1492             if ( status != DW_DLV_OK ) {
1493                /* I think this is legal if the parameter was optimized away. */
1494                dwarf_printf( "%s[%d]: ignoring formal parameter with bogus location.\n", __FILE__, __LINE__ );
1495                break;
1496             }
1497             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1498
1499             //loc_t *loc = (loc_t *)malloc(listLength * sizeof(loc_t));
1500             vector<loc_t *>* locs = new vector<loc_t *>;
1501             bool decodedOffset = decodeLocationListForStaticOffsetOrAddress( locationList, listLength, objFile, locs, NULL);
1502             deallocateLocationList( dbg, locationList, listLength );
1503
1504             if ( ! decodedOffset ) {
1505                dwarf_printf( "%s[%d]: ignoring formal parameter with undecodable location.\n", __FILE__, __LINE__ );
1506                break;
1507             }
1508
1509             assert( (*locs)[0]->stClass != storageAddr );
1510
1511             /* If the DIE has an _abstract_origin, we'll use that for the
1512                remainder of our inquiries. */
1513             Dwarf_Die originEntry = dieEntry;
1514
1515             Dwarf_Attribute originAttribute;
1516             status = dwarf_attr( dieEntry, DW_AT_abstract_origin, & originAttribute, NULL );
1517             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1518
1519             if ( status == DW_DLV_OK ) {
1520                Dwarf_Off originOffset;
1521                status = dwarf_global_formref( originAttribute, & originOffset, NULL );
1522                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1523
1524                status = dwarf_offdie( dbg, originOffset, & originEntry, NULL );
1525                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1526
1527                dwarf_dealloc( dbg, originAttribute, DW_DLA_ATTR );
1528             } /* end if the DIE has an _abstract_origin */
1529
1530             /* Acquire the parameter's name. */
1531             char * parameterName;
1532             status = dwarf_diename( originEntry, & parameterName, NULL );
1533             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1534
1535             /* We can't do anything with anonymous parameters. */
1536             if ( status == DW_DLV_NO_ENTRY ) { break; }
1537             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1538
1539             /* Acquire the parameter's type. */
1540             Dwarf_Attribute typeAttribute;
1541             status = dwarf_attr( originEntry, DW_AT_type, & typeAttribute, NULL );
1542             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1543
1544             if ( status == DW_DLV_NO_ENTRY ) { break; }
1545             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1546
1547             Dwarf_Off typeOffset;
1548             status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
1549             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1550
1551             /* The typeOffset forms a module-unique type identifier,
1552                so the Type look-ups by it rather than name. */
1553             dwarf_printf( "%s[%d]: found formal parameter %s with type %ld\n", __FILE__, __LINE__, parameterName, typeOffset );
1554             Type * parameterType = module->getModuleTypes()->findOrCreateType( typeOffset );
1555
1556             dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
1557
1558
1559             Dwarf_Attribute fileDeclAttribute;
1560             std::string fileName;
1561             status = dwarf_attr( originEntry, DW_AT_decl_file, & fileDeclAttribute, NULL );
1562             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1563             Dwarf_Unsigned fileNameDeclVal;
1564             if ( status == DW_DLV_OK ) {
1565                status = dwarf_formudata(fileDeclAttribute, &fileNameDeclVal, NULL);
1566                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1567                dwarf_dealloc( dbg, fileDeclAttribute, DW_DLA_ATTR );
1568             }
1569             if ( status == DW_DLV_NO_ENTRY )
1570                fileName = "";
1571             else        
1572                fileName = convertCharToString(srcFiles[fileNameDeclVal-1]);
1573
1574             /* Acquire the parameter's lineNo. */
1575             Dwarf_Attribute lineNoAttribute;
1576             Dwarf_Unsigned parameterLineNo;
1577             status = dwarf_attr( originEntry, DW_AT_decl_line, & lineNoAttribute, NULL );
1578             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1579
1580             if ( status == DW_DLV_NO_ENTRY ) {
1581                dwarf_printf( "%s[%d]: ignoring formal parameter without line number.\n", __FILE__, __LINE__ );
1582                parameterLineNo = 0;
1583             }
1584             else{
1585                status = dwarf_formudata( lineNoAttribute, & parameterLineNo, NULL );
1586                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1587                dwarf_dealloc( dbg, lineNoAttribute, DW_DLA_ATTR );
1588             }   
1589
1590
1591             /* We now have the parameter's location, name, type, and line number.
1592                Tell Dyninst about it. */
1593             std::string pName = convertCharToString(parameterName);
1594             localVar * newParameter = new localVar( pName, parameterType, fileName, parameterLineNo);
1595             assert( newParameter != NULL );
1596             newParameter->setLocation(locs);
1597
1598             /* This is just brutally ugly.  Why don't we take care of this invariant automatically? */
1599             Annotatable<localVarCollection, symbol_parameters_a, true> &paramA = *currentFunction;
1600             if (!paramA.size()) {
1601                localVarCollection newVarColl;
1602                paramA.addAnnotation(newVarColl);
1603             }
1604             localVarCollection &sparams = paramA[0];
1605             sparams.addLocalVar(newParameter);
1606
1607             //TODO ??NOT REQUIRED??
1608             //currentFunction->addParam( parameterName, parameterType, parameterLineNo, parameterOffset );
1609
1610             dwarf_printf( "%s[%d]: added formal parameter '%s' of type %p from line %lu.\n", __FILE__, __LINE__, parameterName, parameterType, (unsigned long)parameterLineNo );
1611          } break;
1612
1613       case DW_TAG_base_type: 
1614          {
1615             /* What's the type's name? */
1616             char * typeName;
1617             status = dwarf_diename( dieEntry, & typeName, NULL );
1618             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1619
1620             /* How big is it? */
1621             Dwarf_Attribute byteSizeAttr;
1622             Dwarf_Unsigned byteSize;
1623             status = dwarf_attr( dieEntry, DW_AT_byte_size, & byteSizeAttr, NULL );
1624             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1625             status = dwarf_formudata( byteSizeAttr, & byteSize, NULL );
1626             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1627
1628             dwarf_dealloc( dbg, byteSizeAttr, DW_DLA_ATTR );
1629
1630             /* Generate the appropriate built-in type; since there's no
1631                reliable way to distinguish between a built-in and a scalar,
1632                we don't bother to try. */
1633             std::string tName = convertCharToString(typeName);   
1634             Type * baseType = new typeScalar( dieOffset, byteSize, tName );
1635             assert( baseType != NULL );
1636
1637             /* Add the basic type to our collection. */
1638             dwarf_printf( "Adding base type '%s' (%lu) of size %lu to type collection %p\n", typeName, (unsigned long)dieOffset, (unsigned long)byteSize, module->getModuleTypes() );
1639             baseType = module->getModuleTypes()->addOrUpdateType( baseType );
1640
1641             dwarf_dealloc( dbg, typeName, DW_DLA_STRING );
1642          } break;
1643
1644       case DW_TAG_typedef: 
1645          {
1646             char * definedName = NULL;
1647             status = dwarf_diename( dieEntry, & definedName, NULL );
1648             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1649
1650             Type * referencedType = NULL;
1651             Dwarf_Attribute typeAttribute;
1652             status = dwarf_attr( dieEntry, DW_AT_type, & typeAttribute, NULL );
1653             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1654             if ( status == DW_DLV_NO_ENTRY ) {
1655                /* According to the DWARF spec, "A declaration of the type that is not also a definition."
1656                   This includes constructions like "typedef void _IO_lock_t", from libio.h, which
1657                   cause us to issue a lot of true but spurious-looking warnings about incomplete types.
1658                   So instead of ignoring this entry, point it to the void type.  (This is also more
1659                   in line with our handling of absent DW_AT_type tags everywhere else.) */
1660                referencedType = module->getModuleTypes()->findType( "void" );
1661             }
1662             else {
1663                Dwarf_Off typeOffset;
1664                status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
1665                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1666
1667                dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
1668
1669                /* Look up the referenced type. */
1670                //parsing_printf("%s/%d: %s/%d\n",
1671                //                          __FILE__, __LINE__, definedName, typeOffset);
1672                referencedType = module->getModuleTypes()->findOrCreateType( typeOffset );
1673             }
1674
1675             /* Add the typedef to our collection. */
1676             // //bperr ( "Adding typedef: '%s' as %lu (pointing to %lu)\n", definedName, (unsigned long)dieOffset, (unsigned long)typeOffset );
1677             std::string dName = convertCharToString(definedName);
1678             Type * typedefType = new typeTypedef( dieOffset, referencedType, dName);
1679             typedefType = module->getModuleTypes()->addOrUpdateType( typedefType );
1680
1681             /* Sanity check: typedefs should not have children. */
1682             Dwarf_Die childDwarf;
1683             status = dwarf_child( dieEntry, & childDwarf, NULL );
1684             assert( status == DW_DLV_NO_ENTRY );
1685
1686             dwarf_dealloc( dbg, definedName, DW_DLA_STRING );
1687          } break;
1688
1689       case DW_TAG_array_type: 
1690          {
1691             /* Two words about pgf90 arrays.
1692
1693 Primus: the PGI extensions to DWARF are documented in 
1694 '/p/paradyn/doc/External/manuals/pgf90-dwarf-arrays.txt'.
1695
1696 Secundus: we ignore DW_AT_PGI_lbase, DW_AT_PGI_loffset, and DW_AT_PGI_lstride,
1697 even though libdwarf recognizes them, because our type modelling doesn't allow
1698 us to make use of this information.  Similarly, in virtually every place where
1699 the Portland Group extends DWARF to allow _form_block attributes encoding location
1700 lists, we ignore them.  We should, however, recognize these cases and ignore them
1701 gracefully, that is, without an error. :)
1702              */
1703
1704             char * arrayName = NULL;
1705             status = dwarf_diename( dieEntry, & arrayName, NULL );
1706             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1707
1708             /* Find the type of the elements. */
1709             Dwarf_Attribute typeAttribute;
1710             status = dwarf_attr( dieEntry, DW_AT_type, & typeAttribute, NULL );
1711             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1712
1713             Dwarf_Off typeOffset;
1714             status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
1715             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1716
1717             dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
1718
1719             //parsing_printf("%s/%d: %s/%d\n",
1720             //                     __FILE__, __LINE__, arrayName, typeOffset);
1721             Type * elementType = module->getModuleTypes()->findOrCreateType( typeOffset );
1722
1723             /* Find the range(s) of the elements. */
1724             Dwarf_Die firstRange;
1725             status = dwarf_child( dieEntry, & firstRange, NULL );
1726             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1727             typeArray * baseArrayType = parseMultiDimensionalArray( dbg, firstRange, elementType, module );
1728             assert( baseArrayType != NULL );
1729
1730             /* The baseArrayType is an anonymous type with its own typeID.  Extract
1731                the information and add an array type for this DIE. */
1732             std::string aName = convertCharToString(arrayName);
1733             Type * arrayType = new typeArray( dieOffset, baseArrayType->getBaseType(), baseArrayType->getLow(),
1734                   baseArrayType->getHigh(), aName);
1735             assert( arrayType != NULL );
1736             //setArraySize( arrayType, baseArrayType->getLow(), baseArrayType->getHigh() );
1737             // //bperr ( "Adding array type '%s' (%lu) [%s, %s] @ %p\n", arrayName, (unsigned long)dieOffset, baseArrayType->getLow(), baseArrayType->getHigh(), arrayType );
1738             arrayType = module->getModuleTypes()->addOrUpdateType( arrayType );
1739
1740             /* Don't parse the children again. */
1741             parsedChild = true;
1742
1743             dwarf_dealloc( dbg, firstRange, DW_DLA_DIE );
1744             dwarf_dealloc( dbg, arrayName, DW_DLA_STRING );
1745          } break;
1746
1747       case DW_TAG_subrange_type: 
1748          {
1749             std::string loBound;
1750             std::string hiBound;
1751             parseSubRangeDIE( dbg, dieEntry, loBound, hiBound, module );
1752          } break;
1753
1754       case DW_TAG_enumeration_type: 
1755          {
1756             char * typeName = NULL;
1757             status = dwarf_diename( dieEntry, & typeName, NULL );
1758             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1759
1760             std::string tName = convertCharToString(typeName);
1761             typeEnum* enumerationType = new typeEnum( dieOffset, tName);
1762             assert( enumerationType != NULL );
1763             enumerationType = dynamic_cast<typeEnum *>(module->getModuleTypes()->addOrUpdateType( enumerationType ));
1764             newEnum = enumerationType;
1765
1766             dwarf_dealloc( dbg, typeName, DW_DLA_STRING );
1767          } break;
1768
1769       case DW_TAG_inheritance: 
1770          {
1771             /* Acquire the super class's type. */
1772             Dwarf_Attribute scAttr;
1773             status = dwarf_attr( dieEntry, DW_AT_type, & scAttr, NULL );
1774             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1775
1776             Dwarf_Off scOffset;
1777             status = dwarf_global_formref( scAttr, & scOffset, NULL );
1778             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1779
1780             dwarf_dealloc( dbg, scAttr, DW_DLA_ATTR );
1781
1782             //parsing_printf("%s/%d: inherited %d\n",
1783             //                     __FILE__, __LINE__, scOffset);
1784             Type * superClass = module->getModuleTypes()->findOrCreateType( scOffset );
1785
1786             /* Acquire the visibility, if any.  DWARF calls it accessibility
1787                to distinguish it from symbol table visibility. */
1788             Dwarf_Attribute visAttr;
1789             status = dwarf_attr( dieEntry, DW_AT_accessibility, & visAttr, NULL );
1790             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1791
1792             visibility_t visibility = visPrivate;
1793             if ( status == DW_DLV_OK ) {
1794                Dwarf_Unsigned visValue;
1795                status = dwarf_formudata( visAttr, & visValue, NULL );
1796                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1797
1798                switch( visValue ) {
1799                   case DW_ACCESS_public: visibility = visPublic; break;
1800                   case DW_ACCESS_protected: visibility = visProtected; break;
1801                   case DW_ACCESS_private: visibility = visPrivate; break;
1802                   default:
1803                                           //bperr ( "Uknown visibility, ignoring.\n" );
1804                                           break;
1805                } /* end visibility switch */
1806
1807                dwarf_dealloc( dbg, visAttr, DW_DLA_ATTR );
1808             } /* end if the visibility is specified. */
1809
1810             /* Add a readily-recognizable 'bad' field to represent the superclass.
1811                Type::getComponents() will Do the Right Thing. */
1812             std::string fName = "{superclass}";
1813             currentEnclosure->addField( fName, superClass, -1, visibility );
1814          } break;
1815
1816       case DW_TAG_structure_type:
1817       case DW_TAG_union_type:
1818       case DW_TAG_class_type: 
1819          {
1820             char * typeName = NULL;
1821             status = dwarf_diename( dieEntry, & typeName, NULL );
1822             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1823
1824             Dwarf_Attribute sizeAttr;
1825             Dwarf_Unsigned typeSize = 0;
1826             status = dwarf_attr( dieEntry, DW_AT_byte_size, & sizeAttr, NULL );
1827             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1828
1829             if ( status == DW_DLV_OK ) {
1830                status = dwarf_formudata( sizeAttr, & typeSize, NULL );
1831                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1832
1833                dwarf_dealloc( dbg, sizeAttr, DW_DLA_ATTR );
1834             }
1835
1836             fieldListType * containingType = NULL;
1837             std::string tName = convertCharToString(typeName);
1838             switch ( dieTag ) {
1839                case DW_TAG_structure_type: 
1840                case DW_TAG_class_type: 
1841                   containingType = new typeStruct( dieOffset, tName);
1842                   break;
1843                case DW_TAG_union_type: 
1844                   containingType = new typeUnion( dieOffset, tName);
1845                   break;
1846             }
1847
1848             assert( containingType != NULL );
1849             // //bperr ( "Adding structure, union, or class type '%s' (%lu)\n", typeName, (unsigned long)dieOffset );
1850             containingType = dynamic_cast<fieldListType *>(module->getModuleTypes()->addOrUpdateType( containingType ));
1851             newEnclosure = containingType;
1852
1853             dwarf_dealloc( dbg, typeName, DW_DLA_STRING );
1854          } break;
1855
1856       case DW_TAG_enumerator: 
1857          {
1858             /* An entry in an enumeration. */
1859             char * enumName = NULL;
1860             status = dwarf_diename( dieEntry, & enumName, NULL );
1861             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1862
1863             Dwarf_Attribute valueAttr;
1864             status = dwarf_attr( dieEntry, DW_AT_const_value, & valueAttr, NULL );
1865             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1866
1867             Dwarf_Signed enumValue = 0;
1868             if ( status == DW_DLV_OK ) {
1869                status = dwarf_formsdata( valueAttr, & enumValue, NULL );
1870                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1871
1872                dwarf_dealloc( dbg, valueAttr, DW_DLA_ATTR );
1873             }
1874
1875             // //bperr ( "Adding enum '%s' (%ld) to enumeration '%s' (%d)\n", enumName, (signed long)enumValue, currentEnclosure->getName(), currentEnclosure->getID() );
1876             currentEnum->addConstant( enumName, enumValue );
1877
1878             dwarf_dealloc( dbg, enumName, DW_DLA_STRING );
1879          } break;
1880
1881       case DW_TAG_member: 
1882          {
1883             char * memberName = NULL;
1884             status = dwarf_diename( dieEntry, & memberName, NULL );
1885             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1886
1887             Dwarf_Attribute typeAttribute;
1888             status = dwarf_attr( dieEntry, DW_AT_type, & typeAttribute, NULL );
1889             if ( status == DW_DLV_NO_ENTRY ) break;
1890             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1891
1892             Dwarf_Off typeOffset;
1893             status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
1894             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1895
1896             dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
1897
1898             //parsing_printf("%s/%d: %s/%d\n",
1899             //                     __FILE__, __LINE__, memberName, typeOffset);
1900             Type * memberType = module->getModuleTypes()->findOrCreateType( typeOffset );
1901
1902             Dwarf_Attribute locationAttr;
1903             status = dwarf_attr( dieEntry, DW_AT_data_member_location, & locationAttr, NULL );
1904             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1905
1906             if ( status == DW_DLV_NO_ENTRY ) { break; }
1907             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1908
1909             Dwarf_Locdesc **locationList;
1910             Dwarf_Signed listLength;
1911             status = dwarf_loclist_n( locationAttr, & locationList, & listLength, NULL );
1912             DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1913
1914             dwarf_dealloc( dbg, locationAttr, DW_DLA_ATTR );
1915
1916             //loc_t *loc = (loc_t *)malloc(listLength * sizeof(loc_t));
1917             vector<loc_t *>* locs = new vector<loc_t *>;
1918             long int baseAddress = 0;
1919             bool decodedAddress = decodeLocationListForStaticOffsetOrAddress( locationList, listLength, objFile, locs, & baseAddress );
1920             deallocateLocationList( dbg, locationList, listLength );
1921
1922             if ( ! decodedAddress ) { break; }
1923             assert( decodedAddress );
1924
1925             assert( (*locs)[0]->stClass == storageAddr );
1926
1927             /* DWARF stores offsets in bytes unless the member is a bit field.
1928                Correct memberOffset as indicated.  Also, memberSize is in bytes
1929                from the underlying type, not the # of bits used from it, so
1930                correct that as necessary as well. */
1931             long int memberSize = memberType->getSize();
1932
1933             Dwarf_Attribute bitOffset;
1934             status = dwarf_attr( dieEntry, DW_AT_bit_offset, & bitOffset, NULL );
1935             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1936
1937             if ( status == DW_DLV_OK ) {
1938                Dwarf_Unsigned memberOffset_du = (*locs)[0]->frameOffset;
1939                status = dwarf_formudata( bitOffset, &memberOffset_du, NULL );
1940                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1941
1942                dwarf_dealloc( dbg, bitOffset, DW_DLA_ATTR );
1943
1944                Dwarf_Attribute bitSize;
1945                status = dwarf_attr( dieEntry, DW_AT_bit_size, & bitSize, NULL );
1946                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1947
1948                Dwarf_Unsigned memberSize_du = memberSize;
1949                status = dwarf_formudata( bitSize, &memberSize_du, NULL );
1950                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1951
1952                dwarf_dealloc( dbg, bitSize, DW_DLA_ATTR );
1953
1954                /* If the DW_AT_byte_size field exists, there's some padding.
1955                   FIXME?  We ignore padding for now.  (We also don't seem to handle
1956                   bitfields right in getComponents() anyway...) */
1957             }
1958             else {
1959                (*locs)[0]->frameOffset *= 8;
1960                memberSize *= 8;
1961             } /* end if not a bit field member. */
1962
1963             if ( memberName != NULL ) {
1964                // /* DEBUG */ fprint( stderr, "Adding member to enclosure '%s' (%d): '%s' with type %lu at %ld and size %d\n", currentEnclosure->getName(), currentEnclosure->getID(), memberName, (unsigned long)typeOffset, loc->frameOffset, memberType->getSize() );
1965                std::string fName = convertCharToString(memberName);
1966                currentEnclosure->addField( fName, memberType, (*locs)[0]->frameOffset);
1967                dwarf_dealloc( dbg, memberName, DW_DLA_STRING );
1968             } else {
1969                /* An anonymous union [in a struct]. */
1970                std::string fName = "[anonymous union]";
1971                currentEnclosure->addField( fName, memberType, (*locs)[0]->frameOffset);
1972             }
1973          } break;
1974
1975       case DW_TAG_const_type:
1976       case DW_TAG_packed_type:
1977       case DW_TAG_volatile_type: 
1978          {
1979             char * typeName = NULL;
1980             status = dwarf_diename( dieEntry, & typeName, NULL );
1981             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1982
1983             /* Which type does it modify? */
1984             Dwarf_Attribute typeAttribute;
1985             status = dwarf_attr( dieEntry, DW_AT_type, & typeAttribute, NULL );
1986
1987             int typeSize = 0;
1988             Dwarf_Off typeOffset;
1989             Type * typeModified = NULL;
1990             if ( status == DW_DLV_NO_ENTRY ) {
1991                /* Presumably, a pointer or reference to void. */
1992                typeModified = module->getModuleTypes()->findType( "void" );
1993             } else {                    
1994                status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
1995                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
1996                //parsing_printf("%s/%d: %s/%d\n",
1997                //                          __FILE__, __LINE__, typeName, typeOffset);
1998                typeModified = module->getModuleTypes()->findOrCreateType( typeOffset );
1999                typeSize = typeModified->getSize();
2000
2001                dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
2002             } /* end if typeModified is not void */
2003
2004             // I'm taking out the type qualifiers for right now
2005             std::string tName = convertCharToString(typeName);
2006
2007             //                  Type * modifierType = new Type( typeName, dieOffset, TypeAttrib, typeSize, typeModified, dieTag );
2008             Type * modifierType = new typeTypedef(dieOffset, typeModified, tName);
2009             assert( modifierType != NULL );
2010             // //bperr ( "Adding modifier type '%s' (%lu) modifying (%lu)\n", typeName, (unsigned long)dieOffset, (unsigned long)typeOffset );
2011             modifierType = module->getModuleTypes()->addOrUpdateType( modifierType );
2012             dwarf_dealloc( dbg, typeName, DW_DLA_STRING );
2013          } break;
2014
2015       case DW_TAG_subroutine_type:
2016          /* If the pointer specifies argument types, this DIE has
2017             children of those types. */
2018       case DW_TAG_ptr_to_member_type:
2019       case DW_TAG_pointer_type:
2020       case DW_TAG_reference_type: 
2021          {
2022             char * typeName = NULL;
2023             status = dwarf_diename( dieEntry, & typeName, NULL );
2024             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2025
2026             /* To which type does it point? */
2027             Dwarf_Attribute typeAttribute;
2028             status = dwarf_attr( dieEntry, DW_AT_type, & typeAttribute, NULL );
2029             DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2030
2031             Dwarf_Off typeOffset = 0;
2032             Type * typePointedTo = NULL;
2033             if ( status == DW_DLV_NO_ENTRY ) {
2034                /* Presumably, a pointer or reference to void. */
2035                typePointedTo = module->getModuleTypes()->findType("void");
2036             } else {                    
2037                status = dwarf_global_formref( typeAttribute, & typeOffset, NULL );
2038                DWARF_FALSE_IF( status != DW_DLV_OK, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2039                //parsing_printf("%s/%d: %s/%d\n",
2040                //                          __FILE__, __LINE__, typeName, typeOffset);
2041                typePointedTo = module->getModuleTypes()->findOrCreateType( typeOffset );
2042
2043                dwarf_dealloc( dbg, typeAttribute, DW_DLA_ATTR );
2044             } /* end if typePointedTo is not void */
2045
2046             Type * indirectType = NULL;
2047             std::string tName = convertCharToString(typeName);
2048             switch ( dieTag ) {
2049                case DW_TAG_subroutine_type:
2050                   indirectType = new typeFunction(dieOffset, typePointedTo, tName);
2051                   break;
2052                case DW_TAG_ptr_to_member_type:
2053                case DW_TAG_pointer_type:
2054                   indirectType = new typePointer(dieOffset, typePointedTo, tName);
2055                   break;
2056                case DW_TAG_reference_type:
2057                   indirectType = new typeRef(dieOffset, typePointedTo, tName);
2058                   break;
2059             }
2060
2061             assert( indirectType != NULL );
2062             dwarf_printf( "Adding indirect type '%s' (%lu) pointing to (%lu)\n", typeName, (unsigned long)dieOffset, (unsigned long)typeOffset );
2063             indirectType = module->getModuleTypes()->addOrUpdateType( indirectType );
2064
2065             dwarf_dealloc( dbg, typeName, DW_DLA_STRING );
2066          } break;
2067
2068       case DW_TAG_variant_part:
2069          /* We don't support this (Pascal) type. */
2070       case DW_TAG_string_type:
2071          /* We don't support this (FORTRAN) type. */
2072       default:
2073          /* Nothing of interest. */
2074          // //bperr ( "Entry %lu with tag 0x%x ignored.\n", (unsigned long)dieOffset, dieTag );
2075          break;
2076    } /* end dieTag switch */
2077
2078    /* Recurse to its child, if any. */
2079    Dwarf_Die childDwarf;
2080    status = dwarf_child( dieEntry, & childDwarf, NULL );
2081    DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2082
2083    if ( status == DW_DLV_OK && parsedChild == false ) {         
2084       walkDwarvenTree( dbg, childDwarf, module, objFile, cuOffset, srcFiles, newFunction, newCommonBlock, newEnum, newEnclosure );
2085    }
2086
2087    /* Recurse to its first sibling, if any. */
2088    Dwarf_Die siblingDwarf;
2089    status = dwarf_siblingof( dbg, dieEntry, & siblingDwarf, NULL );
2090    DWARF_FALSE_IF( status == DW_DLV_ERROR, "%s[%d]: error walking DWARF tree.\n", __FILE__, __LINE__ );
2091
2092    /* Deallocate the entry we just parsed. */
2093    dwarf_dealloc( dbg, dieEntry, DW_DLA_DIE );
2094
2095    if ( status == DW_DLV_OK ) {
2096       /* Do the tail-call optimization by hand. */
2097       dieEntry = siblingDwarf;
2098       goto tail_recursion;
2099    }
2100
2101    /* When would we return false? :) */
2102    return true;
2103 } /* end walkDwarvenTree() */
2104
2105 extern void pd_dwarf_handler( Dwarf_Error, Dwarf_Ptr );
2106
2107 void Object::parseDwarfTypes( Symtab *objFile) 
2108 {
2109    // Man do we do to a lot of trouble for this...
2110    /*   
2111       assert( moduleTypes );
2112
2113       if ( moduleTypes->dwarfParsed() ) {
2114       dwarf_printf( "%s[%d]: already parsed %s, moduleTypes = %p\n", __FILE__, __LINE__, fileName, moduleTypes );
2115       std::vector<Symbol *> * bpfuncs = getProcedures( true );
2116       assert( bpfuncs );
2117       for( unsigned int i = 0; i < bpfuncs->size(); i++ ) {
2118       (*bpfuncs)[i]->fixupUnknown( this );
2119       }
2120       return;
2121       }
2122     */          
2123    dwarf_printf( "%s[%d]: parsing %s...\n", __FILE__, __LINE__, objFile );
2124
2125    /* Start the dwarven debugging. */
2126    Dwarf_Debug dbg;
2127    Module *mod = NULL, *fixUnknownMod = NULL;
2128
2129    int status = dwarf_elf_init( elfHdr.e_elfp(), DW_DLC_READ, & pd_dwarf_handler, getErrFunc(), & dbg, NULL );
2130    DWARF_RETURN_IF( status != DW_DLV_OK, "%s[%d]: error initializing libdwarf.\n", __FILE__, __LINE__ );
2131
2132    /* Iterate over the compilation-unit headers. */
2133    Dwarf_Unsigned hdr;
2134
2135    while( dwarf_next_cu_header( dbg, NULL, NULL, NULL, NULL, & hdr, NULL ) == DW_DLV_OK ) {
2136       /* Obtain the module DIE. */
2137       Dwarf_Die moduleDIE;
2138       status = dwarf_siblingof( dbg, NULL, &moduleDIE, NULL );
2139       DWARF_RETURN_IF( status != DW_DLV_OK, "%s[%d]: error finding next CU header.\n", __FILE__, __LINE__ );
2140
2141       /* Make sure we've got the right one. */
2142       Dwarf_Half moduleTag;
2143       status = dwarf_tag( moduleDIE, & moduleTag, NULL );
2144       DWARF_RETURN_IF( status != DW_DLV_OK, "%s[%d]: error acquiring CU header tag.\n", __FILE__, __LINE__ );
2145       assert( moduleTag == DW_TAG_compile_unit );
2146
2147       /* We may need this later. */
2148       Dwarf_Off cuOffset;
2149       status = dwarf_dieoffset( moduleDIE, & cuOffset, NULL );
2150       DWARF_RETURN_IF( status != DW_DLV_OK, "%s[%d]: error acquiring CU header offset.\n", __FILE__, __LINE__ );
2151
2152       /* Extract the name of this module. */
2153       char * moduleName;
2154       status = dwarf_diename( moduleDIE, & moduleName, NULL );
2155       if ( status == DW_DLV_NO_ENTRY ) {
2156          moduleName = strdup( "{ANONYMOUS}" );
2157          assert( moduleName != NULL );
2158       }
2159       DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error acquiring module name.\n", __FILE__, __LINE__ );
2160       dwarf_printf( "%s[%d]: considering compilation unit '%s'\n", __FILE__, __LINE__, moduleName );
2161
2162       /* Set the language, if any. */
2163       Dwarf_Attribute languageAttribute;
2164       status = dwarf_attr( moduleDIE, DW_AT_language, & languageAttribute, NULL );
2165       DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error acquiring language attribute.\n", __FILE__, __LINE__ );
2166
2167       /* Iterate over the tree rooted here; walkDwarvenTree() deallocates the passed-in DIE. */
2168       if (!objFile->findModule(mod, moduleName)){
2169          std::string modName = moduleName;
2170          std::string fName = extract_pathname_tail(modName);
2171          if (!objFile->findModule(mod, fName))
2172          {
2173             modName = objFile->file();
2174             if (!objFile->findModule(mod, modName))
2175                continue;
2176          }
2177       }
2178       if (!fixUnknownMod)
2179          fixUnknownMod = mod;
2180
2181       Dwarf_Signed cnt;
2182       char **srcfiles;
2183       int status;
2184       status = dwarf_srcfiles(moduleDIE, &srcfiles,&cnt, NULL);
2185       DWARF_RETURN_IF( status == DW_DLV_ERROR, "%s[%d]: error acquiring source file names.\n", __FILE__, __LINE__ );
2186
2187       if ( !walkDwarvenTree( dbg, moduleDIE, mod, objFile, cuOffset, srcfiles ) ) {
2188          //bpwarn ( "Error while parsing DWARF info for module '%s'.\n", moduleName );
2189          return;
2190       }
2191       if (status == DW_DLV_OK){
2192          for (unsigned i = 0; i < cnt; ++i) {
2193             /* use srcfiles[i] */
2194             dwarf_dealloc(dbg, srcfiles[i], DW_DLA_STRING);
2195          }
2196          dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST);
2197       }
2198
2199       dwarf_dealloc( dbg, moduleName, DW_DLA_STRING );
2200    } /* end iteration over compilation-unit headers. */
2201
2202    if (!fixUnknownMod)
2203       return;
2204
2205    /* Fix type list. */
2206    typeCollection *moduleTypes = fixUnknownMod->getModuleTypes();
2207    assert(moduleTypes);
2208    hash_map< int, Type * >::iterator typeIter =  moduleTypes->typesByID.begin();
2209    for(;typeIter!=moduleTypes->typesByID.end();typeIter++){
2210       typeIter->second->fixupUnknowns(fixUnknownMod);
2211    } /* end iteratation over types. */
2212
2213    /* Fix the types of variables. */   
2214    std::string variableName;
2215    hash_map< std::string, Type * >::iterator variableIter = moduleTypes->globalVarsByName.begin();
2216    for(;variableIter!=moduleTypes->globalVarsByName.end();variableIter++){ 
2217       if (variableIter->second->getDataClass() == dataUnknownType && 
2218             moduleTypes->findType( variableIter->second->getID() ) != NULL ) {
2219          moduleTypes->globalVarsByName[ variableIter->first ] = moduleTypes->findType( variableIter->second->getID() );
2220       } /* end if data class is unknown but the type exists. */
2221    } /* end iteration over variables. */
2222
2223
2224    // Do Not clean up Elf. We need the Elf pointer when we are writing back to a file again
2225    // writeBackSymbols will not work - giri(7/26/2007)
2226
2227 #if 0
2228    /* Clean up. */
2229    Elf * dwarfElf;
2230    status = dwarf_get_elf( dbg, & dwarfElf, NULL );
2231    DWARF_RETURN_IF( status != DW_DLV_OK, "%s[%d]: error during libdwarf cleanup.\n", __FILE__, __LINE__ );
2232 #endif  
2233
2234    status = dwarf_finish( dbg, NULL );
2235    DWARF_RETURN_IF( status != DW_DLV_OK, "%s[%d]: error during libdwarf cleanup.\n", __FILE__, __LINE__ );
2236
2237    //FIX THIS: Have to be moved, where this is going to be done on a module-by-module basis
2238 #if 0
2239    /* Fix the type references in functions. */
2240    std::vector<Symbol *> funcs;
2241    getAllSymbolsByType(funcs, Symbol::ST_FUNCTION);
2242    for( unsigned int i = 0; i < funcs->size(); i++ ) {
2243       funcs[i].fixupUnknown( this );
2244    }
2245 #endif  
2246    moduleTypes->setDwarfParsed();
2247
2248 } /* end parseDwarfTypes() */
2249
2250 int dwarf_printf(const char *format, ...)
2251 {
2252    static int dyn_debug_dwarf = 0;
2253
2254    if (dyn_debug_dwarf == -1) {
2255       return 0;
2256    }
2257    if (!dyn_debug_dwarf) {
2258       char *p = getenv("DYNINST_DEBUG_DWARF");
2259       if (!p)
2260          p = getenv("SYMTAB_DEBUG_DWARF");
2261       if (p) {
2262          fprintf(stderr, "Enabling SymtabAPI dwarf parsing\n");
2263          dyn_debug_dwarf = 1;
2264       }
2265       else {
2266          dyn_debug_dwarf = -1;
2267          return 0;
2268       }
2269    }
2270
2271    if (!format)
2272       return -1;
2273
2274    va_list va;
2275    va_start(va, format);
2276    int ret = vfprintf(stderr, format, va);
2277    va_end(va);
2278
2279    return ret;
2280 }