diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 5c6b475044be56..51bd34e95c77df 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -717,6 +717,20 @@ bool ObjectFileELF::SetLoadAddress(Target &target, lldb::addr_t value, // 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)); + + // PT_TLS segments can have the same p_vaddr and p_paddr as other + // PT_LOAD segments so we shouldn't load them. If we do load them, then + // the SectionLoadList will incorrectly fill in the instance variable + // SectionLoadList::m_addr_to_sect with the same address as a PT_LOAD + // segment and we won't be able to resolve addresses in the PT_LOAD + // segment whose p_vaddr entry matches that of the PT_TLS. Any variables + // that appear in the PT_TLS segments get resolved by the DWARF + // expressions. If this ever changes we will need to fix all object + // file plug-ins, but until then, we don't want PT_TLS segments to + // remove the entry from SectionLoadList::m_addr_to_sect when we call + // SetSectionLoadAddress() below. + if (section_sp->IsThreadSpecific()) + continue; if (section_sp->Test(SHF_ALLOC) || section_sp->GetType() == eSectionTypeContainer) { lldb::addr_t load_addr = section_sp->GetFileAddress(); diff --git a/lldb/test/Shell/ObjectFile/ELF/PT_TLS-overlap-PT_LOAD.yaml b/lldb/test/Shell/ObjectFile/ELF/PT_TLS-overlap-PT_LOAD.yaml index ea711ec2197fb3..b49de30491fcd8 100644 --- a/lldb/test/Shell/ObjectFile/ELF/PT_TLS-overlap-PT_LOAD.yaml +++ b/lldb/test/Shell/ObjectFile/ELF/PT_TLS-overlap-PT_LOAD.yaml @@ -1,8 +1,20 @@ -# Overlapping PT_LOAD and PT_TLS segments should be able to exist side by side. +# Overlapping PT_LOAD and PT_TLS segments in an object file should be able to +# exist side by side. + +# When an ELF file contains both PT_LOAD and PT_TLS segments where the PT_TLS +# segment has the same p_vaddr and p_paddr as a PT_LOAD segment, this +# was causing LLDB, when loading a ELF object file at an address, to overwrite +# the section load address for a PT_LOAD that shares the same p_vaddr value in +# the section load list's addr to section map for this code. This test ensures +# that no PT_TLS segments get loaded and can't interfere with real segments we +# need to resolved as all access to thread specific memory is only done via +# DWARF location expressions. We also don't have any code that loads any thread +# specific segments at a different address for different threads, so there is +# no reason currently to try and load thread specific segments. # RUN: yaml2obj %s -o %t # RUN: lldb-test object-file %t | FileCheck %s -# RUN: %lldb %t -o "image lookup -a 0x1000" -b | FileCheck --check-prefix=LOOKUP %s + # CHECK: Index: 0 # CHECK-NEXT: ID: 0xffffffffffffffff @@ -26,8 +38,21 @@ # CHECK-NEXT: File size: 0 # CHECK-NEXT: Showing 1 subsections +# RUN: %lldb %t -b \ +# RUN: -o "image lookup -a 0x1000" \ +# RUN: -o "target modules load --file %t --slide 0" \ +# RUN: -o "image lookup -a 0x1000" \ +# RUN: -o "target dump section-load-list" \ +# RUN: | FileCheck --check-prefix=LOOKUP %s + # LOOKUP-LABEL: image lookup -a 0x1000 # LOOKUP: Address: {{.*}}.PT_LOAD[0]..data + 0) +# LOOKUP: target modules load +# LOOKUP: image lookup -a 0x1000 +# LOOKUP: Address: {{.*}}.PT_LOAD[0]..data + 0) +# LOOKUP: target dump section-load-list +# LOOKUP: PT_TLS-overlap-PT_LOAD.yaml.tmp.PT_LOAD[0] +# LOOKUP-NOT: PT_TLS-overlap-PT_LOAD.yaml.tmp.PT_TLS[0] !ELF FileHeader: