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

Alex Bennée posted 4 patches 4 years, 8 months ago
[PATCH v2 4/4] tests/tcg: add HeapInfo checking to semihosting test
Posted by Alex Bennée 4 years, 8 months ago
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(-)

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;
-- 
2.20.1


Re: [PATCH v2 4/4] tests/tcg: add HeapInfo checking to semihosting test
Posted by Keith Packard via 4 years, 8 months ago
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