On 23/03/2021 17.52, Alex Bennée wrote:
Query the SYS_HEAPINFO semicall and do some basic verification of the
information via libc calls.

Signed-off-by: Alex Bennée <alex.ben...@linaro.org>
Message-Id: <20210320133706.21475-10-alex.ben...@linaro.org>

---
v2
   - expand test as suggested by Richard
---
  .../multiarch/arm-compat-semi/semihosting.c   | 55 ++++++++++++++++++-
  1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/tests/tcg/multiarch/arm-compat-semi/semihosting.c 
b/tests/tcg/multiarch/arm-compat-semi/semihosting.c
index b3fd16cd12..8627eee3cf 100644
--- a/tests/tcg/multiarch/arm-compat-semi/semihosting.c
+++ b/tests/tcg/multiarch/arm-compat-semi/semihosting.c
@@ -8,9 +8,13 @@
   */
#define SYS_WRITE0 0x04
+#define SYS_HEAPINFO    0x16
  #define SYS_REPORTEXC   0x18
#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
  #include "semicall.h"
int main(int argc, char *argv[argc])
@@ -21,8 +25,57 @@ int main(int argc, char *argv[argc])
      uintptr_t exit_block[2] = {0x20026, 0};
      uintptr_t exit_code = (uintptr_t) &exit_block;
  #endif
+    struct {
+        void *heap_base;
+        void *heap_limit;
+        void *stack_base;
+        void *stack_limit;
+    } info;
+    void *ptr_to_info = (void *) &info;
- __semi_call(SYS_WRITE0, (uintptr_t) "Hello World");
+    __semi_call(SYS_WRITE0, (uintptr_t) "Checking HeapInfo\n");
+
+    memset(&info, 0, sizeof(info));
+    __semi_call(SYS_HEAPINFO, (uintptr_t) &ptr_to_info);
+
+    if (info.heap_base == NULL || info.heap_limit == NULL) {
+        printf("null heap: %p -> %p\n", info.heap_base, info.heap_limit);
+        exit(1);
+    }
+
+    /* Error if heap base is above limit */
+    if ((uintptr_t) info.heap_base >= (uintptr_t) info.heap_limit) {
+        printf("heap base %p >= heap_limit %p\n",
+               info.heap_base, info.heap_limit);
+        exit(2);
+    }
+
+    if (info.stack_base == NULL || info.stack_limit) {
+        printf("null stack: %p -> %p\n", info.stack_base, info.stack_limit);
+        exit(3);
+    }
+
+    /* check our local variables are indeed inside the reported stack */
+    if (ptr_to_info > info.stack_base) {
+        printf("info appears to be above stack: %p > %p\n", ptr_to_info,
+               info.stack_base);
+        exit(4);
+    } else if (ptr_to_info < info.stack_limit) {
+        printf("info appears to be outside stack: %p < %p\n", ptr_to_info,
+               info.stack_limit);
+        exit(5);
+    }
+
+    if (ptr_to_info > info.heap_base && ptr_to_info < info.heap_limit) {
+        printf("info appears to be inside the heap: %p in %p:%p\n",
+               ptr_to_info, info.heap_base, info.heap_limit);
+        exit(6);
+    }
+
+    printf("heap: %p -> %p\n", info.heap_base, info.heap_limit);
+    printf("stack: %p -> %p\n", info.stack_base, info.stack_limit);
+
+    __semi_call(SYS_WRITE0, (uintptr_t) "Passed HeapInfo checks");
      __semi_call(SYS_REPORTEXC, exit_code);
      /* if we get here we failed */
      return -1;


Reviewed-by: Thomas Huth <th...@redhat.com>


Reply via email to