qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

semihosting.c (2390B)


      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 }