Changeset 34135 in vbox
- Timestamp:
- Nov 17, 2010 10:25:25 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/DBGFCoreWrite.cpp
r34134 r34135 98 98 * @param cProgHdrs Number of program headers. 99 99 * @param cSecHdrs Number of section headers. 100 * @param pcbElfHdr Where to store the size of written header to file,101 * can be NULL.102 100 * 103 101 * @return IPRT status code. 104 102 */ 105 static int Elf64WriteElfHdr(RTFILE hFile, uint16_t cProgHdrs, uint16_t cSecHdrs , uint64_t *pcbElfHdr)103 static int Elf64WriteElfHdr(RTFILE hFile, uint16_t cProgHdrs, uint16_t cSecHdrs) 106 104 { 107 105 Elf64_Ehdr ElfHdr; … … 128 126 ElfHdr.e_shentsize = sizeof(Elf64_Shdr); 129 127 130 int rc = RTFileWrite(hFile, &ElfHdr, sizeof(ElfHdr), NULL /* all */); 131 if (RT_SUCCESS(rc) && pcbElfHdr) 132 *pcbElfHdr = sizeof(ElfHdr); 133 return rc; 128 return RTFileWrite(hFile, &ElfHdr, sizeof(ElfHdr), NULL /* all */); 134 129 } 135 130 … … 145 140 * @param cbMemData Size of contents in memory. 146 141 * @param Phys Physical address, pass zero if not applicable. 147 * @param pcbProgHdr Where to store the size of written header to file,148 * can be NULL.149 142 * 150 143 * @return IPRT status code. 151 144 */ 152 145 static int Elf64WriteProgHdr(RTFILE hFile, uint32_t Type, uint32_t fFlags, uint64_t offFileData, uint64_t cbFileData, 153 uint64_t cbMemData, RTGCPHYS Phys , uint64_t *pcbProgHdr)146 uint64_t cbMemData, RTGCPHYS Phys) 154 147 { 155 148 Elf64_Phdr ProgHdr; … … 162 155 ProgHdr.p_paddr = Phys; 163 156 164 int rc = RTFileWrite(hFile, &ProgHdr, sizeof(ProgHdr), NULL /* all */); 165 if (RT_SUCCESS(rc) && pcbProgHdr) 166 *pcbProgHdr = sizeof(ProgHdr); 167 return rc; 157 return RTFileWrite(hFile, &ProgHdr, sizeof(ProgHdr), NULL /* all */); 168 158 } 169 159 … … 177 167 * @return The size of the NOTE section as rounded to the file alignment. 178 168 */ 179 static inlineuint64_t Elf64NoteSectionSize(const char *pszName, uint64_t cbData)169 static uint64_t Elf64NoteSectionSize(const char *pszName, uint64_t cbData) 180 170 { 181 171 uint64_t cbNote = sizeof(Elf64_Nhdr); … … 198 188 * @param pcv Opaque pointer to the data, if NULL only computes size. 199 189 * @param cbData Size of the data. 200 * @param pcbNoteHdr Where to store the size of written header to file,201 * can be NULL.202 190 * 203 191 * @return IPRT status code. 204 192 */ 205 static int Elf64WriteNoteHdr(RTFILE hFile, uint16_t Type, const char *pszName, const void *pcvData, uint64_t cbData , uint64_t *pcbNoteHdr)193 static int Elf64WriteNoteHdr(RTFILE hFile, uint16_t Type, const char *pszName, const void *pcvData, uint64_t cbData) 206 194 { 207 195 AssertReturn(pcvData, VERR_INVALID_POINTER); … … 319 307 * Collect core information. 320 308 */ 321 uint32_t u32MemRanges = dbgfR3GetRamRangeCount(pVM);322 uint16_t c MemRanges = u32MemRanges < UINT16_MAX - 1 ? u32MemRanges : UINT16_MAX - 1;/* One PT_NOTE Program header */323 uint16_t c ProgHdrs= cMemRanges + 1;309 uint32_t const cu32MemRanges = dbgfR3GetRamRangeCount(pVM); 310 uint16_t const cMemRanges = cu32MemRanges < UINT16_MAX - 1 ? cu32MemRanges : UINT16_MAX - 1; /* One PT_NOTE Program header */ 311 uint16_t const cProgHdrs = cMemRanges + 1; 324 312 325 313 DBGFCOREDESCRIPTOR CoreDescriptor; … … 335 323 336 324 /* 337 * Compute total size of the note section. 338 */ 339 uint64_t cbNoteSection = Elf64NoteSectionSize(s_pcszCoreVBoxCore, sizeof(CoreDescriptor)) 340 + pVM->cCpus * Elf64NoteSectionSize(s_pcszCoreVBoxCpu, sizeof(CPUMCTX)); 341 uint64_t off = 0; 325 * Compute the file layout (see pg_dbgf_vmcore). 326 */ 327 uint64_t const offElfHdr = RTFileTell(hFile); 328 uint64_t const offNoteSection = offElfHdr + sizeof(Elf64_Ehdr); 329 uint64_t const offLoadSections = offNoteSection + sizeof(Elf64_Phdr); 330 uint64_t const cbLoadSections = cMemRanges * sizeof(Elf64_Phdr); 331 uint64_t const offCoreDescriptor= offLoadSections + cbLoadSections; 332 uint64_t const cbCoreDescriptor = Elf64NoteSectionSize(s_pcszCoreVBoxCore, sizeof(CoreDescriptor)); 333 uint64_t const offCpuDumps = offCoreDescriptor + cbCoreDescriptor; 334 uint64_t const cbCpuDumps = pVM->cCpus * Elf64NoteSectionSize(s_pcszCoreVBoxCpu, sizeof(CPUMCTX)); 335 uint64_t const offMemory = offCpuDumps + cbCpuDumps; 336 337 uint64_t const offNoteSectionData = offCoreDescriptor; 338 uint64_t const cbNoteSectionData = cbCoreDescriptor + cbCpuDumps; 342 339 343 340 /* 344 341 * Write ELF header. 345 342 */ 346 uint64_t cbElfHdr = 0; 347 uint64_t cbProgHdr = 0; 348 uint64_t offMemRange = 0; 349 int rc = Elf64WriteElfHdr(hFile, cProgHdrs, 0 /* cSecHdrs */, &cbElfHdr); 350 off += cbElfHdr; 343 int rc = Elf64WriteElfHdr(hFile, cProgHdrs, 0 /* cSecHdrs */); 351 344 if (RT_FAILURE(rc)) 352 345 { … … 358 351 * Write PT_NOTE program header. 359 352 */ 353 Assert(RTFileTell(hFile) == offNoteSection); 360 354 rc = Elf64WriteProgHdr(hFile, PT_NOTE, PF_R, 361 cbElfHdr + cProgHdrs * sizeof(Elf64_Phdr), /* file offset to contents */ 362 cbNoteSection, /* size in core file */ 363 cbNoteSection, /* size in memory */ 364 0, /* physical address */ 365 &cbProgHdr); 366 Assert(cbProgHdr == sizeof(Elf64_Phdr)); 367 off += cbProgHdr; 368 355 offNoteSectionData, /* file offset to contents */ 356 cbNoteSectionData, /* size in core file */ 357 cbNoteSectionData, /* size in memory */ 358 0); /* physical address */ 369 359 if (RT_FAILURE(rc)) 370 360 { … … 376 366 * Write PT_LOAD program header for each memory range. 377 367 */ 378 offMemRange = off + cbNoteSection; /** @todo this isn't taking the cmemRanges of prog hdrs into account. */ 368 Assert(RTFileTell(hFile) == offLoadSections); 369 uint64_t offMemRange = offMemory; 379 370 for (uint16_t iRange = 0; iRange < cMemRanges; iRange++) 380 371 { 381 RTGCPHYS GCPhysStart; 382 RTGCPHYS GCPhysEnd; 383 384 bool fIsMmio; 372 RTGCPHYS GCPhysStart; 373 RTGCPHYS GCPhysEnd; 374 bool fIsMmio; 385 375 rc = PGMR3PhysGetRange(pVM, iRange, &GCPhysStart, &GCPhysEnd, NULL /* pszDesc */, &fIsMmio); 386 376 if (RT_FAILURE(rc)) … … 400 390 cbFileRange, /* size in core file */ 401 391 cbMemRange, /* size in memory */ 402 GCPhysStart, /* physical address */ 403 &cbProgHdr); 404 Assert(cbProgHdr == sizeof(Elf64_Phdr)); 392 GCPhysStart); /* physical address */ 405 393 if (RT_FAILURE(rc)) 406 394 { 407 LogRel((DBGFLOG_NAME ": Elf64WriteProgHdr failed for memory range(%u) cbFileRange=%u cbMemRange=%u rc=%Rrc\n", iRange,408 cbFileRange, cbMemRange, rc));395 LogRel((DBGFLOG_NAME ": Elf64WriteProgHdr failed for memory range(%u) cbFileRange=%u cbMemRange=%u rc=%Rrc\n", 396 iRange, cbFileRange, cbMemRange, rc)); 409 397 return rc; 410 398 } … … 416 404 * Write the Core descriptor note header and data. 417 405 */ 418 rc = Elf64WriteNoteHdr(hFile, NT_VBOXCORE, s_pcszCoreVBoxCore, &CoreDescriptor, sizeof(CoreDescriptor),419 NULL /* pcbNoteHdr */);406 Assert(RTFileTell(hFile) == offCoreDescriptor); 407 rc = Elf64WriteNoteHdr(hFile, NT_VBOXCORE, s_pcszCoreVBoxCore, &CoreDescriptor, sizeof(CoreDescriptor)); 420 408 if (RT_FAILURE(rc)) 421 409 { … … 427 415 * Write the CPU context note headers and data. 428 416 */ 417 Assert(RTFileTell(hFile) == offCpuDumps); 429 418 for (uint32_t iCpu = 0; iCpu < pVM->cCpus; iCpu++) 430 419 { 431 420 PCPUMCTX pCpuCtx = &pVM->aCpus[iCpu].cpum.s.Guest; 432 rc = Elf64WriteNoteHdr(hFile, NT_VBOXCPU, s_pcszCoreVBoxCpu, pCpuCtx, sizeof(CPUMCTX) , NULL /* pcbNoteHdr */);421 rc = Elf64WriteNoteHdr(hFile, NT_VBOXCPU, s_pcszCoreVBoxCpu, pCpuCtx, sizeof(CPUMCTX)); 433 422 if (RT_FAILURE(rc)) 434 423 { … … 441 430 * Write memory ranges. 442 431 */ 432 Assert(RTFileTell(hFile) == offMemory); 443 433 for (uint16_t iRange = 0; iRange < cMemRanges; iRange++) 444 434 { 445 435 RTGCPHYS GCPhysStart; 446 436 RTGCPHYS GCPhysEnd; 447 bool fIsMmio;437 bool fIsMmio; 448 438 rc = PGMR3PhysGetRange(pVM, iRange, &GCPhysStart, &GCPhysEnd, NULL /* pszDesc */, &fIsMmio); 449 439 if (RT_FAILURE(rc)) … … 460 450 */ 461 451 uint64_t cbMemRange = GCPhysEnd - GCPhysStart + 1; 462 uint64_t cPages = cbMemRange >> PAGE_SHIFT;452 uint64_t cPages = cbMemRange >> PAGE_SHIFT; 463 453 for (uint64_t iPage = 0; iPage < cPages; iPage++) 464 454 { 465 const int cbBuf = PAGE_SIZE; 466 void *pvBuf = MMR3HeapAlloc(pVM, MM_TAG_DBGF_CORE_WRITE, cbBuf); 467 if (RT_UNLIKELY(!pvBuf)) 468 { 469 LogRel((DBGFLOG_NAME ": MMR3HeapAlloc failed. iRange=%u iPage=%u\n", iRange, iPage)); 470 return rc; 471 } 472 473 rc = PGMPhysRead(pVM, GCPhysStart, pvBuf, cbBuf); 455 uint8_t abPage[PAGE_SIZE]; 456 rc = PGMPhysRead(pVM, GCPhysStart, abPage, sizeof(abPage)); 474 457 if (RT_FAILURE(rc)) 475 458 { … … 477 460 * For some reason this failed, write out a zero page instead. 478 461 */ 479 LogRel((DBGFLOG_NAME ": PGMPhysRead failed for iRange=%u iPage=%u. rc=%Rrc. Ignoring...\n", iRange, 480 iPage, rc)); 481 memset(pvBuf, 0, cbBuf); 462 LogRel((DBGFLOG_NAME ": PGMPhysRead failed for iRange=%u iPage=%u. rc=%Rrc. Ignoring...\n", iRange, iPage, rc)); 463 RT_ZERO(abPage); 482 464 } 483 465 484 rc = RTFileWrite(hFile, pvBuf, cbBuf, NULL /* all */);466 rc = RTFileWrite(hFile, abPage, sizeof(abPage), NULL /* all */); 485 467 if (RT_FAILURE(rc)) 486 468 { 487 469 LogRel((DBGFLOG_NAME ": RTFileWrite failed. iRange=%u iPage=%u rc=%Rrc\n", iRange, iPage, rc)); 488 MMR3HeapFree(pvBuf);489 470 return rc; 490 471 } 491 492 MMR3HeapFree(pvBuf);493 472 } 494 473 }
Note:
See TracChangeset
for help on using the changeset viewer.