[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] linux-user: MIPS set cpu to r6 CPU if binary is
From: |
Laurent Vivier |
Subject: |
Re: [Qemu-devel] [PATCH] linux-user: MIPS set cpu to r6 CPU if binary is R6 |
Date: |
Tue, 9 Jan 2018 00:34:18 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.5.0 |
Peter, Riku,
what do you think of the idea of using the ELF header to select the CPU
to emulate?
Thanks,
Laurent
Le 19/12/2017 à 12:50, YunQiang Su a écrit :
> MIPS r6 is not just simple super set for pre-R6,
> it also drops some instruction and even changes encoding for some.
> But r6 binary has the same header for binfmt_misc.
>
> So here we need to detect the version of binaries and set
> cpu_model for it.
> ---
> include/elf.h | 4 ++++
> linux-user/elfload.c | 36 ++++++++++++++++++++++++++++++++++++
> linux-user/main.c | 15 +++++++++++++++
> linux-user/qemu.h | 1 +
> 4 files changed, 56 insertions(+)
>
> diff --git a/include/elf.h b/include/elf.h
> index e8a515ce3d..f2104809b1 100644
> --- a/include/elf.h
> +++ b/include/elf.h
> @@ -40,6 +40,10 @@ typedef int64_t Elf64_Sxword;
> #define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */
> #define EF_MIPS_ARCH_32 0x50000000 /* MIPS32 code. */
> #define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */
> +#define EF_MIPS_ARCH_32R2 0x70000000 /* MIPS32r2 code. */
> +#define EF_MIPS_ARCH_64R2 0x80000000 /* MIPS64r2 code. */
> +#define EF_MIPS_ARCH_32R6 0x90000000 /* MIPS32r6 code. */
> +#define EF_MIPS_ARCH_64R6 0xa0000000 /* MIPS64r6 code. */
>
> /* The ABI of a file. */
> #define EF_MIPS_ABI_O32 0x00001000 /* O32 ABI. */
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index 20f3d8c2c3..f9b8e028ca 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -2224,6 +2224,42 @@ static void load_elf_interp(const char *filename,
> struct image_info *info,
> exit(-1);
> }
>
> +uint32_t get_elf_eflags(const char *filename)
> +{
> + int fd, retval;
> + char bprm_buf[BPRM_BUF_SIZE];
> +
> + fd = open(path(filename), O_RDONLY);
> + if (fd < 0) {
> + return 0;
> + }
> + retval = read(fd, bprm_buf, BPRM_BUF_SIZE);
> + close(fd);
> + if (retval < 0) {
> + return 0;
> + }
> + if (retval < BPRM_BUF_SIZE) {
> + memset(bprm_buf + retval, 0, BPRM_BUF_SIZE - retval);
> + }
> +
> + if (bprm_buf[0] != 0x7f
> + || bprm_buf[1] != 'E'
> + || bprm_buf[2] != 'L'
> + || bprm_buf[3] != 'F') {
> + return 0;
> + }
> +
> + struct elfhdr *ehdr = (struct elfhdr *)bprm_buf;
> + if (!elf_check_ident(ehdr)) {
> + return 0;
> + }
> + bswap_ehdr(ehdr);
> + if (!elf_check_ehdr(ehdr)) {
> + return 0;
> + }
> + return ehdr->e_flags;
> +}
> +
> static int symfind(const void *s0, const void *s1)
> {
> target_ulong addr = *(target_ulong *)s0;
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 7c0bffeff6..b4626e5aa0 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -4287,6 +4287,21 @@ int main(int argc, char **argv, char **envp)
> }
> trace_init_file(trace_file);
>
> +#if defined(TARGET_MIPS)
> + if (cpu_model == NULL) {
> + uint32_t eflags = get_elf_eflags(filename);
> +#if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
> + if ((eflags & EF_MIPS_ARCH_64R6) != 0) {
> + cpu_model = "I6400";
> + }
> +#else
> + if ((eflags & EF_MIPS_ARCH_32R6) != 0) {
> + cpu_model = "mips32r6-generic";
> + }
> +#endif
> + }
> +#endif
> +
> /* Zero out regs */
> memset(regs, 0, sizeof(struct target_pt_regs));
>
> diff --git a/linux-user/qemu.h b/linux-user/qemu.h
> index 4edd7d0c08..cf09110bf9 100644
> --- a/linux-user/qemu.h
> +++ b/linux-user/qemu.h
> @@ -190,6 +190,7 @@ int loader_exec(int fdexec, const char *filename, char
> **argv, char **envp,
>
> int load_elf_binary(struct linux_binprm *bprm, struct image_info *info);
> int load_flt_binary(struct linux_binprm *bprm, struct image_info *info);
> +uint32_t get_elf_eflags(const char *filename);
>
> abi_long memcpy_to_target(abi_ulong dest, const void *src,
> unsigned long len);
>
- Re: [Qemu-devel] [PATCH] linux-user: MIPS set cpu to r6 CPU if binary is R6,
Laurent Vivier <=