llvm-project/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp
Pavel Labath 08c38f77c5 Revert "Implement xfer:libraries-svr4:read packet"
D62502, together with D62503 have broken the builds which have XML
support enabled. Reverting D62503 (r364355) fixed that, but has broken
has left some of the tests introduced by D62502 broken more or less
nondeternimistically (it depended on whether the system happens to place
the library list near unreadable pages of memory). I attempted to make a
partial fix for this in r364748, but Jan Kratochvil pointed out that
this reintroduces the problem which reverting D62503 was trying to
solve.

So instead, I back out the whole thing so we can get back to a clean
slate that works for everyone. We can figure out a way forward from
there.

This reverts r364748, r363772 and r363707.

llvm-svn: 364751
2019-07-01 12:41:20 +00:00

110 lines
4.0 KiB
C++

//===-- NativeProcessELF.cpp ---------------------------------- -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "NativeProcessELF.h"
#include "lldb/Utility/DataExtractor.h"
namespace lldb_private {
llvm::Optional<uint64_t>
NativeProcessELF::GetAuxValue(enum AuxVector::EntryType type) {
if (m_aux_vector == nullptr) {
auto buffer_or_error = GetAuxvData();
if (!buffer_or_error)
return llvm::None;
DataExtractor auxv_data(buffer_or_error.get()->getBufferStart(),
buffer_or_error.get()->getBufferSize(),
GetByteOrder(), GetAddressByteSize());
m_aux_vector = llvm::make_unique<AuxVector>(auxv_data);
}
return m_aux_vector->GetAuxValue(type);
}
lldb::addr_t NativeProcessELF::GetSharedLibraryInfoAddress() {
if (!m_shared_library_info_addr.hasValue()) {
if (GetAddressByteSize() == 8)
m_shared_library_info_addr =
GetELFImageInfoAddress<llvm::ELF::Elf64_Ehdr, llvm::ELF::Elf64_Phdr,
llvm::ELF::Elf64_Dyn>();
else
m_shared_library_info_addr =
GetELFImageInfoAddress<llvm::ELF::Elf32_Ehdr, llvm::ELF::Elf32_Phdr,
llvm::ELF::Elf32_Dyn>();
}
return m_shared_library_info_addr.getValue();
}
template <typename ELF_EHDR, typename ELF_PHDR, typename ELF_DYN>
lldb::addr_t NativeProcessELF::GetELFImageInfoAddress() {
llvm::Optional<uint64_t> maybe_phdr_addr =
GetAuxValue(AuxVector::AUXV_AT_PHDR);
llvm::Optional<uint64_t> maybe_phdr_entry_size =
GetAuxValue(AuxVector::AUXV_AT_PHENT);
llvm::Optional<uint64_t> maybe_phdr_num_entries =
GetAuxValue(AuxVector::AUXV_AT_PHNUM);
if (!maybe_phdr_addr || !maybe_phdr_entry_size || !maybe_phdr_num_entries)
return LLDB_INVALID_ADDRESS;
lldb::addr_t phdr_addr = *maybe_phdr_addr;
size_t phdr_entry_size = *maybe_phdr_entry_size;
size_t phdr_num_entries = *maybe_phdr_num_entries;
// Find the PT_DYNAMIC segment (.dynamic section) in the program header and
// what the load bias by calculating the difference of the program header
// load address and its virtual address.
lldb::offset_t load_bias;
bool found_load_bias = false;
lldb::addr_t dynamic_section_addr = 0;
uint64_t dynamic_section_size = 0;
bool found_dynamic_section = false;
ELF_PHDR phdr_entry;
for (size_t i = 0; i < phdr_num_entries; i++) {
size_t bytes_read;
auto error = ReadMemory(phdr_addr + i * phdr_entry_size, &phdr_entry,
sizeof(phdr_entry), bytes_read);
if (!error.Success())
return LLDB_INVALID_ADDRESS;
if (phdr_entry.p_type == llvm::ELF::PT_PHDR) {
load_bias = phdr_addr - phdr_entry.p_vaddr;
found_load_bias = true;
}
if (phdr_entry.p_type == llvm::ELF::PT_DYNAMIC) {
dynamic_section_addr = phdr_entry.p_vaddr;
dynamic_section_size = phdr_entry.p_memsz;
found_dynamic_section = true;
}
}
if (!found_load_bias || !found_dynamic_section)
return LLDB_INVALID_ADDRESS;
// Find the DT_DEBUG entry in the .dynamic section
dynamic_section_addr += load_bias;
ELF_DYN dynamic_entry;
size_t dynamic_num_entries = dynamic_section_size / sizeof(dynamic_entry);
for (size_t i = 0; i < dynamic_num_entries; i++) {
size_t bytes_read;
auto error = ReadMemory(dynamic_section_addr + i * sizeof(dynamic_entry),
&dynamic_entry, sizeof(dynamic_entry), bytes_read);
if (!error.Success())
return LLDB_INVALID_ADDRESS;
// Return the &DT_DEBUG->d_ptr which points to r_debug which contains the
// link_map.
if (dynamic_entry.d_tag == llvm::ELF::DT_DEBUG) {
return dynamic_section_addr + i * sizeof(dynamic_entry) +
sizeof(dynamic_entry.d_tag);
}
}
return LLDB_INVALID_ADDRESS;
}
} // namespace lldb_private