semihosting: Support SYS_HEAPINFO when env->boot_info is not set
env->boot_info is only set in some ARM startup paths, so we cannot rely on it to support the SYS_HEAPINFO semihosting function. When not available, fallback to finding a RAM memory region containing the current stack and use the base of that. Signed-off-by: Keith Packard <keithp@keithp.com> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20210107170717.2098982-5-keithp@keithp.com> Message-Id: <20210108224256.2321-16-alex.bennee@linaro.org>
This commit is contained in:
parent
3c37cfe0b1
commit
095f8c0293
@ -137,6 +137,36 @@ typedef struct GuestFD {
|
||||
|
||||
static GArray *guestfd_array;
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
#include "exec/address-spaces.h"
|
||||
/*
|
||||
* Find the base of a RAM region containing the specified address
|
||||
*/
|
||||
static inline hwaddr
|
||||
common_semi_find_region_base(hwaddr addr)
|
||||
{
|
||||
MemoryRegion *subregion;
|
||||
|
||||
/*
|
||||
* Find the chunk of R/W memory containing the address. This is
|
||||
* used for the SYS_HEAPINFO semihosting call, which should
|
||||
* probably be using information from the loaded application.
|
||||
*/
|
||||
QTAILQ_FOREACH(subregion, &get_system_memory()->subregions,
|
||||
subregions_link) {
|
||||
if (subregion->ram && !subregion->readonly) {
|
||||
Int128 top128 = int128_add(int128_make64(subregion->addr),
|
||||
subregion->size);
|
||||
Int128 addr128 = int128_make64(addr);
|
||||
if (subregion->addr <= addr && int128_lt(addr128, top128)) {
|
||||
return subregion->addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_ARM
|
||||
static inline target_ulong
|
||||
common_semi_arg(CPUState *cs, int argno)
|
||||
@ -175,7 +205,18 @@ common_semi_rambase(CPUState *cs)
|
||||
{
|
||||
CPUArchState *env = cs->env_ptr;
|
||||
const struct arm_boot_info *info = env->boot_info;
|
||||
return info->loader_start;
|
||||
target_ulong sp;
|
||||
|
||||
if (info) {
|
||||
return info->loader_start;
|
||||
}
|
||||
|
||||
if (is_a64(env)) {
|
||||
sp = env->xregs[31];
|
||||
} else {
|
||||
sp = env->regs[13];
|
||||
}
|
||||
return common_semi_find_region_base(sp);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user