//===-- HashedNameToDIE.cpp -------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "HashedNameToDIE.h" void DWARFMappedHash::ExtractDIEArray (const DIEInfoArray &die_info_array, DIEArray &die_offsets) { const size_t count = die_info_array.size(); for (size_t i=0; i"; } DWARFMappedHash::DIEInfo::DIEInfo () : cu_offset (DW_INVALID_OFFSET), offset (DW_INVALID_OFFSET), tag (0), type_flags (0), qualified_name_hash (0) { } DWARFMappedHash::DIEInfo::DIEInfo (dw_offset_t c, dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h) : cu_offset (c), offset (o), tag (t), type_flags (f), qualified_name_hash (h) { } DWARFMappedHash::Prologue::Prologue (dw_offset_t _die_base_offset) : die_base_offset (_die_base_offset), atoms(), atom_mask (0), min_hash_data_byte_size(0), hash_data_has_fixed_byte_size(true) { // Define an array of DIE offsets by first defining an array, // and then define the atom type for the array, in this case // we have an array of DIE offsets AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4); } void DWARFMappedHash::Prologue::ClearAtoms () { hash_data_has_fixed_byte_size = true; min_hash_data_byte_size = 0; atom_mask = 0; atoms.clear(); } bool DWARFMappedHash::Prologue::ContainsAtom (AtomType atom_type) const { return (atom_mask & (1u << atom_type)) != 0; } void DWARFMappedHash::Prologue::Clear () { die_base_offset = 0; ClearAtoms (); } void DWARFMappedHash::Prologue::AppendAtom (AtomType type, dw_form_t form) { atoms.push_back ({type, form}); atom_mask |= 1u << type; switch (form) { case DW_FORM_indirect: case DW_FORM_exprloc: case DW_FORM_flag_present: case DW_FORM_ref_sig8: assert (!"Unhandled atom form"); break; case DW_FORM_string: case DW_FORM_block: case DW_FORM_block1: case DW_FORM_sdata: case DW_FORM_udata: case DW_FORM_ref_udata: case DW_FORM_GNU_addr_index: case DW_FORM_GNU_str_index: hash_data_has_fixed_byte_size = false; // Fall through to the cases below... case DW_FORM_flag: case DW_FORM_data1: case DW_FORM_ref1: case DW_FORM_sec_offset: min_hash_data_byte_size += 1; break; case DW_FORM_block2: hash_data_has_fixed_byte_size = false; // Fall through to the cases below... case DW_FORM_data2: case DW_FORM_ref2: min_hash_data_byte_size += 2; break; case DW_FORM_block4: hash_data_has_fixed_byte_size = false; // Fall through to the cases below... case DW_FORM_data4: case DW_FORM_ref4: case DW_FORM_addr: case DW_FORM_ref_addr: case DW_FORM_strp: min_hash_data_byte_size += 4; break; case DW_FORM_data8: case DW_FORM_ref8: min_hash_data_byte_size += 8; break; } } lldb::offset_t DWARFMappedHash::Prologue::Read (const lldb_private::DataExtractor &data, lldb::offset_t offset) { ClearAtoms (); die_base_offset = data.GetU32 (&offset); const uint32_t atom_count = data.GetU32 (&offset); if (atom_count == 0x00060003u) { // Old format, deal with contents of old pre-release format while (data.GetU32(&offset)) /* do nothing */; // Hardcode to the only known value for now. AppendAtom (eAtomTypeDIEOffset, DW_FORM_data4); } else { for (uint32_t i=0; i::Read (data, offset); if (offset != UINT32_MAX) { offset = header_data.Read (data, offset); } return offset; } bool DWARFMappedHash::Header::Read (const lldb_private::DWARFDataExtractor &data, lldb::offset_t *offset_ptr, DIEInfo &hash_data) const { const size_t num_atoms = header_data.atoms.size(); if (num_atoms == 0) return false; for (size_t i=0; i 0) strm.PutCString (", "); DWARFFormValue form_value (NULL, header_data.atoms[i].form); switch (header_data.atoms[i].type) { case eAtomTypeDIEOffset: // DIE offset, check form for encoding strm.Printf ("{0x%8.8x}", hash_data.offset); break; case eAtomTypeTag: // DW_TAG value for the DIE { const char *tag_cstr = lldb_private::DW_TAG_value_to_name (hash_data.tag); if (tag_cstr) strm.PutCString (tag_cstr); else strm.Printf ("DW_TAG_(0x%4.4x)", hash_data.tag); } break; case eAtomTypeTypeFlags: // Flags from enum TypeFlags strm.Printf ("0x%2.2x", hash_data.type_flags); if (hash_data.type_flags) { strm.PutCString (" ("); if (hash_data.type_flags & eTypeFlagClassIsImplementation) strm.PutCString (" implementation"); strm.PutCString (" )"); } break; case eAtomTypeQualNameHash: // Flags from enum TypeFlags strm.Printf ("0x%8.8x", hash_data.qualified_name_hash); break; default: strm.Printf ("AtomType(0x%x)", header_data.atoms[i].type); break; } } } DWARFMappedHash::MemoryTable::MemoryTable (lldb_private::DWARFDataExtractor &table_data, const lldb_private::DWARFDataExtractor &string_table, const char *name) : MappedHash::MemoryTable (table_data), m_data (table_data), m_string_table (string_table), m_name (name) { } const char * DWARFMappedHash::MemoryTable::GetStringForKeyType (KeyType key) const { // The key in the DWARF table is the .debug_str offset for the string return m_string_table.PeekCStr (key); } bool DWARFMappedHash::MemoryTable::ReadHashData (uint32_t hash_data_offset, HashData &hash_data) const { lldb::offset_t offset = hash_data_offset; offset += 4; // Skip string table offset that contains offset of hash name in .debug_str const uint32_t count = m_data.GetU32 (&offset); if (count > 0) { hash_data.resize(count); for (uint32_t i=0; i 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size)) { // We have at least one HashData entry, and we have enough // data to parse at least "count" HashData entries. // First make sure the entire C string matches... const bool match = strcmp (name, strp_cstr) == 0; if (!match && m_header.header_data.HashDataHasFixedByteSize()) { // If the string doesn't match and we have fixed size data, // we can just add the total byte size of all HashData objects // to the hash data offset and be done... *hash_data_offset_ptr += min_total_hash_data_size; } else { // If the string does match, or we don't have fixed size data // then we need to read the hash data as a stream. If the // string matches we also append all HashData objects to the // value array. for (uint32_t i=0; i 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size)) { const bool match = regex.Execute(strp_cstr); if (!match && m_header.header_data.HashDataHasFixedByteSize()) { // If the regex doesn't match and we have fixed size data, // we can just add the total byte size of all HashData objects // to the hash data offset and be done... *hash_data_offset_ptr += min_total_hash_data_size; } else { // If the string does match, or we don't have fixed size data // then we need to read the hash data as a stream. If the // string matches we also append all HashData objects to the // value array. for (uint32_t i=0; i