linux-user/arm: Create init_main_thread

Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2025-07-28 10:43:26 -10:00
parent 8d4020dd02
commit ea8683d2b3
2 changed files with 43 additions and 49 deletions

View file

@ -480,17 +480,50 @@ void cpu_loop(CPUARMState *env)
}
}
void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
void init_main_thread(CPUState *cs, struct image_info *info)
{
CPUState *cpu = env_cpu(env);
TaskState *ts = get_task_state(cpu);
struct image_info *info = ts->info;
int i;
CPUARMState *env = cpu_env(cs);
abi_ptr stack = info->start_stack;
abi_ptr entry = info->entry;
cpsr_write(env, regs->uregs[16], CPSR_USER | CPSR_EXEC,
CPSRWriteByInstr);
for(i = 0; i < 16; i++) {
env->regs[i] = regs->uregs[i];
cpsr_write(env, ARM_CPU_MODE_USR | (entry & 1 ? CPSR_T : 0),
CPSR_USER | CPSR_EXEC, CPSRWriteByInstr);
env->regs[15] = entry & 0xfffffffe;
env->regs[13] = stack;
/* FIXME - what to for failure of get_user()? */
get_user_ual(env->regs[2], stack + 8); /* envp */
get_user_ual(env->regs[1], stack + 4); /* envp */
/*
* Per the SVR4 ABI, r0 contains a pointer to a function to be
* registered with atexit. A value of 0 means we have no such handler.
*/
env->regs[0] = 0;
/* For uClinux PIC binaries. */
/* XXX: Linux does this only on ARM with no MMU (do we care?) */
env->regs[10] = info->start_data;
/* Support ARM FDPIC. */
if (info_is_fdpic(info)) {
/*
* As described in the ABI document, r7 points to the loadmap info
* prepared by the kernel. If an interpreter is needed, r8 points
* to the interpreter loadmap and r9 points to the interpreter
* PT_DYNAMIC info. If no interpreter is needed, r8 is zero, and
* r9 points to the main program PT_DYNAMIC info.
*/
env->regs[7] = info->loadmap_addr;
if (info->interpreter_loadmap_addr) {
/* Executable is dynamically loaded. */
env->regs[8] = info->interpreter_loadmap_addr;
env->regs[9] = info->interpreter_pt_dynamic_addr;
} else {
env->regs[8] = 0;
env->regs[9] = info->pt_dynamic_addr;
}
}
if (TARGET_BIG_ENDIAN) {

View file

@ -293,46 +293,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
#define ELF_CLASS ELFCLASS32
#define EXSTACK_DEFAULT true
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)
{
abi_long stack = infop->start_stack;
memset(regs, 0, sizeof(*regs));
regs->uregs[16] = ARM_CPU_MODE_USR;
if (infop->entry & 1) {
regs->uregs[16] |= CPSR_T;
}
regs->uregs[15] = infop->entry & 0xfffffffe;
regs->uregs[13] = infop->start_stack;
/* FIXME - what to for failure of get_user()? */
get_user_ual(regs->uregs[2], stack + 8); /* envp */
get_user_ual(regs->uregs[1], stack + 4); /* envp */
/* XXX: it seems that r0 is zeroed after ! */
regs->uregs[0] = 0;
/* For uClinux PIC binaries. */
/* XXX: Linux does this only on ARM with no MMU (do we care ?) */
regs->uregs[10] = infop->start_data;
/* Support ARM FDPIC. */
if (info_is_fdpic(infop)) {
/* As described in the ABI document, r7 points to the loadmap info
* prepared by the kernel. If an interpreter is needed, r8 points
* to the interpreter loadmap and r9 points to the interpreter
* PT_DYNAMIC info. If no interpreter is needed, r8 is zero, and
* r9 points to the main program PT_DYNAMIC info.
*/
regs->uregs[7] = infop->loadmap_addr;
if (infop->interpreter_loadmap_addr) {
/* Executable is dynamically loaded. */
regs->uregs[8] = infop->interpreter_loadmap_addr;
regs->uregs[9] = infop->interpreter_pt_dynamic_addr;
} else {
regs->uregs[8] = 0;
regs->uregs[9] = infop->pt_dynamic_addr;
}
}
}
#define HAVE_INIT_MAIN_THREAD
#define ELF_NREG 18
typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];