Fix vpadd decoding. Clean up control flow target logic and shared pointer constructio...
[dyninst.git] / symtabAPI / src / dwarfWalker.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #include "dwarfWalker.h"
32 #include "headers.h"
33 #include "Module.h"
34 #include "Symtab.h"
35 #include "Collections.h"
36 #include "dwarf.h"
37 #include "Object.h"
38 #include "Object-elf.h"
39 #include "Function.h"
40 #include "debug.h"
41 #include "dwarfExprParser.h"
42 #include "pathName.h"
43 #include "debug_common.h"
44
45 using namespace Dyninst;
46 using namespace SymtabAPI;
47 using namespace Dwarf;
48 using namespace std;
49
50 #define DWARF_FAIL_RET_VAL(x, v) {                                      \
51       int status = (x);                                                 \
52       if (status != DW_DLV_OK) {                                        \
53          types_printf("[%s:%d]: libdwarf returned %d, ret false\n", FILE__, __LINE__, status); \
54          return (v);                                                    \
55       }                                                                 \
56    }
57 #define DWARF_FAIL_RET(x) DWARF_FAIL_RET_VAL(x, false)
58
59 #define DWARF_ERROR_RET_VAL(x, v) {                                     \
60       int status = (x);                                                 \
61       if (status == DW_DLV_ERROR) {                                     \
62          types_printf("[%s:%d]: parsing failure, ret false\n", FILE__, __LINE__); \
63          return (v);                                                    \
64       }                                                                 \
65    }
66 #define DWARF_ERROR_RET(x) DWARF_ERROR_RET_VAL(x, false)
67
68 #define DWARF_CHECK_RET_VAL(x, v) {                                     \
69       if (x) {                                                          \
70          types_printf("[%s:%d]: parsing failure, ret false\n", FILE__, __LINE__); \
71          return (v);                                                    \
72       }                                                                 \
73    }
74 #define DWARF_CHECK_RET(x) DWARF_CHECK_RET_VAL(x, false)
75
76 DwarfWalker::DwarfWalker(Symtab *symtab, Dwarf_Debug &dbg)
77    :
78    dbg_(dbg),
79    mod_(NULL),
80    symtab_(symtab),
81    tc_(NULL),
82    is_mangled_name_(false),
83    modLow(0),
84    modHigh(0),
85    cu_header_length(0),
86    version(0),
87    abbrev_offset(0),
88    addr_size(0),
89    offset_size(0),
90    extension_size(0),
91    signature(),
92    typeoffset(0),
93    next_cu_header(0),
94    compile_offset(0),
95    srcFileList_(NULL)
96 {
97 }
98
99 DwarfWalker::~DwarfWalker() {
100    for(unsigned i = 0; i < srcFiles_.size(); i++)
101    {
102       dwarf_dealloc(dbg(), const_cast<char*>(srcFiles_[i]), DW_DLA_STRING);
103    }
104    if(srcFileList_) dwarf_dealloc(dbg(), srcFileList_, DW_DLA_LIST);
105 }
106
107 bool DwarfWalker::parse() {
108    dwarf_printf("Parsing DWARF for %s\n", symtab_->file().c_str());
109
110    /* Start the dwarven debugging. */
111    Module *fixUnknownMod = NULL;
112    mod_ = NULL;
113
114    /* Prepopulate type signatures for DW_FORM_ref_sig8 */
115    findAllSig8Types();
116
117    /* First .debug_types (0), then .debug_info (1) */
118    for (int i = 0; i < 2; ++i) {
119       Dwarf_Bool is_info = i;
120
121       /* NB: parseModule used to compute compile_offset as 11 bytes before the
122        * first die offset, to account for the header.  This would need 23 bytes
123        * instead for 64-bit format DWARF, and even more for type units.
124        * (See DWARF4 sections 7.4 & 7.5.1.)
125        * But more directly, we know the first CU is just at 0x0, and each
126        * following CU is already reported in next_cu_header.
127        */
128       compile_offset = next_cu_header = 0;
129
130       /* Iterate over the compilation-unit headers. */
131       while (dwarf_next_cu_header_c(dbg(), is_info,
132                                     &cu_header_length,
133                                     &version,
134                                     &abbrev_offset,
135                                     &addr_size,
136                                     &offset_size,
137                                     &extension_size,
138                                     &signature,
139                                     &typeoffset,
140                                     &next_cu_header, NULL) == DW_DLV_OK ) {
141          contexts_.push();
142          bool ret = parseModule(is_info, fixUnknownMod);
143          contexts_.pop();
144          if (!ret) return false;
145          compile_offset = next_cu_header;
146       }
147    }
148    
149    if (!fixUnknownMod)
150       return true;
151
152    dwarf_printf("Fixing types for final module %s\n", fixUnknownMod->fileName().c_str());
153    
154    /* Fix type list. */
155    typeCollection *moduleTypes = typeCollection::getModTypeCollection(fixUnknownMod);
156    assert(moduleTypes);
157    dyn_hash_map< int, Type * >::iterator typeIter =  moduleTypes->typesByID.begin();
158    for (;typeIter!=moduleTypes->typesByID.end();typeIter++)
159    {
160       typeIter->second->fixupUnknowns(fixUnknownMod);
161    } /* end iteration over types. */
162    
163    /* Fix the types of variables. */   
164    std::string variableName;
165    dyn_hash_map< std::string, Type * >::iterator variableIter = moduleTypes->globalVarsByName.begin();
166    for (;variableIter!=moduleTypes->globalVarsByName.end();variableIter++)
167    { 
168       if (variableIter->second->getDataClass() == dataUnknownType && 
169           moduleTypes->findType( variableIter->second->getID() ) != NULL ) 
170       {
171          moduleTypes->globalVarsByName[ variableIter->first ] 
172             = moduleTypes->findType( variableIter->second->getID() );
173       } /* end if data class is unknown but the type exists. */
174    } /* end iteration over variables. */
175       
176    moduleTypes->setDwarfParsed();
177    return true;
178 }
179
180 bool DwarfWalker::parseModule(Dwarf_Bool is_info, Module *&fixUnknownMod) {
181    /* Obtain the module DIE. */
182    Dwarf_Die moduleDIE;
183    DWARF_FAIL_RET(dwarf_siblingof_b( dbg(), NULL, is_info, &moduleDIE, NULL ));
184    
185    /* Make sure we've got the right one. */
186    Dwarf_Half moduleTag;
187    DWARF_FAIL_RET(dwarf_tag( moduleDIE, & moduleTag, NULL ));
188
189    if (moduleTag != DW_TAG_compile_unit
190          && moduleTag != DW_TAG_partial_unit
191          && moduleTag != DW_TAG_type_unit)
192       return false;
193    
194    /* Extract the name of this module. */
195    std::string moduleName;
196    if (!findDieName( moduleDIE, moduleName )) return false;
197
198    if (moduleName.empty() && moduleTag == DW_TAG_type_unit) {
199       uint64_t sig8 = * reinterpret_cast<uint64_t*>(&signature);
200       char buf[20];
201       snprintf(buf, sizeof(buf), "{%016llx}", (long long) sig8);
202       moduleName = buf;
203    }
204
205    if (moduleName.empty()) {
206       moduleName = "{ANONYMOUS}";
207    }
208
209    dwarf_printf("Next DWARF module: %s with DIE %p and tag %d\n", moduleName.c_str(), moduleDIE, moduleTag);
210    
211    /* Set the language, if any. */
212    Dwarf_Attribute languageAttribute;
213    DWARF_ERROR_RET(dwarf_attr( moduleDIE, DW_AT_language, & languageAttribute, NULL ));
214    
215    // Set low and high ranges; this can fail, so don't check return addr.
216    setEntry(moduleDIE);
217
218    // These may not be set.
219    Address tempModLow, tempModHigh;
220    modLow = modHigh = 0;
221    if (findConstant(DW_AT_low_pc, tempModLow)) {
222       obj()->convertDebugOffset(tempModLow, modLow);
223    }
224    if (findConstant(DW_AT_high_pc, tempModHigh)) {
225       obj()->convertDebugOffset(tempModHigh, modHigh);
226    }
227
228    if (!symtab()->findModuleByName(mod_, moduleName))
229    {
230       std::string fName = extract_pathname_tail(moduleName);
231       if (!symtab()->findModuleByName(mod_, fName)) {
232          moduleName = symtab()->file();
233          if (!symtab()->findModuleByName(mod_, moduleName)) {
234             mod_ = symtab()->getDefaultModule();
235          }
236       }
237    }
238
239    dwarf_printf("Mapped to Symtab module %s\n", mod_->fileName().c_str());
240    
241    if (!fixUnknownMod)
242       fixUnknownMod = mod_;
243
244    if (!buildSrcFiles(moduleDIE)) return false;
245    
246    tc_ = typeCollection::getModTypeCollection(mod_);
247
248    if (!parse_int(moduleDIE, true)) return false;
249
250    return true;
251
252
253
254        
255 bool DwarfWalker::buildSrcFiles(Dwarf_Die entry) {
256    for(unsigned i = 0; i < srcFiles_.size(); i++)
257    {
258       dwarf_dealloc(dbg(), const_cast<char*>(srcFiles_[i]), DW_DLA_STRING);
259       if(srcFileList_) {
260          dwarf_dealloc(dbg(), srcFileList_, DW_DLA_LIST);
261          srcFileList_ = NULL;
262       }
263    }
264    srcFiles_.clear();
265
266    Dwarf_Signed cnt = 0;
267    DWARF_ERROR_RET(dwarf_srcfiles(entry, &srcFileList_, &cnt, NULL));
268
269    for (unsigned i = 0; i < cnt; ++i) {
270       srcFiles_.push_back(srcFileList_[i]);
271    }
272    return true;
273 }
274
275 Object *DwarfWalker::obj() { 
276    return symtab_->getObject();
277 }
278
279 // As mentioned in the header, this is separate from parse()
280 // so we can have a non-Context-creating parse method that reuses
281 // the Context from the parent. This allows us to pass in current
282 // function, etc. without the Context stack exploding
283 bool DwarfWalker::parse_int(Dwarf_Die e, bool p) {
284    dwarf_printf("PARSE_INT entry, context size %d\n", (int) contexts_.c.size());
285    // We escape the loop by checking parseSibling() after 
286    // parsing this DIE and its children, if any
287    while(1) {
288       ContextGuard cg(contexts_);
289
290       setEntry(e);
291       setParseSibling(p);
292
293       if (!findTag()) return false;
294       if (!findOffset()) return false;
295       curName() = std::string();
296       setMangledName(false);
297
298       dwarf_printf("(0x%lx) Parsing entry %p with context size %d, func %p, encl %p\n",
299                    id(),
300                    e,
301                    (int) contexts_.c.size(), 
302                    curFunc(),
303                    //                   (curFunc() && !curFunc()->getAllMangledNames().empty()) ? 
304                    //curFunc()->getAllMangledNames()[0].c_str() : "<null>",
305                    curEnclosure());
306
307       bool ret = false;
308       
309    // BLUEGENE BUG HACK
310 #if defined(os_bg)
311       if (tag() == DW_TAG_base_type ||
312           tag() == DW_TAG_const_type ||
313           tag() == DW_TAG_pointer_type) {
314          // XLC compilers nest a bunch of stuff under an invented function; however,
315          // this is broken (they don't close the function properly). If we see a 
316          // tag like this, close off the previous function immediately
317          clearFunc();
318       }
319 #endif
320
321
322
323       switch(tag()) {
324          case DW_TAG_subprogram:
325          case DW_TAG_entry_point:
326              ret = parseSubprogram(NormalFunc);
327              break;
328          case DW_TAG_inlined_subroutine:
329             ret = parseSubprogram(InlinedFunc);
330             break;
331          case DW_TAG_lexical_block:
332             ret = parseLexicalBlock();
333             break;
334          case DW_TAG_common_block:
335             ret = parseCommonBlock();
336             break;
337          case DW_TAG_constant:
338             ret = parseConstant();
339             break;
340          case DW_TAG_variable:
341             ret = parseVariable();
342             break;
343          case DW_TAG_formal_parameter:
344             ret = parseFormalParam();
345             break;
346          case DW_TAG_base_type:
347             ret = parseBaseType();
348             break;
349          case DW_TAG_typedef:
350             ret = parseTypedef();
351             break;
352          case DW_TAG_array_type:
353             ret = parseArray();
354             break;
355          case DW_TAG_subrange_type:
356             ret = parseSubrange();
357             break;
358          case DW_TAG_enumeration_type:
359             ret = parseEnum();
360             break;
361          case DW_TAG_inheritance:
362             ret = parseInheritance();
363             break;
364          case DW_TAG_structure_type:
365          case DW_TAG_union_type:
366          case DW_TAG_class_type: 
367             ret = parseStructUnionClass();
368             break;
369          case DW_TAG_enumerator:
370             ret = parseEnumEntry();
371             break;
372          case DW_TAG_member:
373             ret = parseMember();
374             break;
375          case DW_TAG_const_type:
376          case DW_TAG_packed_type:
377          case DW_TAG_volatile_type: 
378             ret = parseConstPackedVolatile();
379             break;
380          case DW_TAG_subroutine_type:
381             /* If the pointer specifies argument types, this DIE has
382                children of those types. */
383          case DW_TAG_ptr_to_member_type:
384          case DW_TAG_pointer_type:
385          case DW_TAG_reference_type: 
386             ret = parseTypeReferences();
387             break;
388          case DW_TAG_compile_unit:
389             dwarf_printf("(0x%lx) Compilation unit, parsing children\n", id());
390             // Parse child
391             ret = parseChild();
392             break;
393          case DW_TAG_partial_unit:
394             dwarf_printf("(0x%lx) Partial unit, parsing children\n", id());
395             // Parse child
396             ret = parseChild();
397             break;
398          case DW_TAG_type_unit:
399             dwarf_printf("(0x%lx) Type unit, parsing children\n", id());
400             // Parse child
401             ret = parseChild();
402             break;
403          default:
404             dwarf_printf("(0x%lx) Warning: unparsed entry with tag %x\n",
405                          id(), tag());
406             ret = true;
407             break;
408       }
409       
410       dwarf_printf("Finished parsing 0x%lx, ret %d, parseChild %d, parseSibling %d\n",
411                    id(), ret, parseChild(), parseSibling());
412
413       if (ret && parseChild() ) {
414          // Parse children
415          Dwarf_Die childDwarf;
416          int status = dwarf_child( entry(), & childDwarf, NULL );
417          DWARF_CHECK_RET(status == DW_DLV_ERROR);
418          if (status == DW_DLV_OK) {
419             if (!parse_int(childDwarf, true)) return false;
420          }
421       }
422
423       if (!parseSibling()) {
424          dwarf_printf("(0x%lx) Skipping sibling parse\n", id());
425          break;
426       }
427
428       dwarf_printf("(0x%lx) Asking for sibling\n", id());
429       Dwarf_Die siblingDwarf;
430       Dwarf_Bool is_info = dwarf_get_die_infotypes_flag(entry());
431       int status =  dwarf_siblingof_b( dbg(), entry(), is_info, & siblingDwarf, NULL );
432
433       DWARF_CHECK_RET(status == DW_DLV_ERROR);
434       
435       /* Deallocate the entry we just parsed. */
436       dwarf_dealloc( dbg(), entry(), DW_DLA_DIE );
437
438       if (status != DW_DLV_OK) {
439          break;
440       }
441
442       e = siblingDwarf;
443    }
444    
445    dwarf_printf("PARSE_INT exit, context size %d\n", (int) contexts_.c.size());
446    return true;
447 }
448
449 bool DwarfWalker::parseCallsite()
450 {
451    Dwarf_Bool has_line = false, has_file = false;
452    DWARF_FAIL_RET(dwarf_hasattr(entry(), DW_AT_call_file, &has_file, NULL));
453    if (!has_file)
454       return true;
455    DWARF_FAIL_RET(dwarf_hasattr(entry(), DW_AT_call_line, &has_line, NULL));
456    if (!has_line)
457       return true;
458
459    const char* inline_file;
460    bool result = findString(DW_AT_call_file, inline_file);
461    if (!result)
462       return false;
463
464    Dyninst::Offset inline_line;
465    result = findConstant(DW_AT_call_line, inline_line);
466    if (!result)
467       return false;
468
469    InlinedFunction *ifunc = static_cast<InlinedFunction *>(curFunc());
470    ifunc->callsite_file = inline_file;
471    ifunc->callsite_line = inline_line;
472    return true;
473 }
474
475 bool DwarfWalker::setFunctionFromRange(inline_t func_type)
476 {
477    //Use the lowest range as an entry for symbol matching
478    Address lowest = 0x0;
479    bool set_lowest = false;
480    if (!hasRanges()) {
481      dwarf_printf("(0x%lx) setFunctionFromRange has no ranges, returning false\n", id());
482      
483       return false;
484    }
485    for (range_set_t::iterator i = ranges_begin(); i != ranges_end(); i++) {
486       if (!set_lowest) {
487          lowest = i->first;
488          set_lowest = true;
489          continue;
490       }
491       if (lowest > i->first)
492          lowest = i->first;
493    }
494    if (!set_lowest) {
495       //No ranges.  Don't panic, this is probably an abstract origin or specification
496       // we'll get to it latter if it's really used.
497      dwarf_printf("(0x%lx) setFunctionFromRange has ranges, but no lowest, returning false\n", id());
498       return false;
499    }
500
501    if (func_type == InlinedFunc) {
502       FunctionBase *parent = curFunc();
503       if (!parent) {
504          //InlinedSubroutine without containing subprogram.  Weird.
505         dwarf_printf("(0x%lx) setFunctionFromRange found inline without parent, returning false\n", id());
506          return false;
507       }
508       InlinedFunction *ifunc = new InlinedFunction(parent);
509       setFunc(ifunc);
510       return true;
511    }
512
513    //Try to associate the function with existing symbols
514    Function *f = NULL;
515    bool result = symtab()->findFuncByEntryOffset(f, lowest);
516    if (result) {
517       dwarf_printf("(0x%lx) Lookup by offset 0x%lx identifies %p\n",
518                    id(), lowest, curFunc());
519       setFunc(f);
520       return true;
521    } else 
522    {
523      dwarf_printf("(0x%lx) Lookup by offset 0x%lx failed\n", id(), lowest);
524    }
525    
526
527    
528    return true;
529 }
530
531 bool DwarfWalker::parseSubprogram(DwarfWalker::inline_t func_type) {
532    bool name_result;
533    FunctionBase *func = NULL;
534
535    dwarf_printf("(0x%lx) parseSubprogram entry\n", id());
536
537    parseRangeTypes();
538    setFunctionFromRange(func_type);
539    func = curFunc();
540
541    // Name first
542    name_result = findFuncName();
543
544    if (curEnclosure() && !func) {
545       // This is a member function; create the type entry
546       // Since curFunc is false, we're not going back to reparse this
547       // entry with a function object.
548       Type *ftype = NULL;
549       getReturnType(false, ftype);
550       addFuncToContainer(ftype);
551       dwarf_printf("(0x%lx) parseSubprogram not parsing member function's children\n", id());
552       
553       setParseChild(false);
554    }
555
556    //curFunc will be set if we're parsing a defined object, or
557    // if we're recursively parsing a specification or abstract
558    // entry under a defined object.  It'll be unset if we're
559    // parsing a specification or abstract entry at the top-level
560    //This keeps us from parsing abstracts or specifications until
561    // we need them.
562    if (!func) {
563       dwarf_printf("(0x%lx) parseSubprogram not parsing children b/c curFunc() NULL\n", id());
564       setParseChild(false);
565       return true;
566    }
567
568    if (parsedFuncs.find(func) != parsedFuncs.end()) {
569       dwarf_printf("(0x%lx) parseSubprogram not parsing children b/c curFunc() not in parsedFuncs\n", id());
570       if(name_result) {
571           dwarf_printf("\tname is %s\n", curName().c_str());
572       }
573       setParseChild(false);
574       return true;
575    }
576
577    if (name_result && !curName().empty()) {
578       dwarf_printf("(0x%lx) Identified function name as %s\n", id(), curName().c_str());
579       if (isMangledName()) {
580           func->addMangledName(curName(), true);
581       }
582       // Only keep pretty names around for inlines, which probably don't have mangled names
583       else {
584           dwarf_printf("(0x%lx) Adding as pretty name to inline\n", id());
585           func->addPrettyName(curName(), true);
586       }
587    }
588
589    //Collect callsite information for inlined functions.
590    if (func_type == InlinedFunc) {
591       parseCallsite();
592    }
593    
594    // Get the return type
595    Type *returnType = NULL;
596    if (!func->getReturnType()) {
597       getReturnType(false, returnType);
598       if (returnType)
599          func->setReturnType(returnType);
600    }
601
602    // Get range information
603    if (hasRanges()) {
604        if(func->ranges.empty()) {
605            Address last_low = 0, last_high = 0;
606            func->ranges.reserve(rangesSize());
607            for (range_set_t::iterator i = ranges_begin(); i != ranges_end(); i++) {
608                Address low = i->first;
609                Address high = i->second;
610                if (last_low == low && last_high == high)
611                    continue;
612                last_low = low;
613                last_high = high;
614                
615                func->ranges.push_back(FuncRange(low, high - low, func));         
616            }
617        }
618    }
619    // Dwarf outlines some function information. You have the base entry, which contains
620    // address ranges, frame base information, and optionally a "abstract origin"
621    // or "specification" entry that points to more information. 
622    // We want to skip parsing specification or abstract entries until we have
623    // the base entry and can find/create the corresponding function object. 
624
625
626    // Get the frame base if it exists
627    if (!getFrameBase()) return false;
628
629    // Parse parent nodes and their children but not their sibling
630    bool hasAbstractOrigin = false;
631    if (!handleAbstractOrigin(hasAbstractOrigin)) return false;
632    if (hasAbstractOrigin) {
633       dwarf_printf("(0x%lx) Parsing abstract parent\n", id());
634       if (!parse_int(abstractEntry(), false)) return false;
635       dwarf_dealloc(dbg(), abstractEntry(), DW_DLA_DIE); 
636    } 
637    // An abstract origin will point to a specification if it exists
638    // This can actually be three-layered, so backchain again
639    bool hasSpecification = false;
640    if (!handleSpecification(hasSpecification)) return false;
641    if ( hasSpecification ) {
642       dwarf_printf("(0x%lx) Parsing specification entry\n", id());
643       if (!parse_int(specEntry(), false)) return false;
644    }
645
646    parsedFuncs.insert(func);
647
648    return true;
649 }
650
651 bool DwarfWalker::parseHighPCLowPC()
652 {
653    Dwarf_Attribute hasLow;
654
655    Dwarf_Attribute hasHigh;
656    if(dwarf_attr(entry(), DW_AT_low_pc, &hasLow, NULL) != DW_DLV_OK) return false;
657    if(dwarf_attr(entry(), DW_AT_high_pc, &hasHigh, NULL) != DW_DLV_OK) return false;
658
659    Address low, high;
660    Address tempLow, tempHigh;
661    if (!findConstant(DW_AT_low_pc, tempLow)) return false;
662    if (!findConstant(DW_AT_high_pc, tempHigh)) return false;
663    obj()->convertDebugOffset(tempLow, low);
664    obj()->convertDebugOffset(tempHigh, high);
665    Dwarf_Half form;
666    DWARF_FAIL_RET(dwarf_whatform(hasHigh, &form, NULL));
667    
668    if(form != DW_FORM_addr)
669    {
670      high += low;
671    }
672    dwarf_printf("(0x%lx) Lexical block from 0x%lx to 0x%lx\n", id(), low, high);
673    setRange(make_pair(low, high));
674    return true;
675    
676 }
677
678
679 bool DwarfWalker::parseRangeTypes() {
680    dwarf_printf("(0x%lx) Parsing ranges\n", id());
681
682    clearRanges();
683    parseHighPCLowPC();
684    
685
686    Dwarf_Bool hasRanges = false;
687    DWARF_FAIL_RET(dwarf_hasattr(entry(), DW_AT_ranges, &hasRanges, NULL));
688    if (hasRanges) {
689       Address range_offset;
690       if (!findConstant(DW_AT_ranges, range_offset)) return false;
691       
692       Dwarf_Ranges *ranges = NULL;
693       Dwarf_Signed ranges_length = 0;
694       DWARF_FAIL_RET(dwarf_get_ranges_a(dbg(), (Dwarf_Off) range_offset, entry(),
695                                         &ranges, &ranges_length, NULL, NULL));
696
697       bool done = false;
698       for (unsigned i = 0; i < ranges_length && !done; i++) {
699          Dwarf_Ranges *cur = ranges + i;
700          Address cur_base = modLow;
701          switch (cur->dwr_type) {
702             case DW_RANGES_ENTRY: {
703                Address low = cur->dwr_addr1 + cur_base;
704                Address high = cur->dwr_addr2 + cur_base;
705                dwarf_printf("(0x%lx) Lexical block from 0x%lx to 0x%lx\n", id(), low, high);
706                setRange(make_pair(low, high));
707                break;
708             }
709             case DW_RANGES_ADDRESS_SELECTION:
710                cur_base = cur->dwr_addr2;
711                break;
712             case DW_RANGES_END:
713                done = true;
714                break;
715          }
716       }
717       dwarf_ranges_dealloc(dbg(), ranges, ranges_length);
718       
719    }   
720    return true;
721 }
722
723 bool DwarfWalker::parseLexicalBlock() {
724    dwarf_printf("(0x%lx) Parsing lexical block\n", id());
725    return parseRangeTypes();
726 }
727
728 bool DwarfWalker::parseCommonBlock() {
729    dwarf_printf("(0x%lx) Parsing common block\n", id());
730
731    std::string commonBlockName;
732    if (!findDieName( entry(), commonBlockName )) return false;
733    
734    std::vector<Symbol *> commonBlockVars;
735    if (!symtab()->findSymbol(commonBlockVars,
736                              commonBlockName,
737                              Symbol::ST_OBJECT,
738                              SymtabAPI::anyName)) {
739       //pgcc 6 is naming common blocks with a trailing underscore
740       std::string cbvname = commonBlockName + std::string("_");
741       symtab()->findSymbol(commonBlockVars,
742                            cbvname, 
743                            Symbol::ST_OBJECT,
744                            SymtabAPI::anyName);
745    }
746    if (commonBlockVars.empty()) {
747       dwarf_printf("(0x%lx) Couldn't find variable for common block %s\n", id(), commonBlockName.c_str());
748       return false;
749    }
750    
751    Symbol *commonBlockVar = commonBlockVars[0];
752    if(!commonBlockVar)
753    {
754      assert(!"No common block variables to parse!");
755      return false;
756    }
757
758
759    typeCommon *commonBlockType = NULL;
760
761    commonBlockType = dynamic_cast<typeCommon *>(tc()->findVariableType(commonBlockName));
762    if (commonBlockType == NULL) {
763       commonBlockType = new typeCommon( type_id(), commonBlockName );
764       assert( commonBlockType != NULL );
765       tc()->addGlobalVariable( commonBlockName, commonBlockType );
766    }    
767
768    setCommon(commonBlockType);
769
770    return true;
771 }
772
773 bool DwarfWalker::parseConstant() {
774    // Right now we don't handle these
775    dwarf_printf("(0x%lx) Skipping named constant/variable with constant value\n", id());
776    return true;
777 }
778
779 bool DwarfWalker::parseVariable() {
780    dwarf_printf("(0x%lx) ParseVariable entry\n", id());
781    /* Acquire the name, type, and line number. */
782    /* A variable may occur inside a function, as either static or local.
783       A variable may occur inside a container, as C++ static member.
784       A variable may not occur in either, as a global. 
785       
786       For the first two cases, we need the variable's name, its type,
787       its line number, and its offset or address in order to tell
788       Dyninst about it.  Dyninst only needs to know the name and type
789       of a global.  (Actually, it already knows the names of the globals;
790       we're really just telling it the types.)
791       
792       Variables may have two entries, the second, with a _specification,
793       being the only one with the location. */
794       
795    /* If this DIE has a _specification, use that for the rest of our inquiries. */
796    bool hasSpecification = false;
797    if (!handleSpecification(hasSpecification)) return false;
798
799    if (!findName(curName())) return false;
800
801    removeFortranUnderscore(curName());
802
803    /* We'll start with the location, since that's most likely to
804       require the _specification. */
805
806    std::vector<VariableLocation> locs;
807    if (!decodeLocationList(DW_AT_location, NULL, locs)) return false;
808    if (locs.empty()) return true;
809    
810    for (unsigned i=0; i<locs.size(); i++) {
811       //if (locs[i].stClass != storageAddr) 
812       //continue;
813       if (locs[i].lowPC) {
814          Offset newlowpc = locs[i].lowPC;
815          bool result = obj()->convertDebugOffset(locs[i].lowPC, newlowpc);
816          if (result)
817             locs[i].lowPC = newlowpc;
818       }
819       if (locs[i].hiPC) {
820          Offset newhipc = locs[i].hiPC;
821          bool result = obj()->convertDebugOffset(locs[i].hiPC, newhipc);
822          if (result)
823             locs[i].hiPC = newhipc;
824       }
825    }
826
827    Type *type = NULL;
828    if (!findType(type, false)) return false;
829    assert(type);
830    
831    Dwarf_Unsigned variableLineNo;
832    bool hasLineNumber = false;
833    std::string fileName;
834
835    if (curFunc() || curEnclosure()) {
836       if (!getLineInformation(variableLineNo, hasLineNumber, fileName)) return false;
837    }
838
839    if (!curFunc() && !curEnclosure()) {
840       /* The typeOffset forms a module-unique type identifier,
841          so the Type look-ups by it rather than name. */
842       dwarf_printf("(0x%lx) Adding global variable\n", id());
843
844       Dyninst::Offset addr = 0;
845       if (locs.size() && locs[0].stClass == storageAddr)
846          addr = locs[0].frameOffset;
847       Variable *var;
848       bool result = symtab()->findVariableByOffset(var, addr);
849       if (result) {
850          var->setType(type);
851       }      
852       tc()->addGlobalVariable( curName(), type);
853    } /* end if this variable is a global */
854    else if (curFunc()) {
855       /* We now have the variable name, type, offset, and line number.
856          Tell Dyninst about it. */
857       if (!nameDefined()) return true;
858
859       localVar * newVariable = new localVar(curName(),
860                                             type,
861                                             fileName, 
862                                             (int) variableLineNo, 
863                                             curFunc());
864       dwarf_printf("(0x%lx) localVariable '%s' (%p), currentFunction %p\n", 
865                    id(), curName().c_str(), newVariable, curFunc());
866
867       for (unsigned int i = 0; i < locs.size(); ++i) {
868          dwarf_printf("(0x%lx) (%s) Adding location %d of %d: (0x%lx - 0x%lx): %s, %s, %s, %ld\n",
869                       id(), newVariable->getName().c_str(), i+1, (int) locs.size(), locs[i].lowPC, locs[i].hiPC, 
870                       storageClass2Str(locs[i].stClass),
871                       storageRefClass2Str(locs[i].refClass),
872                       locs[i].mr_reg.name().c_str(),
873                       locs[i].frameOffset);
874          newVariable->addLocation(locs[i]);
875       }
876       curFunc()->addLocalVar(newVariable);
877    } /* end if a local or static variable. */
878    else if (curEnclosure()) {
879       if (!nameDefined()) return true;
880       assert( locs[0].stClass != storageRegOffset );
881       dwarf_printf("(0x%lx) Adding variable to an enclosure\n", id());
882
883       curEnclosure()->addField( curName(), type, locs[0].frameOffset);
884    } /* end if this variable is not global */
885    return true;
886 }
887
888 bool DwarfWalker::parseFormalParam() {
889    dwarf_printf("(0x%lx) Parsing formal parameter\n", id());
890
891    /* A formal parameter must occur in the context of a function.
892       (That is, we can't do anything with a formal parameter to a
893       function we don't know about.) */
894    /* It's probably worth noting that a formal parameter may have a
895       default value.  Since, AFAIK, Dyninst does nothing with this information,
896       neither will we. */
897    if (!curFunc()) {
898      dwarf_printf("(0x%lx) No function defined, returning\n", id());
899      return true;
900    }
901
902    /* We need the formal parameter's name, its type, its line number,
903       and its offset from the frame base in order to tell the 
904       rest of Dyninst about it.  A single _formal_parameter
905       DIE may not have all of this information; if it does not,
906       we will ignore it, hoping to catch it when it is later
907       referenced as an _abstract_origin from another _formal_parameter
908       DIE.  If we never find such a DIE, than there is not enough
909       information to introduce it to Dyninst. */
910    
911    /* We begin with the location, since this is the attribute
912       most likely to require using the _abstract_origin. */
913    
914    std::vector<VariableLocation> locs;
915    if (!decodeLocationList(DW_AT_location, NULL, locs)) return false;
916    if (locs.empty()) {
917      dwarf_printf("(0x%lx) No locations associated with formal, returning\n", id());
918      return true;
919    }
920
921    /* If the DIE has an _abstract_origin, we'll use that for the
922       remainder of our inquiries. */
923    bool hasAbstractOrigin;
924    if (!handleAbstractOrigin(hasAbstractOrigin)) return false;
925    if (hasAbstractOrigin) {
926       // Clone to spec entry too
927       setSpecEntry(abstractEntry());
928    }
929
930    if (!findName(curName())) return false;
931    /* We can't do anything with anonymous parameters. */   
932    if (!nameDefined()) {
933      dwarf_printf("(0x%lx) No name associated with formal, returning\n", id());
934      return true; 
935    }
936       
937    /* Acquire the parameter's type. */
938    Type *paramType = NULL;
939    if (!findType(paramType, false)) return false;
940
941    Dwarf_Unsigned lineNo = 0;
942    bool hasLineNumber = false;
943    std::string fileName;
944    if (!getLineInformation(lineNo, hasLineNumber, fileName)) return false;
945    localVar * newParameter = new localVar(curName(), 
946                                           paramType, 
947                                           fileName, (int) lineNo, 
948                                           curFunc());
949    dwarf_printf("(0x%lx) Creating new formal parameter %s/%p (%s) (%p)\n",
950                 id(),
951                 curName().c_str(), 
952                 paramType, paramType->getName().c_str(),
953                 //                ((curFunc() && !curFunc()->getAllMangledNames().empty()) ? 
954                 //curFunc()->getAllMangledNames()[0].c_str() : ""),
955                 curFunc());
956
957    assert( newParameter != NULL );
958    for (unsigned int i = 0; i < locs.size(); ++i)
959    {
960       newParameter->addLocation(locs[i]);
961    }
962    
963    /* This is just brutally ugly.  Why don't we take care of this invariant automatically? */
964    
965    curFunc()->addParam(newParameter);
966    return true;
967 }
968
969 bool DwarfWalker::parseBaseType() {
970    dwarf_printf("(0x%lx) parseBaseType entry\n", id());
971
972    if (!findName(curName())) return false;
973    if (!nameDefined()) {
974       dwarf_printf("(0x%lx) No name for type, returning early\n", id());
975       return true;
976    }
977
978    unsigned size = 0;
979    if (!findSize(size)) return false;
980
981    /* Generate the appropriate built-in type; since there's no
982       reliable way to distinguish between a built-in and a scalar,
983       we don't bother to try. */
984    typeScalar * baseType = new typeScalar( type_id(), (unsigned int) size, curName());
985    assert( baseType != NULL );
986    
987    /* Add the basic type to our collection. */
988    typeScalar *debug = baseType;
989    baseType = tc()->addOrUpdateType( baseType );
990    dwarf_printf("(0x%lx) Created type %p / %s (pre add %p / %s) for id %d, size %d, in TC %p\n", id(), 
991                 baseType, baseType->getName().c_str(),
992                 debug, debug->getName().c_str(),
993                 (int) offset(), size,
994                 tc());
995    
996    return true;
997 }
998
999 bool DwarfWalker::parseTypedef() {
1000    dwarf_printf("(0x%lx) parseTypedef entry\n", id());
1001
1002    if (!findName(curName())) return false;
1003
1004    Type *referencedType = NULL;
1005    if (!findType(referencedType, true)) return false;
1006
1007    if (!nameDefined()) {
1008       if (!fixName(curName(), referencedType)) return false;
1009    }
1010
1011    typeTypedef * typedefType = new typeTypedef( type_id(), referencedType, curName());
1012    typedefType = tc()->addOrUpdateType( typedefType );
1013
1014    return true;
1015 }
1016
1017 bool DwarfWalker::parseArray() {
1018    dwarf_printf("(0x%lx) Parsing array\n", id());
1019    /* Two words about pgf90 arrays.
1020       
1021       Primus: the PGI extensions to DWARF are documented in 
1022       '/p/paradyn/doc/External/manuals/pgf90-dwarf-arrays.txt'.
1023       
1024       Secundus: we ignore DW_AT_PGI_lbase, DW_AT_PGI_loffset, and DW_AT_PGI_lstride,
1025       even though libdwarf recognizes them, because our type modelling doesn't allow
1026       us to make use of this information.  Similarly, in virtually every place where
1027       the Portland Group extends DWARF to allow _form_block attributes encoding location
1028       lists, we ignore them.  We should, however, recognize these cases and ignore them
1029       gracefully, that is, without an error. :)
1030    */
1031
1032    if (!findName(curName())) return false;
1033
1034    // curName may get overridden by the subrange parsing code. 
1035    // TODO: make this part of the context stack. 
1036    std::string nameToUse = curName();
1037
1038    Type *elementType = NULL;
1039    if (!findType(elementType, false)) return false;
1040    if (!elementType) return false;
1041
1042    /* Find the range(s) of the elements. */
1043    Dwarf_Die firstRange;
1044
1045    DWARF_FAIL_RET(dwarf_child( entry(), & firstRange, NULL ));
1046
1047    contexts_.push();
1048
1049    typeArray * baseArrayType = parseMultiDimensionalArray(firstRange, 
1050                                                           elementType);
1051
1052    contexts_.pop();
1053
1054    if (!baseArrayType) return false;
1055    
1056    dwarf_dealloc( dbg(), firstRange, DW_DLA_DIE );
1057    
1058    /* The baseArrayType is an anonymous type with its own typeID.  Extract
1059       the information and add an array type for this DIE. */
1060
1061    dwarf_printf("(0x%lx) Creating array with base type %s, low bound %ld, high bound %ld, named %s\n",
1062                 id(), baseArrayType->getBaseType()->getName().c_str(),
1063                 baseArrayType->getLow(), 
1064                 baseArrayType->getHigh(),
1065                 curName().c_str());
1066    typeArray *arrayType = new typeArray( type_id(),
1067                                          baseArrayType->getBaseType(), 
1068                                          baseArrayType->getLow(),
1069                                          baseArrayType->getHigh(), 
1070                                          nameToUse); 
1071    assert( arrayType != NULL );
1072
1073    arrayType = tc()->addOrUpdateType( arrayType );
1074    
1075    /* Don't parse the children again. */
1076    setParseChild(false);
1077    
1078    return true;
1079 }
1080
1081 bool DwarfWalker::parseSubrange() {
1082    dwarf_printf("(0x%lx) parseSubrange entry\n", id());
1083
1084    std::string loBound;
1085    std::string hiBound;
1086    parseSubrangeAUX(entry(), loBound, hiBound);
1087
1088   return true;
1089 }
1090
1091 bool DwarfWalker::parseEnum() {
1092    dwarf_printf("(0x%lx) parseEnum entry\n", id());
1093    if (!findName(curName())) return false;
1094
1095    typeEnum* enumerationType = new typeEnum( type_id(), curName());
1096    assert( enumerationType != NULL );
1097    enumerationType = dynamic_cast<typeEnum *>(tc()->addOrUpdateType( enumerationType ));
1098
1099    setEnum(enumerationType);
1100    return true;
1101 }
1102
1103 bool DwarfWalker::parseInheritance() {
1104    dwarf_printf("(0x%lx) parseInheritance entry\n", id());
1105
1106    /* Acquire the super class's type. */
1107    Type *superClass = NULL;
1108    if (!findType(superClass, false)) return false;
1109    if (!superClass) return false;
1110
1111    dwarf_printf("(0x%lx) Found %p as superclass\n", id(), superClass);
1112
1113    visibility_t visibility;
1114    if (!findVisibility(visibility)) return false;
1115
1116    /* Add a readily-recognizable 'bad' field to represent the superclass.
1117       Type::getComponents() will Do the Right Thing. */
1118    std::string fName = "{superclass}";
1119    curEnclosure()->addField( fName, superClass, -1, visibility );
1120    dwarf_printf("(0x%lx) Added type %p as %s to %p\n", id(), superClass, fName.c_str(), curEnclosure());
1121    return true;
1122 }
1123
1124 bool DwarfWalker::parseStructUnionClass() {
1125    dwarf_printf("(0x%lx) parseStructUnionClass entry\n", id());
1126
1127    assert(tag() == DW_TAG_structure_type ||
1128           tag() == DW_TAG_union_type ||
1129           tag() == DW_TAG_class_type);
1130
1131    if (!findName(curName())) return false;
1132
1133    bool isDeclaration = false;
1134    if (!hasDeclaration(isDeclaration)) return false;
1135
1136    unsigned size;
1137    if (!findSize(size)) {
1138       if (isDeclaration) return true; 
1139       else return false;
1140    }
1141
1142    fieldListType * containingType = NULL;
1143
1144    switch ( tag() ) {
1145       case DW_TAG_structure_type: 
1146       case DW_TAG_class_type: {
1147          typeStruct *ts = new typeStruct( type_id(), curName());
1148          ts->setSize(size);
1149          containingType = dynamic_cast<fieldListType *>(tc()->addOrUpdateType(ts));
1150          break;
1151       }
1152       case DW_TAG_union_type: 
1153       {
1154          typeUnion *tu = new typeUnion( type_id(), curName());
1155          tu->setSize(size);
1156          containingType = dynamic_cast<fieldListType *>(tc()->addOrUpdateType(tu));
1157          break;
1158       }
1159    }
1160    setEnclosure(containingType);
1161    dwarf_printf("(0x%lx) Started class, union, or struct: %p\n",
1162                 id(), containingType);
1163    return true;
1164 }
1165
1166 bool DwarfWalker::parseEnumEntry() {
1167    dwarf_printf("(0x%lx) parseEnumEntry entry\n", id());
1168
1169    if (!findName(curName())) return false;
1170
1171    long value;
1172    bool valid;
1173    if (!findValue(value, valid)) return false;
1174
1175    curEnum()->addConstant(curName(), value);
1176    return true;
1177 }
1178
1179 bool DwarfWalker::parseMember() {
1180    dwarf_printf("(0x%lx) parseMember entry\n", id());
1181    if (!curEnclosure()) return false;
1182
1183    if (!findName(curName())) return false;
1184
1185    Type *memberType = NULL;
1186    if (!findType(memberType, false)) return false;
1187    if (!memberType) return false;
1188
1189    std::vector<VariableLocation> locs;
1190    Address initialStackValue = 0;
1191    if (!decodeLocationList(DW_AT_data_member_location, &initialStackValue, locs)) return false;
1192
1193    /* DWARF stores offsets in bytes unless the member is a bit field.
1194       Correct memberOffset as indicated.  Also, memberSize is in bytes
1195       from the underlying type, not the # of bits used from it, so
1196       correct that as necessary as well. */
1197    
1198    long int memberSize = memberType->getSize();
1199
1200    // This code changes memberSize, which is then discarded. I'm not sure why...
1201    if (!fixBitFields(locs, memberSize)) return false;
1202
1203    int offset_to_use = locs.size() ? locs[0].frameOffset : -1;
1204
1205    dwarf_printf("(0x%lx) Using offset of 0x%lx\n", id(), offset_to_use);
1206
1207    if (nameDefined()) {
1208       curEnclosure()->addField( curName(), memberType, offset_to_use);
1209    }
1210    else {
1211       curEnclosure()->addField("[anonymous union]", memberType, offset_to_use);
1212    }
1213    return true;
1214 }
1215
1216 // TODO: this looks a lot like parseTypedef. Collapse?
1217 bool DwarfWalker::parseConstPackedVolatile() {
1218    dwarf_printf("(0x%lx) parseConstPackedVolatile entry\n", id());
1219
1220    if (!findName(curName())) return false;
1221
1222    Type *type = NULL;
1223    if (!findType(type, true)) return false;
1224
1225    if (!nameDefined()) {
1226       if (!fixName(curName(), type)) return false;
1227    }
1228
1229    typeTypedef * modifierType = new typeTypedef(type_id(), type, curName());
1230    assert( modifierType != NULL );
1231    modifierType = tc()->addOrUpdateType( modifierType );
1232    return true;
1233 }
1234
1235 bool DwarfWalker::parseTypeReferences() {
1236    dwarf_printf("(0x%lx) parseTypeReferences entry\n", id());
1237
1238    if (!findName(curName())) return false;
1239
1240    Type *typePointedTo = NULL;
1241    if (!findType(typePointedTo, true)) return false;
1242    
1243    Type * indirectType = NULL;
1244    switch ( tag() ) {
1245       case DW_TAG_subroutine_type:
1246          indirectType = new typeFunction(type_id(), typePointedTo, curName());
1247          indirectType = tc()->addOrUpdateType((typeFunction *) indirectType );
1248          break;
1249       case DW_TAG_ptr_to_member_type:
1250       case DW_TAG_pointer_type:
1251          indirectType = new typePointer(type_id(), typePointedTo, curName());
1252          indirectType = tc()->addOrUpdateType((typePointer *) indirectType );
1253          break;
1254       case DW_TAG_reference_type:
1255          indirectType = new typeRef(type_id(), typePointedTo, curName());
1256          indirectType = tc()->addOrUpdateType((typeRef *) indirectType );
1257          break;
1258       default:
1259          return false;
1260    }
1261
1262    assert( indirectType != NULL );
1263    return true;
1264 }
1265
1266 bool DwarfWalker::hasDeclaration(bool &isDecl) {
1267    Dwarf_Bool tmp;
1268    DWARF_FAIL_RET(dwarf_hasattr(entry(),
1269                                 DW_AT_declaration,
1270                                 &tmp, NULL ));
1271    isDecl = tmp;
1272    return true;
1273 }
1274
1275 bool DwarfWalker::findTag() {
1276    Dwarf_Half dieTag;
1277    DWARF_FAIL_RET(dwarf_tag( entry(), & dieTag, NULL ));
1278    setTag(dieTag);
1279    return true;
1280 }
1281
1282
1283 bool DwarfWalker::findOffset() {
1284    Dwarf_Off dieOffset;
1285    DWARF_FAIL_RET(dwarf_dieoffset( entry(), & dieOffset, NULL ));
1286    
1287    setOffset(dieOffset);
1288    return true;
1289 }
1290
1291 bool DwarfWalker::findEntryToUse(Dwarf_Half attr, bool &found, Dwarf_Die &e) {
1292    Dwarf_Bool hasAttr;
1293    DWARF_FAIL_RET(dwarf_hasattr(entry(),
1294                                 attr,
1295                                 &hasAttr, NULL ));
1296    if (hasAttr) {
1297       e = entry();
1298       found = true;
1299       return true;
1300    }
1301
1302    DWARF_FAIL_RET(dwarf_hasattr(specEntry(),
1303                                 attr,
1304                                 &hasAttr, NULL ));
1305    if (hasAttr) {
1306       e = specEntry();
1307       found = true;
1308       return true;
1309    }
1310
1311    DWARF_FAIL_RET(dwarf_hasattr(abstractEntry(),
1312                                 attr,
1313                                 &hasAttr, NULL ));
1314    if (hasAttr) {
1315       e = abstractEntry();
1316       found = true;
1317       return true;
1318    }
1319    found = false;
1320    return true;
1321 }
1322
1323 bool DwarfWalker::handleAbstractOrigin(bool &isAbstract) {
1324    Dwarf_Die absE;
1325
1326    dwarf_printf("(0x%lx) Checking for abstract origin\n", id());
1327    
1328    isAbstract = false;
1329    Dwarf_Bool isAbstractOrigin;
1330
1331    DWARF_FAIL_RET(dwarf_hasattr(entry(),
1332                             DW_AT_abstract_origin, 
1333                             &isAbstractOrigin, NULL ));
1334    
1335    if (!isAbstractOrigin) return true;
1336
1337    isAbstract = true;
1338    dwarf_printf("(0x%lx) abstract_origin is true, looking up reference\n", id());
1339    
1340    Dwarf_Attribute abstractAttribute;
1341    DWARF_FAIL_RET(dwarf_attr( entry(), DW_AT_abstract_origin, & abstractAttribute, NULL ));
1342    
1343    Dwarf_Off abstractOffset;
1344    if (!findDieOffset( abstractAttribute, abstractOffset )) return false;
1345    
1346    Dwarf_Bool is_info = dwarf_get_die_infotypes_flag(entry());
1347    DWARF_FAIL_RET(dwarf_offdie_b( dbg(), abstractOffset, is_info, & absE, NULL));
1348    
1349    dwarf_dealloc( dbg() , abstractAttribute, DW_DLA_ATTR );
1350    
1351    setAbstractEntry(absE);
1352
1353    return true;
1354 }
1355
1356 bool DwarfWalker::handleSpecification(bool &hasSpec) {
1357    Dwarf_Die specE; 
1358
1359    dwarf_printf("(0x%lx) Checking for separate specification\n", id());
1360    hasSpec = false;
1361
1362    Dwarf_Bool hasSpecification;
1363    DWARF_FAIL_RET(dwarf_hasattr( entry(), DW_AT_specification, & hasSpecification, NULL ));
1364
1365    if (!hasSpecification) return true;
1366
1367    hasSpec = true;
1368    
1369    dwarf_printf("(0x%lx) Entry has separate specification, retrieving\n", id());
1370
1371    Dwarf_Attribute specAttribute;
1372    DWARF_FAIL_RET(dwarf_attr( entry(), DW_AT_specification, & specAttribute, NULL ));
1373    
1374    Dwarf_Off specOffset;
1375    if (!findDieOffset( specAttribute, specOffset )) return false;
1376    
1377    Dwarf_Bool is_info = dwarf_get_die_infotypes_flag(entry());
1378    DWARF_FAIL_RET(dwarf_offdie_b( dbg(), specOffset, is_info, & specE, NULL ));
1379    
1380    dwarf_dealloc( dbg(), specAttribute, DW_DLA_ATTR );
1381
1382    setSpecEntry(specE);
1383
1384    return true;
1385 }
1386
1387 bool DwarfWalker::findDieName(Dwarf_Die die, std::string &name) {
1388    char *cname = NULL;
1389
1390    Dwarf_Error error;
1391    int status = dwarf_diename( die, &cname, &error );     
1392
1393    /* Squash errors from unsupported forms, like DW_FORM_GNU_strp_alt. */
1394    if (status == DW_DLV_ERROR) {
1395       if (dwarf_errno(error) == DW_DLE_ATTR_FORM_BAD) {
1396          status = DW_DLV_NO_ENTRY;
1397       }
1398       dwarf_dealloc( dbg(), error, DW_DLA_ERROR );
1399    }
1400
1401    DWARF_CHECK_RET(status == DW_DLV_ERROR);
1402    if (status != DW_DLV_OK) {
1403       name = std::string();
1404       return true;
1405    }
1406
1407    name = cname;
1408    dwarf_dealloc( dbg(), cname, DW_DLA_STRING );
1409    return true;
1410 }
1411
1412 bool DwarfWalker::findName(std::string &name) {
1413    if (!findDieName( specEntry(), name)) return false;
1414    dwarf_printf("(0x%lx) Found name %s\n", id(), name.c_str());
1415    return true;
1416 }
1417    
1418
1419 bool DwarfWalker::findFuncName() {
1420    dwarf_printf("(0x%lx) Checking for function name\n", id());
1421    /* Prefer linkage names. */
1422    char *dwarfName = NULL;
1423
1424    Dwarf_Attribute linkageNameAttr;
1425
1426    int status = dwarf_attr(entry(), DW_AT_MIPS_linkage_name, &linkageNameAttr, NULL);
1427    if (status != DW_DLV_OK)
1428       status = dwarf_attr(entry(), DW_AT_linkage_name, &linkageNameAttr, NULL);
1429    DWARF_CHECK_RET(status == DW_DLV_ERROR);
1430    if ( status == DW_DLV_OK )  {
1431       DWARF_FAIL_RET(dwarf_formstring( linkageNameAttr, &dwarfName, NULL ));
1432       curName() = dwarfName;
1433       setMangledName(true);
1434       dwarf_printf("(0x%lx) Found mangled name of %s, using\n", id(), curName().c_str());
1435       dwarf_dealloc( dbg(), linkageNameAttr, DW_DLA_ATTR );
1436       return true;
1437    } 
1438
1439    findDieName( entry(), curName() );
1440    setMangledName(false);
1441    return true;
1442 }
1443
1444 bool DwarfWalker::getFrameBase() {
1445    dwarf_printf("(0x%lx) Checking for frame pointer information\n", id());
1446
1447    std::vector<VariableLocation> &funlocs = curFunc()->getFramePtrRefForInit();
1448    if (!funlocs.empty()) {
1449       DWARF_CHECK_RET(false);
1450    }
1451
1452    if (!decodeLocationList(DW_AT_frame_base, NULL, funlocs)) return false;
1453    dwarf_printf("(0x%lx) After frame base decode, %d entries\n", id(), (int) funlocs.size());
1454
1455    return true;
1456 }
1457
1458 bool DwarfWalker::getReturnType(bool hasSpecification, Type *&returnType) {
1459    Dwarf_Attribute typeAttribute;
1460    int status = DW_DLV_OK;
1461
1462    Dwarf_Bool is_info = true;
1463    if (hasSpecification) {
1464       is_info = dwarf_get_die_infotypes_flag(specEntry());
1465       status = dwarf_attr( specEntry(), DW_AT_type, & typeAttribute, NULL );
1466    }   
1467    if (!hasSpecification || (status == DW_DLV_NO_ENTRY)) {
1468       is_info = dwarf_get_die_infotypes_flag(entry());
1469       status = dwarf_attr( entry(), DW_AT_type, & typeAttribute, NULL );
1470    }
1471
1472
1473    DWARF_CHECK_RET(status == DW_DLV_ERROR);
1474    if ( status == DW_DLV_NO_ENTRY ) {
1475      dwarf_printf("(0x%lx) Return type is void\n", id());
1476       return false;
1477    }
1478
1479    /* There's a return type attribute. */
1480    dwarf_printf("(0x%lx) Return type is not void\n", id());
1481
1482    bool ret = findAnyType( typeAttribute, is_info, returnType );
1483    dwarf_dealloc( dbg(), typeAttribute, DW_DLA_ATTR );
1484    return ret;
1485 }
1486
1487 // I'm not sure how the provided fieldListType is different from curEnclosure(),
1488 // but that's the way the code was structured and it was working. 
1489 bool DwarfWalker::addFuncToContainer(Type *returnType) {
1490    /* Using the mangled name allows us to distinguish between overridden
1491       functions, but confuses the tests.  Since Type uses vectors
1492       to hold field names, however, duplicate -- demangled names -- are OK. */
1493    
1494    char * demangledName = P_cplus_demangle( curName().c_str(), symtab()->isNativeCompiler() );
1495    std::string toUse;
1496
1497    if (!demangledName) {
1498       dwarf_printf("(0x%lx) Unable to demangle %s, using it as mangled\n", id(), curName().c_str());
1499       toUse = curName();
1500    }
1501    else {
1502       // Strip everything left of the rightmost ':' off to get rid of the class names
1503       toUse = demangledName;
1504       // rfind finds the last occurrence of ':'; add 1 to get past it. 
1505       size_t offset = toUse.rfind(':');
1506       if (offset != toUse.npos) {
1507          toUse = toUse.substr(offset+1);
1508       }
1509    }
1510
1511    typeFunction *funcType = new typeFunction( type_id(), returnType, toUse);
1512    curEnclosure()->addField( toUse, funcType);
1513    free( demangledName );
1514    return true;
1515 }
1516
1517 bool DwarfWalker::findType(Type *&type, bool defaultToVoid) {
1518   // Do *not* return true unless type is actually usable.
1519    int status;
1520
1521    /* Acquire the parameter's type. */
1522    Dwarf_Attribute typeAttribute;
1523    status = dwarf_attr( specEntry(), DW_AT_type, & typeAttribute, NULL );
1524    DWARF_CHECK_RET(status == DW_DLV_ERROR);
1525
1526    if (status == DW_DLV_NO_ENTRY) {
1527       if (defaultToVoid) {
1528          type = tc()->findType("void");
1529          return (type != NULL);
1530       }
1531       return false;
1532    }
1533
1534    Dwarf_Bool is_info = dwarf_get_die_infotypes_flag(specEntry());
1535
1536    bool ret = findAnyType( typeAttribute, is_info, type );
1537    dwarf_dealloc( dbg(), typeAttribute, DW_DLA_ATTR );
1538    return ret;
1539 }
1540
1541 bool DwarfWalker::findDieOffset(Dwarf_Attribute attr, Dwarf_Off &offset) {
1542    Dwarf_Half form;
1543    DWARF_FAIL_RET(dwarf_whatform( attr, &form, NULL ));
1544    switch (form) {
1545       /* These forms are suitable as direct DIE offsets */
1546       case DW_FORM_ref1:
1547       case DW_FORM_ref2:
1548       case DW_FORM_ref4:
1549       case DW_FORM_ref8:
1550       case DW_FORM_ref_udata:
1551       case DW_FORM_ref_addr:
1552       case DW_FORM_data4:
1553       case DW_FORM_data8:
1554          DWARF_FAIL_RET(dwarf_global_formref( attr, &offset, NULL ));
1555          return true;
1556
1557       /* Then there's DW_FORM_sec_offset which refer other sections, or
1558        * DW_FORM_GNU_ref_alt that refers to a whole different file.  We can't
1559        * use such forms as a die offset, even if dwarf_global_formref is
1560        * willing to decode it. */
1561       default:
1562          dwarf_printf("(0x%lx) Can't use form 0x%x as a die offset\n", id(), (int) form);
1563          return false;
1564    }
1565 }
1566
1567 bool DwarfWalker::findAnyType(Dwarf_Attribute typeAttribute,
1568                               Dwarf_Bool is_info, Type *&type) {
1569    /* If this is a ref_sig8, look for the type elsewhere. */
1570    Dwarf_Half form;
1571    DWARF_FAIL_RET(dwarf_whatform(typeAttribute, &form, NULL));
1572    if (form == DW_FORM_ref_sig8) {
1573       Dwarf_Sig8 signature;
1574       DWARF_FAIL_RET(dwarf_formsig8(typeAttribute, &signature, NULL));
1575       return findSig8Type(&signature, type);
1576    }
1577
1578    Dwarf_Off typeOffset;
1579    if (!findDieOffset( typeAttribute, typeOffset )) return false;
1580
1581    /* NB: It's possible for an incomplete type to have a DW_AT_signature
1582     * reference to a complete definition.  For example, GCC may output just the
1583     * subprograms for a struct's methods in one CU, with the full struct
1584     * defined in a type unit.
1585     *
1586     * No DW_AT_type has been found referencing an incomplete type this way,
1587     * but if it did, here's the place to look for that DW_AT_signature and
1588     * recurse into findAnyType again.
1589     */
1590
1591    typeId_t type_id = get_type_id(typeOffset, is_info);
1592
1593    dwarf_printf("(0x%lx) Returned type offset 0x%x\n", id(), (int) typeOffset);
1594    /* The typeOffset forms a module-unique type identifier,
1595       so the Type look-ups by it rather than name. */
1596    type = tc()->findOrCreateType( type_id );
1597    dwarf_printf("(0x%lx) Returning type %p / %s for id 0x%x\n", 
1598                 id(), 
1599                 type, type->getName().c_str(),
1600                 type_id);
1601    return true;
1602 }
1603
1604 bool DwarfWalker::getLineInformation(Dwarf_Unsigned &variableLineNo,
1605                                      bool &hasLineNumber,
1606                                      std::string &fileName) {
1607    Dwarf_Attribute fileDeclAttribute;
1608    int status = dwarf_attr( specEntry(), DW_AT_decl_file, & fileDeclAttribute, NULL );
1609    DWARF_CHECK_RET(status == DW_DLV_ERROR);
1610
1611    if (status == DW_DLV_NO_ENTRY) {
1612       fileName = "";
1613    }
1614    else if (status == DW_DLV_OK) {
1615       Dwarf_Unsigned fileNameDeclVal;
1616       DWARF_FAIL_RET(dwarf_formudata(fileDeclAttribute, &fileNameDeclVal, NULL));
1617       dwarf_dealloc( dbg(), fileDeclAttribute, DW_DLA_ATTR );                   
1618       if (fileNameDeclVal > srcFiles().size() || fileNameDeclVal <= 0) {
1619          dwarf_printf("Dwarf error reading line index %d from srcFiles of size %lu\n",
1620                       fileNameDeclVal, srcFiles().size());
1621          return false;
1622       }
1623       fileName = srcFiles()[fileNameDeclVal-1];
1624    }
1625    else {
1626       return true;
1627    }
1628
1629    Dwarf_Attribute lineNoAttribute;
1630    status = dwarf_attr( specEntry(), DW_AT_decl_line, & lineNoAttribute, NULL );
1631    DWARF_CHECK_RET(status == DW_DLV_ERROR);
1632    if (status != DW_DLV_OK) return true;
1633    
1634    /* We don't need to tell Dyninst a line number for C++ static variables,
1635       so it's OK if there isn't one. */
1636    hasLineNumber = true;
1637    DWARF_FAIL_RET(dwarf_formudata( lineNoAttribute, & variableLineNo, NULL ));
1638    dwarf_dealloc( dbg(), lineNoAttribute, DW_DLA_ATTR );                        
1639
1640    return true;
1641 }
1642
1643 bool DwarfWalker::decodeLocationList(Dwarf_Half attr, 
1644                                      Address *initialStackValue, 
1645                                      std::vector<VariableLocation> &locs) {
1646    dwarf_printf("(0x%lx) decodeLocationList for attr %d\n", id(), attr);
1647
1648    Dwarf_Bool hasAttr = false;
1649    DWARF_FAIL_RET(dwarf_hasattr(entry(), attr, &hasAttr, NULL));
1650
1651    if (!hasAttr) {
1652       dwarf_printf("(0x%lx): no such attribute\n", id());
1653       return true;
1654    }
1655
1656    locs.clear();
1657    
1658    /* Acquire the location of this formal parameter. */
1659    Dwarf_Attribute locationAttribute;
1660    DWARF_FAIL_RET(dwarf_attr( entry(), attr, & locationAttribute, NULL ));
1661
1662    bool isExpr = false;
1663    bool isConstant = false;
1664    Dwarf_Half form;
1665    if (!checkForConstantOrExpr(attr, locationAttribute, isConstant, isExpr, form))
1666      return false;
1667    dwarf_printf("(0x%lx) After checkForConstantOrExpr, form class is 0x%x\n",id(), form);
1668    if (isConstant) {
1669      dwarf_printf("(0x%lx) Decoding constant location\n", id());
1670       if (!decodeConstantLocation(locationAttribute, form, locs)) return false;
1671    }
1672    else if (isExpr) {
1673      dwarf_printf("(0x%lx) Decoding expression without location list\n", id());
1674      if (!decodeExpression(locationAttribute, locs)) return false;
1675    }   
1676    else {
1677      dwarf_printf("(0x%lx) Decoding loclist location\n", id());
1678       Dwarf_Locdesc **locationList;
1679       Dwarf_Signed listLength;
1680       int status = dwarf_loclist_n( locationAttribute, & locationList, & listLength, NULL );
1681       
1682       dwarf_dealloc( dbg(), locationAttribute, DW_DLA_ATTR );
1683       
1684       if (status != DW_DLV_OK) {
1685         
1686
1687         dwarf_printf("(0x%lx) Failed loclist decode: %d\n", id(), status);
1688         return true;
1689       }
1690       
1691       dwarf_printf("(0x%lx) location list with %d entries found\n", id(), (int) listLength);
1692       
1693       if (!decodeLocationListForStaticOffsetOrAddress( locationList,
1694                                                        listLength, 
1695                                                        locs, 
1696                                                        initialStackValue)) {
1697         deallocateLocationList( locationList, listLength );
1698         return false;
1699       }
1700       
1701       
1702       deallocateLocationList( locationList, listLength );
1703    }
1704
1705    return true;
1706 }
1707
1708 bool DwarfWalker::checkForConstantOrExpr(Dwarf_Half attr,
1709                                          Dwarf_Attribute &locationAttribute,
1710                                          bool &constant,
1711                                          bool &expr,
1712                                          Dwarf_Half &form) {
1713    constant = false;
1714    // Get the form (datatype) for this particular attribute
1715    DWARF_FAIL_RET(dwarf_whatform(locationAttribute, &form, NULL));
1716    
1717    // And see if it's a constant
1718    Dwarf_Form_Class formtype = dwarf_get_form_class(version, attr, offset_size, form);
1719    dwarf_printf("(0x%lx) Checking for constant, formtype is 0x%x looking for 0x%x\n", id(), formtype, DW_FORM_CLASS_CONSTANT);
1720
1721    if (formtype == DW_FORM_CLASS_CONSTANT) {
1722       constant = true;
1723    }
1724    else if (formtype == DW_FORM_CLASS_EXPRLOC) {
1725      expr = true;
1726    }
1727    return true;
1728 }
1729
1730 bool DwarfWalker::findString(Dwarf_Half attr,
1731                              const char* &str)
1732 {
1733    Dwarf_Half form;
1734    Dwarf_Attribute strattr;
1735
1736    if (attr == DW_AT_call_file || attr == DW_AT_decl_file) {
1737       unsigned long line_index;
1738       bool result = findConstant(attr, line_index);
1739       if (!result)
1740          return false;
1741       if (line_index == 0) {
1742          str = NULL;
1743          return true;
1744       }
1745       line_index--;
1746       if (line_index >= srcFiles().size()) {
1747          dwarf_printf("Dwarf error reading line index %d from srcFiles of size %lu\n",
1748                       line_index, srcFiles().size());
1749          return false;
1750       }
1751       str = srcFiles()[line_index];
1752       return true;
1753    }
1754
1755    DWARF_FAIL_RET(dwarf_attr(entry(), attr, &strattr, NULL)); 
1756    int status = dwarf_whatform(strattr, &form, NULL);
1757    if (status != DW_DLV_OK) {
1758       dwarf_dealloc(dbg(), strattr, DW_DLA_ATTR);
1759       return false;
1760    }
1761    
1762    bool result;
1763    switch (form) {
1764       case DW_FORM_string: {
1765          char *s = NULL;
1766          DWARF_FAIL_RET(dwarf_formstring(strattr, &s, NULL));
1767          str  = s;
1768          result = true;
1769          break;
1770       }
1771       case DW_FORM_block:
1772       case DW_FORM_block1: 
1773       case DW_FORM_block2:
1774       case DW_FORM_block4: {
1775          Dwarf_Block *block = NULL;
1776          DWARF_FAIL_RET(dwarf_formblock(strattr, &block, NULL));
1777          str = (char *) block->bl_data;
1778          dwarf_dealloc(dbg(), block, DW_DLA_BLOCK);
1779          result = bool(str);
1780          break;
1781       }
1782       default:
1783          result = false;
1784          break;
1785    }
1786    dwarf_dealloc(dbg(), strattr, DW_DLA_ATTR);
1787    return result;
1788 }
1789
1790 bool DwarfWalker::findConstant(Dwarf_Half attr,
1791                                Address &value) {
1792    Dwarf_Bool has = false;
1793    DWARF_FAIL_RET(dwarf_hasattr(entry(), attr, &has, NULL));
1794    if (!has) return false;
1795
1796    // Get the attribute
1797    Dwarf_Attribute d_attr;
1798    DWARF_FAIL_RET(dwarf_attr(entry(), attr, &d_attr, NULL));
1799
1800    Dwarf_Half form;
1801    // Get the form (datatype) for this particular attribute
1802    DWARF_FAIL_RET(dwarf_whatform(d_attr, &form, NULL));
1803
1804    bool ret = findConstantWithForm(d_attr, form, value);
1805    dwarf_dealloc(dbg(), d_attr, DW_DLA_ATTR);
1806    return ret;
1807    
1808 }
1809
1810 bool DwarfWalker::findConstantWithForm(Dwarf_Attribute &locationAttribute,
1811                                        Dwarf_Half form,
1812                                        Address &value) {
1813    value = 0;
1814
1815    switch(form) {
1816       case DW_FORM_addr:
1817          Dwarf_Addr addr;
1818          DWARF_FAIL_RET(dwarf_formaddr(locationAttribute, &addr, NULL));
1819          value = (Address) addr;
1820          return true;
1821       case DW_FORM_sdata:
1822          Dwarf_Signed s_tmp;
1823          DWARF_FAIL_RET(dwarf_formsdata(locationAttribute, &s_tmp, NULL));
1824          value = (Address) s_tmp;
1825          dwarf_printf("(0x%lx) Decoded data of form %x to 0x%lx\n", 
1826                       id(), form, value);
1827          return true;
1828       case DW_FORM_data1:
1829       case DW_FORM_data2:
1830       case DW_FORM_data4:
1831       case DW_FORM_data8:
1832       case DW_FORM_udata:
1833          Dwarf_Unsigned u_tmp;
1834          DWARF_FAIL_RET(dwarf_formudata(locationAttribute, &u_tmp, NULL));
1835          value = (Address) u_tmp;
1836          return true;
1837    case DW_FORM_sec_offset:
1838      DWARF_FAIL_RET(dwarf_global_formref(locationAttribute, &u_tmp, NULL));
1839      value = (Address)(u_tmp);
1840      return true;
1841       default:
1842          dwarf_printf("(0x%lx) Unhandled form 0x%x for constant decode\n", id(), (unsigned) form);
1843          return false;
1844    }
1845 }
1846
1847 bool DwarfWalker::decodeConstantLocation(Dwarf_Attribute &attr, Dwarf_Half form,
1848                                          std::vector<VariableLocation> &locs) {
1849    Address value;
1850    if (!findConstantWithForm(attr, form, value)) return false;
1851    if (!constructConstantVariableLocation(value, locs)) return false;
1852    return true;
1853 }
1854
1855 bool DwarfWalker::constructConstantVariableLocation(Address value,
1856                                                     std::vector<VariableLocation> &locs) {
1857    
1858    VariableLocation loc;
1859    loc.stClass = storageAddr;
1860    loc.refClass = storageNoRef;
1861    loc.frameOffset = value;
1862
1863
1864    if (hasRanges()) {
1865       for (range_set_t::iterator i = ranges_begin(); i != ranges_end(); i++) {
1866          pair<Address, Address> range = *i;
1867          loc.lowPC = range.first;
1868          loc.hiPC = range.second;
1869          locs.push_back(loc);
1870       }
1871    }
1872    else {
1873       loc.lowPC = (Address) 0;
1874       loc.hiPC = (Address) -1;
1875       locs.push_back(loc);
1876    }
1877    
1878    return true;
1879 }
1880
1881 bool DwarfWalker::findSize(unsigned &size) {
1882    Dwarf_Bool hasSize;
1883    DWARF_FAIL_RET(dwarf_hasattr(entry(), DW_AT_byte_size, &hasSize, NULL));
1884    if (!hasSize) return false;
1885
1886    Dwarf_Attribute byteSizeAttr;
1887    Dwarf_Unsigned byteSize;
1888    DWARF_FAIL_RET(dwarf_attr( specEntry(), DW_AT_byte_size, & byteSizeAttr, NULL ));
1889
1890    DWARF_FAIL_RET(dwarf_formudata( byteSizeAttr, & byteSize, NULL ));
1891    
1892    dwarf_dealloc( dbg(), byteSizeAttr, DW_DLA_ATTR );
1893    size = (unsigned) byteSize;
1894    return true;
1895 }
1896
1897 bool DwarfWalker::findVisibility(visibility_t &visibility) {
1898    /* Acquire the visibility, if any.  DWARF calls it accessibility
1899       to distinguish it from symbol table visibility. */
1900    Dwarf_Attribute visAttr;
1901    int status = dwarf_attr( entry(), DW_AT_accessibility, & visAttr, NULL );
1902    DWARF_CHECK_RET(status == DW_DLV_ERROR);
1903    if (status != DW_DLV_OK) {
1904       visibility = visPrivate;
1905       return true;
1906    }
1907
1908    Dwarf_Unsigned visValue;
1909    DWARF_FAIL_RET(dwarf_formudata( visAttr, & visValue, NULL ));
1910    
1911    switch( visValue ) {
1912       case DW_ACCESS_public: visibility = visPublic; break;
1913       case DW_ACCESS_protected: visibility = visProtected; break;
1914       case DW_ACCESS_private: visibility = visPrivate; break;
1915       default:
1916          //bperr ( "Uknown visibility, ignoring.\n" );
1917          break;
1918    } /* end visibility switch */
1919    
1920    dwarf_dealloc( dbg(), visAttr, DW_DLA_ATTR );
1921
1922    return true;
1923 }
1924
1925 bool DwarfWalker::findValue(long &value, bool &valid) {
1926    Dwarf_Attribute valueAttr;
1927    int status = dwarf_attr( entry(), DW_AT_const_value, & valueAttr, NULL );
1928    DWARF_CHECK_RET(status == DW_DLV_ERROR);
1929    
1930    if (status != DW_DLV_OK) {
1931       valid = false;
1932       return true;
1933    }
1934
1935    Dwarf_Signed enumValue;
1936
1937    DWARF_FAIL_RET(dwarf_formsdata(valueAttr, &enumValue, NULL));
1938
1939    value = enumValue;
1940    valid = true;
1941
1942    dwarf_dealloc( dbg(), valueAttr, DW_DLA_ATTR );
1943    return true;
1944 }
1945
1946 bool DwarfWalker::fixBitFields(std::vector<VariableLocation> &locs,
1947                                long &size) {
1948    Dwarf_Attribute bitOffset;
1949    int status = dwarf_attr( entry(), DW_AT_bit_offset, & bitOffset, NULL );
1950    DWARF_CHECK_RET(status == DW_DLV_ERROR);
1951    
1952    if ( status == DW_DLV_OK && locs.size() ) 
1953    {
1954       Dwarf_Unsigned memberOffset_du = locs[0].frameOffset;
1955       
1956       DWARF_FAIL_RET(dwarf_formudata( bitOffset, &memberOffset_du, NULL ));
1957       
1958       dwarf_dealloc( dbg(), bitOffset, DW_DLA_ATTR );
1959       
1960       Dwarf_Attribute bitSize;
1961       DWARF_FAIL_RET(dwarf_attr( entry(), DW_AT_bit_size, & bitSize, NULL ));
1962       
1963       Dwarf_Unsigned memberSize_du = size;
1964       DWARF_FAIL_RET(dwarf_formudata( bitSize, &memberSize_du, NULL ));
1965
1966       dwarf_dealloc( dbg(), bitSize, DW_DLA_ATTR );
1967       
1968       /* If the DW_AT_byte_size field exists, there's some padding.
1969          FIXME?  We ignore padding for now.  (We also don't seem to handle
1970          bitfields right in getComponents() anyway...) */
1971    }
1972    else 
1973    {
1974       if (locs.size())
1975          locs[0].frameOffset *= 8;
1976       size *= 8;
1977    } /* end if not a bit field member. */
1978    return true;
1979 }
1980
1981 bool DwarfWalker::fixName(std::string &name, Type *type) {
1982    switch(tag()){
1983       case DW_TAG_const_type:
1984          name = std::string("const ") + type->getName();
1985          break;
1986       case DW_TAG_packed_type:
1987          name = std::string("packed ") + type->getName();
1988          break;
1989       case DW_TAG_volatile_type:
1990          name = std::string("volatile ") + type->getName();
1991          break;
1992       default:
1993          return false;
1994    }
1995    return true;
1996 }
1997
1998 void DwarfWalker::removeFortranUnderscore(std::string &name) {
1999       /* If we're fortran, get rid of the trailing _ */
2000    if (!curFunc() && !curEnclosure()) return;
2001
2002    supportedLanguages lang = mod()->language();
2003    if ((lang != lang_Fortran) &&
2004        (lang != lang_CMFortran) &&
2005        (lang != lang_Fortran_with_pretty_debug)) return;
2006    
2007    if (name[name.length()-1] == '_') {
2008       name = name.substr(0, name.length()-1);
2009    }
2010 }
2011
2012 bool DwarfWalker::parseSubrangeAUX(Dwarf_Die entry,
2013                                    std::string &loBound,
2014                                    std::string &hiBound) {
2015    dwarf_printf("(0x%lx) Parsing subrange /w/ auxiliary function\n", id());
2016    loBound = "{unknown or default}";
2017    hiBound = "{unknown or default}";
2018
2019    /* Set the default lower bound, if we know it. */
2020    switch ( mod()->language() ) {
2021       case lang_Fortran:
2022       case lang_Fortran_with_pretty_debug:
2023       case lang_CMFortran:
2024          loBound = "1";
2025          break;
2026       case lang_C:
2027       case lang_CPlusPlus:
2028          loBound = "0";
2029          break;
2030       default:
2031          break;
2032    } /* end default lower bound switch */
2033    
2034    /* Look for the lower bound. */
2035    Dwarf_Attribute lowerBoundAttribute;
2036    Dwarf_Bool is_info = dwarf_get_die_infotypes_flag(entry);
2037    int status = dwarf_attr( entry, DW_AT_lower_bound, & lowerBoundAttribute, NULL );
2038    DWARF_CHECK_RET(status == DW_DLV_ERROR);
2039    
2040    if ( status == DW_DLV_OK ) {
2041       if (!decipherBound(lowerBoundAttribute, is_info, loBound )) return false;
2042       dwarf_dealloc( dbg(), lowerBoundAttribute, DW_DLA_ATTR );
2043    } /* end if we found a lower bound. */
2044    
2045    /* Look for the upper bound. */
2046    Dwarf_Attribute upperBoundAttribute;
2047    status = dwarf_attr( entry, DW_AT_upper_bound, & upperBoundAttribute, NULL );
2048    DWARF_CHECK_RET(status == DW_DLV_ERROR);
2049
2050    if ( status == DW_DLV_NO_ENTRY ) {
2051       status = dwarf_attr( entry, DW_AT_count, & upperBoundAttribute, NULL );
2052       DWARF_CHECK_RET(status == DW_DLV_ERROR);
2053    }
2054
2055    if ( status == DW_DLV_OK ) {
2056       if (!decipherBound(upperBoundAttribute, is_info, hiBound )) return false;
2057       dwarf_dealloc( dbg(), upperBoundAttribute, DW_DLA_ATTR );
2058    } /* end if we found an upper bound or count. */
2059    
2060    /* Construct the range type. */
2061    if (!findName(curName())) return false;
2062    if (!nameDefined()) {
2063       curName() = "{anonymousRange}";
2064    }
2065
2066    Dwarf_Off subrangeOffset;
2067    DWARF_ERROR_RET(dwarf_dieoffset( entry, & subrangeOffset, NULL ));
2068    typeId_t type_id = get_type_id(subrangeOffset, is_info);
2069
2070    errno = 0;
2071    unsigned long low_conv = strtoul(loBound.c_str(), NULL, 10);
2072    if (errno) {
2073       low_conv = LONG_MIN;
2074    }
2075    
2076    errno = 0;
2077    unsigned long hi_conv = strtoul(hiBound.c_str(), NULL, 10);
2078    if (errno)  {
2079       hi_conv = LONG_MAX;
2080    }  
2081    dwarf_printf("(0x%lx) Adding subrange type: id %d, low %ld, high %ld, named %s\n",
2082                 id(), type_id, 
2083                 low_conv, hi_conv, curName().c_str());
2084    typeSubrange * rangeType = new typeSubrange( type_id, 
2085                                                 0, low_conv, hi_conv, curName() );
2086    assert( rangeType != NULL );
2087    rangeType = tc()->addOrUpdateType( rangeType );
2088    dwarf_printf("(0x%lx) Subrange has pointer %p (tc %p)\n", id(), rangeType, tc());
2089    return true;
2090 }
2091
2092 typeArray *DwarfWalker::parseMultiDimensionalArray(Dwarf_Die range, 
2093                                                    Type * elementType)
2094 {
2095   char buf[32];
2096   /* Get the (negative) typeID for this range/subarray. */
2097   Dwarf_Off dieOffset;
2098   DWARF_FAIL_RET_VAL(dwarf_dieoffset( range, & dieOffset, NULL ), NULL);
2099
2100   /* Determine the range. */
2101   std::string loBound;
2102   std::string hiBound;
2103   parseSubrangeAUX(range, loBound, hiBound);
2104
2105   /* Does the recursion continue? */
2106   Dwarf_Die nextSibling;
2107   Dwarf_Bool is_info = dwarf_get_die_infotypes_flag(range);
2108   int status = dwarf_siblingof_b( dbg(), range, is_info, & nextSibling, NULL );
2109   DWARF_CHECK_RET_VAL(status == DW_DLV_ERROR, NULL);
2110
2111   snprintf(buf, 31, "__array%d", (int) offset());
2112
2113   if ( status == DW_DLV_NO_ENTRY ) {
2114     /* Terminate the recursion by building an array type out of the elemental type.
2115        Use the negative dieOffset to avoid conflicts with the range type created
2116        by parseSubRangeDIE(). */
2117     // N.B.  I'm going to ignore the type id, and just create an anonymous type here
2118      std::string aName = buf;
2119      typeArray* innermostType = new typeArray( elementType, 
2120                                                atoi( loBound.c_str() ), 
2121                                                atoi( hiBound.c_str() ), 
2122                                                aName );
2123      assert( innermostType != NULL );
2124      Type * typ = tc()->addOrUpdateType( innermostType );
2125     innermostType = dynamic_cast<typeArray *>(typ);
2126     return innermostType;
2127   } /* end base-case of recursion. */
2128
2129   /* If it does, build this array type out of the array type returned from the next recusion. */
2130   typeArray * innerType = parseMultiDimensionalArray( nextSibling, elementType);
2131   assert( innerType != NULL );
2132   // same here - type id ignored    jmo
2133   std::string aName = buf;
2134   typeArray * outerType = new typeArray( innerType, atoi(loBound.c_str()), atoi(hiBound.c_str()), aName);
2135   assert( outerType != NULL );
2136   Type *typ = tc()->addOrUpdateType( outerType );
2137   outerType = static_cast<typeArray *>(typ);
2138
2139   dwarf_dealloc( dbg(), nextSibling, DW_DLA_DIE );
2140   return outerType;
2141 } /* end parseMultiDimensionalArray() */
2142
2143 bool DwarfWalker::decipherBound(Dwarf_Attribute boundAttribute, Dwarf_Bool is_info,
2144                                 std::string &boundString )
2145 {
2146    Dwarf_Half boundForm;
2147    DWARF_FAIL_RET(dwarf_whatform( boundAttribute, & boundForm, NULL ));
2148    
2149    switch( boundForm ) {
2150       case DW_FORM_data1:
2151       case DW_FORM_data2:
2152       case DW_FORM_data4:
2153       case DW_FORM_data8:
2154       case DW_FORM_udata: 
2155       {
2156          dwarf_printf("(0x%lx) Decoding form %d with formudata\n",
2157                       id(), boundForm);
2158                      
2159          Dwarf_Unsigned constantBound;
2160          DWARF_FAIL_RET(dwarf_formudata( boundAttribute, & constantBound, NULL ));
2161          char bString[40];
2162          sprintf(bString, "%llu", (unsigned long long)constantBound);
2163          boundString = bString;
2164          return true;
2165       } break;
2166
2167       case DW_FORM_sdata:
2168       {
2169          dwarf_printf("(0x%lx) Decoding form %d with formsdata\n",
2170                       id(), boundForm);
2171                      
2172          Dwarf_Signed constantBound;
2173          DWARF_FAIL_RET(dwarf_formsdata( boundAttribute, & constantBound, NULL ));
2174          char bString[40];
2175          sprintf(bString, "%lld", (long long)constantBound);
2176          boundString = bString;
2177          return true;
2178       } break;
2179       
2180       case DW_FORM_ref_addr:
2181       case DW_FORM_ref1:
2182       case DW_FORM_ref2:
2183       case DW_FORM_ref4:
2184       case DW_FORM_ref8:
2185       case DW_FORM_ref_udata: 
2186       {
2187          /* Acquire the referenced DIE. */
2188          Dwarf_Off boundOffset;
2189          DWARF_FAIL_RET(dwarf_global_formref( boundAttribute, & boundOffset, NULL ));
2190          
2191          Dwarf_Die boundEntry;
2192          DWARF_FAIL_RET(dwarf_offdie_b( dbg(), boundOffset, is_info, & boundEntry, NULL ));
2193          
2194          /* Does it have a name? */
2195          if (findDieName( boundEntry, boundString )
2196                && !boundString.empty())
2197             return true;
2198          
2199          /* Does it describe a nameless constant? */
2200          Dwarf_Attribute constBoundAttribute;
2201          int status = dwarf_attr( boundEntry, DW_AT_const_value, & constBoundAttribute, NULL );
2202          DWARF_CHECK_RET(status == DW_DLV_ERROR);
2203          
2204          if ( status == DW_DLV_OK ) {
2205             Dwarf_Unsigned constBoundValue;
2206             DWARF_FAIL_RET(dwarf_formudata( constBoundAttribute, & constBoundValue, NULL ));
2207             
2208             char bString[40];
2209             sprintf(bString, "%lu", (unsigned long)constBoundValue);
2210             boundString = bString;
2211             
2212             dwarf_dealloc( dbg(), boundEntry, DW_DLA_DIE );
2213             dwarf_dealloc( dbg(), constBoundAttribute, DW_DLA_ATTR );
2214             return true;
2215          }
2216          
2217          return false;
2218       } break;
2219       case DW_FORM_block:
2220       case DW_FORM_block1:
2221       {
2222          /* PGI extends DWARF to allow some bounds to be location lists.  Since we can't
2223             do anything sane with them, ignore them. */
2224          // Dwarf_Locdesc * locationList;
2225          // Dwarf_Signed listLength;
2226          // status = dwarf_loclist( boundAttribute, & locationList, & listLength, NULL );
2227          boundString = "{PGI extension}";
2228          return false;
2229       } break;
2230       
2231       default:
2232          //bperr ( "Invalid bound form 0x%x\n", boundForm );
2233          boundString = "{invalid bound form}";
2234          return false;
2235          break;
2236    } /* end boundForm switch */
2237    return true;
2238 }
2239
2240 bool DwarfWalker::decodeExpression(Dwarf_Attribute &attr,
2241                                    std::vector<VariableLocation> &locs) {
2242   Dwarf_Unsigned expr_len;
2243   Dwarf_Ptr expr_ptr;
2244   DWARF_FAIL_RET(dwarf_formexprloc(attr, &expr_len, &expr_ptr, NULL));
2245   unsigned char *bitstream = (unsigned char *) expr_ptr;
2246
2247   // expr_ptr is a pointer to a bytestream. Try to turn it into a Dwarf_Locdesc so
2248   // we can use decodeDwarfExpression. 
2249
2250   dwarf_printf("(0x%lx) bitstream for expr has len %d\n", id(), expr_len);
2251   for (unsigned i = 0; i < expr_len; ++i) {
2252     dwarf_printf("(0x%lx) \t %#hhx\n", id(), bitstream[i]);
2253   }
2254
2255   Dwarf_Signed cnt;
2256   Dwarf_Locdesc *descs;
2257
2258   DWARF_FAIL_RET(dwarf_loclist_from_expr_a(dbg(), expr_ptr, expr_len, addr_size, 
2259                                            &descs, &cnt, NULL));
2260   assert(cnt == 1);
2261
2262   bool ret = decodeLocationListForStaticOffsetOrAddress(&descs, cnt, locs, NULL);
2263   //deallocateLocationList(&descs, cnt);
2264   return ret;
2265 }
2266
2267 bool DwarfWalker::decodeLocationListForStaticOffsetOrAddress( Dwarf_Locdesc **locationList, 
2268                                                               Dwarf_Signed listLength, 
2269                                                               std::vector<VariableLocation>& locs,
2270                                                               Address * initialStackValue)
2271 {
2272    locs.clear();
2273
2274   /* We make a few heroic assumptions about locations in this decoder.
2275
2276   We assume that all locations are either frame base-relative offsets,
2277   encoded with DW_OP_fbreg, or are absolute addresses.  We assume these
2278   locations are invariant with respect to the PC, which implies that all
2279   location lists have a single entry.  We assume that no location is
2280   calculated at run-time.
2281
2282   We make these assumptions to match the assumptions of the rest of
2283   Dyninst, which makes no provision for pc-variant or run-time calculated
2284   locations, aside from the frame pointer.  However, it assumes that a frame
2285   pointer is readily available, which, on IA-64, it is not.  For that reason,
2286   when we encounter a function with a DW_AT_frame_base (effectively all of them),
2287   we do NOT use this decoder; we decode the location into an AST, which we
2288   will use to calculate the frame pointer when asked to do frame-relative operations.
2289   (These calculations will be invalid until the frame pointer is established,
2290   which may require some fiddling with the location of the 'entry' instpoint.) */
2291
2292   /* We now parse the complete location list for variables and parameters within a
2293    * function. We still ignore the location list defined for DW_AT_frame_base of the
2294    * function as the frame pointer is readily available on all platforms(except for IA64)
2295    * May be we would need to parse the location list for IA64 functions to store the 
2296    * register numbers and offsets and use it based on the pc value. 
2297    */
2298
2299    uint64_t max_addr = (addr_size == 4) ? 0xffffffff : 0xffffffffffffffff;
2300    Address base = modLow;
2301  
2302    for (unsigned locIndex = 0 ; locIndex < listLength; locIndex++) {
2303                    
2304       /* There is only one location. */
2305       Dwarf_Locdesc *location = locationList[locIndex];
2306
2307       VariableLocation loc;
2308       // Initialize location values.
2309       loc.stClass = storageAddr;
2310       loc.refClass = storageNoRef;
2311
2312       // If location == 0..-1, it's "unset" and we keep the big range unless
2313       // we're in a lexical block construct. 
2314       // 
2315       dwarf_printf("(0x%lx) Decoding entry %d of %d over range 0x%lx - 0x%lx, mod 0x%lx - 0x%lx, base 0x%lx\n", 
2316                    id(), locIndex+1, (int) listLength,
2317                    (long) location->ld_lopc,
2318                    (long) location->ld_hipc,
2319                    modLow, modHigh, base);
2320
2321       if (location->ld_lopc == max_addr) {
2322          //This is a base address selection entry, which changes the base address of 
2323          // subsequent entries
2324          base = location->ld_hipc;
2325          continue;
2326       }
2327
2328       long int *tmp = (long int *)initialStackValue;
2329       bool result = decodeDwarfExpression(location, tmp, loc,
2330                                           symtab()->getArchitecture());
2331       if (!result) {
2332          dwarf_printf("(0x%lx): decodeDwarfExpr failed\n", id());
2333          continue;
2334       }
2335
2336       if (location->ld_lopc == 0 &&
2337           location->ld_hipc == (Dwarf_Addr) ~0) {
2338          // Unset low and high. Use the lexical block info if present, otherwise
2339          // pass through. 
2340          if (hasRanges()) {
2341             dwarf_printf("(0x%lx) Using lexical range\n", id());
2342             for (range_set_t::iterator i = ranges_begin(); i != ranges_end(); i++) {
2343                pair<Address, Address> range = *i;
2344                loc.lowPC = range.first;
2345                loc.hiPC = range.second;
2346
2347                dwarf_printf("(0x%lx) Variable valid over range 0x%lx to 0x%lx\n", 
2348                             id(), loc.lowPC, loc.hiPC);
2349                locs.push_back(loc);
2350             }
2351          }
2352          else {
2353             dwarf_printf("(0x%lx) Using open location range\n", id());            
2354             loc.lowPC = location->ld_lopc;
2355             loc.hiPC = location->ld_hipc;
2356
2357             dwarf_printf("(0x%lx) Variable valid over range 0x%lx to 0x%lx\n", 
2358                          id(), loc.lowPC, loc.hiPC);
2359             locs.push_back(loc);
2360          }
2361       }
2362       else {
2363          dwarf_printf("(0x%lx) Using lexical range, shifted by module low\n", id());
2364          loc.lowPC = location->ld_lopc + base;
2365          loc.hiPC = location->ld_hipc + base;
2366
2367          dwarf_printf("(0x%lx) Variable valid over range 0x%lx to 0x%lx\n", 
2368                       id(), loc.lowPC, loc.hiPC);
2369          locs.push_back(loc);
2370       }
2371    }
2372    
2373    /* decode successful */
2374    return !locs.empty();
2375 } /* end decodeLocationListForStaticOffsetOrAddress() */
2376
2377 void DwarfWalker::deallocateLocationList( Dwarf_Locdesc * locationList, 
2378                                           Dwarf_Signed listLength ) 
2379 {
2380   for( int i = 0; i < listLength; i++ ) {
2381      dwarf_dealloc( dbg(), locationList[i].ld_s, DW_DLA_LOC_BLOCK );
2382   }
2383   dwarf_dealloc( dbg(), locationList, DW_DLA_LOCDESC );
2384 } /* end deallocateLocationList() */
2385
2386 void DwarfWalker::deallocateLocationList( Dwarf_Locdesc ** locationList, 
2387                                           Dwarf_Signed listLength ) 
2388 {
2389   for( int i = 0; i < listLength; i++ ) {
2390      dwarf_dealloc( dbg(), locationList[i]->ld_s, DW_DLA_LOC_BLOCK );
2391      dwarf_dealloc( dbg(), locationList[i], DW_DLA_LOCDESC );
2392   }
2393   dwarf_dealloc( dbg(), locationList, DW_DLA_LIST );
2394 } /* end deallocateLocationList() */
2395
2396 void DwarfWalker::setEntry(Dwarf_Die entry) {
2397    contexts_.setEntry(entry);
2398    contexts_.setSpecEntry(entry);
2399    contexts_.setAbstractEntry(entry);
2400 }
2401 void DwarfWalker::Contexts::push() {
2402    if (c.empty()) {
2403       c.push(Context());
2404    }
2405    else {
2406       c.push(Context(c.top()));
2407    }
2408 }
2409
2410 void DwarfWalker::Contexts::pop() {
2411    assert(!c.empty());
2412    c.pop();
2413 }
2414
2415 void DwarfWalker::Contexts::setFunc(FunctionBase *f) {
2416   // Bug workaround; if we're setting a function, ignore
2417   // any preceding lexical information since we probably 
2418   // nested. 
2419   c.top().func = f;
2420 }
2421
2422 void DwarfWalker::Contexts::clearFunc() {
2423   // We can't edit in the middle of the stack...
2424
2425   std::stack<Context> repl;
2426   while (!c.empty()) {
2427     repl.push(c.top());
2428     c.pop();
2429   }
2430
2431   while (!repl.empty()) {
2432     c.push(repl.top());
2433     c.top().func = NULL;
2434     repl.pop();
2435   }
2436 }
2437
2438 typeId_t DwarfWalker::get_type_id(Dwarf_Off offset, bool is_info)
2439 {
2440   auto& type_ids = is_info ? info_type_ids_ : types_type_ids_;
2441   auto it = type_ids.find(offset);
2442   if (it != type_ids.end())
2443     return it->second;
2444
2445   size_t size = info_type_ids_.size() + types_type_ids_.size();
2446   typeId_t id = (typeId_t) size + 1;
2447   type_ids[offset] = id;
2448   return id;
2449 }
2450
2451 typeId_t DwarfWalker::type_id()
2452 {
2453   Dwarf_Bool is_info = dwarf_get_die_infotypes_flag(entry());
2454   return get_type_id(offset(), is_info);
2455 }
2456
2457 void DwarfWalker::findAllSig8Types()
2458 {
2459    /* First .debug_types (0), then .debug_info (1).
2460     * In DWARF4, only .debug_types contains DW_TAG_type_unit,
2461     * but DWARF5 is considering them for .debug_info too.*/
2462    for (int i = 0; i < 2; ++i) {
2463       Dwarf_Bool is_info = i;
2464       compile_offset = next_cu_header = 0;
2465
2466       /* Iterate over the compilation-unit headers. */
2467       while (dwarf_next_cu_header_c(dbg(), is_info,
2468                                     &cu_header_length,
2469                                     &version,
2470                                     &abbrev_offset,
2471                                     &addr_size,
2472                                     &offset_size,
2473                                     &extension_size,
2474                                     &signature,
2475                                     &typeoffset,
2476                                     &next_cu_header, NULL) == DW_DLV_OK ) {
2477          parseModuleSig8(is_info);
2478          compile_offset = next_cu_header;
2479       }
2480    }
2481 }
2482
2483 bool DwarfWalker::parseModuleSig8(Dwarf_Bool is_info)
2484 {
2485    /* Obtain the type DIE. */
2486    Dwarf_Die typeDIE;
2487    DWARF_FAIL_RET(dwarf_siblingof_b( dbg(), NULL, is_info, &typeDIE, NULL ));
2488
2489    /* Make sure we've got the right one. */
2490    Dwarf_Half typeTag;
2491    DWARF_FAIL_RET(dwarf_tag( typeDIE, & typeTag, NULL ));
2492
2493    if (typeTag != DW_TAG_type_unit)
2494       return false;
2495
2496    /* typeoffset is relative to the type unit; we want the global offset. */
2497    Dwarf_Off cu_off, cu_length;
2498    DWARF_FAIL_RET(dwarf_die_CU_offset_range( typeDIE, &cu_off, &cu_length, NULL ));
2499
2500    uint64_t sig8 = * reinterpret_cast<uint64_t*>(&signature);
2501    typeId_t type_id = get_type_id(cu_off + typeoffset, is_info);
2502    sig8_type_ids_[sig8] = type_id;
2503
2504    dwarf_printf("Mapped Sig8 {%016llx} to type id 0x%x\n", (long long) sig8, type_id);
2505    return true;
2506 }
2507
2508 bool DwarfWalker::findSig8Type(Dwarf_Sig8 *signature, Type *&returnType)
2509 {
2510    uint64_t sig8 = * reinterpret_cast<uint64_t*>(signature);
2511    auto it = sig8_type_ids_.find(sig8);
2512    if (it != sig8_type_ids_.end()) {
2513       typeId_t type_id = it->second;
2514       returnType = tc()->findOrCreateType( type_id );
2515       dwarf_printf("Found Sig8 {%016llx} as type id 0x%x\n", (long long) sig8, type_id);
2516       return true;
2517    }
2518
2519    dwarf_printf("Couldn't find Sig8 {%016llx}!\n", (long long) sig8);
2520    return false;
2521 }