From patchwork Tue Mar 29 15:49:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1610719 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=YYPkL8sl; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org (client-ip=2404:9400:2:0:216:3eff:fee1:b9f1; helo=lists.ozlabs.org; envelope-from=pdbg-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org; receiver=) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2404:9400:2:0:216:3eff:fee1:b9f1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KSYv93CC8z9sFk for ; Wed, 30 Mar 2022 02:51:01 +1100 (AEDT) Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4KSYv92RYTz2xtT for ; Wed, 30 Mar 2022 02:51:01 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=YYPkL8sl; dkim-atps=neutral X-Original-To: pdbg@lists.ozlabs.org Delivered-To: pdbg@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::1029; helo=mail-pj1-x1029.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=YYPkL8sl; dkim-atps=neutral Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4KSYv63zQYz2yHB for ; Wed, 30 Mar 2022 02:50:58 +1100 (AEDT) Received: by mail-pj1-x1029.google.com with SMTP id d30so867626pjk.0 for ; Tue, 29 Mar 2022 08:50:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=W9cAZDfOJs27KEAa+sTStUtS4QsFLYSPasaCCP3S0kQ=; b=YYPkL8slrbZV7KAyDui2VLfVw9mFFfZsMdfZ5DjLIeqcT/JRrWXWmame9fQ4WTn5sb jGeSHaSDjNHJJiRLPrM0EfgQ7dVDv4zKShfE1LhsDdxNgWX1BlFBcAcyyloSrEBGZmEZ FqjRf1D6G/IXvjrjwABtgG1zlnnGbB/UwhA2hJJrG9qC9Sq363ghhx6/kgetstSdkL/6 ynFP2rsLVKnHvscr0pcG0WDFt0Euwd+lgA4csaFL2TAf/iWugWSQGy5vm2GNXPLtLe8n Qvc4DA5o1I1ZikOmqMLqUEUvBS97xQ0ljSSkSvXVmaQiRZufrQJ1WLIQltYwJroPXcpw Kx/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=W9cAZDfOJs27KEAa+sTStUtS4QsFLYSPasaCCP3S0kQ=; b=XAmNRcHOGod13HTII9xXpPS5RKvcjgjJ/1uz3tJmsHu0zCsteZeSERebQMxdKUuzah A4npLy5jDOiTVoW17HJGDbxeHxYR50O+6FYY6VBuOZoNlpVLZhxePNP0sf832wQdJRNf nq5j/lEFfKepraoekF8EyNDtLB4l84cxiPJnJSjZkrxNWEoWMbDItz4uJSq5QcsEsPns vRLC0c4o6BvH7++sNzneDLX88udTmXKoZQTHqzboSN8CblMH/nx8su3w/CM1i6mPEJx/ qWa1rx1tPKXwBkPy2MHKb4HFb/0JmYF1Rwg0KTeItUob+vXq5XrI1KL163hfWTucvNOg A1gA== X-Gm-Message-State: AOAM533384yzDHnnuom8PXqYj+NiqAdBztyqgyDZTqN0rgeNkPxOd3zb 4qFz48jSkEuCBGJe0tYB6JhOQPzD8V4= X-Google-Smtp-Source: ABdhPJzzOu38hPgVsCpEwzO0xhKBBBbAu9djY+W8g51MGVCd4FPOPaXSw4L+29R35NkZXyxhjgyHIw== X-Received: by 2002:a17:903:3051:b0:156:2d03:3434 with SMTP id u17-20020a170903305100b001562d033434mr3831738pla.101.1648569056379; Tue, 29 Mar 2022 08:50:56 -0700 (PDT) Received: from bobo.ibm.com (58-6-255-110.tpgi.com.au. [58.6.255.110]) by smtp.gmail.com with ESMTPSA id s35-20020a056a001c6300b004fb20b5d6c1sm14163564pfw.40.2022.03.29.08.50.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Mar 2022 08:50:56 -0700 (PDT) From: Nicholas Piggin To: pdbg@lists.ozlabs.org Date: Wed, 30 Mar 2022 01:49:30 +1000 Message-Id: <20220329154931.493851-38-npiggin@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20220329154931.493851-1-npiggin@gmail.com> References: <20220329154931.493851-1-npiggin@gmail.com> MIME-Version: 1.0 Subject: [Pdbg] [PATCH v2 37/38] gdbserver: handle gdb breakpoint commands X-BeenThere: pdbg@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "mailing list for https://github.com/open-power/pdbg development" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Nicholas Piggin Errors-To: pdbg-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Pdbg" Handle the z/Z breakpoint clear/set gdb commands and maintain the list of breakpoints in the server. This allows breakpoint matching to distinguish between attn in host software, and avoids the problematic gdb break op logic in put_mem. Signed-off-by: Nicholas Piggin --- src/gdb_parser.rl | 5 + src/gdb_parser_precompile.c | 343 ++++++++++++++++++++---------------- src/pdbgproxy.c | 214 +++++++++++++++++++++- src/pdbgproxy.h | 1 + 4 files changed, 401 insertions(+), 162 deletions(-) diff --git a/src/gdb_parser.rl b/src/gdb_parser.rl index abb361a..4404833 100644 --- a/src/gdb_parser.rl +++ b/src/gdb_parser.rl @@ -121,6 +121,10 @@ qf_threadinfo = ('qfThreadInfo' @{cmd = QF_THREADINFO;}); qs_threadinfo = ('qsThreadInfo' @{cmd = QS_THREADINFO;}); + # breakpoints + set_break = ('Z0,' xdigit+ $hex_digit %push ',4' @{cmd = SET_BREAK;}); + clear_break = ('z0,' xdigit+ $hex_digit %push ',4' @{cmd = CLEAR_BREAK;}); + # vCont packet parsing v_contq = ('vCont?' @{rsp = "vCont;c;C;s;S";}); v_contc = ('vCont;c' any* @{cmd = V_CONTC;}); @@ -135,6 +139,7 @@ v_contq | v_contc | v_conts | qf_threadinfo | qs_threadinfo | get_mem | put_mem | + set_break | clear_break | detach | unknown ); cmd = (('$' ((commands & ^'#'*) >reset $crc) diff --git a/src/gdb_parser_precompile.c b/src/gdb_parser_precompile.c index 97cdae2..68502ac 100644 --- a/src/gdb_parser_precompile.c +++ b/src/gdb_parser_precompile.c @@ -11,7 +11,7 @@ #include "debug.h" -#line 149 "src/gdb_parser.rl" +#line 154 "src/gdb_parser.rl" static enum gdb_command cmd = NONE; @@ -31,86 +31,96 @@ static bool ack_mode = true; #line 32 "src/gdb_parser.c" static const char _gdb_actions[] = { 0, 1, 0, 1, 1, 1, 2, 1, - 3, 1, 14, 1, 24, 1, 25, 1, - 26, 1, 27, 2, 0, 1, 2, 2, + 3, 1, 14, 1, 26, 1, 27, 1, + 28, 1, 29, 2, 0, 1, 2, 2, 1, 2, 3, 1, 2, 3, 5, 2, 4, 1, 2, 13, 1, 2, 14, 1, 2, 15, 1, 2, 16, 1, 2, 17, 1, 2, 19, 1, 2, 20, 1, 2, 21, 1, 2, 22, 1, 2, 23, 1, - 3, 0, 6, 1, 3, 0, 7, 1, - 3, 0, 9, 1, 3, 0, 10, 1, - 3, 0, 11, 1, 3, 0, 12, 1, - 3, 2, 8, 1, 3, 3, 18, 1 - + 2, 24, 1, 2, 25, 1, 3, 0, + 6, 1, 3, 0, 7, 1, 3, 0, + 9, 1, 3, 0, 10, 1, 3, 0, + 11, 1, 3, 0, 12, 1, 3, 2, + 8, 1, 3, 3, 18, 1 }; static const short _gdb_key_offsets[] = { - 0, 0, 12, 13, 19, 25, 32, 39, - 41, 43, 50, 58, 66, 73, 80, 88, - 95, 103, 110, 112, 114, 116, 118, 120, - 122, 124, 126, 128, 130, 132, 134, 136, - 138, 140, 147, 155, 163, 170, 177, 185, - 191, 193, 195, 197, 199, 201, 203, 205, - 207, 214, 216, 218, 220, 222, 224, 226, - 228, 230, 232, 233, 235, 237, 239, 241, - 243, 245, 247, 249, 251, 253, 255, 257, - 259, 261, 263, 265, 267, 269, 271, 273, - 275, 277, 279, 281, 284, 287, 288, 289 + 0, 0, 14, 15, 21, 27, 34, 41, + 43, 45, 52, 60, 68, 75, 82, 90, + 97, 105, 112, 114, 116, 118, 120, 122, + 124, 126, 128, 130, 132, 134, 136, 138, + 140, 142, 149, 157, 165, 172, 174, 176, + 183, 191, 193, 200, 208, 214, 216, 218, + 220, 222, 224, 226, 228, 230, 237, 239, + 241, 243, 245, 247, 249, 251, 253, 255, + 256, 258, 260, 262, 264, 266, 268, 270, + 272, 274, 276, 278, 280, 282, 284, 286, + 288, 290, 292, 294, 296, 298, 300, 302, + 304, 307, 310, 311, 312, 314, 316, 323, + 331, 333 }; static const char _gdb_trans_keys[] = { - 35, 63, 68, 72, 77, 81, 84, 103, - 109, 112, 113, 118, 35, 48, 57, 65, - 70, 97, 102, 48, 57, 65, 70, 97, - 102, 35, 48, 57, 65, 70, 97, 102, - 35, 48, 57, 65, 70, 97, 102, 35, - 103, 35, 112, 35, 48, 57, 65, 70, - 97, 102, 35, 46, 48, 57, 65, 70, - 97, 102, 35, 112, 48, 57, 65, 70, + 35, 63, 68, 72, 77, 81, 84, 90, + 103, 109, 112, 113, 118, 122, 35, 48, + 57, 65, 70, 97, 102, 48, 57, 65, + 70, 97, 102, 35, 48, 57, 65, 70, 97, 102, 35, 48, 57, 65, 70, 97, - 102, 35, 48, 57, 65, 70, 97, 102, - 35, 44, 48, 57, 65, 70, 97, 102, - 35, 48, 57, 65, 70, 97, 102, 35, - 58, 48, 57, 65, 70, 97, 102, 35, - 48, 57, 65, 70, 97, 102, 35, 83, - 35, 116, 35, 97, 35, 114, 35, 116, - 35, 78, 35, 111, 35, 65, 35, 99, - 35, 107, 35, 77, 35, 111, 35, 100, - 35, 101, 35, 112, 35, 48, 57, 65, - 70, 97, 102, 35, 46, 48, 57, 65, - 70, 97, 102, 35, 112, 48, 57, 65, + 102, 35, 103, 35, 112, 35, 48, 57, + 65, 70, 97, 102, 35, 46, 48, 57, + 65, 70, 97, 102, 35, 112, 48, 57, + 65, 70, 97, 102, 35, 48, 57, 65, 70, 97, 102, 35, 48, 57, 65, 70, + 97, 102, 35, 44, 48, 57, 65, 70, 97, 102, 35, 48, 57, 65, 70, 97, - 102, 35, 44, 48, 57, 65, 70, 97, - 102, 35, 65, 67, 83, 102, 115, 35, - 116, 35, 116, 35, 97, 35, 99, 35, - 104, 35, 101, 35, 100, 35, 58, 35, - 48, 57, 65, 70, 97, 102, 35, 117, - 35, 112, 35, 112, 35, 111, 35, 114, - 35, 116, 35, 101, 35, 100, 35, 58, - 35, 35, 84, 35, 104, 35, 114, 35, - 101, 35, 97, 35, 100, 35, 73, 35, - 110, 35, 102, 35, 111, 35, 84, 35, - 104, 35, 114, 35, 101, 35, 97, 35, - 100, 35, 73, 35, 110, 35, 102, 35, - 111, 35, 67, 35, 111, 35, 110, 35, - 116, 35, 59, 63, 35, 99, 115, 35, - 35, 3, 36, 43, 45, 0 + 102, 35, 58, 48, 57, 65, 70, 97, + 102, 35, 48, 57, 65, 70, 97, 102, + 35, 83, 35, 116, 35, 97, 35, 114, + 35, 116, 35, 78, 35, 111, 35, 65, + 35, 99, 35, 107, 35, 77, 35, 111, + 35, 100, 35, 101, 35, 112, 35, 48, + 57, 65, 70, 97, 102, 35, 46, 48, + 57, 65, 70, 97, 102, 35, 112, 48, + 57, 65, 70, 97, 102, 35, 48, 57, + 65, 70, 97, 102, 35, 48, 35, 44, + 35, 48, 57, 65, 70, 97, 102, 35, + 44, 48, 57, 65, 70, 97, 102, 35, + 52, 35, 48, 57, 65, 70, 97, 102, + 35, 44, 48, 57, 65, 70, 97, 102, + 35, 65, 67, 83, 102, 115, 35, 116, + 35, 116, 35, 97, 35, 99, 35, 104, + 35, 101, 35, 100, 35, 58, 35, 48, + 57, 65, 70, 97, 102, 35, 117, 35, + 112, 35, 112, 35, 111, 35, 114, 35, + 116, 35, 101, 35, 100, 35, 58, 35, + 35, 84, 35, 104, 35, 114, 35, 101, + 35, 97, 35, 100, 35, 73, 35, 110, + 35, 102, 35, 111, 35, 84, 35, 104, + 35, 114, 35, 101, 35, 97, 35, 100, + 35, 73, 35, 110, 35, 102, 35, 111, + 35, 67, 35, 111, 35, 110, 35, 116, + 35, 59, 63, 35, 99, 115, 35, 35, + 35, 48, 35, 44, 35, 48, 57, 65, + 70, 97, 102, 35, 44, 48, 57, 65, + 70, 97, 102, 35, 52, 3, 36, 43, + 45, 0 }; static const char _gdb_single_lengths[] = { - 0, 12, 1, 0, 0, 1, 1, 2, + 0, 14, 1, 0, 0, 1, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 1, 2, 2, 1, 1, 2, 6, + 2, 1, 2, 2, 1, 2, 2, 1, + 2, 2, 1, 2, 6, 2, 2, 2, + 2, 2, 2, 2, 2, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 3, 3, 1, 1, 4 + 3, 3, 1, 1, 2, 2, 1, 2, + 2, 4 }; static const char _gdb_range_lengths[] = { @@ -118,125 +128,138 @@ static const char _gdb_range_lengths[] = { 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3, 3, 3, 3, 3, 3, 0, + 0, 3, 3, 3, 3, 0, 0, 3, + 3, 0, 3, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 3, 3, + 0, 0 }; static const short _gdb_index_offsets[] = { - 0, 0, 13, 15, 19, 23, 28, 33, - 36, 39, 44, 50, 56, 61, 66, 72, - 77, 83, 88, 91, 94, 97, 100, 103, - 106, 109, 112, 115, 118, 121, 124, 127, - 130, 133, 138, 144, 150, 155, 160, 166, - 173, 176, 179, 182, 185, 188, 191, 194, - 197, 202, 205, 208, 211, 214, 217, 220, - 223, 226, 229, 231, 234, 237, 240, 243, - 246, 249, 252, 255, 258, 261, 264, 267, - 270, 273, 276, 279, 282, 285, 288, 291, - 294, 297, 300, 303, 307, 311, 313, 315 + 0, 0, 15, 17, 21, 25, 30, 35, + 38, 41, 46, 52, 58, 63, 68, 74, + 79, 85, 90, 93, 96, 99, 102, 105, + 108, 111, 114, 117, 120, 123, 126, 129, + 132, 135, 140, 146, 152, 157, 160, 163, + 168, 174, 177, 182, 188, 195, 198, 201, + 204, 207, 210, 213, 216, 219, 224, 227, + 230, 233, 236, 239, 242, 245, 248, 251, + 253, 256, 259, 262, 265, 268, 271, 274, + 277, 280, 283, 286, 289, 292, 295, 298, + 301, 304, 307, 310, 313, 316, 319, 322, + 325, 329, 333, 335, 337, 340, 343, 348, + 354, 357 }; static const char _gdb_indicies[] = { 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 0, 14, 13, 15, - 15, 15, 16, 17, 17, 17, 16, 14, - 18, 18, 18, 13, 19, 18, 18, 18, - 13, 14, 20, 13, 14, 21, 13, 14, - 22, 22, 22, 13, 14, 23, 22, 22, - 22, 13, 14, 21, 24, 24, 24, 13, - 19, 24, 24, 24, 13, 14, 25, 25, - 25, 13, 14, 26, 25, 25, 25, 13, - 14, 27, 27, 27, 13, 14, 28, 27, - 27, 27, 13, 14, 29, 29, 29, 13, - 14, 30, 13, 14, 31, 13, 14, 32, - 13, 14, 33, 13, 14, 34, 13, 14, - 35, 13, 14, 36, 13, 14, 37, 13, - 14, 38, 13, 14, 39, 13, 14, 40, - 13, 14, 41, 13, 14, 42, 13, 14, - 43, 13, 14, 44, 13, 14, 45, 45, - 45, 13, 14, 46, 45, 45, 45, 13, - 14, 44, 47, 47, 47, 13, 14, 47, - 47, 47, 13, 14, 48, 48, 48, 13, - 14, 49, 48, 48, 48, 13, 14, 50, - 51, 52, 53, 54, 13, 14, 55, 13, - 14, 56, 13, 14, 57, 13, 14, 58, - 13, 14, 59, 13, 14, 60, 13, 14, - 61, 13, 14, 62, 13, 14, 63, 63, - 63, 13, 14, 64, 13, 14, 65, 13, - 14, 66, 13, 14, 67, 13, 14, 68, - 13, 14, 69, 13, 14, 70, 13, 14, - 71, 13, 14, 72, 13, 74, 73, 14, - 75, 13, 14, 76, 13, 14, 77, 13, - 14, 78, 13, 14, 79, 13, 14, 80, - 13, 14, 81, 13, 14, 82, 13, 14, - 83, 13, 14, 84, 13, 14, 85, 13, - 14, 86, 13, 14, 87, 13, 14, 88, - 13, 14, 89, 13, 14, 90, 13, 14, - 91, 13, 14, 92, 13, 14, 93, 13, - 14, 94, 13, 14, 95, 13, 14, 96, - 13, 14, 97, 13, 14, 98, 13, 14, - 99, 100, 13, 14, 101, 102, 13, 14, - 103, 14, 104, 105, 106, 107, 108, 16, - 0 + 9, 10, 11, 12, 13, 14, 0, 16, + 15, 17, 17, 17, 18, 19, 19, 19, + 18, 16, 20, 20, 20, 15, 21, 20, + 20, 20, 15, 16, 22, 15, 16, 23, + 15, 16, 24, 24, 24, 15, 16, 25, + 24, 24, 24, 15, 16, 23, 26, 26, + 26, 15, 21, 26, 26, 26, 15, 16, + 27, 27, 27, 15, 16, 28, 27, 27, + 27, 15, 16, 29, 29, 29, 15, 16, + 30, 29, 29, 29, 15, 16, 31, 31, + 31, 15, 16, 32, 15, 16, 33, 15, + 16, 34, 15, 16, 35, 15, 16, 36, + 15, 16, 37, 15, 16, 38, 15, 16, + 39, 15, 16, 40, 15, 16, 41, 15, + 16, 42, 15, 16, 43, 15, 16, 44, + 15, 16, 45, 15, 16, 46, 15, 16, + 47, 47, 47, 15, 16, 48, 47, 47, + 47, 15, 16, 46, 49, 49, 49, 15, + 16, 49, 49, 49, 15, 16, 50, 15, + 16, 51, 15, 16, 52, 52, 52, 15, + 16, 53, 52, 52, 52, 15, 16, 54, + 15, 16, 55, 55, 55, 15, 16, 56, + 55, 55, 55, 15, 16, 57, 58, 59, + 60, 61, 15, 16, 62, 15, 16, 63, + 15, 16, 64, 15, 16, 65, 15, 16, + 66, 15, 16, 67, 15, 16, 68, 15, + 16, 69, 15, 16, 70, 70, 70, 15, + 16, 71, 15, 16, 72, 15, 16, 73, + 15, 16, 74, 15, 16, 75, 15, 16, + 76, 15, 16, 77, 15, 16, 78, 15, + 16, 79, 15, 81, 80, 16, 82, 15, + 16, 83, 15, 16, 84, 15, 16, 85, + 15, 16, 86, 15, 16, 87, 15, 16, + 88, 15, 16, 89, 15, 16, 90, 15, + 16, 91, 15, 16, 92, 15, 16, 93, + 15, 16, 94, 15, 16, 95, 15, 16, + 96, 15, 16, 97, 15, 16, 98, 15, + 16, 99, 15, 16, 100, 15, 16, 101, + 15, 16, 102, 15, 16, 103, 15, 16, + 104, 15, 16, 105, 15, 16, 106, 107, + 15, 16, 108, 109, 15, 16, 110, 16, + 111, 16, 112, 15, 16, 113, 15, 16, + 114, 114, 114, 15, 16, 115, 114, 114, + 114, 15, 16, 116, 15, 117, 118, 119, + 120, 18, 0 }; static const char _gdb_trans_targs[] = { 2, 3, 2, 5, 7, 13, 18, 32, - 2, 37, 5, 39, 79, 2, 3, 4, - 0, 87, 6, 3, 8, 9, 10, 11, - 12, 14, 15, 16, 17, 17, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 2, 33, 34, 35, 36, - 38, 5, 40, 2, 49, 59, 69, 41, - 42, 43, 44, 45, 46, 47, 48, 48, - 50, 51, 52, 53, 54, 55, 56, 57, - 58, 2, 3, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 2, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 2, 80, - 81, 82, 83, 84, 2, 85, 86, 85, - 86, 87, 1, 87, 87 + 37, 2, 42, 5, 44, 84, 92, 2, + 3, 4, 0, 97, 6, 3, 8, 9, + 10, 11, 12, 14, 15, 16, 17, 17, + 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 2, 33, 34, + 35, 36, 38, 39, 40, 41, 2, 43, + 5, 45, 2, 54, 64, 74, 46, 47, + 48, 49, 50, 51, 52, 53, 53, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 2, 3, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 2, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 2, 85, 86, + 87, 88, 89, 2, 90, 91, 90, 91, + 93, 94, 95, 96, 2, 97, 1, 97, + 97 }; static const char _gdb_trans_actions[] = { - 19, 1, 80, 84, 19, 68, 19, 19, - 72, 64, 76, 19, 19, 3, 0, 7, - 0, 28, 25, 5, 3, 3, 3, 3, - 92, 25, 22, 25, 88, 31, 3, 3, + 19, 1, 86, 90, 19, 74, 19, 19, + 19, 78, 70, 82, 19, 19, 19, 3, + 0, 7, 0, 28, 25, 5, 3, 3, + 3, 3, 98, 25, 22, 25, 94, 31, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 40, 3, 3, 3, 43, - 25, 22, 3, 46, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 34, + 3, 3, 3, 3, 3, 40, 3, 3, + 3, 43, 3, 3, 25, 22, 55, 25, + 22, 3, 46, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 34, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 37, 9, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 49, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 52, 3, - 3, 3, 3, 3, 55, 3, 3, 58, - 61, 11, 13, 15, 17 + 37, 9, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 49, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 52, 3, 3, + 3, 3, 3, 61, 3, 3, 64, 67, + 3, 3, 25, 22, 58, 11, 13, 15, + 17 }; -static const int gdb_start = 87; -static const int gdb_first_final = 87; +static const int gdb_start = 97; +static const int gdb_first_final = 97; static const int gdb_error = 0; -static const int gdb_en_main = 87; +static const int gdb_en_main = 97; -#line 165 "src/gdb_parser.rl" +#line 170 "src/gdb_parser.rl" void parser_init(command_cb *callbacks) { -#line 235 "src/gdb_parser.c" +#line 258 "src/gdb_parser.c" { cs = gdb_start; } -#line 169 "src/gdb_parser.rl" +#line 174 "src/gdb_parser.rl" command_callbacks = callbacks; } @@ -247,7 +270,7 @@ int parse_buffer(char *buf, size_t len, void *priv) char *pe = p + len; -#line 251 "src/gdb_parser.c" +#line 274 "src/gdb_parser.c" { int _klen; unsigned int _trans; @@ -470,33 +493,41 @@ _match: break; case 21: #line 125 "src/gdb_parser.rl" - {rsp = "vCont;c;C;s;S";} + {cmd = SET_BREAK;} break; case 22: #line 126 "src/gdb_parser.rl" - {cmd = V_CONTC;} + {cmd = CLEAR_BREAK;} break; case 23: -#line 127 "src/gdb_parser.rl" - {cmd = V_CONTS;} +#line 129 "src/gdb_parser.rl" + {rsp = "vCont;c;C;s;S";} break; case 24: #line 130 "src/gdb_parser.rl" - { if (command_callbacks) command_callbacks[INTERRUPT](stack, priv); PR_INFO("RAGEL:interrupt\n");} + {cmd = V_CONTC;} break; case 25: -#line 141 "src/gdb_parser.rl" - {PR_INFO("RAGEL:cmd\n");} +#line 131 "src/gdb_parser.rl" + {cmd = V_CONTS;} break; case 26: -#line 144 "src/gdb_parser.rl" - {PR_INFO("RAGEL:ack\n");} +#line 134 "src/gdb_parser.rl" + { if (command_callbacks) command_callbacks[INTERRUPT](stack, priv); PR_INFO("RAGEL:interrupt\n");} break; case 27: -#line 145 "src/gdb_parser.rl" +#line 146 "src/gdb_parser.rl" + {PR_INFO("RAGEL:cmd\n");} + break; + case 28: +#line 149 "src/gdb_parser.rl" + {PR_INFO("RAGEL:ack\n");} + break; + case 29: +#line 150 "src/gdb_parser.rl" {PR_INFO("RAGEL:nack\n");} break; -#line 500 "src/gdb_parser.c" +#line 531 "src/gdb_parser.c" } } @@ -509,7 +540,7 @@ _again: _out: {} } -#line 179 "src/gdb_parser.rl" +#line 184 "src/gdb_parser.rl" if (cs == gdb_error) { printf("parse error\n"); diff --git a/src/pdbgproxy.c b/src/pdbgproxy.c index 687f766..c257361 100644 --- a/src/pdbgproxy.c +++ b/src/pdbgproxy.c @@ -664,6 +664,192 @@ out: send_response(fd, OK); } +#define MAX_BPS 64 +static uint64_t bps[MAX_BPS]; +static uint32_t saved_insn[MAX_BPS]; +static int nr_bps = 0; + +static int set_bp(uint64_t addr) +{ + int i; + + if (nr_bps == MAX_BPS) + return -1; + + if (addr == -1ULL) + return -1; + + for (i = 0; i < MAX_BPS; i++) { + if (bps[i] == -1ULL) { + bps[i] = addr; + nr_bps++; + return 0; + } + } + + return -1; +} + +static int clear_bp(uint64_t addr) +{ + int i; + + if (nr_bps == 0) + return -1; + + if (addr == -1ULL) + return -1; + + for (i = 0; i < MAX_BPS; i++) { + if (bps[i] == addr) { + bps[i] = -1ULL; + nr_bps--; + return 0; + } + } + + return -1; +} + +static int get_insn(uint64_t addr, uint32_t *insn) +{ + uint64_t linear_map; + + linear_map = get_real_addr(addr); + if (linear_map != -1UL) { + if (read_memory(linear_map, 4, insn, 1)) { + PR_ERROR("Unable to read memory\n"); + return -1; + } + } else { + /* Virtual address */ + return -1; + } + + return 0; +} + +static int put_insn(uint64_t addr, uint32_t insn) +{ + uint64_t linear_map; + + linear_map = get_real_addr(addr); + if (linear_map != -1UL) { + if (write_memory(linear_map, 4, &insn, 8)) { + PR_ERROR("Unable to write memory\n"); + return -1; + } + } else { + /* Virtual address */ + return -1; + } + + return 0; +} + +static void init_breakpoints(void) +{ + int i; + + for (i = 0; i < MAX_BPS; i++) + bps[i] = -1ULL; +} + +static bool match_breakpoint(uint64_t addr) +{ + int i; + + if (nr_bps == 0) + return false; + + for (i = 0; i < MAX_BPS; i++) { + if (bps[i] == addr) + return true; + } + + return false; +} + +static int install_breakpoints(void) +{ + uint8_t attn_opcode[] = {0x00, 0x00, 0x02, 0x00}; + uint32_t *attn = (uint32_t *)&attn_opcode[0]; + uint64_t msr; + int i; + + if (!nr_bps) + return 0; + + /* Check endianess in MSR */ + if (thread_getmsr(thread_target, &msr)) { + PR_ERROR("Couldn't read the MSR to set breakpoint endian"); + return -1; + } + + if (msr & 1) /* currently little endian */ + *attn = bswap_32(*attn); + + for (i = 0; i < MAX_BPS; i++) { + if (bps[i] == -1ULL) + continue; + if (get_insn(bps[i], &saved_insn[i])) + continue; /* XXX: handle properly */ + if (put_insn(bps[i], *attn)) + continue; /* XXX: handle properly */ + } + + set_attn(true); + + return 0; +} + +static int uninstall_breakpoints(void) +{ + int i; + + if (!nr_bps) + return 0; + + for (i = 0; i < MAX_BPS; i++) { + if (bps[i] == -1ULL) + continue; + if (put_insn(bps[i], saved_insn[i])) + continue; /* XXX: handle properly */ + + } + + set_attn(false); + + return 0; +} + + +static void set_break(uint64_t *stack, void *priv) +{ + uint64_t addr; + + /* stack[0] is the address */ + addr = stack[0]; + + if (!set_bp(addr)) + send_response(fd, OK); + else + send_response(fd, ERROR(ENOMEM)); +} + +static void clear_break(uint64_t *stack, void *priv) +{ + uint64_t addr; + + /* stack[0] is the address */ + addr = stack[0]; + + if (!clear_bp(addr)) + send_response(fd, OK); + else + send_response(fd, ERROR(ENOENT)); +} + static void v_conts(uint64_t *stack, void *priv) { struct thread *thread = target_to_thread(thread_target); @@ -709,6 +895,8 @@ static void start_all(void) { struct pdbg_target *target; + install_breakpoints(); + for_each_path_target_class("thread", target) { struct thread *thread = target_to_thread(target); struct gdb_thread *gdb_thread; @@ -843,14 +1031,26 @@ static void stop_all(void) gdb_thread->stop_attn = true; if (!(status.active)) - PR_ERROR("Error thread inactive after trap\n"); - /* Restore NIA to before break */ + PR_ERROR("Error thread inactive after attn\n"); + if (thread_getnia(target, &nia)) PR_ERROR("Error during getnia\n"); - if (thread_putnia(target, nia - 4)) - PR_ERROR("Error during putnia\n"); + + /* + * If we hit a non-breakpoint attn we still want to + * switch to that thread, but we don't rewind the nip + * so as to advance over the attn. + */ + if (match_breakpoint(nia - 4)) { + PR_INFO("thread pir=%llx attn is breakpoint\n", gdb_thread->pir); + /* Restore NIA to breakpoint address */ + if (thread_putnia(target, nia - 4)) + PR_ERROR("Error during putnia\n"); + } } } + + uninstall_breakpoints(); } static void interrupt(uint64_t *stack, void *priv) @@ -918,8 +1118,6 @@ static void poll(void) } } - set_attn(false); - state = IDLE; poll_interval = VCONT_POLL_DELAY; @@ -991,6 +1189,8 @@ static command_cb callbacks[LAST_CMD + 1] = { qs_threadinfo, get_mem, put_mem, + set_break, + clear_break, interrupt, detach, NULL}; @@ -1107,6 +1307,8 @@ static int gdbserver(uint16_t port) struct pdbg_target *first_stopped_target = NULL; struct pdbg_target *first_attn_target = NULL; + init_breakpoints(); + for_each_path_target_class("thread", target) { struct thread *thread = target_to_thread(target); struct gdb_thread *gdb_thread; diff --git a/src/pdbgproxy.h b/src/pdbgproxy.h index cafd4cb..6a89444 100644 --- a/src/pdbgproxy.h +++ b/src/pdbgproxy.h @@ -6,6 +6,7 @@ enum gdb_command {NONE, GET_GPRS, GET_SPR, V_CONTC, V_CONTS, QF_THREADINFO, QS_THREADINFO, GET_MEM, PUT_MEM, + SET_BREAK, CLEAR_BREAK, INTERRUPT, DETACH, LAST_CMD}; typedef void (*command_cb)(uint64_t *stack, void *priv);