#include "qemu/guest-random.h"
#include "qemu/units.h"
#include "qemu/selfmap.h"
+#include "qemu/lockable.h"
#include "qapi/error.h"
+#include "qemu/error-report.h"
#include "target_signal.h"
+#include "accel/tcg/debuginfo.h"
#ifdef _ARCH_PPC64
#undef ARCH_DLINFO
#ifdef TARGET_I386
-#define ELF_PLATFORM get_elf_platform()
-
-static const char *get_elf_platform(void)
-{
- static char elf_platform[] = "i386";
- int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL);
- if (family > 6)
- family = 6;
- if (family >= 3)
- elf_platform[1] = '0' + family;
- return elf_platform;
-}
-
#define ELF_HWCAP get_elf_hwcap()
static uint32_t get_elf_hwcap(void)
#define ELF_CLASS ELFCLASS64
#define ELF_ARCH EM_X86_64
+#define ELF_PLATFORM "x86_64"
+
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
{
regs->rax = 0;
(*regs)[26] = tswapreg(env->segs[R_GS].selector & 0xffff);
}
+#if ULONG_MAX > UINT32_MAX
+#define INIT_GUEST_COMMPAGE
+static bool init_guest_commpage(void)
+{
+ /*
+ * The vsyscall page is at a high negative address aka kernel space,
+ * which means that we cannot actually allocate it with target_mmap.
+ * We still should be able to use page_set_flags, unless the user
+ * has specified -R reserved_va, which would trigger an assert().
+ */
+ if (reserved_va != 0 &&
+ TARGET_VSYSCALL_PAGE + TARGET_PAGE_SIZE - 1 > reserved_va) {
+ error_report("Cannot allocate vsyscall page");
+ exit(EXIT_FAILURE);
+ }
+ page_set_flags(TARGET_VSYSCALL_PAGE,
+ TARGET_VSYSCALL_PAGE | ~TARGET_PAGE_MASK,
+ PAGE_EXEC | PAGE_VALID);
+ return true;
+}
+#endif
#else
#define ELF_START_MMAP 0x80000000
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_386
+#define ELF_PLATFORM get_elf_platform()
+#define EXSTACK_DEFAULT true
+
+static const char *get_elf_platform(void)
+{
+ static char elf_platform[] = "i386";
+ int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL);
+ if (family > 6) {
+ family = 6;
+ }
+ if (family >= 3) {
+ elf_platform[1] = '0' + family;
+ }
+ return elf_platform;
+}
+
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)
{
#define ELF_ARCH EM_ARM
#define ELF_CLASS ELFCLASS32
+#define EXSTACK_DEFAULT true
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)
static bool init_guest_commpage(void)
{
- void *want = g2h_untagged(HI_COMMPAGE & -qemu_host_page_size);
+ abi_ptr commpage = HI_COMMPAGE & -qemu_host_page_size;
+ void *want = g2h_untagged(commpage);
void *addr = mmap(want, qemu_host_page_size, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
perror("Protecting guest commpage");
exit(EXIT_FAILURE);
}
+
+ page_set_flags(commpage, commpage | ~qemu_host_page_mask,
+ PAGE_READ | PAGE_EXEC | PAGE_VALID);
return true;
}
ARM_HWCAP2_A64_RNG = 1 << 16,
ARM_HWCAP2_A64_BTI = 1 << 17,
ARM_HWCAP2_A64_MTE = 1 << 18,
+ ARM_HWCAP2_A64_ECV = 1 << 19,
+ ARM_HWCAP2_A64_AFP = 1 << 20,
+ ARM_HWCAP2_A64_RPRES = 1 << 21,
+ ARM_HWCAP2_A64_MTE3 = 1 << 22,
+ ARM_HWCAP2_A64_SME = 1 << 23,
+ ARM_HWCAP2_A64_SME_I16I64 = 1 << 24,
+ ARM_HWCAP2_A64_SME_F64F64 = 1 << 25,
+ ARM_HWCAP2_A64_SME_I8I32 = 1 << 26,
+ ARM_HWCAP2_A64_SME_F16F32 = 1 << 27,
+ ARM_HWCAP2_A64_SME_B16F32 = 1 << 28,
+ ARM_HWCAP2_A64_SME_F32F32 = 1 << 29,
+ ARM_HWCAP2_A64_SME_FA64 = 1 << 30,
};
#define ELF_HWCAP get_elf_hwcap()
GET_FEATURE_ID(aa64_rndr, ARM_HWCAP2_A64_RNG);
GET_FEATURE_ID(aa64_bti, ARM_HWCAP2_A64_BTI);
GET_FEATURE_ID(aa64_mte, ARM_HWCAP2_A64_MTE);
+ GET_FEATURE_ID(aa64_sme, (ARM_HWCAP2_A64_SME |
+ ARM_HWCAP2_A64_SME_F32F32 |
+ ARM_HWCAP2_A64_SME_B16F32 |
+ ARM_HWCAP2_A64_SME_F16F32 |
+ ARM_HWCAP2_A64_SME_I8I32));
+ GET_FEATURE_ID(aa64_sme_f64f64, ARM_HWCAP2_A64_SME_F64F64);
+ GET_FEATURE_ID(aa64_sme_i16i64, ARM_HWCAP2_A64_SME_I16I64);
+ GET_FEATURE_ID(aa64_sme_fa64, ARM_HWCAP2_A64_SME_FA64);
return hwcaps;
}
#else
#define ELF_CLASS ELFCLASS32
+#define EXSTACK_DEFAULT true
#endif
QEMU_PPC_FEATURE2_DARN = 0x00200000, /* darn random number insn */
QEMU_PPC_FEATURE2_SCV = 0x00100000, /* scv syscall */
QEMU_PPC_FEATURE2_HTM_NO_SUSPEND = 0x00080000, /* TM w/o suspended state */
+ QEMU_PPC_FEATURE2_ARCH_3_1 = 0x00040000, /* ISA 3.1 */
+ QEMU_PPC_FEATURE2_MMA = 0x00020000, /* Matrix-Multiply Assist */
};
#define ELF_HWCAP get_elf_hwcap()
QEMU_PPC_FEATURE2_VEC_CRYPTO);
GET_FEATURE2(PPC2_ISA300, QEMU_PPC_FEATURE2_ARCH_3_00 |
QEMU_PPC_FEATURE2_DARN | QEMU_PPC_FEATURE2_HAS_IEEE128);
+ GET_FEATURE2(PPC2_ISA310, QEMU_PPC_FEATURE2_ARCH_3_1 |
+ QEMU_PPC_FEATURE2_MMA);
#undef GET_FEATURE
#undef GET_FEATURE2
(*regs)[36] = tswapreg(env->lr);
(*regs)[37] = tswapreg(cpu_read_xer(env));
- for (i = 0; i < ARRAY_SIZE(env->crf); i++) {
- ccr |= env->crf[i] << (32 - ((i + 1) * 4));
- }
+ ccr = ppc_get_cr(env);
(*regs)[38] = tswapreg(ccr);
}
#endif
+#ifdef TARGET_LOONGARCH64
+
+#define ELF_START_MMAP 0x80000000
+
+#define ELF_CLASS ELFCLASS64
+#define ELF_ARCH EM_LOONGARCH
+#define EXSTACK_DEFAULT true
+
+#define elf_check_arch(x) ((x) == EM_LOONGARCH)
+
+static inline void init_thread(struct target_pt_regs *regs,
+ struct image_info *infop)
+{
+ /*Set crmd PG,DA = 1,0 */
+ regs->csr.crmd = 2 << 3;
+ regs->csr.era = infop->entry;
+ regs->regs[3] = infop->start_stack;
+}
+
+/* See linux kernel: arch/loongarch/include/asm/elf.h */
+#define ELF_NREG 45
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
+
+enum {
+ TARGET_EF_R0 = 0,
+ TARGET_EF_CSR_ERA = TARGET_EF_R0 + 33,
+ TARGET_EF_CSR_BADV = TARGET_EF_R0 + 34,
+};
+
+static void elf_core_copy_regs(target_elf_gregset_t *regs,
+ const CPULoongArchState *env)
+{
+ int i;
+
+ (*regs)[TARGET_EF_R0] = 0;
+
+ for (i = 1; i < ARRAY_SIZE(env->gpr); i++) {
+ (*regs)[TARGET_EF_R0 + i] = tswapreg(env->gpr[i]);
+ }
+
+ (*regs)[TARGET_EF_CSR_ERA] = tswapreg(env->pc);
+ (*regs)[TARGET_EF_CSR_BADV] = tswapreg(env->CSR_BADV);
+}
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE 4096
+
+#define ELF_HWCAP get_elf_hwcap()
+
+/* See arch/loongarch/include/uapi/asm/hwcap.h */
+enum {
+ HWCAP_LOONGARCH_CPUCFG = (1 << 0),
+ HWCAP_LOONGARCH_LAM = (1 << 1),
+ HWCAP_LOONGARCH_UAL = (1 << 2),
+ HWCAP_LOONGARCH_FPU = (1 << 3),
+ HWCAP_LOONGARCH_LSX = (1 << 4),
+ HWCAP_LOONGARCH_LASX = (1 << 5),
+ HWCAP_LOONGARCH_CRC32 = (1 << 6),
+ HWCAP_LOONGARCH_COMPLEX = (1 << 7),
+ HWCAP_LOONGARCH_CRYPTO = (1 << 8),
+ HWCAP_LOONGARCH_LVZ = (1 << 9),
+ HWCAP_LOONGARCH_LBT_X86 = (1 << 10),
+ HWCAP_LOONGARCH_LBT_ARM = (1 << 11),
+ HWCAP_LOONGARCH_LBT_MIPS = (1 << 12),
+};
+
+static uint32_t get_elf_hwcap(void)
+{
+ LoongArchCPU *cpu = LOONGARCH_CPU(thread_cpu);
+ uint32_t hwcaps = 0;
+
+ hwcaps |= HWCAP_LOONGARCH_CRC32;
+
+ if (FIELD_EX32(cpu->env.cpucfg[1], CPUCFG1, UAL)) {
+ hwcaps |= HWCAP_LOONGARCH_UAL;
+ }
+
+ if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, FP)) {
+ hwcaps |= HWCAP_LOONGARCH_FPU;
+ }
+
+ if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LAM)) {
+ hwcaps |= HWCAP_LOONGARCH_LAM;
+ }
+
+ return hwcaps;
+}
+
+#define ELF_PLATFORM "loongarch"
+
+#endif /* TARGET_LOONGARCH64 */
+
#ifdef TARGET_MIPS
#define ELF_START_MMAP 0x80000000
#define ELF_CLASS ELFCLASS32
#endif
#define ELF_ARCH EM_MIPS
+#define EXSTACK_DEFAULT true
#ifdef TARGET_ABI_MIPSN32
#define elf_check_abi(x) ((x) & EF_MIPS_ABI2)
#define elf_check_abi(x) (!((x) & EF_MIPS_ABI2))
#endif
+#define ELF_BASE_PLATFORM get_elf_base_platform()
+
+#define MATCH_PLATFORM_INSN(_flags, _base_platform) \
+ do { if ((cpu->env.insn_flags & (_flags)) == _flags) \
+ { return _base_platform; } } while (0)
+
+static const char *get_elf_base_platform(void)
+{
+ MIPSCPU *cpu = MIPS_CPU(thread_cpu);
+
+ /* 64 bit ISAs goes first */
+ MATCH_PLATFORM_INSN(CPU_MIPS64R6, "mips64r6");
+ MATCH_PLATFORM_INSN(CPU_MIPS64R5, "mips64r5");
+ MATCH_PLATFORM_INSN(CPU_MIPS64R2, "mips64r2");
+ MATCH_PLATFORM_INSN(CPU_MIPS64R1, "mips64");
+ MATCH_PLATFORM_INSN(CPU_MIPS5, "mips5");
+ MATCH_PLATFORM_INSN(CPU_MIPS4, "mips4");
+ MATCH_PLATFORM_INSN(CPU_MIPS3, "mips3");
+
+ /* 32 bit ISAs */
+ MATCH_PLATFORM_INSN(CPU_MIPS32R6, "mips32r6");
+ MATCH_PLATFORM_INSN(CPU_MIPS32R5, "mips32r5");
+ MATCH_PLATFORM_INSN(CPU_MIPS32R2, "mips32r2");
+ MATCH_PLATFORM_INSN(CPU_MIPS32R1, "mips32");
+ MATCH_PLATFORM_INSN(CPU_MIPS2, "mips2");
+
+ /* Fallback */
+ return "mips";
+}
+#undef MATCH_PLATFORM_INSN
+
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)
{
exit(EXIT_FAILURE);
}
- page_set_flags(LO_COMMPAGE, LO_COMMPAGE + TARGET_PAGE_SIZE,
+ page_set_flags(LO_COMMPAGE, LO_COMMPAGE | ~TARGET_PAGE_MASK,
PAGE_READ | PAGE_EXEC | PAGE_VALID);
return true;
}
regs->gr[31] = infop->entry;
}
+#define LO_COMMPAGE 0
+
+static bool init_guest_commpage(void)
+{
+ void *want = g2h_untagged(LO_COMMPAGE);
+ void *addr = mmap(want, qemu_host_page_size, PROT_NONE,
+ MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
+
+ if (addr == MAP_FAILED) {
+ perror("Allocating guest commpage");
+ exit(EXIT_FAILURE);
+ }
+ if (addr != want) {
+ return false;
+ }
+
+ /*
+ * On Linux, page zero is normally marked execute only + gateway.
+ * Normal read or write is supposed to fail (thus PROT_NONE above),
+ * but specific offsets have kernel code mapped to raise permissions
+ * and implement syscalls. Here, simply mark the page executable.
+ * Special case the entry points during translation (see do_page_zero).
+ */
+ page_set_flags(LO_COMMPAGE, LO_COMMPAGE | ~TARGET_PAGE_MASK,
+ PAGE_EXEC | PAGE_VALID);
+ return true;
+}
+
#endif /* TARGET_HPPA */
#ifdef TARGET_XTENSA
regs->windowstart = 1;
regs->areg[1] = infop->start_stack;
regs->pc = infop->entry;
+ if (info_is_fdpic(infop)) {
+ regs->areg[4] = infop->loadmap_addr;
+ regs->areg[5] = infop->interpreter_loadmap_addr;
+ if (infop->interpreter_loadmap_addr) {
+ regs->areg[6] = infop->interpreter_pt_dynamic_addr;
+ } else {
+ regs->areg[6] = infop->pt_dynamic_addr;
+ }
+ }
}
/* See linux kernel: arch/xtensa/include/asm/elf.h. */
#endif /* TARGET_HEXAGON */
+#ifndef ELF_BASE_PLATFORM
+#define ELF_BASE_PLATFORM (NULL)
+#endif
+
#ifndef ELF_PLATFORM
#define ELF_PLATFORM (NULL)
#endif
#define bswaptls(ptr) bswap32s(ptr)
#endif
+#ifndef EXSTACK_DEFAULT
+#define EXSTACK_DEFAULT false
+#endif
+
#include "elf.h"
/* We must delay the following stanzas until after "elf.h". */
struct image_info *info)
{
abi_ulong size, error, guard;
+ int prot;
size = guest_stack_size;
if (size < STACK_LOWER_LIMIT) {
size = STACK_LOWER_LIMIT;
}
- guard = TARGET_PAGE_SIZE;
- if (guard < qemu_real_host_page_size()) {
- guard = qemu_real_host_page_size();
+
+ if (STACK_GROWS_DOWN) {
+ guard = TARGET_PAGE_SIZE;
+ if (guard < qemu_real_host_page_size()) {
+ guard = qemu_real_host_page_size();
+ }
+ } else {
+ /* no guard page for hppa target where stack grows upwards. */
+ guard = 0;
}
- error = target_mmap(0, size + guard, PROT_READ | PROT_WRITE,
+ prot = PROT_READ | PROT_WRITE;
+ if (info->exec_stack) {
+ prot |= PROT_EXEC;
+ }
+ error = target_mmap(0, size + guard, prot,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (error == -1) {
perror("mmap stack");
info->stack_limit = error + guard;
return info->stack_limit + size - sizeof(void *);
} else {
- target_mprotect(error + size, guard, PROT_NONE);
info->stack_limit = error + size;
return error;
}
/* Ensure that the bss page(s) are valid */
if ((page_get_flags(last_bss-1) & prot) != prot) {
- page_set_flags(elf_bss & TARGET_PAGE_MASK, last_bss, prot | PAGE_VALID);
+ page_set_flags(elf_bss & TARGET_PAGE_MASK, last_bss - 1,
+ prot | PAGE_VALID);
}
if (host_start < host_map_start) {
}
}
-#ifdef TARGET_ARM
+#if defined(TARGET_ARM)
static int elf_is_fdpic(struct elfhdr *exec)
{
return exec->e_ident[EI_OSABI] == ELFOSABI_ARM_FDPIC;
}
+#elif defined(TARGET_XTENSA)
+static int elf_is_fdpic(struct elfhdr *exec)
+{
+ return exec->e_ident[EI_OSABI] == ELFOSABI_XTENSA_FDPIC;
+}
#else
/* Default implementation, always false. */
static int elf_is_fdpic(struct elfhdr *exec)
int i;
abi_ulong u_rand_bytes;
uint8_t k_rand_bytes[16];
- abi_ulong u_platform;
- const char *k_platform;
+ abi_ulong u_platform, u_base_platform;
+ const char *k_platform, *k_base_platform;
const int n = sizeof(elf_addr_t);
sp = p;
}
}
+ u_base_platform = 0;
+ k_base_platform = ELF_BASE_PLATFORM;
+ if (k_base_platform) {
+ size_t len = strlen(k_base_platform) + 1;
+ if (STACK_GROWS_DOWN) {
+ sp -= (len + n - 1) & ~(n - 1);
+ u_base_platform = sp;
+ /* FIXME - check return value of memcpy_to_target() for failure */
+ memcpy_to_target(sp, k_base_platform, len);
+ } else {
+ memcpy_to_target(sp, k_base_platform, len);
+ u_base_platform = sp;
+ sp += len + 1;
+ }
+ }
+
u_platform = 0;
k_platform = ELF_PLATFORM;
if (k_platform) {
}
size = (DLINFO_ITEMS + 1) * 2;
+ if (k_base_platform)
+ size += 2;
if (k_platform)
size += 2;
#ifdef DLINFO_ARCH_ITEMS
NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);
#endif
+ if (u_base_platform) {
+ NEW_AUX_ENT(AT_BASE_PLATFORM, u_base_platform);
+ }
if (u_platform) {
NEW_AUX_ENT(AT_PLATFORM, u_platform);
}
}
#if defined(HI_COMMPAGE)
-#define LO_COMMPAGE 0
+#define LO_COMMPAGE -1
#elif defined(LO_COMMPAGE)
#define HI_COMMPAGE 0
#else
#define HI_COMMPAGE 0
-#define LO_COMMPAGE 0
+#define LO_COMMPAGE -1
+#ifndef INIT_GUEST_COMMPAGE
#define init_guest_commpage() true
#endif
+#endif
static void pgb_fail_in_use(const char *image_name)
{
if ((guest_hiaddr - guest_base) > ~(uintptr_t)0) {
error_report("%s: requires more virtual address space "
"than the host can provide (0x%" PRIx64 ")",
- image_name, (uint64_t)guest_hiaddr - guest_base);
+ image_name, (uint64_t)guest_hiaddr + 1 - guest_base);
exit(EXIT_FAILURE);
}
#endif
/* Reserve the address space for the binary, or reserved_va. */
test = g2h_untagged(guest_loaddr);
- addr = mmap(test, guest_hiaddr - guest_loaddr, PROT_NONE, flags, -1, 0);
+ addr = mmap(test, guest_hiaddr - guest_loaddr + 1, PROT_NONE, flags, -1, 0);
if (test != addr) {
pgb_fail_in_use(image_name);
}
qemu_log_mask(CPU_LOG_PAGE,
- "%s: base @ %p for " TARGET_ABI_FMT_ld " bytes\n",
- __func__, addr, guest_hiaddr - guest_loaddr);
+ "%s: base @ %p for %" PRIu64 " bytes\n",
+ __func__, addr, (uint64_t)guest_hiaddr - guest_loaddr + 1);
}
/**
if (hiaddr != orig_hiaddr) {
error_report("%s: requires virtual address space that the "
"host cannot provide (0x%" PRIx64 ")",
- image_name, (uint64_t)orig_hiaddr);
+ image_name, (uint64_t)orig_hiaddr + 1);
exit(EXIT_FAILURE);
}
* arithmetic wraps around.
*/
if (sizeof(uintptr_t) == 8 || loaddr >= 0x80000000u) {
- hiaddr = (uintptr_t) 4 << 30;
+ hiaddr = UINT32_MAX;
} else {
offset = -(HI_COMMPAGE & -align);
}
- } else if (LO_COMMPAGE != 0) {
+ } else if (LO_COMMPAGE != -1) {
loaddr = MIN(loaddr, LO_COMMPAGE & -align);
}
- addr = pgb_find_hole(loaddr, hiaddr - loaddr, align, offset);
+ addr = pgb_find_hole(loaddr, hiaddr - loaddr + 1, align, offset);
if (addr == -1) {
/*
* If HI_COMMPAGE, there *might* be a non-consecutive allocation
/* Reserve the memory on the host. */
assert(guest_base != 0);
test = g2h_untagged(0);
- addr = mmap(test, reserved_va, PROT_NONE, flags, -1, 0);
+ addr = mmap(test, reserved_va + 1, PROT_NONE, flags, -1, 0);
if (addr == MAP_FAILED || addr != test) {
error_report("Unable to reserve 0x%lx bytes of virtual address "
"space at %p (%s) for use as guest address space (check your "
"virtual memory ulimit setting, min_mmap_addr or reserve less "
- "using -R option)", reserved_va, test, strerror(errno));
+ "using -R option)", reserved_va + 1, test, strerror(errno));
exit(EXIT_FAILURE);
}
qemu_log_mask(CPU_LOG_PAGE, "%s: base @ %p for %lu bytes\n",
- __func__, addr, reserved_va);
+ __func__, addr, reserved_va + 1);
}
void probe_guest_base(const char *image_name, abi_ulong guest_loaddr,
*/
loaddr = -1, hiaddr = 0;
info->alignment = 0;
+ info->exec_stack = EXSTACK_DEFAULT;
for (i = 0; i < ehdr->e_phnum; ++i) {
struct elf_phdr *eppnt = phdr + i;
if (eppnt->p_type == PT_LOAD) {
if (a < loaddr) {
loaddr = a;
}
- a = eppnt->p_vaddr + eppnt->p_memsz;
+ a = eppnt->p_vaddr + eppnt->p_memsz - 1;
if (a > hiaddr) {
hiaddr = a;
}
if (!parse_elf_properties(image_fd, info, eppnt, bprm_buf, &err)) {
goto exit_errmsg;
}
+ } else if (eppnt->p_type == PT_GNU_STACK) {
+ info->exec_stack = eppnt->p_flags & PF_X;
}
}
* In both cases, we will overwrite pages in this range with mappings
* from the executable.
*/
- load_addr = target_mmap(loaddr, hiaddr - loaddr, PROT_NONE,
+ load_addr = target_mmap(loaddr, (size_t)hiaddr - loaddr + 1, PROT_NONE,
MAP_PRIVATE | MAP_ANON | MAP_NORESERVE |
(ehdr->e_type == ET_EXEC ? MAP_FIXED : 0),
-1, 0);
load_symbols(ehdr, image_fd, load_bias);
}
+ debuginfo_report_elf(image_name, image_fd, load_bias);
+
mmap_unlock();
close(image_fd);
static int symfind(const void *s0, const void *s1)
{
- target_ulong addr = *(target_ulong *)s0;
struct elf_sym *sym = (struct elf_sym *)s1;
+ __typeof(sym->st_value) addr = *(uint64_t *)s0;
int result = 0;
+
if (addr < sym->st_value) {
result = -1;
} else if (addr >= sym->st_value + sym->st_size) {
return result;
}
-static const char *lookup_symbolxx(struct syminfo *s, target_ulong orig_addr)
+static const char *lookup_symbolxx(struct syminfo *s, uint64_t orig_addr)
{
#if ELF_CLASS == ELFCLASS32
struct elf_sym *syms = s->disas_symtab.elf32;
info->notes_size += note_size(&info->notes[i]);
/* read and fill status of all threads */
- cpu_list_lock();
- CPU_FOREACH(cpu) {
- if (cpu == thread_cpu) {
- continue;
+ WITH_QEMU_LOCK_GUARD(&qemu_cpu_list_lock) {
+ CPU_FOREACH(cpu) {
+ if (cpu == thread_cpu) {
+ continue;
+ }
+ fill_thread_info(info, cpu->env_ptr);
}
- fill_thread_info(info, cpu->env_ptr);
}
- cpu_list_unlock();
return (0);
}