summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
diff options
context:
space:
mode:
authorTamas Berghammer <tberghammer@google.com>2016-02-25 12:23:43 +0000
committerTamas Berghammer <tberghammer@google.com>2016-02-25 12:23:43 +0000
commit31a2f8f9f55ebdbb02da6c3c08a35fe251c72595 (patch)
treeb0c72671aa1f9a908af990402a49b59b851530a6 /lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
parent72ac8a840fb0ea4d72747b3f5dcf260dcd345672 (diff)
downloadbcm5719-llvm-31a2f8f9f55ebdbb02da6c3c08a35fe251c72595.tar.gz
bcm5719-llvm-31a2f8f9f55ebdbb02da6c3c08a35fe251c72595.zip
Add support for handling absolute symbols in ELF
Most address represented in lldb as section plus offset and handling of absolute addresses is problematic in several location because of lack of necessary information (e.g. Target) or because of performance issues. This CL change the way ObjectFileELF handle the absolute symbols with creating a pseudo section for each symbol. With this change all existing code designed to work with addresses in the form of section plus offset will work with absolute symbols as well. Differential revision: http://reviews.llvm.org/D17450 llvm-svn: 261859
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp')
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp68
1 files changed, 44 insertions, 24 deletions
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 2ee2b1371b5..acde882b63f 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -921,10 +921,14 @@ ObjectFileELF::SetLoadAddress (Target &target,
// Iterate through the object file sections to find all
// of the sections that have SHF_ALLOC in their flag bits.
SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
- // if (section_sp && !section_sp->IsThreadSpecific())
if (section_sp && section_sp->Test(SHF_ALLOC))
{
- lldb::addr_t load_addr = section_sp->GetFileAddress() + value;
+ lldb::addr_t load_addr = section_sp->GetFileAddress();
+ // We don't want to update the load address of a section with type
+ // eSectionTypeAbsoluteAddress as they already have the absolute load address
+ // already specified
+ if (section_sp->GetType() != eSectionTypeAbsoluteAddress)
+ load_addr += value;
// On 32-bit systems the load address have to fit into 4 bytes. The rest of
// the bytes are the overflow from the addition.
@@ -2058,6 +2062,8 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
ArchSpec arch;
GetArchitecture(arch);
+ ModuleSP module_sp(GetModule());
+ SectionList* module_section_list = module_sp ? module_sp->GetSectionList() : nullptr;
// Local cache to avoid doing a FindSectionByName for each symbol. The "const char*" key must
// came from a ConstString object so they can be compared by pointer
@@ -2083,9 +2089,9 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
SectionSP symbol_section_sp;
SymbolType symbol_type = eSymbolTypeInvalid;
- Elf64_Half symbol_idx = symbol.st_shndx;
+ Elf64_Half section_idx = symbol.st_shndx;
- switch (symbol_idx)
+ switch (section_idx)
{
case SHN_ABS:
symbol_type = eSymbolTypeAbsolute;
@@ -2094,7 +2100,7 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
symbol_type = eSymbolTypeUndefined;
break;
default:
- symbol_section_sp = section_list->GetSectionAtIndex(symbol_idx);
+ symbol_section_sp = section_list->GetSectionAtIndex(section_idx);
break;
}
@@ -2278,30 +2284,44 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
}
}
- // symbol_value_offset may contain 0 for ARM symbols or -1 for
- // THUMB symbols. See above for more details.
+ // 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 == nullptr && section_idx == SHN_ABS && symbol.st_size != 0)
+ {
+ // We don't have a section for a symbol with non-zero size. Create a new section for it
+ // so the address range covered by the symbol is also covered by the module (represented
+ // through the section list). It is needed so module lookup for the addresses covered
+ // by this symbol will be successfull. This case happens for absolute symbols.
+ ConstString fake_section_name(std::string(".absolute.") + symbol_name);
+ symbol_section_sp = std::make_shared<Section>(module_sp,
+ this,
+ SHN_ABS,
+ fake_section_name,
+ eSectionTypeAbsoluteAddress,
+ symbol_value,
+ symbol.st_size,
+ 0, 0, 0,
+ SHF_ALLOC);
+
+ module_section_list->AddSection(symbol_section_sp);
+ section_list->AddSection(symbol_section_sp);
+ }
+
if (symbol_section_sp && CalculateType() != ObjectFile::Type::eTypeObjectFile)
symbol_value -= symbol_section_sp->GetFileAddress();
- if (symbol_section_sp)
+ if (symbol_section_sp && module_section_list && module_section_list != section_list)
{
- ModuleSP module_sp(GetModule());
- if (module_sp)
- {
- SectionList *module_section_list = module_sp->GetSectionList();
- if (module_section_list && module_section_list != section_list)
- {
- const ConstString &sect_name = symbol_section_sp->GetName();
- auto section_it = section_name_to_section.find(sect_name.GetCString());
- if (section_it == section_name_to_section.end())
- section_it = section_name_to_section.emplace(
- sect_name.GetCString(),
- module_section_list->FindSectionByName (sect_name)).first;
- if (section_it->second && section_it->second->GetFileSize())
- symbol_section_sp = section_it->second;
- }
- }
+ const ConstString &sect_name = symbol_section_sp->GetName();
+ auto section_it = section_name_to_section.find(sect_name.GetCString());
+ if (section_it == section_name_to_section.end())
+ section_it = section_name_to_section.emplace(
+ sect_name.GetCString(),
+ module_section_list->FindSectionByName (sect_name)).first;
+ if (section_it->second && section_it->second->GetFileSize())
+ symbol_section_sp = section_it->second;
}
bool is_global = symbol.getBinding() == STB_GLOBAL;
OpenPOWER on IntegriCloud