diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2023-03-21 14:09:34 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2023-03-21 14:09:34 +0000 |
commit | 8de6e6e12e623ea402274d4cf24de20ed7e40717 (patch) | |
tree | cff4fa0dd52eb546af35b3c23221a6d3a6000e5e /contrib/elf2dmp/main.c | |
parent | 42d55ab1706912bd21c916dc818279f113ae2791 (diff) | |
parent | 5787d17a42f7af4bd117e5d6bfa54b1fdf93c255 (diff) |
Merge tag 'pull-target-arm-20230321' of https://git.linaro.org/people/pmaydell/qemu-arm into staging
target-arm queue:
* contrib/elf2dmp: Support Windows Server 2022
* hw/char/cadence_uart: Fix guards on invalid BRGR/BDIV settings
* target/arm: Add Neoverse-N1 IMPDEF registers
* hw/usb/imx: Fix out of bounds access in imx_usbphy_read()
* docs/system/arm/cpu-features.rst: Fix formatting
* target/arm: Don't advertise aarch64-pauth.xml to gdb
# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmQZrwQZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3gmFD/9Ib/G7f21IQkhi0d0MoJeQ
# 529QbzHbXH272OvO2zFdev98o6EVbbeGzGqgaa0lv6OASwvNUIFVJAwZUX6Bb756
# dJ9k5aS2249SGQ8AzM65bCL4HxSVFan5+t9P890SyQk3zIzzQtSVjci/K2P2cFx1
# bKzbCZys/qjZgncPaPeuc9irkmAKlqc9UwqgUV3xvhBAfq1eFHk/bVIhcTVxNwUy
# quCYOt1GwtsOKn+nUcKclOcmBb7diCu6iFCGlO7XF9Rjaa+egW3OhUnGqUFROsdu
# j4drjeQT8gWY92m8PlnsZb0YUeefAwD7iVZGIAEp3G+9GEXdOvotrQVKtMLMZkq0
# /YInUjYAFu1w7DqhelvSYGVoVioP13HxsFWpmKNYNSJIHtS7QCfmHfUBPQnWjHD5
# XUO/K7vbsp69yi/rDDoHvQ3sqxJUuiF1Wuyj+hRK1JXRhLkRL+tBE7urlqqoJ1wH
# 0vL6oNj5GdvNJssIkb7yXx72irgAUu8XTC7bEvGCVfaylmei3SsS35qQmGePzO/z
# ok7WePQ/tM/FJ8JLVTXur9YsG7EqMROdszQRE4Yla3NE6BOr7HCCj7ZdCfy5SXL4
# IlZ69UELcYghcfIDRrRLXDSdfs98voRxIRDHy0rz64hUHlLBOnfqw/dcHvZBAB09
# CV7QPcDOR87jY228DT4EzA==
# =D7pq
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 21 Mar 2023 13:20:04 GMT
# gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg: issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# gpg: aka "Peter Maydell <peter@archaic.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE
* tag 'pull-target-arm-20230321' of https://git.linaro.org/people/pmaydell/qemu-arm:
target/arm: Don't advertise aarch64-pauth.xml to gdb
docs/system/arm/cpu-features.rst: Fix formatting
hw/usb/imx: Fix out of bounds access in imx_usbphy_read()
contrib/elf2dmp: add PE name check and Windows Server 2022 support
contrib/elf2dmp: move PE dir search to pe_get_data_dir_entry
contrib/elf2dmp: fix code style
hw/char/cadence_uart: Fix guards on invalid BRGR/BDIV settings
target/arm: Add Neoverse-N1 registers
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'contrib/elf2dmp/main.c')
-rw-r--r-- | contrib/elf2dmp/main.c | 108 |
1 files changed, 74 insertions, 34 deletions
diff --git a/contrib/elf2dmp/main.c b/contrib/elf2dmp/main.c index d77b8f98f7..89f0c69ab0 100644 --- a/contrib/elf2dmp/main.c +++ b/contrib/elf2dmp/main.c @@ -17,6 +17,7 @@ #define SYM_URL_BASE "https://msdl.microsoft.com/download/symbols/" #define PDB_NAME "ntkrnlmp.pdb" +#define PE_NAME "ntoskrnl.exe" #define INITIAL_MXCSR 0x1f80 @@ -282,14 +283,16 @@ static int fill_header(WinDumpHeader64 *hdr, struct pa_space *ps, }; for (i = 0; i < ps->block_nr; i++) { - h.PhysicalMemoryBlock.NumberOfPages += ps->block[i].size / ELF2DMP_PAGE_SIZE; + h.PhysicalMemoryBlock.NumberOfPages += + ps->block[i].size / ELF2DMP_PAGE_SIZE; h.PhysicalMemoryBlock.Run[i] = (WinDumpPhyMemRun64) { .BasePage = ps->block[i].paddr / ELF2DMP_PAGE_SIZE, .PageCount = ps->block[i].size / ELF2DMP_PAGE_SIZE, }; } - h.RequiredDumpSpace += h.PhysicalMemoryBlock.NumberOfPages << ELF2DMP_PAGE_BITS; + h.RequiredDumpSpace += + h.PhysicalMemoryBlock.NumberOfPages << ELF2DMP_PAGE_BITS; *hdr = h; @@ -299,7 +302,8 @@ static int fill_header(WinDumpHeader64 *hdr, struct pa_space *ps, static int fill_context(KDDEBUGGER_DATA64 *kdbg, struct va_space *vs, QEMU_Elf *qe) { - int i; + int i; + for (i = 0; i < qe->state_nr; i++) { uint64_t Prcb; uint64_t Context; @@ -330,6 +334,45 @@ static int fill_context(KDDEBUGGER_DATA64 *kdbg, return 0; } +static int pe_get_data_dir_entry(uint64_t base, void *start_addr, int idx, + void *entry, size_t size, struct va_space *vs) +{ + const char e_magic[2] = "MZ"; + const char Signature[4] = "PE\0\0"; + IMAGE_DOS_HEADER *dos_hdr = start_addr; + IMAGE_NT_HEADERS64 nt_hdrs; + IMAGE_FILE_HEADER *file_hdr = &nt_hdrs.FileHeader; + IMAGE_OPTIONAL_HEADER64 *opt_hdr = &nt_hdrs.OptionalHeader; + IMAGE_DATA_DIRECTORY *data_dir = nt_hdrs.OptionalHeader.DataDirectory; + + QEMU_BUILD_BUG_ON(sizeof(*dos_hdr) >= ELF2DMP_PAGE_SIZE); + + if (memcmp(&dos_hdr->e_magic, e_magic, sizeof(e_magic))) { + return 1; + } + + if (va_space_rw(vs, base + dos_hdr->e_lfanew, + &nt_hdrs, sizeof(nt_hdrs), 0)) { + return 1; + } + + if (memcmp(&nt_hdrs.Signature, Signature, sizeof(Signature)) || + file_hdr->Machine != 0x8664 || opt_hdr->Magic != 0x020b) { + return 1; + } + + if (va_space_rw(vs, + base + data_dir[idx].VirtualAddress, + entry, size, 0)) { + return 1; + } + + printf("Data directory entry #%d: RVA = 0x%08"PRIx32"\n", idx, + (uint32_t)data_dir[idx].VirtualAddress); + + return 0; +} + static int write_dump(struct pa_space *ps, WinDumpHeader64 *hdr, const char *name) { @@ -363,45 +406,38 @@ static int write_dump(struct pa_space *ps, return fclose(dmp_file); } +static bool pe_check_export_name(uint64_t base, void *start_addr, + struct va_space *vs) +{ + IMAGE_EXPORT_DIRECTORY export_dir; + const char *pe_name; + + if (pe_get_data_dir_entry(base, start_addr, IMAGE_FILE_EXPORT_DIRECTORY, + &export_dir, sizeof(export_dir), vs)) { + return false; + } + + pe_name = va_space_resolve(vs, base + export_dir.Name); + if (!pe_name) { + return false; + } + + return !strcmp(pe_name, PE_NAME); +} + static int pe_get_pdb_symstore_hash(uint64_t base, void *start_addr, char *hash, struct va_space *vs) { - const char e_magic[2] = "MZ"; - const char Signature[4] = "PE\0\0"; const char sign_rsds[4] = "RSDS"; - IMAGE_DOS_HEADER *dos_hdr = start_addr; - IMAGE_NT_HEADERS64 nt_hdrs; - IMAGE_FILE_HEADER *file_hdr = &nt_hdrs.FileHeader; - IMAGE_OPTIONAL_HEADER64 *opt_hdr = &nt_hdrs.OptionalHeader; - IMAGE_DATA_DIRECTORY *data_dir = nt_hdrs.OptionalHeader.DataDirectory; IMAGE_DEBUG_DIRECTORY debug_dir; OMFSignatureRSDS rsds; char *pdb_name; size_t pdb_name_sz; size_t i; - QEMU_BUILD_BUG_ON(sizeof(*dos_hdr) >= ELF2DMP_PAGE_SIZE); - - if (memcmp(&dos_hdr->e_magic, e_magic, sizeof(e_magic))) { - return 1; - } - - if (va_space_rw(vs, base + dos_hdr->e_lfanew, - &nt_hdrs, sizeof(nt_hdrs), 0)) { - return 1; - } - - if (memcmp(&nt_hdrs.Signature, Signature, sizeof(Signature)) || - file_hdr->Machine != 0x8664 || opt_hdr->Magic != 0x020b) { - return 1; - } - - printf("Debug Directory RVA = 0x%08"PRIx32"\n", - (uint32_t)data_dir[IMAGE_FILE_DEBUG_DIRECTORY].VirtualAddress); - - if (va_space_rw(vs, - base + data_dir[IMAGE_FILE_DEBUG_DIRECTORY].VirtualAddress, - &debug_dir, sizeof(debug_dir), 0)) { + if (pe_get_data_dir_entry(base, start_addr, IMAGE_FILE_DEBUG_DIRECTORY, + &debug_dir, sizeof(debug_dir), vs)) { + eprintf("Failed to get Debug Directory\n"); return 1; } @@ -473,6 +509,7 @@ int main(int argc, char *argv[]) uint64_t KdDebuggerDataBlock; KDDEBUGGER_DATA64 *kdbg; uint64_t KdVersionBlock; + bool kernel_found = false; if (argc != 3) { eprintf("usage:\n\t%s elf_file dmp_file\n", argv[0]); @@ -520,11 +557,14 @@ int main(int argc, char *argv[]) } if (*(uint16_t *)nt_start_addr == 0x5a4d) { /* MZ */ - break; + if (pe_check_export_name(KernBase, nt_start_addr, &vs)) { + kernel_found = true; + break; + } } } - if (!nt_start_addr) { + if (!kernel_found) { eprintf("Failed to find NT kernel image\n"); err = 1; goto out_ps; |