|
36 | 36 | #include "llvm/Support/LEB128.h" |
37 | 37 | #include "llvm/Support/Path.h" |
38 | 38 | #include "llvm/Support/ThreadPool.h" |
| 39 | +#include <iostream> |
39 | 40 | #include <vector> |
40 | 41 |
|
41 | 42 | namespace llvm { |
@@ -2297,8 +2298,135 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) { |
2297 | 2298 |
|
2298 | 2299 | // Create a map of stmt sequence offsets to original row indices. |
2299 | 2300 | DenseMap<uint64_t, unsigned> SeqOffToOrigRow; |
2300 | | - for (const DWARFDebugLine::Sequence &Seq : LT->Sequences) |
2301 | | - SeqOffToOrigRow[Seq.StmtSeqOffset] = Seq.FirstRowIndex; |
| 2301 | + DenseMap<uint64_t, unsigned> LineTableMapping; |
| 2302 | + // The DWARF parser's discovery of sequences can be incomplete. To |
| 2303 | + // ensure all DW_AT_LLVM_stmt_sequence attributes can be patched, we |
| 2304 | + // build a map from both the parser's results and a manual |
| 2305 | + // reconstruction. |
| 2306 | + if (!LT->Rows.empty()) { |
| 2307 | + // First, trust the sequences that the DWARF parser did identify. |
| 2308 | + for (const DWARFDebugLine::Sequence &Seq : LT->Sequences) { |
| 2309 | + LineTableMapping[Seq.StmtSeqOffset] = Seq.FirstRowIndex; |
| 2310 | + } |
| 2311 | + |
| 2312 | + // Second, manually find sequence boundaries and match them to the |
| 2313 | + // sorted attributes to handle sequences the parser might have missed. |
| 2314 | + auto StmtAttrs = Unit.getStmtSeqListAttributes(); |
| 2315 | + llvm::sort(StmtAttrs, |
| 2316 | + [](const PatchLocation &A, const PatchLocation &B) { |
| 2317 | + return A.get() < B.get(); |
| 2318 | + }); |
| 2319 | + |
| 2320 | + std::vector<size_t> SeqStartRows; |
| 2321 | + SeqStartRows.push_back(0); |
| 2322 | + for (size_t i = 0; i < LT->Rows.size() - 1; ++i) |
| 2323 | + if (LT->Rows[i].EndSequence) |
| 2324 | + SeqStartRows.push_back(i + 1); |
| 2325 | + |
| 2326 | + // While SeqOffToOrigRow parsed from CU could be the ground truth, |
| 2327 | + // e.g. |
| 2328 | + // |
| 2329 | + // SeqOff Row |
| 2330 | + // 0x08 9 |
| 2331 | + // 0x14 15 |
| 2332 | + // |
| 2333 | + // The StmtAttrs and SeqStartRows may not match perfectly, e.g. |
| 2334 | + // |
| 2335 | + // StmtAttrs SeqStartRows |
| 2336 | + // 0x04 3 |
| 2337 | + // 0x08 5 |
| 2338 | + // 0x10 9 |
| 2339 | + // 0x12 11 |
| 2340 | + // 0x14 15 |
| 2341 | + // |
| 2342 | + // In this case, we don't want to assign 5 to 0x08, since we know 0x08 |
| 2343 | + // maps to 9. If we do a dummy 1:1 mapping 0x10 will be mapped to 9 |
| 2344 | + // which is incorrect. The expected behavior is ignore 5, realign the |
| 2345 | + // table based on the result from the line table: |
| 2346 | + // |
| 2347 | + // StmtAttrs SeqStartRows |
| 2348 | + // 0x04 3 |
| 2349 | + // -- 5 |
| 2350 | + // 0x08 9 <- LineTableMapping ground truth |
| 2351 | + // 0x10 11 |
| 2352 | + // 0x12 -- |
| 2353 | + // 0x14 15 <- LineTableMapping ground truth |
| 2354 | + |
| 2355 | + // Dummy last element to make sure StmtAttrIdx and SeqStartIdx always |
| 2356 | + // run out first. Can't directly use TombstoneKey/TombstoneVal, that's |
| 2357 | + // preserved. |
| 2358 | + constexpr size_t DummyKey = UINT64_MAX - 2; |
| 2359 | + constexpr unsigned DummyVal = UINT32_MAX - 2; |
| 2360 | + LineTableMapping[DummyKey] = DummyVal; |
| 2361 | + SmallVector<uint64_t> SortedLineTableKeys(LineTableMapping.keys()); |
| 2362 | + llvm::sort(SortedLineTableKeys); |
| 2363 | + for (auto Key : SortedLineTableKeys) { |
| 2364 | + std::cout << std::hex << Key << " " << LineTableMapping[Key] |
| 2365 | + << "\n"; |
| 2366 | + } |
| 2367 | + for (auto StmtAttr : StmtAttrs) { |
| 2368 | + std::cout << std::hex << StmtAttr.get() << "\n"; |
| 2369 | + } |
| 2370 | + for (auto Row : SeqStartRows) { |
| 2371 | + std::cout << std::hex << Row << "\n"; |
| 2372 | + } |
| 2373 | + |
| 2374 | + size_t StmtAttrIdx = 0, SeqStartIdx = 0; |
| 2375 | + size_t NextSeqOff = 0; |
| 2376 | + unsigned NextRow = 0; |
| 2377 | + |
| 2378 | + auto StmtIdxValidAndSmallerThanNext = [&]() { |
| 2379 | + return StmtAttrIdx < StmtAttrs.size() && |
| 2380 | + StmtAttrs[StmtAttrIdx].get() < NextSeqOff; |
| 2381 | + }; |
| 2382 | + |
| 2383 | + auto SeqStartIdxValidAndSmallerThanNext = [&]() { |
| 2384 | + return SeqStartIdx < SeqStartRows.size() && |
| 2385 | + SeqStartRows[SeqStartIdx] < NextRow; |
| 2386 | + }; |
| 2387 | + for (size_t i = 0; i < SortedLineTableKeys.size(); ++i) { |
| 2388 | + NextSeqOff = SortedLineTableKeys[i]; |
| 2389 | + NextRow = LineTableMapping[NextSeqOff]; |
| 2390 | + // If both StmtAttrs and SeqStartRows points to value not in |
| 2391 | + // the LineTableMapping yet, we do a dummy one to one mapping and |
| 2392 | + // move the pointer. |
| 2393 | + while (StmtIdxValidAndSmallerThanNext() && |
| 2394 | + SeqStartIdxValidAndSmallerThanNext()) { |
| 2395 | + SeqOffToOrigRow[StmtAttrs[StmtAttrIdx].get()] = |
| 2396 | + SeqStartRows[SeqStartIdx]; |
| 2397 | + ++StmtAttrIdx; |
| 2398 | + ++SeqStartIdx; |
| 2399 | + } |
| 2400 | + // One of the pointer points to the value at or past Next in the |
| 2401 | + // LineTableMapping, We move the pointer to re-align with the |
| 2402 | + // LineTableMapping |
| 2403 | + while (StmtIdxValidAndSmallerThanNext()) { |
| 2404 | + ++StmtAttrIdx; |
| 2405 | + } |
| 2406 | + while (SeqStartIdxValidAndSmallerThanNext()) { |
| 2407 | + ++SeqStartIdx; |
| 2408 | + } |
| 2409 | + // Use the LineTableMapping's result as the ground truth and move |
| 2410 | + // on. |
| 2411 | + SeqOffToOrigRow[NextSeqOff] = NextRow; |
| 2412 | + } |
| 2413 | + // size_t i = 0, j = 0; |
| 2414 | + // while (i < StmtAttrs.size() && j < SeqStartRows.size()) { |
| 2415 | + // auto It = SeqOffToOrigRow.find(StmtAttrs[i].get()); |
| 2416 | + // // The match is not set, use current result. |
| 2417 | + // if (It == SeqOffToOrigRow.end()) { |
| 2418 | + // SeqOffToOrigRow.try_emplace(StmtAttrs[i].get(), |
| 2419 | + // SeqStartRows[j]); |
| 2420 | + // } else { |
| 2421 | + // while (It->second != SeqStartRows[j] && j < |
| 2422 | + // SeqStartRows.size()) { |
| 2423 | + // ++j; |
| 2424 | + // } |
| 2425 | + // } |
| 2426 | + // ++i; |
| 2427 | + // ++j; |
| 2428 | + // } |
| 2429 | + } |
2302 | 2430 |
|
2303 | 2431 | // Create a map of original row indices to new row indices. |
2304 | 2432 | DenseMap<size_t, size_t> OrigRowToNewRow; |
|
0 commit comments