@@ -218,6 +218,9 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
218218 RegisterMemberFunctionHandler (
219219 StringExtractorGDBRemote::eServerPacketType_jLLDBTraceGetBinaryData,
220220 &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData);
221+ RegisterMemberFunctionHandler (
222+ StringExtractorGDBRemote::eServerPacketType_jMultiBreakpoint,
223+ &GDBRemoteCommunicationServerLLGS::Handle_jMultiBreakpoint);
221224
222225 RegisterMemberFunctionHandler (StringExtractorGDBRemote::eServerPacketType_g,
223226 &GDBRemoteCommunicationServerLLGS::Handle_g);
@@ -3105,6 +3108,65 @@ GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) {
31053108 ExecuteRemoveBreakpoint (packet.GetStringRef ()));
31063109}
31073110
3111+ GDBRemoteCommunication::PacketResult
3112+ GDBRemoteCommunicationServerLLGS::Handle_jMultiBreakpoint (
3113+ StringExtractorGDBRemote &packet) {
3114+ llvm::StringRef packet_str = packet.GetStringRef ();
3115+ if (!packet_str.consume_front (" jMultiBreakpoint:" ))
3116+ return SendIllFormedResponse (packet,
3117+ " Invalid jMultiBreakpoint packet prefix" );
3118+
3119+ llvm::Expected<llvm::json::Value> parsed = llvm::json::parse (packet_str);
3120+ if (!parsed) {
3121+ llvm::consumeError (parsed.takeError ());
3122+ return SendIllFormedResponse (packet,
3123+ " jMultiBreakpoint did not contain valid JSON" );
3124+ }
3125+ llvm::json::Object *request_dict = parsed->getAsObject ();
3126+ if (!request_dict)
3127+ return SendIllFormedResponse (
3128+ packet, " jMultiBreakpoint did not contain a JSON dictionary" );
3129+
3130+ llvm::json::Array *request_array =
3131+ request_dict->getArray (" breakpoint_requests" );
3132+ if (!request_array)
3133+ return SendIllFormedResponse (
3134+ packet,
3135+ " jMultiBreakpoint did not contain a valid 'breakpoint_requests' field" );
3136+
3137+ llvm::json::Array reply_array;
3138+ for (const llvm::json::Value &value : *request_array) {
3139+ std::optional<llvm::StringRef> request = value.getAsString ();
3140+ if (!request)
3141+ return SendIllFormedResponse (packet,
3142+ " jMultiBreakpoint had a non-string entry" );
3143+ BreakpointResult result = request->starts_with (" Z" )
3144+ ? ExecuteSetBreakpoint (*request)
3145+ : ExecuteRemoveBreakpoint (*request);
3146+ switch (result.kind ) {
3147+ case BreakpointResult::Kind::OK :
3148+ reply_array.push_back (" OK" );
3149+ break ;
3150+ case BreakpointResult::Kind::Error:
3151+ reply_array.push_back (llvm::formatv (" E{0:X-2}" , result.error_code ).str ());
3152+ break ;
3153+ case BreakpointResult::Kind::IllFormed:
3154+ reply_array.push_back (" E03" );
3155+ break ;
3156+ }
3157+ }
3158+
3159+ llvm::json::Object dict;
3160+ dict.try_emplace (" results" , std::move (reply_array));
3161+
3162+ StreamString stream;
3163+ stream.AsRawOstream () << llvm::json::Value (std::move (dict));
3164+ StringRef response_str = stream.GetString ();
3165+ StreamGDBRemote response;
3166+ response.PutEscapedBytes (response_str.data (), response_str.size ());
3167+ return SendPacketNoLock (response.GetString ());
3168+ }
3169+
31083170GDBRemoteCommunication::PacketResult
31093171GDBRemoteCommunicationServerLLGS::Handle_s (StringExtractorGDBRemote &packet) {
31103172 Log *log = GetLog (LLDBLog::Process | LLDBLog::Thread);
@@ -4320,6 +4382,7 @@ std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures(
43204382 " QListThreadsInStopReply+" ,
43214383 " qXfer:features:read+" ,
43224384 " QNonStop+" ,
4385+ " jMultiBreakpoint+" ,
43234386 });
43244387
43254388 // report server-only features
0 commit comments