@@ -217,6 +217,9 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
217217 RegisterMemberFunctionHandler (
218218 StringExtractorGDBRemote::eServerPacketType_jLLDBTraceGetBinaryData,
219219 &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData);
220+ RegisterMemberFunctionHandler (
221+ StringExtractorGDBRemote::eServerPacketType_jMultiBreakpoint,
222+ &GDBRemoteCommunicationServerLLGS::Handle_jMultiBreakpoint);
220223
221224 RegisterMemberFunctionHandler (StringExtractorGDBRemote::eServerPacketType_g,
222225 &GDBRemoteCommunicationServerLLGS::Handle_g);
@@ -3123,6 +3126,65 @@ GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) {
31233126 ExecuteRemoveBreakpoint (packet.GetStringRef ()));
31243127}
31253128
3129+ GDBRemoteCommunication::PacketResult
3130+ GDBRemoteCommunicationServerLLGS::Handle_jMultiBreakpoint (
3131+ StringExtractorGDBRemote &packet) {
3132+ llvm::StringRef packet_str = packet.GetStringRef ();
3133+ if (!packet_str.consume_front (" jMultiBreakpoint:" ))
3134+ return SendIllFormedResponse (packet,
3135+ " Invalid jMultiBreakpoint packet prefix" );
3136+
3137+ llvm::Expected<llvm::json::Value> parsed = llvm::json::parse (packet_str);
3138+ if (!parsed) {
3139+ llvm::consumeError (parsed.takeError ());
3140+ return SendIllFormedResponse (
3141+ packet, " jMultiBreakpoint did not contain a JSON dictionary" );
3142+ }
3143+ llvm::json::Object *request_dict = parsed->getAsObject ();
3144+ if (!request_dict)
3145+ return SendIllFormedResponse (
3146+ packet, " jMultiBreakpoint did not contain a JSON dictionary" );
3147+
3148+ llvm::json::Array *request_array =
3149+ request_dict->getArray (" breakpoint_requests" );
3150+ if (!request_array)
3151+ return SendIllFormedResponse (
3152+ packet,
3153+ " jMultiBreakpoint did not contain a valid 'breakpoint_requests' field" );
3154+
3155+ llvm::json::Array reply_array;
3156+ for (const llvm::json::Value &value : *request_array) {
3157+ std::optional<llvm::StringRef> request = value.getAsString ();
3158+ if (!request)
3159+ return SendIllFormedResponse (packet,
3160+ " jMultiBreakpoint had a non-string entry" );
3161+ BreakpointResult result = request->starts_with (" Z" )
3162+ ? ExecuteSetBreakpoint (*request)
3163+ : ExecuteRemoveBreakpoint (*request);
3164+ switch (result.kind ) {
3165+ case BreakpointResult::Kind::OK :
3166+ reply_array.push_back (" OK" );
3167+ break ;
3168+ case BreakpointResult::Kind::Error:
3169+ reply_array.push_back (llvm::formatv (" E{0:X-2}" , result.error_code ).str ());
3170+ break ;
3171+ case BreakpointResult::Kind::IllFormed:
3172+ reply_array.push_back (" E03" );
3173+ break ;
3174+ }
3175+ }
3176+
3177+ llvm::json::Object dict;
3178+ dict.try_emplace (" results" , std::move (reply_array));
3179+
3180+ StreamString stream;
3181+ stream.AsRawOstream () << llvm::json::Value (std::move (reply_array));
3182+ StringRef response_str = stream.GetString ();
3183+ StreamGDBRemote response;
3184+ response.PutEscapedBytes (response_str.data (), response_str.size ());
3185+ return SendPacketNoLock (response.GetString ());
3186+ }
3187+
31263188GDBRemoteCommunication::PacketResult
31273189GDBRemoteCommunicationServerLLGS::Handle_s (StringExtractorGDBRemote &packet) {
31283190 Log *log = GetLog (LLDBLog::Process | LLDBLog::Thread);
@@ -4338,6 +4400,7 @@ std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures(
43384400 " QListThreadsInStopReply+" ,
43394401 " qXfer:features:read+" ,
43404402 " QNonStop+" ,
4403+ " jMultiBreakpoint+" ,
43414404 });
43424405
43434406 // report server-only features
0 commit comments