mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
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: YunQiang Su <syq@debian.org> [lv: split the patch and some cleanup in get_elf_eflags()] Signed-off-by: Laurent Vivier <laurent@vivier.eu> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20180220173307.25125-3-laurent@vivier.eu>
This commit is contained in:
parent
542ca43498
commit
768fe76e92
3 changed files with 46 additions and 10 deletions
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue