From 83544cf660d96e191f539ddb5e49aa6aa1feb93c Mon Sep 17 00:00:00 2001 From: Tamas Berghammer Date: Tue, 7 Apr 2015 10:43:50 +0000 Subject: [PATCH] Ignore mapping symbols on aarch64 ELF symbol tables on aarch64 may contains some mapping symbols. They provide information about the underlying data but interfere with symbol look-up of lldb. They are already ignored on arm32. With this CL they will be ignored on aarch64 also. Differential revision: http://reviews.llvm.org/D8776 llvm-svn: 234307 --- .../Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 127 +++++++++++++-------- lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h | 5 + 2 files changed, 82 insertions(+), 50 deletions(-) diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 0ca92de..9c0ec8e 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -895,25 +895,18 @@ ObjectFileELF::GetAddressClass (addr_t file_addr) if (res != eAddressClassCode) return res; - ArchSpec arch_spec; - GetArchitecture(arch_spec); - if (arch_spec.GetMachine() != llvm::Triple::arm) - return res; - - auto symtab = GetSymtab(); - if (symtab == nullptr) - return res; - - auto symbol = symtab->FindSymbolContainingFileAddress(file_addr); - if (symbol == nullptr) - return res; + auto ub = m_address_class_map.upper_bound(file_addr); + if (ub == m_address_class_map.begin()) + { + // No entry in the address class map before the address. Return + // default address class for an address in a code section. + return eAddressClassCode; + } - // Thumb symbols have the lower bit set in the flags field so we just check - // for that. - if (symbol->GetFlags() & ARM_ELF_SYM_IS_THUMB) - res = eAddressClassCodeAlternateISA; + // Move iterator to the address class entry preceding address + --ub; - return res; + return ub->second; } size_t @@ -1872,45 +1865,79 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, } } - ArchSpec arch; int64_t symbol_value_offset = 0; uint32_t additional_flags = 0; - if (GetArchitecture(arch) && - arch.GetMachine() == llvm::Triple::arm) + ArchSpec arch; + if (GetArchitecture(arch)) { - // ELF symbol tables may contain some mapping symbols. They provide - // information about the underlying data. There are three of them - // currently defined: - // $a[.]* - marks an ARM instruction sequence - // $t[.]* - marks a THUMB instruction sequence - // $d[.]* - marks a data item sequence (e.g. lit pool) - // These symbols interfere with normal debugger operations and we - // don't need them. We can drop them here. - - static const llvm::StringRef g_armelf_arm_marker("$a"); - static const llvm::StringRef g_armelf_thumb_marker("$t"); - static const llvm::StringRef g_armelf_data_marker("$d"); - llvm::StringRef symbol_name_ref(symbol_name); - - if (symbol_name && - (symbol_name_ref.startswith(g_armelf_arm_marker) || - symbol_name_ref.startswith(g_armelf_thumb_marker) || - symbol_name_ref.startswith(g_armelf_data_marker))) - continue; + if (arch.GetMachine() == llvm::Triple::arm) + { + if (symbol.getBinding() == STB_LOCAL && symbol_name && symbol_name[0] == '$') + { + // These are reserved for the specification (e.g.: mapping + // symbols). We don't want to add them to the symbol table. + + llvm::StringRef symbol_name_ref(symbol_name); + if (symbol_name_ref == "$a" || symbol_name_ref.startswith("$a.")) + { + // $a[.]* - marks an ARM instruction sequence + m_address_class_map[symbol.st_value] = eAddressClassCode; + } + else if (symbol_name_ref == "$b" || symbol_name_ref.startswith("$b.") || + symbol_name_ref == "$t" || symbol_name_ref.startswith("$t.")) + { + // $b[.]* - marks a THUMB BL instruction sequence + // $t[.]* - marks a THUMB instruction sequence + m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA; + } + else if (symbol_name_ref == "$d" || symbol_name_ref.startswith("$d.")) + { + // $d[.]* - marks a data item sequence (e.g. lit pool) + m_address_class_map[symbol.st_value] = eAddressClassData; + } - // THUMB functions have the lower bit of their address set. Fixup - // the actual address and mark the symbol as THUMB. - if (symbol_type == eSymbolTypeCode && symbol.st_value & 1) + continue; + } + } + else if (arch.GetMachine() == llvm::Triple::aarch64) { - // Substracting 1 from the address effectively unsets - // the low order bit, which results in the address - // actually pointing to the beginning of the symbol. - // This delta will be used below in conjuction with - // symbol.st_value to produce the final symbol_value - // that we store in the symtab. - symbol_value_offset = -1; - additional_flags = ARM_ELF_SYM_IS_THUMB; + if (symbol.getBinding() == STB_LOCAL && symbol_name && symbol_name[0] == '$') + { + // These are reserved for the specification (e.g.: mapping + // symbols). We don't want to add them to the symbol table. + + llvm::StringRef symbol_name_ref(symbol_name); + if (symbol_name_ref == "$x" || symbol_name_ref.startswith("$x.")) + { + // $x[.]* - marks an A64 instruction sequence + m_address_class_map[symbol.st_value] = eAddressClassCode; + } + else if (symbol_name_ref == "$d" || symbol_name_ref.startswith("$d.")) + { + // $d[.]* - marks a data item sequence (e.g. lit pool) + m_address_class_map[symbol.st_value] = eAddressClassData; + } + + continue; + } + } + + if (arch.GetMachine() == llvm::Triple::arm) + { + // THUMB functions have the lower bit of their address set. Fixup + // the actual address and mark the symbol as THUMB. + if (symbol_type == eSymbolTypeCode && symbol.st_value & 1) + { + // Substracting 1 from the address effectively unsets + // the low order bit, which results in the address + // actually pointing to the beginning of the symbol. + // This delta will be used below in conjuction with + // symbol.st_value to produce the final symbol_value + // that we store in the symtab. + symbol_value_offset = -1; + additional_flags = ARM_ELF_SYM_IS_THUMB; + } } } diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index fd5ee45..8ea3dab 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -219,6 +219,8 @@ private: typedef DynamicSymbolColl::iterator DynamicSymbolCollIter; typedef DynamicSymbolColl::const_iterator DynamicSymbolCollConstIter; + typedef std::map FileAddressToAddressClassMap; + /// Version of this reader common to all plugins based on this class. static const uint32_t m_plugin_version = 1; static const uint32_t g_core_uuid_magic; @@ -252,6 +254,9 @@ private: /// The architecture detected from parsing elf file contents. lldb_private::ArchSpec m_arch_spec; + /// The address class for each symbol in the elf file + FileAddressToAddressClassMap m_address_class_map; + /// Returns a 1 based index of the given section header. size_t SectionIndex(const SectionHeaderCollIter &I); -- 2.7.4