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