From 932a0e0bbec7939a89431bdc31316afbf2d23cde Mon Sep 17 00:00:00 2001
From: Yuan Fu <casouri@gmail.com>
Date: Sat, 5 Oct 2019 22:42:07 -0400
Subject: [PATCH 1/4] Enhance support for expressions as memory address
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Before the memory buffer evaluates the expression as address
and use the fixed result in each stop. This change stores the
expression itself and reevaluates it in each stop for an address.
Then displays the value of the memory at that address.

lisp/progmodes/gdb-mi.el (gdb-memory-address-expression): new
  (gdb-memory-address): change default value, add docstring
  (def-gdb-trigger-and-handler gdb-invalidate-memory,
  gdb-memory-set-address): replace ’gdb-memory-address’ with
    ’gdb-memory-address-expression’
  (gdb-memory-header): Add display for ’gdb-memory-address-expression’,
    move the mouse event from address to expression
---
 lisp/progmodes/gdb-mi.el | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index b08d487af3..bd4d216860 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -3445,7 +3445,7 @@ gdb-memory-unit
 (def-gdb-trigger-and-handler
   gdb-invalidate-memory
   (format "-data-read-memory %s %s %d %d %d"
-          gdb-memory-address
+          (gdb-mi-quote gdb-memory-address-expression)
           gdb-memory-format
           gdb-memory-unit
           gdb-memory-rows
@@ -3535,7 +3535,7 @@ gdb-memory-set-address
   "Set the start memory address."
   (interactive)
   (let ((arg (read-from-minibuffer "Memory address: ")))
-    (setq gdb-memory-address arg))
+    (setq gdb-memory-address-expression arg))
   (gdb-invalidate-memory 'update))
 
 (defmacro def-gdb-set-positive-number (name variable echo-string &optional doc)
@@ -3718,7 +3718,15 @@ gdb-memory-font-lock-keywords
 (defvar gdb-memory-header
   '(:eval
     (concat
-     "Start address["
+     "Start address "
+     (propertize gdb-memory-address-expression
+                 'face font-lock-warning-face
+                 'help-echo "mouse-1: set start address"
+                 'mouse-face 'mode-line-highlight
+                 'local-map (gdb-make-header-line-mouse-map
+                             'mouse-1
+                             #'gdb-memory-set-address-event))
+     " ["
      (propertize "-"
                  'face font-lock-warning-face
                  'help-echo "mouse-1: decrement address"
@@ -3736,12 +3744,7 @@ gdb-memory-header
                              #'gdb-memory-show-next-page))
      "]: "
      (propertize gdb-memory-address
-                 'face font-lock-warning-face
-                 'help-echo "mouse-1: set start address"
-                 'mouse-face 'mode-line-highlight
-                 'local-map (gdb-make-header-line-mouse-map
-                             'mouse-1
-                             #'gdb-memory-set-address-event))
+                 'face font-lock-warning-face)
      "  Rows: "
      (propertize (number-to-string gdb-memory-rows)
                  'face font-lock-warning-face
-- 
2.24.1


From d4e98f53dcb228b58f6c72b41ce2150160e863d7 Mon Sep 17 00:00:00 2001
From: Yuan Fu <casouri@gmail.com>
Date: Mon, 7 Oct 2019 20:36:23 -0400
Subject: [PATCH 2/4] Fix memory buffer code in gdb-mi
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* lisp/progmodes/gdb-mi.el (gdb-read-memory-custom):
Break infinite loop. Change ’error’ to ’user-error’
---
 lisp/progmodes/gdb-mi.el | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index bd4d216860..662671885c 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -3498,10 +3498,12 @@ gdb-read-memory-custom
                                             gdb-memory-format)))))
             (newline)))
       ;; Show last page instead of empty buffer when out of bounds
-      (progn
-        (let ((gdb-memory-address gdb-memory-last-address))
+      (when gdb-memory-last-address
+        (let ((gdb-memory-address-expression gdb-memory-last-address))
+          ;; avoid infinite loop
+          (setq gdb-memory-last-address nil)
           (gdb-invalidate-memory 'update)
-          (error err-msg))))))
+          (user-error "Error when retrieving memory: %s Displaying last successful page" err-msg))))))
 
 (defvar gdb-memory-mode-map
   (let ((map (make-sparse-keymap)))
-- 
2.24.1


From dc5008ac30718fd1e1920bb07300a0a2e10835c4 Mon Sep 17 00:00:00 2001
From: Yuan Fu <casouri@gmail.com>
Date: Mon, 7 Oct 2019 20:52:15 -0400
Subject: [PATCH 3/4] Protect against nil memory address in gdb-mi

* lisp/progmodes/gdb-mi.el (gdb-memory-header):
Protect against nil value
---
 lisp/progmodes/gdb-mi.el | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index 662671885c..eec11ebf0c 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -3721,7 +3721,7 @@ gdb-memory-header
   '(:eval
     (concat
      "Start address "
-     (propertize gdb-memory-address-expression
+     (propertize (or gdb-memory-address-expression "N/A")
                  'face font-lock-warning-face
                  'help-echo "mouse-1: set start address"
                  'mouse-face 'mode-line-highlight
@@ -3745,7 +3745,7 @@ gdb-memory-header
                              'mouse-1
                              #'gdb-memory-show-next-page))
      "]: "
-     (propertize gdb-memory-address
+     (propertize (or gdb-memory-address "N/A")
                  'face font-lock-warning-face)
      "  Rows: "
      (propertize (number-to-string gdb-memory-rows)
-- 
2.24.1


From 5b784a7312623b83dbeecafcbe0421c1035f9483 Mon Sep 17 00:00:00 2001
From: Yuan Fu <casouri@gmail.com>
Date: Mon, 7 Oct 2019 21:17:01 -0400
Subject: [PATCH 4/4] =?UTF-8?q?Display=20warning=20when=20address=20expres?=
 =?UTF-8?q?sion=20and=20address=20doesn=E2=80=99t=20match?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* lisp/progmodes/gdb-mi.el (gdb--memory-display-warning): new
(gdb-read-memory-custom, gdb-memory-header): Add warning
---
 lisp/progmodes/gdb-mi.el | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index eec11ebf0c..bdd01e0747 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -112,6 +112,12 @@ gdb-memory-next-page
   "Address of next memory page for program memory buffer.")
 (defvar	gdb-memory-prev-page nil
   "Address of previous memory page for program memory buffer.")
+(defvar-local gdb--memory-display-warning nil
+  "Display warning on memory header if t.
+
+When error occurs when retrieving memory, gdb-mi displays the last
+successful page. In that case the expression might not match the
+memory displayed.")
 
 (defvar gdb-thread-number nil
   "Main current thread.
@@ -3485,6 +3491,9 @@ gdb-read-memory-custom
          (err-msg (bindat-get-field res 'msg)))
     (if (not err-msg)
         (let ((memory (bindat-get-field res 'memory)))
+          (when gdb-memory-last-address
+            ;; nil means last retrieve emits error or just started the session
+            (setq gdb--memory-display-warning nil))
           (setq gdb-memory-address (bindat-get-field res 'addr))
           (setq gdb-memory-next-page (bindat-get-field res 'next-page))
           (setq gdb-memory-prev-page (bindat-get-field res 'prev-page))
@@ -3501,7 +3510,8 @@ gdb-read-memory-custom
       (when gdb-memory-last-address
         (let ((gdb-memory-address-expression gdb-memory-last-address))
           ;; avoid infinite loop
-          (setq gdb-memory-last-address nil)
+          (setq gdb-memory-last-address nil
+                gdb--memory-display-warning t)
           (gdb-invalidate-memory 'update)
           (user-error "Error when retrieving memory: %s Displaying last successful page" err-msg))))))
 
@@ -3728,6 +3738,9 @@ gdb-memory-header
                  'local-map (gdb-make-header-line-mouse-map
                              'mouse-1
                              #'gdb-memory-set-address-event))
+     (if gdb--memory-display-warning
+         (propertize " !" 'face '(:inherit error :weight bold))
+       "")
      " ["
      (propertize "-"
                  'face font-lock-warning-face
-- 
2.24.1

