[LLDB][MIPS] Fix Core file Architecture and OS information.

Reviewers: labath, clayborg

Subscribers: jaydeep, bhushan, lldb-commits, slthakur

Differential Revision: https://reviews.llvm.org/D31280

llvm-svn: 299199
This commit is contained in:
Nitesh Jain 2017-03-31 11:06:25 +00:00
parent 750bde62dd
commit 706c520558
9 changed files with 63 additions and 6 deletions

View File

@ -21,10 +21,14 @@ class LinuxCoreTestCase(TestBase):
_i386_pid = 32306
_x86_64_pid = 32259
_s390x_pid = 1045
_mips64_n64_pid = 25619
_mips64_n32_pid = 3670
_mips_o32_pid = 3532
_i386_regions = 4
_x86_64_regions = 5
_s390x_regions = 2
_mips_regions = 5
def setUp(self):
super(LinuxCoreTestCase, self).setUp()
@ -40,6 +44,18 @@ class LinuxCoreTestCase(TestBase):
"""Test that lldb can read the process information from an i386 linux core file."""
self.do_test("linux-i386", self._i386_pid, self._i386_regions)
def test_mips_o32(self):
"""Test that lldb can read the process information from an MIPS O32 linux core file."""
self.do_test("linux-mipsel-gnuabio32", self._mips_o32_pid, self._mips_regions)
def test_mips_n32(self):
"""Test that lldb can read the process information from an MIPS N32 linux core file """
self.do_test("linux-mips64el-gnuabin32", self._mips64_n32_pid, self._mips_regions)
def test_mips_n64(self):
"""Test that lldb can read the process information from an MIPS N64 linux core file """
self.do_test("linux-mips64el-gnuabi64", self._mips64_n64_pid, self._mips_regions)
@skipIf(oslist=['windows'])
@skipIf(triple='^mips')
def test_x86_64(self):

View File

@ -288,10 +288,26 @@ static uint32_t kalimbaVariantFromElfFlags(const elf::elf_word e_flags) {
return kal_arch_variant;
}
static uint32_t mipsVariantFromElfFlags(const elf::elf_word e_flags,
uint32_t endian) {
const uint32_t mips_arch = e_flags & llvm::ELF::EF_MIPS_ARCH;
static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) {
const uint32_t mips_arch = header.e_flags & llvm::ELF::EF_MIPS_ARCH;
uint32_t endian = header.e_ident[EI_DATA];
uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown;
uint32_t fileclass = header.e_ident[EI_CLASS];
// If there aren't any elf flags available (e.g core elf file) then return default
// 32 or 64 bit arch (without any architecture revision) based on object file's class.
if (header.e_type == ET_CORE) {
switch (fileclass) {
case llvm::ELF::ELFCLASS32:
return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el
: ArchSpec::eMIPSSubType_mips32;
case llvm::ELF::ELFCLASS64:
return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el
: ArchSpec::eMIPSSubType_mips64;
default:
return arch_variant;
}
}
switch (mips_arch) {
case llvm::ELF::EF_MIPS_ARCH_1:
@ -326,7 +342,7 @@ static uint32_t mipsVariantFromElfFlags(const elf::elf_word e_flags,
static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) {
if (header.e_machine == llvm::ELF::EM_MIPS)
return mipsVariantFromElfFlags(header.e_flags, header.e_ident[EI_DATA]);
return mipsVariantFromElfFlags(header);
return llvm::ELF::EM_CSR_KALIMBA == header.e_machine
? kalimbaVariantFromElfFlags(header.e_flags)
@ -1349,6 +1365,10 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
}
break;
}
if (arch_spec.IsMIPS() &&
arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS)
// The note.n_name == LLDB_NT_OWNER_GNU is valid for Linux platform
arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
}
// Process NetBSD ELF notes.
else if ((note.n_name == LLDB_NT_OWNER_NETBSD) &&
@ -1450,6 +1470,12 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
break;
}
}
if (arch_spec.IsMIPS() &&
arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS)
// In case of MIPSR6, the LLDB_NT_OWNER_GNU note is missing
// for some cases (e.g. compile with -nostdlib)
// Hence set OS to Linux
arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
}
}

View File

@ -214,9 +214,12 @@ Error ProcessElfCore::DoLoadCore() {
// Even if the architecture is set in the target, we need to override
// it to match the core file which is always single arch.
ArchSpec arch(m_core_module_sp->GetArchitecture());
if (arch.IsValid())
GetTarget().SetArchitecture(arch);
ArchSpec target_arch = GetTarget().GetArchitecture();
ArchSpec core_arch(m_core_module_sp->GetArchitecture());
target_arch.MergeFrom(core_arch);
GetTarget().SetArchitecture(target_arch);
SetUnixSignals(UnixSignals::Create(GetArchitecture()));
// Ensure we found at least one thread that was stopped on a signal.
@ -370,6 +373,10 @@ size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
lldb::addr_t bytes_left =
0; // Number of bytes available in the core file from the given address
// Don't proceed if core file doesn't contain the actual data for this address range.
if (file_start == file_end)
return 0;
// Figure out how many on-disk bytes remain in this segment
// starting at the given offset
if (file_end > file_start + offset)
@ -652,6 +659,8 @@ Error ProcessElfCore::ParseThreadContextsFromNoteSegment(
// The result from FXSAVE is in NT_PRXFPREG for i386 core files
if (arch.GetCore() == ArchSpec::eCore_x86_64_x86_64)
thread_data->fpregset = note_data;
else if(arch.IsMIPS())
thread_data->fpregset = note_data;
break;
case NT_PRPSINFO:
have_prpsinfo = true;
@ -719,6 +728,12 @@ ArchSpec ProcessElfCore::GetArchitecture() {
(ObjectFileELF *)(m_core_module_sp->GetObjectFile());
ArchSpec arch;
core_file->GetArchitecture(arch);
ArchSpec target_arch = GetTarget().GetArchitecture();
if (target_arch.IsMIPS())
return target_arch;
return arch;
}