Exemplo n.º 1
0
//----------------------------------------------------------------------
// Parse
//
// Parses the .debug_info section and uses the .debug_abbrev section
// and various other sections in the SymbolFileDWARF class and calls the
// supplied callback function each time a compile unit header, or debug
// information entry is successfully parsed. This function can be used
// for different tasks such as parsing the file contents into a
// structured data, dumping, verifying and much more.
//----------------------------------------------------------------------
void DWARFDebugInfo::Parse(SymbolFileDWARF *dwarf2Data, Callback callback,
                           void *userData) {
  if (dwarf2Data) {
    lldb::offset_t offset = 0;
    uint32_t depth = 0;
    DWARFDebugInfoEntry die;

    DWARFCompileUnitSP cu;
    while ((cu = DWARFCompileUnit::Extract(dwarf2Data, &offset))) {
      const dw_offset_t next_cu_offset = cu->GetNextCompileUnitOffset();

      depth = 0;
      // Call the callback function with no DIE pointer for the compile unit
      // and get the offset that we are to continue to parse from
      offset = callback(dwarf2Data, cu.get(), NULL, offset, depth, userData);

      // Make sure we are within our compile unit
      if (offset < next_cu_offset) {
        // We are in our compile unit, parse starting at the offset
        // we were told to parse
        bool done = false;
        while (!done && die.Extract(dwarf2Data, cu.get(), &offset)) {
          // Call the callback function with DIE pointer that falls within the
          // compile unit
          offset =
              callback(dwarf2Data, cu.get(), &die, offset, depth, userData);

          if (die.IsNULL()) {
            if (depth)
              --depth;
            else
              done = true; // We are done with this compile unit!
          } else if (die.HasChildren())
            ++depth;
        }
      }

      // Make sure the offset returned is valid, and if not stop parsing.
      // Returning DW_INVALID_OFFSET from this callback is a good way to end
      // all parsing
      if (!dwarf2Data->get_debug_info_data().ValidOffset(offset))
        break;

      // Make sure we start on a proper
      offset = next_cu_offset;
    }
  }
}
Exemplo n.º 2
0
//----------------------------------------------------------------------
// Parse
//
// Parses the .debug_info section and uses the .debug_abbrev section
// and various other sections in the SymbolFileDWARF class and calls the
// supplied callback function each time a compile unit header, or debug
// information entry is successfully parsed. This function can be used
// for different tasks such as parsing the file contents into a
// structured data, dumping, verifying and much more.
//----------------------------------------------------------------------
void
DWARFDebugInfo::Parse(SymbolFileDWARF* dwarf2Data, Callback callback, void* userData)
{
    if (dwarf2Data)
    {
        lldb::offset_t offset = 0;
        uint32_t depth = 0;
        DWARFCompileUnitSP cu(new DWARFCompileUnit(dwarf2Data));
        if (cu.get() == NULL)
            return;
        DWARFDebugInfoEntry die;

        while (cu->Extract(dwarf2Data->get_debug_info_data(), &offset))
        {
            const dw_offset_t next_cu_offset = cu->GetNextCompileUnitOffset();

            depth = 0;
            // Call the callback function with no DIE pointer for the compile unit
            // and get the offset that we are to continue to parse from
            offset = callback(dwarf2Data, cu.get(), NULL, offset, depth, userData);

            // Make sure we are within our compile unit
            if (offset < next_cu_offset)
            {
                // We are in our compile unit, parse starting at the offset
                // we were told to parse
                bool done = false;
                while (!done && die.Extract(dwarf2Data, cu.get(), &offset))
                {
                    // Call the callback function with DIE pointer that falls within the compile unit
                    offset = callback(dwarf2Data, cu.get(), &die, offset, depth, userData);

                    if (die.IsNULL())
                    {
                        if (depth)
                            --depth;
                        else
                            done = true;    // We are done with this compile unit!
                    }
                    else if (die.HasChildren())
                        ++depth;
                }
            }

            // Make sure the offset returned is valid, and if not stop parsing.
            // Returning DW_INVALID_OFFSET from this callback is a good way to end
            // all parsing
            if (!dwarf2Data->get_debug_info_data().ValidOffset(offset))
                break;

            // See if during the callback anyone retained a copy of the compile
            // unit other than ourselves and if so, let whomever did own the object
            // and create a new one for our own use!
            if (!cu.unique())
                cu.reset(new DWARFCompileUnit(dwarf2Data));


            // Make sure we start on a proper
            offset = next_cu_offset;
        }
    }
}