1 /* 2 * linux-user semihosting checks 3 * 4 * Copyright (c) 2019 5 * Written by Alex Bennée <alex.bennee@linaro.org> 6 * 7 * SPDX-License-Identifier: GPL-3.0-or-later 8 */ 9 10 #define SYS_WRITE0 0x04 11 #define SYS_HEAPINFO 0x16 12 #define SYS_REPORTEXC 0x18 13 14 #include <stdint.h> 15 #include <stdlib.h> 16 #include <stdio.h> 17 #include <string.h> 18 #include "semicall.h" 19 20 int main(int argc, char *argv[argc]) 21 { 22 #if UINTPTR_MAX == UINT32_MAX 23 uintptr_t exit_code = 0x20026; 24 #else 25 uintptr_t exit_block[2] = {0x20026, 0}; 26 uintptr_t exit_code = (uintptr_t) &exit_block; 27 #endif 28 struct { 29 void *heap_base; 30 void *heap_limit; 31 void *stack_base; 32 void *stack_limit; 33 } info; 34 void *ptr_to_info = (void *) &info; 35 36 __semi_call(SYS_WRITE0, (uintptr_t) "Checking HeapInfo\n"); 37 38 memset(&info, 0, sizeof(info)); 39 __semi_call(SYS_HEAPINFO, (uintptr_t) &ptr_to_info); 40 41 if (info.heap_base == NULL || info.heap_limit == NULL) { 42 printf("null heap: %p -> %p\n", info.heap_base, info.heap_limit); 43 exit(1); 44 } 45 46 /* Error if heap base is above limit */ 47 if ((uintptr_t) info.heap_base >= (uintptr_t) info.heap_limit) { 48 printf("heap base %p >= heap_limit %p\n", 49 info.heap_base, info.heap_limit); 50 exit(2); 51 } 52 53 if (info.stack_base == NULL || info.stack_limit) { 54 printf("null stack: %p -> %p\n", info.stack_base, info.stack_limit); 55 exit(3); 56 } 57 58 /* check our local variables are indeed inside the reported stack */ 59 if (ptr_to_info > info.stack_base) { 60 printf("info appears to be above stack: %p > %p\n", ptr_to_info, 61 info.stack_base); 62 exit(4); 63 } else if (ptr_to_info < info.stack_limit) { 64 printf("info appears to be outside stack: %p < %p\n", ptr_to_info, 65 info.stack_limit); 66 exit(5); 67 } 68 69 if (ptr_to_info > info.heap_base && ptr_to_info < info.heap_limit) { 70 printf("info appears to be inside the heap: %p in %p:%p\n", 71 ptr_to_info, info.heap_base, info.heap_limit); 72 exit(6); 73 } 74 75 printf("heap: %p -> %p\n", info.heap_base, info.heap_limit); 76 printf("stack: %p -> %p\n", info.stack_base, info.stack_limit); 77 78 __semi_call(SYS_WRITE0, (uintptr_t) "Passed HeapInfo checks"); 79 __semi_call(SYS_REPORTEXC, exit_code); 80 /* if we get here we failed */ 81 return -1; 82 } 83