2 * Copyright (c) 2018 Virtuozzo International GmbH
4 * This work is licensed under the terms of the GNU GPL, version 2 or later.
8 #include "qemu/osdep.h"
12 #define QEMU_NOTE_NAME "QEMU"
15 #define ROUND_UP(n, d) (((n) + (d) - 1) & -(0 ? (n) : (d)))
19 #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
22 #define ELF_NOTE_SIZE(hdr_size, name_size, desc_size) \
23 ((DIV_ROUND_UP((hdr_size), 4) + \
24 DIV_ROUND_UP((name_size), 4) + \
25 DIV_ROUND_UP((desc_size), 4)) * 4)
27 int is_system(QEMUCPUState
*s
)
29 return s
->gs
.base
>> 63;
32 static char *nhdr_get_name(Elf64_Nhdr
*nhdr
)
34 return (char *)nhdr
+ ROUND_UP(sizeof(*nhdr
), 4);
37 static void *nhdr_get_desc(Elf64_Nhdr
*nhdr
)
39 return nhdr_get_name(nhdr
) + ROUND_UP(nhdr
->n_namesz
, 4);
42 static Elf64_Nhdr
*nhdr_get_next(Elf64_Nhdr
*nhdr
)
44 return (void *)((uint8_t *)nhdr
+ ELF_NOTE_SIZE(sizeof(*nhdr
),
45 nhdr
->n_namesz
, nhdr
->n_descsz
));
48 Elf64_Phdr
*elf64_getphdr(void *map
)
50 Elf64_Ehdr
*ehdr
= map
;
51 Elf64_Phdr
*phdr
= (void *)((uint8_t *)map
+ ehdr
->e_phoff
);
56 Elf64_Half
elf_getphdrnum(void *map
)
58 Elf64_Ehdr
*ehdr
= map
;
63 static int init_states(QEMU_Elf
*qe
)
65 Elf64_Phdr
*phdr
= elf64_getphdr(qe
->map
);
66 Elf64_Nhdr
*start
= (void *)((uint8_t *)qe
->map
+ phdr
[0].p_offset
);
67 Elf64_Nhdr
*end
= (void *)((uint8_t *)start
+ phdr
[0].p_memsz
);
71 if (phdr
[0].p_type
!= PT_NOTE
) {
72 eprintf("Failed to find PT_NOTE\n");
76 qe
->has_kernel_gs_base
= 1;
78 for (nhdr
= start
; nhdr
< end
; nhdr
= nhdr_get_next(nhdr
)) {
79 if (!strcmp(nhdr_get_name(nhdr
), QEMU_NOTE_NAME
)) {
80 QEMUCPUState
*state
= nhdr_get_desc(nhdr
);
82 if (state
->size
< sizeof(*state
)) {
83 eprintf("CPU #%zu: QEMU CPU state size %u doesn't match\n",
86 * We assume either every QEMU CPU state has KERNEL_GS_BASE or
89 qe
->has_kernel_gs_base
= 0;
95 printf("%zu CPU states has been found\n", cpu_nr
);
97 qe
->state
= malloc(sizeof(*qe
->state
) * cpu_nr
);
104 for (nhdr
= start
; nhdr
< end
; nhdr
= nhdr_get_next(nhdr
)) {
105 if (!strcmp(nhdr_get_name(nhdr
), QEMU_NOTE_NAME
)) {
106 qe
->state
[cpu_nr
] = nhdr_get_desc(nhdr
);
111 qe
->state_nr
= cpu_nr
;
116 static void exit_states(QEMU_Elf
*qe
)
121 int QEMU_Elf_init(QEMU_Elf
*qe
, const char *filename
)
126 qe
->gmf
= g_mapped_file_new(filename
, TRUE
, &gerr
);
128 eprintf("Failed to map ELF dump file \'%s\'\n", filename
);
132 qe
->map
= g_mapped_file_get_contents(qe
->gmf
);
133 qe
->size
= g_mapped_file_get_length(qe
->gmf
);
135 if (init_states(qe
)) {
136 eprintf("Failed to extract QEMU CPU states\n");
144 g_mapped_file_unref(qe
->gmf
);
149 void QEMU_Elf_exit(QEMU_Elf
*qe
)
152 g_mapped_file_unref(qe
->gmf
);