mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-05 00:49:43 +00:00
Fix linux x86 debugging on a linux x86 host (32-bit on 32-bit).
This change fixes up issues with specifying the size of the i386 register infos for FPU registers. The bug was that for the i386 register context, the size of the FPU registers were still being computed based on the x86_64 FXSAVE structure. This change permits the FPR_SIZE macro to optionally be defined outside of RegisterInfos_i386.h, which RegisterContextLinux_i386.cpp does properly. It redefines the FPR_i386 structure with all the accessible parts that RegisterInfos_i386.h wants to see, which we had not done before when we made the overall size of the structure properly sized a recently. This change also modifies POSIXThread to create a RegisterContextLinux_i386 only when the host is 32-bit; otherwise, it uses the RegisterContextLinux_x86_64, which works properly for 32-bit and 64-bit inferiors on a 64-bit host. I tested this debugging a Linux x86 exe on an x86 host (Ubuntu 13.10 x86), and debugging a Linux x86 exe and a Linux x86-64 exe on an x86-64 host (Ubuntu 12.04 LTS). Those cases all worked. Thanks to Matthew Gardiner who discoverd may key insights into tracking down the issue. The motivation for this change and some of the code originates from him via this thread: http://lists.cs.uiuc.edu/pipermail/lldb-commits/Week-of-Mon-20140224/010554.html llvm-svn: 202428
This commit is contained in:
parent
95833f33bd
commit
4507f06aaa
@ -168,9 +168,9 @@ PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size
|
||||
|
||||
errno = 0;
|
||||
if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
|
||||
result = ptrace(static_cast<__ptrace_request>(req), pid, *(unsigned int *)addr, data);
|
||||
result = ptrace(static_cast<__ptrace_request>(req), static_cast<pid_t>(pid), *(unsigned int *)addr, data);
|
||||
else
|
||||
result = ptrace(static_cast<__ptrace_request>(req), pid, addr, data);
|
||||
result = ptrace(static_cast<__ptrace_request>(req), static_cast<pid_t>(pid), addr, data);
|
||||
|
||||
if (log)
|
||||
log->Printf("ptrace(%s, %" PRIu64 ", %p, %p, %zu)=%lX called from file %s line %d",
|
||||
|
@ -190,7 +190,17 @@ POSIXThread::GetRegisterContext()
|
||||
reg_interface = new RegisterContextFreeBSD_x86_64(target_arch);
|
||||
break;
|
||||
case llvm::Triple::Linux:
|
||||
reg_interface = new RegisterContextLinux_x86_64(target_arch);
|
||||
if (Host::GetArchitecture().GetAddressByteSize() == 4)
|
||||
{
|
||||
// 32-bit hosts run with a RegisterContextLinux_i386 context.
|
||||
reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_i386(target_arch));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert((Host::GetArchitecture().GetAddressByteSize() == 8) && "Register setting path assumes this is a 64-bit host");
|
||||
// X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 register context.
|
||||
reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_x86_64(target_arch));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false && "OS not supported");
|
||||
|
@ -36,14 +36,30 @@ struct GPR
|
||||
|
||||
struct FPR_i386
|
||||
{
|
||||
int32_t cwd;
|
||||
int32_t swd;
|
||||
int32_t twd;
|
||||
int32_t fip;
|
||||
int32_t fcs;
|
||||
int32_t foo;
|
||||
int32_t fos;
|
||||
int32_t st_space [20];
|
||||
uint16_t fctrl; // FPU Control Word (fcw)
|
||||
uint16_t fstat; // FPU Status Word (fsw)
|
||||
uint16_t ftag; // FPU Tag Word (ftw)
|
||||
uint16_t fop; // Last Instruction Opcode (fop)
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint64_t fip; // Instruction Pointer
|
||||
uint64_t fdp; // Data Pointer
|
||||
} x86_64;
|
||||
struct
|
||||
{
|
||||
uint32_t fioff; // FPU IP Offset (fip)
|
||||
uint32_t fiseg; // FPU IP Selector (fcs)
|
||||
uint32_t fooff; // FPU Operand Pointer Offset (foo)
|
||||
uint32_t foseg; // FPU Operand Pointer Selector (fos)
|
||||
} i386;
|
||||
} ptr;
|
||||
uint32_t mxcsr; // MXCSR Register State
|
||||
uint32_t mxcsrmask; // MXCSR Mask
|
||||
MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes
|
||||
XMMReg xmm[8]; // 8*16 bytes for each XMM-reg = 128 bytes
|
||||
uint32_t padding[56];
|
||||
};
|
||||
|
||||
struct UserArea
|
||||
@ -69,6 +85,7 @@ struct UserArea
|
||||
#define DR_SIZE sizeof(UserArea::u_debugreg[0])
|
||||
#define DR_OFFSET(reg_index) \
|
||||
(LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index]))
|
||||
#define FPR_SIZE(reg) sizeof(((FPR_i386*)NULL)->reg)
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure.
|
||||
|
@ -24,7 +24,9 @@
|
||||
(LLVM_EXTENSION offsetof(YMM, regname))
|
||||
|
||||
// Number of bytes needed to represent a FPR.
|
||||
#if !defined(FPR_SIZE)
|
||||
#define FPR_SIZE(reg) sizeof(((FXSAVE*)NULL)->reg)
|
||||
#endif
|
||||
|
||||
// Number of bytes needed to represent the i'th FP register.
|
||||
#define FP_SIZE sizeof(((MMSReg*)NULL)->bytes)
|
||||
|
Loading…
x
Reference in New Issue
Block a user