Skip to content

Commit ab77720

Browse files
aokblastgithub-actions[bot]
authored andcommitted
Automerge: [LLDB, FreeBSD, x86] Fix empty register set when trying to get size of register (#162890)
The register set information is stored as a singleton in GetRegisterInfo_i386. However, other functions later access this information assuming it is stored in GetSharedRegisterInfoVector. To resolve this inconsistency, we remove the original construction logic and instead initialize the singleton using llvm::call_once within the appropriate function (GetSharedRegisterInfoVector_i386).
2 parents 1ef96eb + c9b07f3 commit ab77720

File tree

1 file changed

+20
-24
lines changed

1 file changed

+20
-24
lines changed

lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "RegisterContextFreeBSD_x86_64.h"
1010
#include "RegisterContextFreeBSD_i386.h"
1111
#include "RegisterContextPOSIX_x86.h"
12+
#include "llvm/Support/Threading.h"
1213
#include <vector>
1314

1415
using namespace lldb_private;
@@ -69,40 +70,34 @@ struct UserArea {
6970
#include "RegisterInfos_x86_64.h"
7071
#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT
7172

72-
static std::vector<lldb_private::RegisterInfo> &GetSharedRegisterInfoVector() {
73-
static std::vector<lldb_private::RegisterInfo> register_infos;
74-
return register_infos;
75-
}
76-
77-
static const RegisterInfo *
78-
GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) {
79-
static std::vector<lldb_private::RegisterInfo> g_register_infos(
80-
GetSharedRegisterInfoVector());
81-
82-
// Allocate RegisterInfo only once
83-
if (g_register_infos.empty()) {
84-
// Copy the register information from base class
85-
std::unique_ptr<RegisterContextFreeBSD_i386> reg_interface(
86-
new RegisterContextFreeBSD_i386(arch));
87-
const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
88-
g_register_infos.insert(g_register_infos.end(), &base_info[0],
89-
&base_info[k_num_registers_i386]);
73+
static std::vector<lldb_private::RegisterInfo> &
74+
GetSharedRegisterInfoVector_i386(const lldb_private::ArchSpec &arch) {
75+
static std::vector<lldb_private::RegisterInfo> g_register_infos;
76+
static llvm::once_flag g_initialized;
77+
llvm::call_once(g_initialized, [&]() {
78+
if (g_register_infos.empty()) {
79+
// Copy the register information from base class
80+
std::unique_ptr<RegisterContextFreeBSD_i386> reg_interface(
81+
new RegisterContextFreeBSD_i386(arch));
82+
const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
83+
g_register_infos.insert(g_register_infos.end(), &base_info[0],
84+
&base_info[k_num_registers_i386]);
9085

9186
// Include RegisterInfos_x86_64 to update the g_register_infos structure
9287
// with x86_64 offsets.
9388
#define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
9489
#include "RegisterInfos_x86_64.h"
9590
#undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
96-
}
97-
98-
return &g_register_infos[0];
91+
}
92+
});
93+
return g_register_infos;
9994
}
10095

10196
static const RegisterInfo *
10297
PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
10398
switch (target_arch.GetMachine()) {
10499
case llvm::Triple::x86:
105-
return GetRegisterInfo_i386(target_arch);
100+
return &GetSharedRegisterInfoVector_i386(target_arch)[0];
106101
case llvm::Triple::x86_64:
107102
return g_register_infos_x86_64;
108103
default:
@@ -116,9 +111,10 @@ PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) {
116111
switch (target_arch.GetMachine()) {
117112
case llvm::Triple::x86:
118113
// This vector should have already been filled.
119-
assert(!GetSharedRegisterInfoVector().empty() &&
114+
assert(!GetSharedRegisterInfoVector_i386(target_arch).empty() &&
120115
"i386 register info vector not filled.");
121-
return static_cast<uint32_t>(GetSharedRegisterInfoVector().size());
116+
return static_cast<uint32_t>(
117+
GetSharedRegisterInfoVector_i386(target_arch).size());
122118
case llvm::Triple::x86_64:
123119
return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) /
124120
sizeof(g_register_infos_x86_64[0]));

0 commit comments

Comments
 (0)