26 enum Extension : uint32_t {
28 kQStartNoAckMode = (1u << 1),
29 kQXferFeaturesRead = (1u << 2),
30 kQXferAuxvRead = (1u << 3),
31 kQXferLibrariesSVR4Read = (1u << 4),
32 kQXferLibrariesRead = (1u << 5),
33 kQListThreadsInStopReply = (1u << 6),
34 kQPassSignals = (1u << 7),
35 kBreakpointCommands = (1u << 8),
36 kMultiprocess = (1u << 9),
37 kQDisableRandomization = (1u << 10),
38 kQNonStop = (1u << 11),
39 kQProgramSignals = (1u << 12),
40 kQXferSiginfoRead = (1u << 13),
41 kQXferSiginfoWrite = (1u << 14),
42 kForkEvents = (1u << 15),
43 kVForkEvents = (1u << 16),
44 kQXferOSDataRead = (1u << 17),
45 kQXferThreadsRead = (1u << 18),
55 void enable(Extension extension) {
56 _supported |= extension;
57 _enabled = _requested & _supported;
60 void disable(Extension extension) {
61 _supported &= ~static_cast<uint32_t>(extension);
62 _enabled = _requested & _supported;
65 void negotiate(std::string
const &feature) {
67 if (!find(feature, extension))
70 _requested |= extension;
71 _enabled = _requested & _supported;
74 bool enabled(Extension extension)
const {
75 return (_enabled & extension) != 0;
78 bool supported(Extension extension)
const {
79 return (_supported & extension) != 0;
82 std::string feature(Extension extension)
const {
83 return feature(extension, supported(extension));
86 std::string feature(Extension extension,
bool state)
const {
87 char const *featureName = this->name(extension);
88 if (featureName ==
nullptr)
91 std::string feature(featureName);
92 feature.push_back(state ?
'+' :
'-');
96 AdvertisedFeature advertise(Extension extension,
97 bool advertiseWhenUnsupported =
false)
const {
98 bool isSupported = supported(extension);
99 char const *featureName = name(extension);
100 if (featureName ==
nullptr || (!isSupported && !advertiseWhenUnsupported))
101 return {
nullptr,
false};
103 return {featureName, isSupported};
106 char const *name(Extension extension)
const {
107 for (
auto const &entry : kEntries) {
108 if (entry.extension == extension)
116 bool find(std::string
const &feature, Extension &extension)
const {
117 for (
auto const &entry : kEntries) {
118 if (feature == entry.name) {
119 extension = entry.extension;
133 static constexpr Entry kEntries[] = {
135 {kQStartNoAckMode,
"QStartNoAckMode"},
136 {kQXferFeaturesRead,
"qXfer:features:read"},
137 {kQXferAuxvRead,
"qXfer:auxv:read"},
138 {kQXferLibrariesSVR4Read,
"qXfer:libraries-svr4:read"},
139 {kQXferLibrariesRead,
"qXfer:libraries:read"},
140 {kQListThreadsInStopReply,
"QListThreadsInStopReply"},
141 {kQPassSignals,
"QPassSignals"},
142 {kBreakpointCommands,
"BreakpointCommands"},
143 {kMultiprocess,
"multiprocess"},
144 {kQDisableRandomization,
"QDisableRandomization"},
145 {kQNonStop,
"QNonStop"},
146 {kQProgramSignals,
"QProgramSignals"},
147 {kQXferSiginfoRead,
"qXfer:siginfo:read"},
148 {kQXferSiginfoWrite,
"qXfer:siginfo:write"},
149 {kForkEvents,
"fork-events"},
150 {kVForkEvents,
"vfork-events"},
151 {kQXferOSDataRead,
"qXfer:osdata:read"},
152 {kQXferThreadsRead,
"qXfer:threads:read"},
156 uint32_t _requested = 0;
157 uint32_t _supported = 0;
158 uint32_t _enabled = 0;