VirtualBox

source: vbox/trunk/src/VBox/VMM/DBGFCoreWrite.cpp@ 32054

Last change on this file since 32054 was 32050, checked in by vboxsync, 14 years ago

VMM/DBGFCoreWrite: bits.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.8 KB
Line 
1/* $Id: DBGFCoreWrite.cpp 32050 2010-08-27 12:48:09Z vboxsync $ */
2/** @file
3 * DBGF - Debugger Facility, Guest Core Dump.
4 */
5
6/*
7 * Copyright (C) 2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#define LOG_GROUP LOG_GROUP_DBGF
23#include <iprt/param.h>
24#include <iprt/file.h>
25#include <VBox/dbgf.h>
26#include "DBGFInternal.h"
27#include <VBox/vm.h>
28#include <VBox/err.h>
29#include <VBox/log.h>
30
31#include "../Runtime/include/internal/ldrELF64.h"
32
33/*
34 * VBox VMCore Format:
35 * [ ELF 64 Header] -- Only 1
36 *
37 * [ PT_NOTE ] -- Only 1
38 * - Offset into list of Notes (Note Hdr + data) of VBox CPUs.
39 * - (Any Additional custom Note sections)
40 *
41 * [ PT_LOAD ] -- One for each contiguous memory chunk
42 * - Memory offset
43 * - File offset
44 *
45 * Per-CPU register dump
46 * - CPU 1 Note Hdr + Data
47 * - CPU 2 Note Hdr + Data
48 * ...
49 * (Additional custom notes Hdr+data)
50 * - VBox 1 Note Hdr + Data
51 * - VBox 2 Note Hdr + Data
52 * ...
53 * Memory dump
54 *
55 */
56
57/**
58 * ELF function to write 64-bit ELF header.
59 *
60 * @param hFile The file to write to.
61 * @param cProgHdrs Number of program headers.
62 * @param cSecHdrs Number of section headers.
63 * @param pcbElfHdr Where to store the size of written header to file,
64 * can be NULL.
65 *
66 * @return IPRT status code.
67 */
68static int Elf64WriteElfHdr(RTFILE hFile, uint16_t cProgHdrs, uint16_t cSecHdrs, size_t *pcbElfHdr)
69{
70 Elf64_Ehdr ElfHdr;
71 RT_ZERO(ElfHdr);
72 ElfHdr.e_ident[EI_MAG0] = ELFMAG0;
73 ElfHdr.e_ident[EI_MAG1] = ELFMAG1;
74 ElfHdr.e_ident[EI_MAG2] = ELFMAG2;
75 ElfHdr.e_ident[EI_MAG3] = ELFMAG3;
76 ElfHdr.e_ident[EI_DATA] = ELFDATA2LSB;
77 ElfHdr.e_type = ET_CORE;
78 ElfHdr.e_version = EV_CURRENT;
79 ElfHdr.e_ident[EI_CLASS] = ELFCLASS64;
80 /* 32-bit VMs will produce cores with e_machine EM_386. */
81#ifdef RT_ARCH_AMD64
82 ElfHdr.e_machine = EM_X86_64;
83#else
84 ElfHdr.e_machine = EM_386;
85#endif
86 ElfHdr.e_phnum = cProgHdrs;
87 ElfHdr.e_shnum = cSecHdrs;
88 ElfHdr.e_ehsize = sizeof(ElfHdr);
89 ElfHdr.e_phoff = sizeof(ElfHdr);
90 ElfHdr.e_phentsize = sizeof(Elf64_Phdr);
91 ElfHdr.e_shentsize = sizeof(Elf64_Shdr);
92
93 int rc = RTFileWrite(hFile, &ElfHdr, sizeof(ElfHdr), NULL /* full write */);
94 if (RT_SUCCESS(rc) && pcbElfHdr)
95 *pcbElfHdr = sizeof(ElfHdr);
96 return rc;
97}
98
99
100/**
101 * ELF function to write 64-bit program header.
102 *
103 * @param hFile The file to write to.
104 * @param Type Type of program header (PT_*).
105 * @param fFlags Flags (access permissions).
106 * @param offFileData File offset of contents.
107 * @param cbFileData Size of contents in the file.
108 * @param cbMemData Size of contents in memory.
109 * @param pcbProgHdr Where to store the size of written header to file,
110 * can be NULL.
111 *
112 * @return IPRT status code.
113 */
114static int Elf64WriteProgHdr(RTFILE hFile, uint32_t Type, uint32_t fFlags, RTFOFF offFileData, size_t cbFileData, size_t cbMemData,
115 size_t *pcbProgHdr)
116{
117 Elf64_Phdr ProgHdr;
118 RT_ZERO(ProgHdr);
119 ProgHdr.p_type = Type;
120 ProgHdr.p_flags = fFlags;
121 ProgHdr.p_offset = offFileData;
122 ProgHdr.p_filesz = cbFileData;
123 ProgHdr.p_memsz = cbMemData;
124
125 int rc = RTFileWrite(hFile, &ProgHdr, sizeof(ProgHdr), NULL /* full write */);
126 if (RT_SUCCESS(rc) && pcbProgHdr)
127 *pcbProgHdr = sizeof(ProgHdr);
128 return rc;
129}
130
131
132/**
133 * Count the number of memory blobs that go into the core file.
134 *
135 * We cannot do a page-by-page dump of the entire guest memory as there will be
136 * way too many entries. Also we don't want to dump MMIO regions which means we
137 * cannot have a 1:1 mapping between core file offset and memory offset. Instead
138 * we dump the memory in blobs. A memory blob is a contiguous memory area
139 * suitable for dumping to a core file.
140 *
141 * @param pVM The VM handle.
142 * @oaram idCpu The target CPU ID.
143 *
144 * @return Number of memory blobs.
145 */
146static int dbgfR3CountMemoryBlobs(PVM pVM, VMCPUID idCpu)
147{
148 /* @todo */
149 return 0;
150}
151
152
153/**
154 * EMT worker function for DBGFR3CoreWrite.
155 *
156 * @param pVM The VM handle.
157 * @param idCpu The target CPU ID.
158 * @param pszDumpPath The full path of the file to dump into.
159 *
160 * @return VBox status code.
161 */
162static DECLCALLBACK(int) dbgfR3CoreWrite(PVM pVM, VMCPUID idCpu, const char *pszDumpPath)
163{
164 /*
165 * Validate input.
166 */
167 Assert(idCpu == VMMGetCpuId(pVM));
168 AssertReturn(pszDumpPath, VERR_INVALID_POINTER);
169
170 /*
171 * Halt the VM if it is not already halted.
172 */
173 int rc = VINF_SUCCESS;
174 if (!DBGFR3IsHalted(pVM))
175 {
176 rc = DBGFR3Halt(pVM);
177 if (RT_FAILURE(rc))
178 return rc;
179 }
180
181 /*
182 * Collect core information.
183 */
184 uint16_t cMemBlobs = dbgfR3CountMemoryBlobs(pVM, idCpu);
185 uint16_t cProgHdrs = cMemBlobs + 1; /* One PT_NOTE Program header */
186
187 /*
188 * Write the core file.
189 */
190 RTFILE hFile = NIL_RTFILE;
191 rc = RTFileOpen(&hFile, pszDumpPath, RTFILE_O_CREATE | RTFILE_O_READWRITE);
192 if (RT_SUCCESS(rc))
193 {
194 size_t cbElfHdr = 0;
195 rc = Elf64WriteElfHdr(hFile, 0, 0 /* cSecHdrs */, &cbElfHdr);
196 if (RT_SUCCESS(rc))
197 {
198
199 }
200
201 RTFileClose(hFile);
202 }
203
204 /*
205 * Resume the VM.
206 */
207 DBGFR3Resume(pVM);
208
209 return rc;
210}
211
212
213/**
214 * Write core dump of the guest.
215 *
216 * @return VBox status code.
217 * @param pVM The VM handle.
218 * @param idCpu The target CPU ID.
219 * @param pszDumpPath The path of the file to dump into, cannot be
220 * NULL.
221 */
222VMMR3DECL(int) DBGFR3CoreWrite(PVM pVM, VMCPUID idCpu, const char *pszDumpPath)
223{
224 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
225 AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
226 AssertReturn(pszDumpPath, VERR_INVALID_HANDLE);
227
228 /*
229 * Pass the core write request down to EMT.
230 */
231 return VMR3ReqCallWaitU(pVM->pUVM, idCpu, (PFNRT)dbgfR3CoreWrite, 3, pVM, idCpu, pszDumpPath);
232}
233
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette