//===-- DWARFLocationList.cpp -----------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "DWARFLocationList.h" #include "lldb/Core/Stream.h" #include "DWARFCompileUnit.h" #include "DWARFDebugInfo.h" #include "DWARFLocationDescription.h" using namespace lldb_private; dw_offset_t DWARFLocationList::Dump(Stream &s, const DWARFCompileUnit* cu, const DWARFDataExtractor& debug_loc_data, lldb::offset_t offset) { uint64_t start_addr, end_addr; uint32_t addr_size = DWARFCompileUnit::GetAddressByteSize(cu); s.SetAddressByteSize(DWARFCompileUnit::GetAddressByteSize(cu)); dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0; while (debug_loc_data.ValidOffset(offset)) { start_addr = debug_loc_data.GetMaxU64(&offset,addr_size); end_addr = debug_loc_data.GetMaxU64(&offset,addr_size); if (start_addr == 0 && end_addr == 0) break; s.PutCString("\n "); s.Indent(); if (cu) s.AddressRange (start_addr + base_addr, end_addr + base_addr, cu->GetAddressByteSize(), NULL, ": "); uint32_t loc_length = debug_loc_data.GetU16(&offset); DWARFDataExtractor locationData(debug_loc_data, offset, loc_length); // if ( dump_flags & DWARFDebugInfo::eDumpFlag_Verbose ) *ostrm_ptr << " ( "; print_dwarf_expression (s, locationData, addr_size, 4, false); offset += loc_length; } return offset; } bool DWARFLocationList::Extract(const DWARFDataExtractor& debug_loc_data, lldb::offset_t* offset_ptr, DWARFDataExtractor& location_list_data) { // Initialize with no data just in case we don't find anything location_list_data.Clear(); size_t loc_list_length = Size(debug_loc_data, *offset_ptr); if (loc_list_length > 0) { location_list_data.SetData(debug_loc_data, *offset_ptr, loc_list_length); *offset_ptr += loc_list_length; return true; } return false; } size_t DWARFLocationList::Size(const DWARFDataExtractor& debug_loc_data, lldb::offset_t offset) { const dw_offset_t debug_loc_offset = offset; while (debug_loc_data.ValidOffset(offset)) { dw_addr_t start_addr = debug_loc_data.GetAddress(&offset); dw_addr_t end_addr = debug_loc_data.GetAddress(&offset); if (start_addr == 0 && end_addr == 0) break; uint16_t loc_length = debug_loc_data.GetU16(&offset); offset += loc_length; } if (offset > debug_loc_offset) return offset - debug_loc_offset; return 0; }