qemu/tests/tcg/multiarch/arm-compat-semi/semihosting.c
<<
>>
Prefs
   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
  20int 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