//----------------------------------------------------------------------
// DumpCallback
//
// A callback function for the static DWARFDebugInfo::Parse() function
// that gets called each time a compile unit header or debug information
// entry is successfully parsed.
//
// This function dump DWARF information and obey recurse depth and
// whether a single DIE is to be dumped (or all of the data).
//----------------------------------------------------------------------
static dw_offset_t DumpCallback(SymbolFileDWARF *dwarf2Data,
                                DWARFCompileUnit *cu, DWARFDebugInfoEntry *die,
                                const dw_offset_t next_offset,
                                const uint32_t curr_depth, void *userData) {
  DumpInfo *dumpInfo = (DumpInfo *)userData;
  Stream *s = dumpInfo->strm;
  bool show_parents =
      s->GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowAncestors);

  if (die) {
    // Are we dumping everything?
    if (dumpInfo->die_offset == DW_INVALID_OFFSET) {
      // Yes we are dumping everything. Obey our recurse level though
      if (curr_depth < dumpInfo->recurse_depth)
        die->Dump(dwarf2Data, cu, *s, 0);
    } else {
      // We are dumping a specific DIE entry by offset
      if (dumpInfo->die_offset == die->GetOffset()) {
        // We found the DIE we were looking for, dump it!
        if (show_parents) {
          s->SetIndentLevel(0);
          const uint32_t num_ancestors = dumpInfo->ancestors.size();
          if (num_ancestors > 0) {
            for (uint32_t i = 0; i < num_ancestors - 1; ++i) {
              dumpInfo->ancestors[i].Dump(dwarf2Data, cu, *s, 0);
              s->IndentMore();
            }
          }
        }

        dumpInfo->found_depth = curr_depth;

        die->Dump(dwarf2Data, cu, *s, 0);

        // Note that we found the DIE we were looking for
        dumpInfo->found_die = true;

        // Since we are dumping a single DIE, if there are no children we are
        // done!
        if (!die->HasChildren() || dumpInfo->recurse_depth == 0)
          return DW_INVALID_OFFSET; // Return an invalid address to end parsing
      } else if (dumpInfo->found_die) {
        // Are we done with all the children?
        if (curr_depth <= dumpInfo->found_depth)
          return DW_INVALID_OFFSET;

        // We have already found our DIE and are printing it's children. Obey
        // our recurse depth and return an invalid offset if we get done
        // dumping all of the children
        if (dumpInfo->recurse_depth == UINT32_MAX ||
            curr_depth <= dumpInfo->found_depth + dumpInfo->recurse_depth)
          die->Dump(dwarf2Data, cu, *s, 0);
      } else if (dumpInfo->die_offset > die->GetOffset()) {
        if (show_parents)
          dumpInfo->ancestors.back() = *die;
      }
    }

    // Keep up with our indent level
    if (die->IsNULL()) {
      if (show_parents)
        dumpInfo->ancestors.pop_back();

      if (curr_depth <= 1)
        return cu->GetNextCompileUnitOffset();
      else
        s->IndentLess();
    } else if (die->HasChildren()) {
      if (show_parents) {
        DWARFDebugInfoEntry null_die;
        dumpInfo->ancestors.push_back(null_die);
      }
      s->IndentMore();
    }
  } else {
    if (cu == NULL)
      s->PutCString("NULL - cu");
    // We have a compile unit, reset our indent level to zero just in case
    s->SetIndentLevel(0);

    // See if we are dumping everything?
    if (dumpInfo->die_offset == DW_INVALID_OFFSET) {
      // We are dumping everything
      if (cu) {
        cu->Dump(s);
        return cu->GetFirstDIEOffset(); // Return true to parse all DIEs in this
                                        // Compile Unit
      } else {
        return DW_INVALID_OFFSET;
      }
    } else {
      if (show_parents) {
        dumpInfo->ancestors.clear();
        dumpInfo->ancestors.resize(1);
      }

      // We are dumping only a single DIE possibly with it's children and
      // we must find it's compile unit before we can dump it properly
      if (cu && dumpInfo->die_offset < cu->GetFirstDIEOffset()) {
        // Not found, maybe the DIE offset provided wasn't correct?
        //  *ostrm_ptr << "DIE at offset " << HEX32 << dumpInfo->die_offset << "
        //  was not found." << endl;
        return DW_INVALID_OFFSET;
      } else {
        // See if the DIE is in this compile unit?
        if (cu && dumpInfo->die_offset < cu->GetNextCompileUnitOffset()) {
          return next_offset;
          //  // We found our compile unit that contains our DIE, just skip to
          //  dumping the requested DIE...
          //  return dumpInfo->die_offset;
        } else {
          // Skip to the next compile unit as the DIE isn't in the current one!
          if (cu) {
            return cu->GetNextCompileUnitOffset();
          } else {
            return DW_INVALID_OFFSET;
          }
        }
      }
    }
  }

  // Just return the current offset to parse the next CU or DIE entry
  return next_offset;
}
Beispiel #2
0
bool
CompilerType::SetValueFromScalar (const Scalar &value, Stream &strm)
{
    if (!IsValid())
        return false;

    // Aggregate types don't have scalar values
    if (!IsAggregateType ())
    {
        strm.GetFlags().Set(Stream::eBinary);
        uint64_t count = 0;
        lldb::Encoding encoding = GetEncoding (count);
        
        if (encoding == lldb::eEncodingInvalid || count != 1)
            return false;
        
        const uint64_t bit_width = GetBitSize(nullptr);
        // This function doesn't currently handle non-byte aligned assignments
        if ((bit_width % 8) != 0)
            return false;
        
        const uint64_t byte_size = (bit_width + 7 ) / 8;
        switch (encoding)
        {
            case lldb::eEncodingInvalid:
                break;
            case lldb::eEncodingVector:
                break;
            case lldb::eEncodingUint:
                switch (byte_size)
            {
                case 1: strm.PutHex8(value.UInt()); return true;
                case 2: strm.PutHex16(value.UInt()); return true;
                case 4: strm.PutHex32(value.UInt()); return true;
                case 8: strm.PutHex64(value.ULongLong()); return true;
                default:
                    break;
            }
                break;
                
            case lldb::eEncodingSint:
                switch (byte_size)
            {
                case 1: strm.PutHex8(value.SInt()); return true;
                case 2: strm.PutHex16(value.SInt()); return true;
                case 4: strm.PutHex32(value.SInt()); return true;
                case 8: strm.PutHex64(value.SLongLong()); return true;
                default:
                    break;
            }
                break;
                
            case lldb::eEncodingIEEE754:
                if (byte_size <= sizeof(long double))
                {
                    if (byte_size == sizeof(float))
                    {
                        strm.PutFloat(value.Float());
                        return true;
                    }
                    else
                        if (byte_size == sizeof(double))
                        {
                            strm.PutDouble(value.Double());
                            return true;
                        }
                        else
                            if (byte_size == sizeof(long double))
                            {
                                strm.PutDouble(value.LongDouble());
                                return true;
                            }
                }
                break;
        }
    }
    return false;
}