qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug 1918302] Re: qemu-system-arm segfaults while servicing SYS_HEAPINFO


From: Simon Tatham
Subject: [Bug 1918302] Re: qemu-system-arm segfaults while servicing SYS_HEAPINFO
Date: Thu, 25 Mar 2021 14:48:12 -0000

Firstly, I agree with Peter's comment – this test image is exactly an
example of what he describes, in that it carefully doesn't make any use
of the value of SP it started up with (doesn't push or pop anything,
doesn't make sp-relative offsets). Very near the start, it invokes
SYS_HEAPINFO to decide what to set SP to.

I retried the image with qemu master, running qemu-system-arm itself
inside gdb to help figure out what was going on. What seems to happen,
in detail, is:

1. common_semi_find_region_base falls through to the fallback "return 0;" at 
the end of the function, because the iteration found no subregion at all with 
subregion->ram set to true. In fact the five regions it iterated through were:
addr = 0x4000a000, size = 0x1000, ram = 0x0, readonly = 0x0
addr = 0x40009000, size = 0x1000, ram = 0x0, readonly = 0x0
addr = 0x40008000, size = 0x1000, ram = 0x0, readonly = 0x0
addr = 0xf0000000, size = 0x10000000, ram = 0x0, readonly = 0x0
addr = 0x40000000, size = 0x20000000, ram = 0x0, readonly = 0x0

2. So common_semi_rambase returns zero to the TARGET_SYS_HEAPINFO
handler in do_common_semihosting().

3. current_machine->ram_size is set to 0x8000000, and with rambase=0, the 
SYS_HEAPINFO handler ends up computing the following values in retvals[]:
retvals[0] (heap base)   = 0x4000000
retvals[1] (heap limit)  = 0x8000000
retvals[2] (stack base)  = 0x8000000
retvals[3] (stack limit) = 0x0

4. The setup code faithfully initializes sp to 0x8000000, and then crashes on 
the first PUSH instruction that the program executes:
0x00001950:  b5b0       push     {r4, r5, r7, lr}

5. That's how we end up in the tight loop at 0xce4 as mentioned above:
in this test image, that's the address of the dummy handler for (among
other things) memory faults.

The emulated machine definitely has some RAM at 0x20000000, because
that's where the SYS_HEAPINFO output block was, and the semihosting code
was happy to write to there. So I think SYS_HEAPINFO surely _ought_ to
have returned some heap and stack values in that region. And the reason
it didn't was that for some reason it didn't find any RAM regions at all
in the iteration through get_system_memory()->subregions.

So I think there are still two problems. Using the input value of SP to
decide which RAM region to return is surely the wrong policy, because SP
is literally uninitialised at this point. But also, finding any RAM
regions *at all* seems to be failing in this case.

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1918302

Title:
  qemu-system-arm segfaults while servicing SYS_HEAPINFO

Status in QEMU:
  Fix Committed

Bug description:
  I compiled QEMU version 5.2.0 from source on Ubuntu 18.04, and tried
  to use it to run the attached bare-metal Arm hello-world image, using
  the command line

  qemu-system-arm -M microbit -semihosting -nographic -device
  loader,file=hello.hex

  The result was that qemu-system-arm itself died of a segfault.
  Compiling it for debugging, the location of the segfault was in
  target/arm/arm-semi.c, in the case handler for the semihosting call
  TARGET_SYS_HEAPINFO, on line 1020 which assigns to 'rambase':

              const struct arm_boot_info *info = env->boot_info;
              target_ulong rambase = info->loader_start;

  and the problem seems to be that 'info', aka env->boot_info, is NULL
  in this context.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1918302/+subscriptions



reply via email to

[Prev in Thread] Current Thread [Next in Thread]