Commit 768fe76e authored by YunQiang Su's avatar YunQiang Su Committed by Laurent Vivier
Browse files

linux-user: introduce functions to detect CPU type



Add a function to return ELF e_flags and use it
to select the CPU model.

Signed-off-by: default avatarYunQiang Su <syq@debian.org>
[lv: split the patch and some cleanup in get_elf_eflags()]
Signed-off-by: default avatarLaurent Vivier <laurent@vivier.eu>
Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-Id: <20180220173307.25125-3-laurent@vivier.eu>
parent 542ca434
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -2396,6 +2396,41 @@ give_up:
    g_free(syms);
}

uint32_t get_elf_eflags(int fd)
{
    struct elfhdr ehdr;
    off_t offset;
    int ret;

    /* Read ELF header */
    offset = lseek(fd, 0, SEEK_SET);
    if (offset == (off_t) -1) {
        return 0;
    }
    ret = read(fd, &ehdr, sizeof(ehdr));
    if (ret < sizeof(ehdr)) {
        return 0;
    }
    offset = lseek(fd, offset, SEEK_SET);
    if (offset == (off_t) -1) {
        return 0;
    }

    /* Check ELF signature */
    if (!elf_check_ident(&ehdr)) {
        return 0;
    }

    /* check header */
    bswap_ehdr(&ehdr);
    if (!elf_check_ehdr(&ehdr)) {
        return 0;
    }

    /* return architecture id */
    return ehdr.e_flags;
}

int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
{
    struct image_info interp_info;
+10 −10
Original line number Diff line number Diff line
@@ -4344,8 +4344,17 @@ int main(int argc, char **argv, char **envp)

    init_qemu_uname_release();

    execfd = qemu_getauxval(AT_EXECFD);
    if (execfd == 0) {
        execfd = open(filename, O_RDONLY);
        if (execfd < 0) {
            printf("Error while loading %s: %s\n", filename, strerror(errno));
            _exit(EXIT_FAILURE);
        }
    }

    if (cpu_model == NULL) {
        cpu_model = cpu_get_model(0);
        cpu_model = cpu_get_model(get_elf_eflags(execfd));
    }
    tcg_exec_init(0);
    /* NOTE: we need to init the CPU at this stage to get
@@ -4438,15 +4447,6 @@ int main(int argc, char **argv, char **envp)
    cpu->opaque = ts;
    task_settid(ts);

    execfd = qemu_getauxval(AT_EXECFD);
    if (execfd == 0) {
        execfd = open(filename, O_RDONLY);
        if (execfd < 0) {
            printf("Error while loading %s: %s\n", filename, strerror(errno));
            _exit(EXIT_FAILURE);
        }
    }

    ret = loader_exec(execfd, filename, target_argv, target_environ, regs,
        info, &bprm);
    if (ret != 0) {
+1 −0
Original line number Diff line number Diff line
@@ -186,6 +186,7 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp,
             struct target_pt_regs * regs, struct image_info *infop,
             struct linux_binprm *);

uint32_t get_elf_eflags(int fd);
int load_elf_binary(struct linux_binprm *bprm, struct image_info *info);
int load_flt_binary(struct linux_binprm *bprm, struct image_info *info);