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