Пример #1
0
void
DWARFDebugRanges::Dump(Stream &s, const DataExtractor& debug_ranges_data, uint32_t* offset_ptr, dw_addr_t cu_base_addr)
{
    uint32_t addr_size = s.GetAddressByteSize();
    bool verbose = s.GetVerbose();

    dw_addr_t base_addr = cu_base_addr;
    while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size))
    {
        dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
        dw_addr_t end   = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
        // Extend 4 byte addresses that consits of 32 bits of 1's to be 64 bits
        // of ones
        if (begin == 0xFFFFFFFFull && addr_size == 4)
            begin = DW_INVALID_ADDRESS;

        s.Indent();
        if (verbose)
        {
            s.AddressRange(begin, end, sizeof (dw_addr_t), " offsets = ");
        }


        if (begin == 0 && end == 0)
        {
            s.PutCString(" End");
            break;
        }
        else if (begin == DW_INVALID_ADDRESS)
        {
            // A base address selection entry
            base_addr = end;
            s.Address(base_addr, sizeof (dw_addr_t), " Base address = ");
        }
        else
        {
            // Convert from offset to an address
            dw_addr_t begin_addr = begin + base_addr;
            dw_addr_t end_addr = end + base_addr;

            s.AddressRange(begin_addr, end_addr, sizeof (dw_addr_t), verbose ? " ==> addrs = " : NULL);
        }
    }
}
Пример #2
0
//----------------------------------------------------------------------
// 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())
                {
                    // This DIE is in this compile unit!
                    if (s->GetVerbose())
                        cu->Dump(s); // Dump the compile unit for the DIE in verbose mode

                    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;
}
Пример #3
0
void
DWARFFormValue::Dump(Stream &s, const DWARFDataExtractor* debug_str_data, const DWARFCompileUnit* cu) const
{
    uint64_t uvalue = Unsigned();
    bool cu_relative_offset = false;

    bool verbose = s.GetVerbose();

    switch (m_form)
    {
    case DW_FORM_addr:      s.Address(uvalue, sizeof (uint64_t)); break;
    case DW_FORM_flag:
    case DW_FORM_data1:     s.PutHex8(uvalue);     break;
    case DW_FORM_data2:     s.PutHex16(uvalue);        break;
    case DW_FORM_sec_offset:
    case DW_FORM_data4:     s.PutHex32(uvalue);        break;
    case DW_FORM_ref_sig8:
    case DW_FORM_data8:     s.PutHex64(uvalue);        break;
    case DW_FORM_string:    s.QuotedCString(AsCString(NULL));          break;
    case DW_FORM_exprloc:
    case DW_FORM_block:
    case DW_FORM_block1:
    case DW_FORM_block2:
    case DW_FORM_block4:
        if (uvalue > 0)
        {
            switch (m_form)
            {
            case DW_FORM_exprloc:
            case DW_FORM_block:  s.Printf("<0x%" PRIx64 "> ", uvalue);                break;
            case DW_FORM_block1: s.Printf("<0x%2.2x> ", (uint8_t)uvalue);      break;
            case DW_FORM_block2: s.Printf("<0x%4.4x> ", (uint16_t)uvalue);     break;
            case DW_FORM_block4: s.Printf("<0x%8.8x> ", (uint32_t)uvalue);     break;
            default:                                                            break;
            }

            const uint8_t* data_ptr = m_value.data;
            if (data_ptr)
            {
                const uint8_t* end_data_ptr = data_ptr + uvalue;    // uvalue contains size of block
                while (data_ptr < end_data_ptr)
                {
                    s.Printf("%2.2x ", *data_ptr);
                    ++data_ptr;
                }
            }
            else
                s.PutCString("NULL");
        }
        break;

    case DW_FORM_sdata:     s.PutSLEB128(uvalue); break;
    case DW_FORM_udata:     s.PutULEB128(uvalue); break;
    case DW_FORM_strp:
        if (debug_str_data)
        {
            if (verbose)
                s.Printf(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue);

            const char* dbg_str = AsCString(debug_str_data);
            if (dbg_str)
                s.QuotedCString(dbg_str);
        }
        else
        {
            s.PutHex32(uvalue);
        }
        break;

    case DW_FORM_ref_addr:
    {
        if (cu->GetVersion() <= 2)
            s.Address(uvalue, sizeof (uint64_t) * 2);
        else
            s.Address(uvalue, 4 * 2);// 4 for DWARF32, 8 for DWARF64, but we don't support DWARF64 yet
        break;
    }
    case DW_FORM_ref1:      cu_relative_offset = true;  if (verbose) s.Printf("cu + 0x%2.2x", (uint8_t)uvalue); break;
    case DW_FORM_ref2:      cu_relative_offset = true;  if (verbose) s.Printf("cu + 0x%4.4x", (uint16_t)uvalue); break;
    case DW_FORM_ref4:      cu_relative_offset = true;  if (verbose) s.Printf("cu + 0x%4.4x", (uint32_t)uvalue); break;
    case DW_FORM_ref8:      cu_relative_offset = true;  if (verbose) s.Printf("cu + 0x%8.8" PRIx64, uvalue); break;
    case DW_FORM_ref_udata: cu_relative_offset = true;  if (verbose) s.Printf("cu + 0x%" PRIx64, uvalue); break;

    // All DW_FORM_indirect attributes should be resolved prior to calling this function
    case DW_FORM_indirect:  s.PutCString("DW_FORM_indirect"); break;
    case DW_FORM_flag_present: break;
    default:
        s.Printf("DW_FORM(0x%4.4x)", m_form);
        break;
    }

    if (cu_relative_offset)
    {
        if (verbose)
            s.PutCString(" => ");

        s.Printf("{0x%8.8" PRIx64 "}", (uvalue + (cu ? cu->GetOffset() : 0)));
    }
}