diff mbox series

[v2,4/4] tests/tcg: add HeapInfo checking to semihosting test

Message ID 20210309141727.12522-5-alex.bennee@linaro.org
State Superseded
Headers show
Series semihosting/next (SYS_HEAPINFO fix) | expand

Commit Message

Alex Bennée March 9, 2021, 2:17 p.m. UTC
Query the SYS_HEAPINFO semicall and do some basic verification of the
information via libc calls.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

---
 .../multiarch/arm-compat-semi/semihosting.c   | 35 ++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

-- 
2.20.1

Comments

Xingtao Yao (Fujitsu)" via March 9, 2021, 5:08 p.m. UTC | #1
Alex Bennée <alex.bennee@linaro.org> writes:

> +    asprintf(&heap_info, "heap: %p -> %p\n", info.heap_base, info.heap_limit);

> +    __semi_call(SYS_WRITE0, (uintptr_t) heap_info);

> +    if (info.heap_base != brk) {


That requires qemu to know a lot about the run-time environment, which
it rarely does in my experience of embedded systems...

All I've been able to check is whether the heap base is not below the
heap limit and the stack base is not above the stack limit. Not exactly
great validation, but at least it caught the case where I set the stack
limit to the top of the stack?

	if (block.heap_base != NULL && block.heap_limit != NULL) {
		/* Error if heap base is above limit */
		if ((uintptr_t) block.heap_base >= (uintptr_t) block.heap_limit) {
			printf("heap base %p >= heap_limit %p\n",
			       block.heap_base, block.heap_limit);
			exit(1);
		}
	}
	if (block.stack_base != NULL && block.stack_limit != NULL) {
		/* Error if stack base is below limit */
		if ((uintptr_t) block.stack_base < (uintptr_t) block.stack_limit) {
			printf("stack base %p < stack_limit %p\n",
			       block.stack_base, block.stack_limit);
			exit(2);
		}
	}
	exit(0);


-- 
-keith
diff mbox series

Patch

diff --git a/tests/tcg/multiarch/arm-compat-semi/semihosting.c b/tests/tcg/multiarch/arm-compat-semi/semihosting.c
index b3fd16cd12..5fa3c0a82d 100644
--- a/tests/tcg/multiarch/arm-compat-semi/semihosting.c
+++ b/tests/tcg/multiarch/arm-compat-semi/semihosting.c
@@ -8,9 +8,16 @@ 
  */
 
 #define SYS_WRITE0      0x04
+#define SYS_HEAPINFO    0x16
 #define SYS_REPORTEXC   0x18
 
+#define _GNU_SOURCE  /* asprintf is a GNU extension */
+
 #include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
 #include "semicall.h"
 
 int main(int argc, char *argv[argc])
@@ -21,8 +28,34 @@  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;
+    char *heap_info, *stack_info;
+    void *brk = sbrk(0);
+
+    __semi_call(SYS_WRITE0, (uintptr_t) "Checking HeapInfo\n");
+
+    memset(&info, 0, sizeof(info));
+    __semi_call(SYS_HEAPINFO, (uintptr_t) &ptr_to_info);
+
+    asprintf(&heap_info, "heap: %p -> %p\n", info.heap_base, info.heap_limit);
+    __semi_call(SYS_WRITE0, (uintptr_t) heap_info);
+    if (info.heap_base != brk) {
+        sprintf(heap_info, "heap mismatch: %p\n", brk);
+        __semi_call(SYS_WRITE0, (uintptr_t) heap_info);
+        return -1;
+    }
+
+    asprintf(&stack_info, "stack: %p -> %p\n", info.stack_base, info.stack_limit);
+    __semi_call(SYS_WRITE0, (uintptr_t) stack_info);
+    free(heap_info);
+    free(stack_info);
 
-    __semi_call(SYS_WRITE0, (uintptr_t) "Hello World");
     __semi_call(SYS_REPORTEXC, exit_code);
     /* if we get here we failed */
     return -1;