Use std::vector for the array of RegisterInfo structs that describe the register context.
- Ensures that this container is populated once for the lifetime of lldb --- In particular, static methods can query this data even after the first RegisterContext has been destroyed. - Uses a singleton function to avoid global constructors. Thanks to Greg Clayton for the suggestion! llvm-svn: 183313
This commit is contained in:
		
							parent
							
								
									ffcc010767
								
							
						
					
					
						commit
						a3dd4899e8
					
				| 
						 | 
				
			
			@ -8,6 +8,7 @@
 | 
			
		|||
//===---------------------------------------------------------------------===//
 | 
			
		||||
 | 
			
		||||
#include "RegisterContextFreeBSD_x86_64.h"
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
using namespace lldb_private;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -18,13 +19,13 @@ using namespace lldb_private;
 | 
			
		|||
// Update the FreeBSD specific information (offset and size).
 | 
			
		||||
#define UPDATE_GPR_INFO(reg)                                                \
 | 
			
		||||
do {                                                                        \
 | 
			
		||||
    m_register_infos[gpr_##reg].byte_size = sizeof(GPR::reg);               \
 | 
			
		||||
    m_register_infos[gpr_##reg].byte_offset = GPR_OFFSET(reg);              \
 | 
			
		||||
    GetRegisterContext()[gpr_##reg].byte_size = sizeof(GPR::reg);               \
 | 
			
		||||
    GetRegisterContext()[gpr_##reg].byte_offset = GPR_OFFSET(reg);              \
 | 
			
		||||
} while(false);
 | 
			
		||||
 | 
			
		||||
#define UPDATE_I386_GPR_INFO(i386_reg, reg)                                 \
 | 
			
		||||
do {                                                                        \
 | 
			
		||||
    m_register_infos[gpr_##i386_reg].byte_offset = GPR_OFFSET(reg);         \
 | 
			
		||||
    GetRegisterContext()[gpr_##i386_reg].byte_offset = GPR_OFFSET(reg);         \
 | 
			
		||||
} while(false);
 | 
			
		||||
 | 
			
		||||
typedef struct _GPR
 | 
			
		||||
| 
						 | 
				
			
			@ -57,20 +58,18 @@ typedef struct _GPR
 | 
			
		|||
    uint64_t ss;
 | 
			
		||||
} GPR;
 | 
			
		||||
 | 
			
		||||
RegisterInfo *RegisterContextFreeBSD_x86_64::m_register_infos = nullptr;
 | 
			
		||||
// Use a singleton function to avoid global constructors in shared libraries.
 | 
			
		||||
static std::vector<RegisterInfo> & GetRegisterContext () {
 | 
			
		||||
    static std::vector<RegisterInfo> g_register_infos;
 | 
			
		||||
    return g_register_infos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
RegisterContextFreeBSD_x86_64::RegisterContextFreeBSD_x86_64(Thread &thread, uint32_t concrete_frame_idx):
 | 
			
		||||
    RegisterContext_x86_64(thread, concrete_frame_idx)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RegisterContextFreeBSD_x86_64::~RegisterContextFreeBSD_x86_64()
 | 
			
		||||
{
 | 
			
		||||
    if (m_register_infos)
 | 
			
		||||
        delete m_register_infos;
 | 
			
		||||
    m_register_infos = nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
RegisterContextFreeBSD_x86_64::GetGPRSize()
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -81,19 +80,18 @@ const RegisterInfo *
 | 
			
		|||
RegisterContextFreeBSD_x86_64::GetRegisterInfo()
 | 
			
		||||
{
 | 
			
		||||
    // Allocate RegisterInfo only once
 | 
			
		||||
    if (!m_register_infos)
 | 
			
		||||
    if (GetRegisterContext().empty())
 | 
			
		||||
    {
 | 
			
		||||
        m_register_infos = new RegisterInfo[k_num_registers];
 | 
			
		||||
        // Copy the register information from base class
 | 
			
		||||
        if (m_register_infos)
 | 
			
		||||
        const RegisterInfo *base_info = RegisterContext_x86_64::GetRegisterInfo();
 | 
			
		||||
        if (base_info)
 | 
			
		||||
        {
 | 
			
		||||
            memcpy(m_register_infos, RegisterContext_x86_64::GetRegisterInfo(),
 | 
			
		||||
                   sizeof(RegisterInfo) * k_num_registers);
 | 
			
		||||
            // Update the Linux specific register information (offset and size).
 | 
			
		||||
            GetRegisterContext().insert(GetRegisterContext().end(), &base_info[0], &base_info[k_num_registers]);
 | 
			
		||||
            // Update the FreeBSD specific register information (offset and size).
 | 
			
		||||
            UpdateRegisterInfo();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return m_register_infos;
 | 
			
		||||
    return &GetRegisterContext()[0];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,6 @@ class RegisterContextFreeBSD_x86_64:
 | 
			
		|||
{
 | 
			
		||||
public:
 | 
			
		||||
    RegisterContextFreeBSD_x86_64(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
 | 
			
		||||
    virtual ~RegisterContextFreeBSD_x86_64();
 | 
			
		||||
 | 
			
		||||
    size_t
 | 
			
		||||
    GetGPRSize();
 | 
			
		||||
| 
						 | 
				
			
			@ -28,9 +27,6 @@ protected:
 | 
			
		|||
 | 
			
		||||
    virtual void
 | 
			
		||||
    UpdateRegisterInfo();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    static lldb_private::RegisterInfo *m_register_infos;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@
 | 
			
		|||
//===---------------------------------------------------------------------===//
 | 
			
		||||
 | 
			
		||||
#include "RegisterContextLinux_x86_64.h"
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
using namespace lldb_private;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -18,13 +19,13 @@ using namespace lldb_private;
 | 
			
		|||
// Update the Linux specific information (offset and size).
 | 
			
		||||
#define UPDATE_GPR_INFO(reg)                                                \
 | 
			
		||||
do {                                                                        \
 | 
			
		||||
    m_register_infos[gpr_##reg].byte_size = sizeof(GPR::reg);               \
 | 
			
		||||
    m_register_infos[gpr_##reg].byte_offset = GPR_OFFSET(reg);              \
 | 
			
		||||
    GetRegisterContext()[gpr_##reg].byte_size = sizeof(GPR::reg);               \
 | 
			
		||||
    GetRegisterContext()[gpr_##reg].byte_offset = GPR_OFFSET(reg);              \
 | 
			
		||||
} while(false);
 | 
			
		||||
 | 
			
		||||
#define UPDATE_I386_GPR_INFO(i386_reg, reg)                                 \
 | 
			
		||||
do {                                                                        \
 | 
			
		||||
    m_register_infos[gpr_##i386_reg].byte_offset = GPR_OFFSET(reg);         \
 | 
			
		||||
    GetRegisterContext()[gpr_##i386_reg].byte_offset = GPR_OFFSET(reg);         \
 | 
			
		||||
} while(false);
 | 
			
		||||
 | 
			
		||||
#define DR_OFFSET(reg_index)                                                \
 | 
			
		||||
| 
						 | 
				
			
			@ -32,8 +33,8 @@ do {                                                                        \
 | 
			
		|||
 | 
			
		||||
#define UPDATE_DR_INFO(reg_index)                                                \
 | 
			
		||||
do {                                                                             \
 | 
			
		||||
    m_register_infos[dr##reg_index].byte_size = sizeof(UserArea::u_debugreg[0]); \
 | 
			
		||||
    m_register_infos[dr##reg_index].byte_offset = DR_OFFSET(reg_index);          \
 | 
			
		||||
    GetRegisterContext()[dr##reg_index].byte_size = sizeof(UserArea::u_debugreg[0]); \
 | 
			
		||||
    GetRegisterContext()[dr##reg_index].byte_offset = DR_OFFSET(reg_index);          \
 | 
			
		||||
} while(false);
 | 
			
		||||
 | 
			
		||||
typedef struct _GPR
 | 
			
		||||
| 
						 | 
				
			
			@ -92,20 +93,17 @@ struct UserArea
 | 
			
		|||
    uint64_t fault_address; // Control register CR3.
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
RegisterInfo *RegisterContextLinux_x86_64::m_register_infos = nullptr;
 | 
			
		||||
// Use a singleton function to avoid global constructors in shared libraries.
 | 
			
		||||
static std::vector<RegisterInfo> & GetRegisterContext () {
 | 
			
		||||
    static std::vector<RegisterInfo> g_register_infos;
 | 
			
		||||
    return g_register_infos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(Thread &thread, uint32_t concrete_frame_idx):
 | 
			
		||||
    RegisterContext_x86_64(thread, concrete_frame_idx)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RegisterContextLinux_x86_64::~RegisterContextLinux_x86_64()
 | 
			
		||||
{
 | 
			
		||||
    if (m_register_infos)
 | 
			
		||||
        delete [] m_register_infos;
 | 
			
		||||
    m_register_infos = nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t
 | 
			
		||||
RegisterContextLinux_x86_64::GetGPRSize()
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -116,19 +114,18 @@ const RegisterInfo *
 | 
			
		|||
RegisterContextLinux_x86_64::GetRegisterInfo()
 | 
			
		||||
{
 | 
			
		||||
    // Allocate RegisterInfo only once
 | 
			
		||||
    if (!m_register_infos)
 | 
			
		||||
    if (GetRegisterContext().empty())
 | 
			
		||||
    {
 | 
			
		||||
        m_register_infos = new RegisterInfo[k_num_registers];
 | 
			
		||||
        // Copy the register information from base class
 | 
			
		||||
        if (m_register_infos)
 | 
			
		||||
        const RegisterInfo *base_info = RegisterContext_x86_64::GetRegisterInfo();
 | 
			
		||||
        if (base_info)
 | 
			
		||||
        {
 | 
			
		||||
            memcpy(m_register_infos, RegisterContext_x86_64::GetRegisterInfo(),
 | 
			
		||||
                   sizeof(RegisterInfo) * k_num_registers);
 | 
			
		||||
            GetRegisterContext().insert(GetRegisterContext().end(), &base_info[0], &base_info[k_num_registers]);
 | 
			
		||||
            // Update the Linux specific register information (offset and size).
 | 
			
		||||
            UpdateRegisterInfo();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return m_register_infos;
 | 
			
		||||
    return &GetRegisterContext()[0];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,6 @@ class RegisterContextLinux_x86_64:
 | 
			
		|||
{
 | 
			
		||||
public:
 | 
			
		||||
    RegisterContextLinux_x86_64(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
 | 
			
		||||
    virtual ~RegisterContextLinux_x86_64();
 | 
			
		||||
 | 
			
		||||
    size_t
 | 
			
		||||
    GetGPRSize();
 | 
			
		||||
| 
						 | 
				
			
			@ -28,9 +27,6 @@ protected:
 | 
			
		|||
 | 
			
		||||
    virtual void
 | 
			
		||||
    UpdateRegisterInfo();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    static lldb_private::RegisterInfo *m_register_infos;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue