Mercurial > hg > CbC > CbC_llvm
comparison llvm/lib/DebugInfo/GSYM/DwarfTransformer.cpp @ 236:c4bab56944e8 llvm-original
LLVM 16
author | kono |
---|---|
date | Wed, 09 Nov 2022 17:45:10 +0900 |
parents | 79ff65ed7e25 |
children | 1f2b6ac9f198 |
comparison
equal
deleted
inserted
replaced
232:70dce7da266c | 236:c4bab56944e8 |
---|---|
8 | 8 |
9 #include <thread> | 9 #include <thread> |
10 #include <unordered_set> | 10 #include <unordered_set> |
11 | 11 |
12 #include "llvm/DebugInfo/DIContext.h" | 12 #include "llvm/DebugInfo/DIContext.h" |
13 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" | |
13 #include "llvm/DebugInfo/DWARF/DWARFContext.h" | 14 #include "llvm/DebugInfo/DWARF/DWARFContext.h" |
14 #include "llvm/Support/Error.h" | 15 #include "llvm/Support/Error.h" |
15 #include "llvm/Support/ThreadPool.h" | 16 #include "llvm/Support/ThreadPool.h" |
16 #include "llvm/Support/raw_ostream.h" | 17 #include "llvm/Support/raw_ostream.h" |
17 | 18 |
258 | 259 |
259 | 260 |
260 if (!CUI.LineTable->lookupAddressRange(SecAddress, RangeSize, RowVector)) { | 261 if (!CUI.LineTable->lookupAddressRange(SecAddress, RangeSize, RowVector)) { |
261 // If we have a DW_TAG_subprogram but no line entries, fall back to using | 262 // If we have a DW_TAG_subprogram but no line entries, fall back to using |
262 // the DW_AT_decl_file an d DW_AT_decl_line if we have both attributes. | 263 // the DW_AT_decl_file an d DW_AT_decl_line if we have both attributes. |
263 if (auto FileIdx = | 264 std::string FilePath = Die.getDeclFile( |
264 dwarf::toUnsigned(Die.findRecursively({dwarf::DW_AT_decl_file}))) { | 265 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath); |
265 if (auto Line = | 266 if (FilePath.empty()) |
266 dwarf::toUnsigned(Die.findRecursively({dwarf::DW_AT_decl_line}))) { | 267 return; |
267 LineEntry LE(StartAddress, CUI.DWARFToGSYMFileIndex(Gsym, *FileIdx), | 268 if (auto Line = |
268 *Line); | 269 dwarf::toUnsigned(Die.findRecursively({dwarf::DW_AT_decl_line}))) { |
269 FI.OptLineTable = LineTable(); | 270 LineEntry LE(StartAddress, Gsym.insertFile(FilePath), *Line); |
270 FI.OptLineTable->push(LE); | 271 FI.OptLineTable = LineTable(); |
271 // LE.Addr = EndAddress; | 272 FI.OptLineTable->push(LE); |
272 // FI.OptLineTable->push(LE); | |
273 } | |
274 } | 273 } |
275 return; | 274 return; |
276 } | 275 } |
277 | 276 |
278 FI.OptLineTable = LineTable(); | 277 FI.OptLineTable = LineTable(); |
287 // we will get a RowIndex for the previous valid line table row which won't | 286 // we will get a RowIndex for the previous valid line table row which won't |
288 // be contained in our function. This is usually a bug in the DWARF due to | 287 // be contained in our function. This is usually a bug in the DWARF due to |
289 // linker problems or LTO or other DWARF re-linking so it is worth emitting | 288 // linker problems or LTO or other DWARF re-linking so it is worth emitting |
290 // an error, but not worth stopping the creation of the GSYM. | 289 // an error, but not worth stopping the creation of the GSYM. |
291 if (!FI.Range.contains(RowAddress)) { | 290 if (!FI.Range.contains(RowAddress)) { |
292 if (RowAddress < FI.Range.Start) { | 291 if (RowAddress < FI.Range.start()) { |
293 Log << "error: DIE has a start address whose LowPC is between the " | 292 Log << "error: DIE has a start address whose LowPC is between the " |
294 "line table Row[" << RowIndex << "] with address " | 293 "line table Row[" << RowIndex << "] with address " |
295 << HEX64(RowAddress) << " and the next one.\n"; | 294 << HEX64(RowAddress) << " and the next one.\n"; |
296 Die.dump(Log, 0, DIDumpOptions::getForSingleDIE()); | 295 Die.dump(Log, 0, DIDumpOptions::getForSingleDIE()); |
297 RowAddress = FI.Range.Start; | 296 RowAddress = FI.Range.start(); |
298 } else { | 297 } else { |
299 continue; | 298 continue; |
300 } | 299 } |
301 } | 300 } |
302 | 301 |
392 // and the debug info wasn't able to be stripped from the DWARF. If | 391 // and the debug info wasn't able to be stripped from the DWARF. If |
393 // the LowPC isn't zero or -1, then we should emit an error. | 392 // the LowPC isn't zero or -1, then we should emit an error. |
394 if (Range.LowPC != 0) { | 393 if (Range.LowPC != 0) { |
395 if (!Gsym.isQuiet()) { | 394 if (!Gsym.isQuiet()) { |
396 // Unexpected invalid address, emit a warning | 395 // Unexpected invalid address, emit a warning |
397 Log << "warning: DIE has an address range whose start address is " | 396 OS << "warning: DIE has an address range whose start address is " |
398 "not in any executable sections (" | 397 "not in any executable sections (" |
399 << *Gsym.GetValidTextRanges() | 398 << *Gsym.GetValidTextRanges() |
400 << ") and will not be processed:\n"; | 399 << ") and will not be processed:\n"; |
401 Die.dump(Log, 0, DIDumpOptions::getForSingleDIE()); | 400 Die.dump(OS, 0, DIDumpOptions::getForSingleDIE()); |
402 } | 401 } |
403 } | 402 } |
404 break; | 403 break; |
405 } | 404 } |
406 | 405 |
407 FunctionInfo FI; | 406 FunctionInfo FI; |
408 FI.setStartAddress(Range.LowPC); | 407 FI.Range = {Range.LowPC, Range.HighPC}; |
409 FI.setEndAddress(Range.HighPC); | |
410 FI.Name = *NameIndex; | 408 FI.Name = *NameIndex; |
411 if (CUI.LineTable) { | 409 if (CUI.LineTable) { |
412 convertFunctionLineTable(OS, CUI, Die, Gsym, FI); | 410 convertFunctionLineTable(OS, CUI, Die, Gsym, FI); |
413 } | 411 } |
414 if (hasInlineInfo(Die, 0)) { | 412 if (hasInlineInfo(Die, 0)) { |
427 handleDie(OS, CUI, ChildDie); | 425 handleDie(OS, CUI, ChildDie); |
428 } | 426 } |
429 | 427 |
430 Error DwarfTransformer::convert(uint32_t NumThreads) { | 428 Error DwarfTransformer::convert(uint32_t NumThreads) { |
431 size_t NumBefore = Gsym.getNumFunctionInfos(); | 429 size_t NumBefore = Gsym.getNumFunctionInfos(); |
430 auto getDie = [&](DWARFUnit &DwarfUnit) -> DWARFDie { | |
431 DWARFDie ReturnDie = DwarfUnit.getUnitDIE(false); | |
432 if (llvm::Optional<uint64_t> DWOId = DwarfUnit.getDWOId()) { | |
433 DWARFUnit *DWOCU = DwarfUnit.getNonSkeletonUnitDIE(false).getDwarfUnit(); | |
434 if (!DWOCU->isDWOUnit()) { | |
435 std::string DWOName = dwarf::toString( | |
436 DwarfUnit.getUnitDIE().find( | |
437 {dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), | |
438 ""); | |
439 Log << "warning: Unable to retrieve DWO .debug_info section for " | |
440 << DWOName << "\n"; | |
441 } else { | |
442 ReturnDie = DWOCU->getUnitDIE(false); | |
443 } | |
444 } | |
445 return ReturnDie; | |
446 }; | |
432 if (NumThreads == 1) { | 447 if (NumThreads == 1) { |
433 // Parse all DWARF data from this thread, use the same string/file table | 448 // Parse all DWARF data from this thread, use the same string/file table |
434 // for everything | 449 // for everything |
435 for (const auto &CU : DICtx.compile_units()) { | 450 for (const auto &CU : DICtx.compile_units()) { |
436 DWARFDie Die = CU->getUnitDIE(false); | 451 DWARFDie Die = getDie(*CU); |
437 CUInfo CUI(DICtx, dyn_cast<DWARFCompileUnit>(CU.get())); | 452 CUInfo CUI(DICtx, dyn_cast<DWARFCompileUnit>(CU.get())); |
438 handleDie(Log, CUI, Die); | 453 handleDie(Log, CUI, Die); |
439 } | 454 } |
440 } else { | 455 } else { |
441 // LLVM Dwarf parser is not thread-safe and we need to parse all DWARF up | 456 // LLVM Dwarf parser is not thread-safe and we need to parse all DWARF up |
456 pool.wait(); | 471 pool.wait(); |
457 | 472 |
458 // Now convert all DWARF to GSYM in a thread pool. | 473 // Now convert all DWARF to GSYM in a thread pool. |
459 std::mutex LogMutex; | 474 std::mutex LogMutex; |
460 for (const auto &CU : DICtx.compile_units()) { | 475 for (const auto &CU : DICtx.compile_units()) { |
461 DWARFDie Die = CU->getUnitDIE(false /*CUDieOnly*/); | 476 DWARFDie Die = getDie(*CU); |
462 if (Die) { | 477 if (Die) { |
463 CUInfo CUI(DICtx, dyn_cast<DWARFCompileUnit>(CU.get())); | 478 CUInfo CUI(DICtx, dyn_cast<DWARFCompileUnit>(CU.get())); |
464 pool.async([this, CUI, &LogMutex, Die]() mutable { | 479 pool.async([this, CUI, &LogMutex, Die]() mutable { |
465 std::string ThreadLogStorage; | 480 std::string ThreadLogStorage; |
466 raw_string_ostream ThreadOS(ThreadLogStorage); | 481 raw_string_ostream ThreadOS(ThreadLogStorage); |
531 Log << "error: address " << HEX64(Addr) << " has " | 546 Log << "error: address " << HEX64(Addr) << " has " |
532 << NumDwarfInlineInfos << " DWARF inline frames and GSYM has " | 547 << NumDwarfInlineInfos << " DWARF inline frames and GSYM has " |
533 << LR->Locations.size() << "\n"; | 548 << LR->Locations.size() << "\n"; |
534 Log << " " << NumDwarfInlineInfos << " DWARF frames:\n"; | 549 Log << " " << NumDwarfInlineInfos << " DWARF frames:\n"; |
535 for (size_t Idx = 0; Idx < NumDwarfInlineInfos; ++Idx) { | 550 for (size_t Idx = 0; Idx < NumDwarfInlineInfos; ++Idx) { |
536 const auto dii = DwarfInlineInfos.getFrame(Idx); | 551 const auto &dii = DwarfInlineInfos.getFrame(Idx); |
537 Log << " [" << Idx << "]: " << dii.FunctionName << " @ " | 552 Log << " [" << Idx << "]: " << dii.FunctionName << " @ " |
538 << dii.FileName << ':' << dii.Line << '\n'; | 553 << dii.FileName << ':' << dii.Line << '\n'; |
539 } | 554 } |
540 Log << " " << LR->Locations.size() << " GSYM frames:\n"; | 555 Log << " " << LR->Locations.size() << " GSYM frames:\n"; |
541 for (size_t Idx = 0, count = LR->Locations.size(); | 556 for (size_t Idx = 0, count = LR->Locations.size(); |
551 | 566 |
552 for (size_t Idx = 0, count = LR->Locations.size(); Idx < count; | 567 for (size_t Idx = 0, count = LR->Locations.size(); Idx < count; |
553 ++Idx) { | 568 ++Idx) { |
554 const auto &gii = LR->Locations[Idx]; | 569 const auto &gii = LR->Locations[Idx]; |
555 if (Idx < NumDwarfInlineInfos) { | 570 if (Idx < NumDwarfInlineInfos) { |
556 const auto dii = DwarfInlineInfos.getFrame(Idx); | 571 const auto &dii = DwarfInlineInfos.getFrame(Idx); |
557 gsymFilename = LR->getSourceFile(Idx); | 572 gsymFilename = LR->getSourceFile(Idx); |
558 // Verify function name | 573 // Verify function name |
559 if (dii.FunctionName.find(gii.Name.str()) != 0) | 574 if (dii.FunctionName.find(gii.Name.str()) != 0) |
560 Log << "error: address " << HEX64(Addr) << " DWARF function \"" | 575 Log << "error: address " << HEX64(Addr) << " DWARF function \"" |
561 << dii.FunctionName.c_str() | 576 << dii.FunctionName.c_str() |