forked from OSchip/llvm-project
Fix for Bug 25338
Summary: The issue arises because LLDB is not able to read the vdso library correctly. The fix adds memory allocation callbacks to allocate sufficient memory in case the requested offsets don't fit in the memory buffer allocated for the ELF. Reviewers: lldb-commits, clayborg, deepak2427, ovyalov, labath, tberghammer Differential Revision: http://reviews.llvm.org/D16107 llvm-svn: 258122
This commit is contained in:
parent
f8f2d46002
commit
15f89c420b
|
@ -15,8 +15,7 @@ class AssertingInferiorTestCase(TestBase):
|
||||||
mydir = TestBase.compute_mydir(__file__)
|
mydir = TestBase.compute_mydir(__file__)
|
||||||
|
|
||||||
@expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
|
@expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
|
||||||
@expectedFailurei386("llvm.org/pr25338")
|
@expectedFailureLinux("llvm.org/pr25338", archs=['arm'])
|
||||||
@expectedFailureLinux("llvm.org/pr25338", archs=['arm', 'i386'])
|
|
||||||
def test_inferior_asserting(self):
|
def test_inferior_asserting(self):
|
||||||
"""Test that lldb reliably catches the inferior asserting (command)."""
|
"""Test that lldb reliably catches the inferior asserting (command)."""
|
||||||
self.build()
|
self.build()
|
||||||
|
@ -30,8 +29,7 @@ class AssertingInferiorTestCase(TestBase):
|
||||||
self.inferior_asserting_registers()
|
self.inferior_asserting_registers()
|
||||||
|
|
||||||
@expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
|
@expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
|
||||||
@expectedFailurei386("llvm.org/pr25338")
|
@expectedFailureLinux("llvm.org/pr25338", archs=['arm'])
|
||||||
@expectedFailureLinux("llvm.org/pr25338", archs=['arm', 'i386'])
|
|
||||||
def test_inferior_asserting_disassemble(self):
|
def test_inferior_asserting_disassemble(self):
|
||||||
"""Test that lldb reliably disassembles frames after asserting (command)."""
|
"""Test that lldb reliably disassembles frames after asserting (command)."""
|
||||||
self.build()
|
self.build()
|
||||||
|
@ -45,16 +43,14 @@ class AssertingInferiorTestCase(TestBase):
|
||||||
self.inferior_asserting_python()
|
self.inferior_asserting_python()
|
||||||
|
|
||||||
@expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
|
@expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
|
||||||
@expectedFailurei386("llvm.org/pr25338")
|
@expectedFailureLinux("llvm.org/pr25338", archs=['arm'])
|
||||||
@expectedFailureLinux("llvm.org/pr25338", archs=['arm', 'i386'])
|
|
||||||
def test_inferior_asserting_expr(self):
|
def test_inferior_asserting_expr(self):
|
||||||
"""Test that the lldb expression interpreter can read from the inferior after asserting (command)."""
|
"""Test that the lldb expression interpreter can read from the inferior after asserting (command)."""
|
||||||
self.build()
|
self.build()
|
||||||
self.inferior_asserting_expr()
|
self.inferior_asserting_expr()
|
||||||
|
|
||||||
@expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
|
@expectedFailureWindows("llvm.org/pr21793: need to implement support for detecting assertion / abort on Windows")
|
||||||
@expectedFailurei386("llvm.org/pr25338")
|
@expectedFailureLinux("llvm.org/pr25338", archs=['arm'])
|
||||||
@expectedFailureLinux("llvm.org/pr25338", archs=['arm', 'i386'])
|
|
||||||
def test_inferior_asserting_step(self):
|
def test_inferior_asserting_step(self):
|
||||||
"""Test that lldb functions correctly after stepping through a call to assert()."""
|
"""Test that lldb functions correctly after stepping through a call to assert()."""
|
||||||
self.build()
|
self.build()
|
||||||
|
|
|
@ -14,7 +14,6 @@ import lldbsuite.test.lldbutil as lldbutil
|
||||||
class NoreturnUnwind(TestBase):
|
class NoreturnUnwind(TestBase):
|
||||||
mydir = TestBase.compute_mydir(__file__)
|
mydir = TestBase.compute_mydir(__file__)
|
||||||
|
|
||||||
@expectedFailurei386("llvm.org/pr25338")
|
|
||||||
@skipIfWindows # clang-cl does not support gcc style attributes.
|
@skipIfWindows # clang-cl does not support gcc style attributes.
|
||||||
def test (self):
|
def test (self):
|
||||||
"""Test that we can backtrace correctly with 'noreturn' functions on the stack"""
|
"""Test that we can backtrace correctly with 'noreturn' functions on the stack"""
|
||||||
|
|
|
@ -75,7 +75,6 @@ class HelloWorldTestCase(TestBase):
|
||||||
|
|
||||||
@add_test_categories(['pyapi'])
|
@add_test_categories(['pyapi'])
|
||||||
@expectedFailureWindows("llvm.org/pr24600")
|
@expectedFailureWindows("llvm.org/pr24600")
|
||||||
@expectedFailurei386("llvm.org/pr25338")
|
|
||||||
@skipIfiOSSimulator
|
@skipIfiOSSimulator
|
||||||
def test_with_attach_to_process_with_id_api(self):
|
def test_with_attach_to_process_with_id_api(self):
|
||||||
"""Create target, spawn a process, and attach to it with process id."""
|
"""Create target, spawn a process, and attach to it with process id."""
|
||||||
|
@ -105,7 +104,6 @@ class HelloWorldTestCase(TestBase):
|
||||||
|
|
||||||
@add_test_categories(['pyapi'])
|
@add_test_categories(['pyapi'])
|
||||||
@expectedFailureWindows("llvm.org/pr24600")
|
@expectedFailureWindows("llvm.org/pr24600")
|
||||||
@expectedFailurei386("llvm.org/pr25338")
|
|
||||||
@skipIfiOSSimulator
|
@skipIfiOSSimulator
|
||||||
def test_with_attach_to_process_with_name_api(self):
|
def test_with_attach_to_process_with_name_api(self):
|
||||||
"""Create target, spawn a process, and attach to it with process name."""
|
"""Create target, spawn a process, and attach to it with process name."""
|
||||||
|
|
|
@ -729,7 +729,10 @@ ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
|
||||||
SectionHeaderColl section_headers;
|
SectionHeaderColl section_headers;
|
||||||
lldb_private::UUID &uuid = spec.GetUUID();
|
lldb_private::UUID &uuid = spec.GetUUID();
|
||||||
|
|
||||||
GetSectionHeaderInfo(section_headers, data, header, uuid, gnu_debuglink_file, gnu_debuglink_crc, spec.GetArchitecture ());
|
using namespace std::placeholders;
|
||||||
|
const SetDataFunction set_data = std::bind(&ObjectFileELF::SetData, std::cref(data), _1, _2, _3);
|
||||||
|
GetSectionHeaderInfo(section_headers, set_data, header, uuid, gnu_debuglink_file, gnu_debuglink_crc, spec.GetArchitecture ());
|
||||||
|
|
||||||
|
|
||||||
llvm::Triple &spec_triple = spec.GetArchitecture ().GetTriple ();
|
llvm::Triple &spec_triple = spec.GetArchitecture ().GetTriple ();
|
||||||
|
|
||||||
|
@ -759,7 +762,7 @@ ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
|
||||||
data.SetData(data_sp);
|
data.SetData(data_sp);
|
||||||
}
|
}
|
||||||
ProgramHeaderColl program_headers;
|
ProgramHeaderColl program_headers;
|
||||||
GetProgramHeaderInfo(program_headers, data, header);
|
GetProgramHeaderInfo(program_headers, set_data, header);
|
||||||
|
|
||||||
size_t segment_data_end = 0;
|
size_t segment_data_end = 0;
|
||||||
for (ProgramHeaderCollConstIter I = program_headers.begin();
|
for (ProgramHeaderCollConstIter I = program_headers.begin();
|
||||||
|
@ -1256,7 +1259,7 @@ ObjectFileELF::ParseDependentModules()
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
size_t
|
size_t
|
||||||
ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
|
ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
|
||||||
DataExtractor &object_data,
|
const SetDataFunction &set_data,
|
||||||
const ELFHeader &header)
|
const ELFHeader &header)
|
||||||
{
|
{
|
||||||
// We have already parsed the program headers
|
// We have already parsed the program headers
|
||||||
|
@ -1274,7 +1277,7 @@ ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
|
||||||
const size_t ph_size = header.e_phnum * header.e_phentsize;
|
const size_t ph_size = header.e_phnum * header.e_phentsize;
|
||||||
const elf_off ph_offset = header.e_phoff;
|
const elf_off ph_offset = header.e_phoff;
|
||||||
DataExtractor data;
|
DataExtractor data;
|
||||||
if (data.SetData(object_data, ph_offset, ph_size) != ph_size)
|
if (set_data(data, ph_offset, ph_size) != ph_size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
|
@ -1298,7 +1301,10 @@ ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
|
||||||
size_t
|
size_t
|
||||||
ObjectFileELF::ParseProgramHeaders()
|
ObjectFileELF::ParseProgramHeaders()
|
||||||
{
|
{
|
||||||
return GetProgramHeaderInfo(m_program_headers, m_data, m_header);
|
using namespace std::placeholders;
|
||||||
|
return GetProgramHeaderInfo(m_program_headers,
|
||||||
|
std::bind(&ObjectFileELF::SetDataWithReadMemoryFallback, this, _1, _2, _3),
|
||||||
|
m_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
lldb_private::Error
|
lldb_private::Error
|
||||||
|
@ -1511,7 +1517,7 @@ ObjectFileELF::RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, l
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
size_t
|
size_t
|
||||||
ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,
|
ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,
|
||||||
lldb_private::DataExtractor &object_data,
|
const SetDataFunction &set_data,
|
||||||
const elf::ELFHeader &header,
|
const elf::ELFHeader &header,
|
||||||
lldb_private::UUID &uuid,
|
lldb_private::UUID &uuid,
|
||||||
std::string &gnu_debuglink_file,
|
std::string &gnu_debuglink_file,
|
||||||
|
@ -1569,7 +1575,7 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,
|
||||||
const size_t sh_size = header.e_shnum * header.e_shentsize;
|
const size_t sh_size = header.e_shnum * header.e_shentsize;
|
||||||
const elf_off sh_offset = header.e_shoff;
|
const elf_off sh_offset = header.e_shoff;
|
||||||
DataExtractor sh_data;
|
DataExtractor sh_data;
|
||||||
if (sh_data.SetData (object_data, sh_offset, sh_size) != sh_size)
|
if (set_data (sh_data, sh_offset, sh_size) != sh_size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
|
@ -1590,7 +1596,7 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,
|
||||||
const Elf64_Off offset = sheader.sh_offset;
|
const Elf64_Off offset = sheader.sh_offset;
|
||||||
lldb_private::DataExtractor shstr_data;
|
lldb_private::DataExtractor shstr_data;
|
||||||
|
|
||||||
if (shstr_data.SetData (object_data, offset, byte_size) == byte_size)
|
if (set_data (shstr_data, offset, byte_size) == byte_size)
|
||||||
{
|
{
|
||||||
for (SectionHeaderCollIter I = section_headers.begin();
|
for (SectionHeaderCollIter I = section_headers.begin();
|
||||||
I != section_headers.end(); ++I)
|
I != section_headers.end(); ++I)
|
||||||
|
@ -1610,7 +1616,7 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,
|
||||||
if (sheader.sh_type == SHT_MIPS_ABIFLAGS)
|
if (sheader.sh_type == SHT_MIPS_ABIFLAGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (section_size && (data.SetData (object_data, sheader.sh_offset, section_size) == section_size))
|
if (section_size && (set_data (data, sheader.sh_offset, section_size) == section_size))
|
||||||
{
|
{
|
||||||
lldb::offset_t ase_offset = 12; // MIPS ABI Flags Version: 0
|
lldb::offset_t ase_offset = 12; // MIPS ABI Flags Version: 0
|
||||||
arch_flags |= data.GetU32 (&ase_offset);
|
arch_flags |= data.GetU32 (&ase_offset);
|
||||||
|
@ -1631,7 +1637,7 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,
|
||||||
if (name == g_sect_name_gnu_debuglink)
|
if (name == g_sect_name_gnu_debuglink)
|
||||||
{
|
{
|
||||||
DataExtractor data;
|
DataExtractor data;
|
||||||
if (section_size && (data.SetData (object_data, sheader.sh_offset, section_size) == section_size))
|
if (section_size && (set_data (data, sheader.sh_offset, section_size) == section_size))
|
||||||
{
|
{
|
||||||
lldb::offset_t gnu_debuglink_offset = 0;
|
lldb::offset_t gnu_debuglink_offset = 0;
|
||||||
gnu_debuglink_file = data.GetCStr (&gnu_debuglink_offset);
|
gnu_debuglink_file = data.GetCStr (&gnu_debuglink_offset);
|
||||||
|
@ -1653,7 +1659,7 @@ ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,
|
||||||
{
|
{
|
||||||
// Allow notes to refine module info.
|
// Allow notes to refine module info.
|
||||||
DataExtractor data;
|
DataExtractor data;
|
||||||
if (section_size && (data.SetData (object_data, sheader.sh_offset, section_size) == section_size))
|
if (section_size && (set_data (data, sheader.sh_offset, section_size) == section_size))
|
||||||
{
|
{
|
||||||
Error error = RefineModuleDetailsFromNote (data, arch_spec, uuid);
|
Error error = RefineModuleDetailsFromNote (data, arch_spec, uuid);
|
||||||
if (error.Fail ())
|
if (error.Fail ())
|
||||||
|
@ -1719,7 +1725,41 @@ ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const
|
||||||
size_t
|
size_t
|
||||||
ObjectFileELF::ParseSectionHeaders()
|
ObjectFileELF::ParseSectionHeaders()
|
||||||
{
|
{
|
||||||
return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc, m_arch_spec);
|
using namespace std::placeholders;
|
||||||
|
|
||||||
|
return GetSectionHeaderInfo(m_section_headers,
|
||||||
|
std::bind(&ObjectFileELF::SetDataWithReadMemoryFallback, this, _1, _2, _3),
|
||||||
|
m_header,
|
||||||
|
m_uuid,
|
||||||
|
m_gnu_debuglink_file,
|
||||||
|
m_gnu_debuglink_crc,
|
||||||
|
m_arch_spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
lldb::offset_t
|
||||||
|
ObjectFileELF::SetData(const lldb_private::DataExtractor &src, lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length)
|
||||||
|
{
|
||||||
|
return dst.SetData(src, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
lldb::offset_t
|
||||||
|
ObjectFileELF::SetDataWithReadMemoryFallback(lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length)
|
||||||
|
{
|
||||||
|
if (offset + length <= m_data.GetByteSize())
|
||||||
|
return dst.SetData(m_data, offset, length);
|
||||||
|
|
||||||
|
const auto process_sp = m_process_wp.lock();
|
||||||
|
if (process_sp != nullptr)
|
||||||
|
{
|
||||||
|
addr_t file_size = offset + length;
|
||||||
|
|
||||||
|
DataBufferSP data_sp = ReadMemory(process_sp, m_memory_addr, file_size);
|
||||||
|
if (!data_sp)
|
||||||
|
return false;
|
||||||
|
m_data.SetData(data_sp, 0, file_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst.SetData(m_data, offset, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ObjectFileELF::ELFSectionHeaderInfo *
|
const ObjectFileELF::ELFSectionHeaderInfo *
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
// C++ Includes
|
// C++ Includes
|
||||||
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// Other libraries and framework includes
|
// Other libraries and framework includes
|
||||||
|
@ -231,6 +232,7 @@ private:
|
||||||
typedef DynamicSymbolColl::const_iterator DynamicSymbolCollConstIter;
|
typedef DynamicSymbolColl::const_iterator DynamicSymbolCollConstIter;
|
||||||
|
|
||||||
typedef std::map<lldb::addr_t, lldb::AddressClass> FileAddressToAddressClassMap;
|
typedef std::map<lldb::addr_t, lldb::AddressClass> FileAddressToAddressClassMap;
|
||||||
|
typedef std::function<lldb::offset_t (lldb_private::DataExtractor &, lldb::offset_t, lldb::offset_t)> SetDataFunction;
|
||||||
|
|
||||||
/// Version of this reader common to all plugins based on this class.
|
/// Version of this reader common to all plugins based on this class.
|
||||||
static const uint32_t m_plugin_version = 1;
|
static const uint32_t m_plugin_version = 1;
|
||||||
|
@ -279,7 +281,7 @@ private:
|
||||||
// Parses the ELF program headers.
|
// Parses the ELF program headers.
|
||||||
static size_t
|
static size_t
|
||||||
GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
|
GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
|
||||||
lldb_private::DataExtractor &data,
|
const SetDataFunction &set_data,
|
||||||
const elf::ELFHeader &header);
|
const elf::ELFHeader &header);
|
||||||
|
|
||||||
// Finds PT_NOTE segments and calculates their crc sum.
|
// Finds PT_NOTE segments and calculates their crc sum.
|
||||||
|
@ -302,7 +304,7 @@ private:
|
||||||
/// Parses the elf section headers and returns the uuid, debug link name, crc, archspec.
|
/// Parses the elf section headers and returns the uuid, debug link name, crc, archspec.
|
||||||
static size_t
|
static size_t
|
||||||
GetSectionHeaderInfo(SectionHeaderColl §ion_headers,
|
GetSectionHeaderInfo(SectionHeaderColl §ion_headers,
|
||||||
lldb_private::DataExtractor &data,
|
const SetDataFunction &set_data,
|
||||||
const elf::ELFHeader &header,
|
const elf::ELFHeader &header,
|
||||||
lldb_private::UUID &uuid,
|
lldb_private::UUID &uuid,
|
||||||
std::string &gnu_debuglink_file,
|
std::string &gnu_debuglink_file,
|
||||||
|
@ -437,6 +439,13 @@ private:
|
||||||
|
|
||||||
static lldb_private::Error
|
static lldb_private::Error
|
||||||
RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch_spec, lldb_private::UUID &uuid);
|
RefineModuleDetailsFromNote (lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch_spec, lldb_private::UUID &uuid);
|
||||||
|
|
||||||
|
|
||||||
|
static lldb::offset_t
|
||||||
|
SetData(const lldb_private::DataExtractor &src, lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length);
|
||||||
|
|
||||||
|
lldb::offset_t
|
||||||
|
SetDataWithReadMemoryFallback(lldb_private::DataExtractor &dst, lldb::offset_t offset, lldb::offset_t length);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // liblldb_ObjectFileELF_h_
|
#endif // liblldb_ObjectFileELF_h_
|
||||||
|
|
Loading…
Reference in New Issue