summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
diff options
context:
space:
mode:
authorTodd Fiala <todd.fiala@gmail.com>2014-09-15 22:33:39 +0000
committerTodd Fiala <todd.fiala@gmail.com>2014-09-15 22:33:39 +0000
commitfbd703add593253cdea7f18fa0648844905b59a2 (patch)
tree86c38f787be8b8732e9e7cb098f898214b96fcd7 /lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
parentcbe802e7301712eb293aecb8176498edbe3021e1 (diff)
downloadbcm5719-llvm-fbd703add593253cdea7f18fa0648844905b59a2.tar.gz
bcm5719-llvm-fbd703add593253cdea7f18fa0648844905b59a2.zip
ELF: store the thumbness of a function in symbol flags.
This allows us to fixup the address of the symbol as soon as we parse it so that lldb is not confused thinking there are two different symbols in the binary (one with the thumb bit, one without). Also, differentiating between THUMB and ARM symbols allows the debugger to place the right type of breakpoint. Change by Stephane Sezer. llvm-svn: 217841
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp')
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp55
1 files changed, 53 insertions, 2 deletions
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 2541b2c628a..d075312c84c 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -826,6 +826,38 @@ ObjectFileELF::GetAddressByteSize() const
return m_data.GetAddressByteSize();
}
+// Top 16 bits of the `Symbol` flags are available.
+#define ARM_ELF_SYM_IS_THUMB (1 << 16)
+
+AddressClass
+ObjectFileELF::GetAddressClass (addr_t file_addr)
+{
+ auto res = ObjectFile::GetAddressClass (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;
+
+ // 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;
+
+ return res;
+}
+
size_t
ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I)
{
@@ -1747,6 +1779,8 @@ 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)
@@ -1770,6 +1804,20 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
symbol_name_ref.startswith(g_armelf_thumb_marker) ||
symbol_name_ref.startswith(g_armelf_data_marker)))
continue;
+
+ // 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;
+ }
}
// If the symbol section we've found has no data (SHT_NOBITS), then check the module section
@@ -1792,12 +1840,15 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
}
}
- uint64_t symbol_value = symbol.st_value;
+ // symbol_value_offset may contain 0 for ARM symbols or -1 for
+ // THUMB symbols. See above for more details.
+ uint64_t symbol_value = symbol.st_value | symbol_value_offset;
if (symbol_section_sp && CalculateType() != ObjectFile::Type::eTypeObjectFile)
symbol_value -= symbol_section_sp->GetFileAddress();
bool is_global = symbol.getBinding() == STB_GLOBAL;
- uint32_t flags = symbol.st_other << 8 | symbol.st_info;
+ uint32_t flags = symbol.st_other << 8 | symbol.st_info | additional_flags;
bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
+
Symbol dc_symbol(
i + start_id, // ID is the original symbol table index.
symbol_name, // Symbol name.
OpenPOWER on IntegriCloud