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