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:
Ashok Thirumurthi 2013-06-05 14:12:43 +00:00
parent ffcc010767
commit a3dd4899e8
4 changed files with 32 additions and 45 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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