//---------------------------------------------------------------------- // 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; }
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; }