summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/lit/Modules/ELF/PT_LOAD-overlap-PT_TLS.yaml63
-rw-r--r--lldb/lit/Modules/ELF/PT_TLS-overlap-PT_LOAD.yaml63
-rw-r--r--lldb/source/Core/Section.cpp2
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp45
4 files changed, 156 insertions, 17 deletions
diff --git a/lldb/lit/Modules/ELF/PT_LOAD-overlap-PT_TLS.yaml b/lldb/lit/Modules/ELF/PT_LOAD-overlap-PT_TLS.yaml
new file mode 100644
index 00000000000..d6844666804
--- /dev/null
+++ b/lldb/lit/Modules/ELF/PT_LOAD-overlap-PT_TLS.yaml
@@ -0,0 +1,63 @@
+# Overlapping PT_LOAD and PT_TLS segments should be able to exist side by side.
+
+# RUN: yaml2obj %s > %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
+# CHECK-NEXT: Name: PT_TLS[0]
+# CHECK-NEXT: Type: container
+# CHECK-NEXT: Permissions: rw-
+# CHECK-NEXT: Thread specific: yes
+# CHECK-NEXT: VM address: 0x1000
+# CHECK-NEXT: VM size: 16
+# CHECK-NEXT: File size: 0
+# CHECK-NEXT: Showing 1 subsections
+
+# CHECK: Index: 1
+# CHECK-NEXT: ID: 0xfffffffffffffffe
+# CHECK-NEXT: Name: PT_LOAD[0]
+# CHECK-NEXT: Type: container
+# CHECK-NEXT: Permissions: rw-
+# CHECK-NEXT: Thread specific: no
+# CHECK-NEXT: VM address: 0x1000
+# CHECK-NEXT: VM size: 16
+# CHECK-NEXT: File size: 16
+# CHECK-NEXT: Showing 1 subsections
+
+# LOOKUP-LABEL: image lookup -a 0x1000
+# LOOKUP: Address: {{.*}}.PT_LOAD[0]..data + 0)
+
+!ELF
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_ARM
+Sections:
+ - Name: .tbss
+ Type: SHT_NOBITS
+ Flags: [ SHF_ALLOC, SHF_WRITE, SHF_TLS ]
+ Address: 0x1000
+ AddressAlign: 0x4
+ Size: 0x10
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_WRITE ]
+ Address: 0x1000
+ AddressAlign: 0x4
+ Size: 0x10
+ProgramHeaders:
+ - Type: PT_TLS
+ Flags: [ PF_R, PF_W ]
+ VAddr: 0x1000
+ Align: 0x4
+ Sections:
+ - Section: .tbss
+ - Type: PT_LOAD
+ Flags: [ PF_W, PF_R ]
+ VAddr: 0x1000
+ Align: 0x4
+ Sections:
+ - Section: .data
diff --git a/lldb/lit/Modules/ELF/PT_TLS-overlap-PT_LOAD.yaml b/lldb/lit/Modules/ELF/PT_TLS-overlap-PT_LOAD.yaml
new file mode 100644
index 00000000000..cd3939e0541
--- /dev/null
+++ b/lldb/lit/Modules/ELF/PT_TLS-overlap-PT_LOAD.yaml
@@ -0,0 +1,63 @@
+# Overlapping PT_LOAD and PT_TLS segments should be able to exist side by side.
+
+# RUN: yaml2obj %s > %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
+# CHECK-NEXT: Name: PT_LOAD[0]
+# CHECK-NEXT: Type: container
+# CHECK-NEXT: Permissions: rw-
+# CHECK-NEXT: Thread specific: no
+# CHECK-NEXT: VM address: 0x1000
+# CHECK-NEXT: VM size: 16
+# CHECK-NEXT: File size: 16
+# CHECK-NEXT: Showing 1 subsections
+
+# CHECK: Index: 1
+# CHECK-NEXT: ID: 0xfffffffffffffffe
+# CHECK-NEXT: Name: PT_TLS[0]
+# CHECK-NEXT: Type: container
+# CHECK-NEXT: Permissions: rw-
+# CHECK-NEXT: Thread specific: yes
+# CHECK-NEXT: VM address: 0x1000
+# CHECK-NEXT: VM size: 16
+# CHECK-NEXT: File size: 0
+# CHECK-NEXT: Showing 1 subsections
+
+# LOOKUP-LABEL: image lookup -a 0x1000
+# LOOKUP: Address: {{.*}}.PT_LOAD[0]..data + 0)
+
+!ELF
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_ARM
+Sections:
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_WRITE ]
+ Address: 0x1000
+ AddressAlign: 0x4
+ Size: 0x10
+ - Name: .tbss
+ Type: SHT_NOBITS
+ Flags: [ SHF_ALLOC, SHF_WRITE, SHF_TLS ]
+ Address: 0x1000
+ AddressAlign: 0x4
+ Size: 0x10
+ProgramHeaders:
+ - Type: PT_LOAD
+ Flags: [ PF_W, PF_R ]
+ VAddr: 0x1000
+ Align: 0x4
+ Sections:
+ - Section: .data
+ - Type: PT_TLS
+ Flags: [ PF_R, PF_W ]
+ VAddr: 0x1000
+ Align: 0x4
+ Sections:
+ - Section: .tbss
diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp
index f30ddd2c18c..de017ed3783 100644
--- a/lldb/source/Core/Section.cpp
+++ b/lldb/source/Core/Section.cpp
@@ -269,7 +269,7 @@ bool Section::ResolveContainedAddress(addr_t offset, Address &so_addr,
bool Section::ContainsFileAddress(addr_t vm_addr) const {
const addr_t file_addr = GetFileAddress();
- if (file_addr != LLDB_INVALID_ADDRESS) {
+ if (file_addr != LLDB_INVALID_ADDRESS && !IsThreadSpecific()) {
if (file_addr <= vm_addr) {
const addr_t offset = (vm_addr - file_addr) * m_target_byte_size;
return offset < GetByteSize();
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 50d6b8f864c..9f8ab3761c8 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -1712,6 +1712,8 @@ class VMAddressProvider {
VMMap Segments = VMMap(Alloc);
VMMap Sections = VMMap(Alloc);
lldb_private::Log *Log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES);
+ size_t SegmentCount = 0;
+ std::string SegmentName;
VMRange GetVMRange(const ELFSectionHeader &H) {
addr_t Address = H.sh_addr;
@@ -1726,18 +1728,23 @@ class VMAddressProvider {
}
public:
- VMAddressProvider(ObjectFile::Type Type) : ObjectType(Type) {}
+ VMAddressProvider(ObjectFile::Type Type, llvm::StringRef SegmentName)
+ : ObjectType(Type), SegmentName(SegmentName) {}
+
+ std::string GetNextSegmentName() const {
+ return llvm::formatv("{0}[{1}]", SegmentName, SegmentCount).str();
+ }
llvm::Optional<VMRange> GetAddressInfo(const ELFProgramHeader &H) {
if (H.p_memsz == 0) {
- LLDB_LOG(Log,
- "Ignoring zero-sized PT_LOAD segment. Corrupt object file?");
+ LLDB_LOG(Log, "Ignoring zero-sized {0} segment. Corrupt object file?",
+ SegmentName);
return llvm::None;
}
if (Segments.overlaps(H.p_vaddr, H.p_vaddr + H.p_memsz)) {
- LLDB_LOG(Log,
- "Ignoring overlapping PT_LOAD segment. Corrupt object file?");
+ LLDB_LOG(Log, "Ignoring overlapping {0} segment. Corrupt object file?",
+ SegmentName);
return llvm::None;
}
return VMRange(H.p_vaddr, H.p_memsz);
@@ -1772,6 +1779,7 @@ public:
void AddSegment(const VMRange &Range, SectionSP Seg) {
Segments.insert(Range.GetRangeBase(), Range.GetRangeEnd(), std::move(Seg));
+ ++SegmentCount;
}
void AddSection(SectionAddressInfo Info, SectionSP Sect) {
@@ -1790,28 +1798,31 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
return;
m_sections_up = llvm::make_unique<SectionList>();
- VMAddressProvider address_provider(GetType());
+ VMAddressProvider regular_provider(GetType(), "PT_LOAD");
+ VMAddressProvider tls_provider(GetType(), "PT_TLS");
- size_t LoadID = 0;
for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) {
const ELFProgramHeader &PHdr = EnumPHdr.value();
- if (PHdr.p_type != PT_LOAD)
+ if (PHdr.p_type != PT_LOAD && PHdr.p_type != PT_TLS)
continue;
- auto InfoOr = address_provider.GetAddressInfo(PHdr);
+ VMAddressProvider &provider =
+ PHdr.p_type == PT_TLS ? tls_provider : regular_provider;
+ auto InfoOr = provider.GetAddressInfo(PHdr);
if (!InfoOr)
continue;
- ConstString Name(("PT_LOAD[" + llvm::Twine(LoadID++) + "]").str());
uint32_t Log2Align = llvm::Log2_64(std::max<elf_xword>(PHdr.p_align, 1));
SectionSP Segment = std::make_shared<Section>(
- GetModule(), this, SegmentID(EnumPHdr.index()), Name,
- eSectionTypeContainer, InfoOr->GetRangeBase(), InfoOr->GetByteSize(),
- PHdr.p_offset, PHdr.p_filesz, Log2Align, /*flags*/ 0);
+ GetModule(), this, SegmentID(EnumPHdr.index()),
+ ConstString(provider.GetNextSegmentName()), eSectionTypeContainer,
+ InfoOr->GetRangeBase(), InfoOr->GetByteSize(), PHdr.p_offset,
+ PHdr.p_filesz, Log2Align, /*flags*/ 0);
Segment->SetPermissions(GetPermissions(PHdr));
+ Segment->SetIsThreadSpecific(PHdr.p_type == PT_TLS);
m_sections_up->AddSection(Segment);
- address_provider.AddSegment(*InfoOr, std::move(Segment));
+ provider.AddSegment(*InfoOr, std::move(Segment));
}
ParseSectionHeaders();
@@ -1826,7 +1837,9 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
const uint64_t file_size =
header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
- auto InfoOr = address_provider.GetAddressInfo(header);
+ VMAddressProvider &provider =
+ header.sh_flags & SHF_TLS ? tls_provider : regular_provider;
+ auto InfoOr = provider.GetAddressInfo(header);
if (!InfoOr)
continue;
@@ -1857,7 +1870,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
section_sp->SetIsThreadSpecific(header.sh_flags & SHF_TLS);
(InfoOr->Segment ? InfoOr->Segment->GetChildren() : *m_sections_up)
.AddSection(section_sp);
- address_provider.AddSection(std::move(*InfoOr), std::move(section_sp));
+ provider.AddSection(std::move(*InfoOr), std::move(section_sp));
}
// For eTypeDebugInfo files, the Symbol Vendor will take care of updating the
OpenPOWER on IntegriCloud