[llvm] [DWARFLinker] Fix matching logic to remove type 1 missing offsets (PR #149618)

Peter Rong via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 22 13:50:24 PDT 2025


https://github.com/DataCorrupted updated https://github.com/llvm/llvm-project/pull/149618

>From f9c446a12c878614b48b50058f7d976ff9cf0e02 Mon Sep 17 00:00:00 2001
From: Peter Rong <PeterRong at meta.com>
Date: Fri, 18 Jul 2025 10:09:02 -0700
Subject: [PATCH 1/8] [DWARFLinker] Fix matching logic to remove type 1 missing
 offsets and duplicated offsets

---
 llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp  | 132 ++-
 .../tools/dsymutil/ARM/stmt-seq-macho.test    | 778 +++++++++++-------
 2 files changed, 599 insertions(+), 311 deletions(-)

diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index 222dc88098102..5c2d15da5d315 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -36,6 +36,7 @@
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/ThreadPool.h"
+#include <iostream>
 #include <vector>
 
 namespace llvm {
@@ -2297,8 +2298,135 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
 
         // Create a map of stmt sequence offsets to original row indices.
         DenseMap<uint64_t, unsigned> SeqOffToOrigRow;
-        for (const DWARFDebugLine::Sequence &Seq : LT->Sequences)
-          SeqOffToOrigRow[Seq.StmtSeqOffset] = Seq.FirstRowIndex;
+        DenseMap<uint64_t, unsigned> LineTableMapping;
+        // The DWARF parser's discovery of sequences can be incomplete. To
+        // ensure all DW_AT_LLVM_stmt_sequence attributes can be patched, we
+        // build a map from both the parser's results and a manual
+        // reconstruction.
+        if (!LT->Rows.empty()) {
+          // First, trust the sequences that the DWARF parser did identify.
+          for (const DWARFDebugLine::Sequence &Seq : LT->Sequences) {
+            LineTableMapping[Seq.StmtSeqOffset] = Seq.FirstRowIndex;
+          }
+
+          // Second, manually find sequence boundaries and match them to the
+          // sorted attributes to handle sequences the parser might have missed.
+          auto StmtAttrs = Unit.getStmtSeqListAttributes();
+          llvm::sort(StmtAttrs,
+                     [](const PatchLocation &A, const PatchLocation &B) {
+                       return A.get() < B.get();
+                     });
+
+          std::vector<size_t> SeqStartRows;
+          SeqStartRows.push_back(0);
+          for (size_t i = 0; i < LT->Rows.size() - 1; ++i)
+            if (LT->Rows[i].EndSequence)
+              SeqStartRows.push_back(i + 1);
+
+          // While SeqOffToOrigRow parsed from CU could be the ground truth,
+          // e.g.
+          //
+          // SeqOff     Row
+          // 0x08        9
+          // 0x14       15
+          //
+          // The StmtAttrs and SeqStartRows may not match perfectly, e.g.
+          //
+          // StmtAttrs  SeqStartRows
+          // 0x04        3
+          // 0x08        5
+          // 0x10        9
+          // 0x12       11
+          // 0x14       15
+          //
+          // In this case, we don't want to assign 5 to 0x08, since we know 0x08
+          // maps to 9. If we do a dummy 1:1 mapping 0x10 will be mapped to 9
+          // which is incorrect. The expected behavior is ignore 5, realign the
+          // table based on the result from the line table:
+          //
+          // StmtAttrs  SeqStartRows
+          // 0x04        3
+          //   --        5
+          // 0x08        9 <- LineTableMapping ground truth
+          // 0x10       11
+          // 0x12       --
+          // 0x14       15 <- LineTableMapping ground truth
+
+          // Dummy last element to make sure StmtAttrIdx and SeqStartIdx always
+          // run out first. Can't directly use TombstoneKey/TombstoneVal, that's
+          // preserved.
+          constexpr size_t DummyKey = UINT64_MAX - 2;
+          constexpr unsigned DummyVal = UINT32_MAX - 2;
+          LineTableMapping[DummyKey] = DummyVal;
+          SmallVector<uint64_t> SortedLineTableKeys(LineTableMapping.keys());
+          llvm::sort(SortedLineTableKeys);
+          for (auto Key : SortedLineTableKeys) {
+            std::cout << std::hex << Key << " " << LineTableMapping[Key]
+                      << "\n";
+          }
+          for (auto StmtAttr : StmtAttrs) {
+            std::cout << std::hex << StmtAttr.get() << "\n";
+          }
+          for (auto Row : SeqStartRows) {
+            std::cout << std::hex << Row << "\n";
+          }
+
+          size_t StmtAttrIdx = 0, SeqStartIdx = 0;
+          size_t NextSeqOff = 0;
+          unsigned NextRow = 0;
+
+          auto StmtIdxValidAndSmallerThanNext = [&]() {
+            return StmtAttrIdx < StmtAttrs.size() &&
+                   StmtAttrs[StmtAttrIdx].get() < NextSeqOff;
+          };
+
+          auto SeqStartIdxValidAndSmallerThanNext = [&]() {
+            return SeqStartIdx < SeqStartRows.size() &&
+                   SeqStartRows[SeqStartIdx] < NextRow;
+          };
+          for (size_t i = 0; i < SortedLineTableKeys.size(); ++i) {
+            NextSeqOff = SortedLineTableKeys[i];
+            NextRow = LineTableMapping[NextSeqOff];
+            // If both StmtAttrs and SeqStartRows points to value not in
+            // the LineTableMapping yet, we do a dummy one to one mapping and
+            // move the pointer.
+            while (StmtIdxValidAndSmallerThanNext() &&
+                   SeqStartIdxValidAndSmallerThanNext()) {
+              SeqOffToOrigRow[StmtAttrs[StmtAttrIdx].get()] =
+                  SeqStartRows[SeqStartIdx];
+              ++StmtAttrIdx;
+              ++SeqStartIdx;
+            }
+            // One of the pointer points to the value at or past Next in the
+            // LineTableMapping, We move the pointer to re-align with the
+            // LineTableMapping
+            while (StmtIdxValidAndSmallerThanNext()) {
+              ++StmtAttrIdx;
+            }
+            while (SeqStartIdxValidAndSmallerThanNext()) {
+              ++SeqStartIdx;
+            }
+            // Use the LineTableMapping's result as the ground truth and move
+            // on.
+            SeqOffToOrigRow[NextSeqOff] = NextRow;
+          }
+          // size_t i = 0, j = 0;
+          // while (i < StmtAttrs.size() && j < SeqStartRows.size()) {
+          //   auto It = SeqOffToOrigRow.find(StmtAttrs[i].get());
+          //   // The match is not set, use current result.
+          //   if (It == SeqOffToOrigRow.end()) {
+          //     SeqOffToOrigRow.try_emplace(StmtAttrs[i].get(),
+          //     SeqStartRows[j]);
+          //   } else {
+          //     while (It->second != SeqStartRows[j] && j <
+          //     SeqStartRows.size()) {
+          //       ++j;
+          //     }
+          //   }
+          //   ++i;
+          //   ++j;
+          // }
+        }
 
         // Create a map of original row indices to new row indices.
         DenseMap<size_t, size_t> OrigRowToNewRow;
diff --git a/llvm/test/tools/dsymutil/ARM/stmt-seq-macho.test b/llvm/test/tools/dsymutil/ARM/stmt-seq-macho.test
index f2fe794e1b484..db223cda43247 100644
--- a/llvm/test/tools/dsymutil/ARM/stmt-seq-macho.test
+++ b/llvm/test/tools/dsymutil/ARM/stmt-seq-macho.test
@@ -5,7 +5,13 @@
 # RUN: yaml2obj %t/stmt_seq_macho.o.yaml   -o %t/stmt_seq_macho.o
 # RUN: dsymutil --flat --verify-dwarf=none -oso-prepend-path %t %t/stmt_seq_macho.exe -o %t/stmt_seq_macho.dSYM
 # RUN: llvm-dwarfdump --debug-info --debug-line -v %t/stmt_seq_macho.dSYM | sort | FileCheck %s -check-prefix=CHECK_DSYM
+# RUN: llvm-dwarfdump --debug-info --debug-line -v %t/stmt_seq_macho.dSYM > %t/stmt_seq_macho.dSYM.txt
+# RUN: cat %t/stmt_seq_macho.dSYM.txt | sort | FileCheck %s -check-prefix=CHECK_DSYM
+# RUN: cat %t/stmt_seq_macho.dSYM.txt | FileCheck %s -check-prefix=CHECK_NO_INVALID_OFFSET
+# RUN: cat stmt_seq_macho.dSYM.txt | grep DW_AT_LLVM_stmt_sequence | sort | uniq -d | wc -l | FileCheck %s -check-prefix=CHECK_NO_DUPLICATES
 
+# CHECK_NO_DUPLICATES: 0
+# CHECK_NO_INVALID_OFFSET-NOT: DW_AT_LLVM_stmt_sequence{{.*}}0xfffffff
 # CHECK_DSYM: DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset] ([[OFFSET1:(0x[0-9a-f]+)]])
 # CHECK_DSYM: DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset] ([[OFFSET2:(0x[0-9a-f]+)]])
 # CHECK_DSYM: DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset] ([[OFFSET3:(0x[0-9a-f]+)]])
@@ -18,6 +24,9 @@
 
 #--- stmt_seq_macho.cpp
 #define ATTRIB extern "C" __attribute__((noinline))
+ATTRIB int function1_copy1(int a) {
+  return ++a;
+}
 
 ATTRIB int function3_copy1(int a) {
     int b = a + 3;
@@ -51,6 +60,7 @@ int main() {
     sum += function2_copy2(3);
     sum += function3_copy2(41);
     sum += function2_copy1(11);
+    sum += function1_copy1(42);
     length_error e("test");
     return sum;
 }
@@ -108,9 +118,9 @@ LoadCommands:
     cmdsize:         1032
     segname:         ''
     vmaddr:          0
-    vmsize:          2793
+    vmsize:          3125
     fileoff:         1208
-    filesize:        2793
+    filesize:        3125
     maxprot:         7
     initprot:        7
     nsects:          12
@@ -119,18 +129,18 @@ LoadCommands:
       - sectname:        __text
         segname:         __TEXT
         addr:            0x0
-        size:            128
+        size:            148
         offset:          0x4B8
         align:           2
-        reloff:          0xFA8
-        nreloc:          7
+        reloff:          0x10F0
+        nreloc:          8
         flags:           0x80000400
         reserved1:       0x0
         reserved2:       0x0
         reserved3:       0x0
-        content:         00100011C0035FD600580051C0035FD600100011C0035FD600580051C0035FD6FFC300D1F44F01A9FD7B02A9FD8300916000805200000094F30300AA20058052000000941400130B6001805200000094F30300AA0100009021000091E03F0091000000948002130BFD7B42A9F44F41A9FFC30091C0035FD600000014C0035FD6
+        content:         00040011C0035FD600100011C0035FD600580051C0035FD600100011C0035FD600580051C0035FD6FFC300D1F44F01A9FD7B02A9FD8300916000805200000094F30300AA20058052000000941400130B6001805200000094F30300AA40058052000000947302000B0100009021000091E03F0091000000948002130BFD7B42A9F44F41A9FFC30091C0035FD600000014C0035FD6
         relocations:
-          - address:         0x78
+          - address:         0x8C
             symbolnum:       4
             pcrel:           true
             length:          2
@@ -138,7 +148,7 @@ LoadCommands:
             type:            2
             scattered:       false
             value:           0
-          - address:         0x60
+          - address:         0x74
             symbolnum:       3
             pcrel:           true
             length:          2
@@ -146,7 +156,7 @@ LoadCommands:
             type:            2
             scattered:       false
             value:           0
-          - address:         0x58
+          - address:         0x6C
             symbolnum:       1
             pcrel:           false
             length:          2
@@ -154,7 +164,7 @@ LoadCommands:
             type:            4
             scattered:       false
             value:           0
-          - address:         0x54
+          - address:         0x68
             symbolnum:       1
             pcrel:           true
             length:          2
@@ -162,7 +172,7 @@ LoadCommands:
             type:            3
             scattered:       false
             value:           0
-          - address:         0x4C
+          - address:         0x60
             symbolnum:       5
             pcrel:           true
             length:          2
@@ -170,16 +180,24 @@ LoadCommands:
             type:            2
             scattered:       false
             value:           0
-          - address:         0x40
-            symbolnum:       8
+          - address:         0x54
+            symbolnum:       6
             pcrel:           true
             length:          2
             extern:          true
             type:            2
             scattered:       false
             value:           0
-          - address:         0x34
-            symbolnum:       6
+          - address:         0x48
+            symbolnum:       9
+            pcrel:           true
+            length:          2
+            extern:          true
+            type:            2
+            scattered:       false
+            value:           0
+          - address:         0x3C
+            symbolnum:       7
             pcrel:           true
             length:          2
             extern:          true
@@ -188,9 +206,9 @@ LoadCommands:
             value:           0
       - sectname:        __cstring
         segname:         __TEXT
-        addr:            0x80
+        addr:            0x94
         size:            5
-        offset:          0x538
+        offset:          0x54C
         align:           0
         reloff:          0x0
         nreloc:          0
@@ -201,9 +219,9 @@ LoadCommands:
         content:         '7465737400'
       - sectname:        __debug_loc
         segname:         __DWARF
-        addr:            0x85
+        addr:            0x99
         size:            412
-        offset:          0x53D
+        offset:          0x551
         align:           0
         reloff:          0x0
         nreloc:          0
@@ -211,12 +229,12 @@ LoadCommands:
         reserved1:       0x0
         reserved2:       0x0
         reserved3:       0x0
-        content:         00000000000000000400000000000000010050040000000000000008000000000000000400A301509F0000000000000000000000000000000000000000000000000400000000000000030070039F0000000000000000000000000000000008000000000000000C000000000000000100500C0000000000000010000000000000000400A301509F0000000000000000000000000000000010000000000000001400000000000000010050140000000000000018000000000000000400A301509F0000000000000000000000000000000010000000000000001400000000000000030070039F0000000000000000000000000000000018000000000000001C000000000000000100501C0000000000000020000000000000000400A301509F000000000000000000000000000000001C0000000000000020000000000000000100500000000000000000000000000000000030000000000000003C00000000000000030011009F3C0000000000000048000000000000000100634800000000000000540000000000000001006400000000000000000000000000000000
+        content:         08000000000000000C000000000000000100500C0000000000000010000000000000000400A301509F0000000000000000000000000000000008000000000000000C00000000000000030070039F0000000000000000000000000000000010000000000000001400000000000000010050140000000000000018000000000000000400A301509F0000000000000000000000000000000018000000000000001C000000000000000100501C0000000000000020000000000000000400A301509F0000000000000000000000000000000018000000000000001C00000000000000030070039F0000000000000000000000000000000020000000000000002400000000000000010050240000000000000028000000000000000400A301509F00000000000000000000000000000000240000000000000028000000000000000100500000000000000000000000000000000038000000000000004400000000000000030011009F4400000000000000500000000000000001006350000000000000005C0000000000000001006400000000000000000000000000000000
       - sectname:        __debug_abbrev
         segname:         __DWARF
-        addr:            0x221
-        size:            359
-        offset:          0x6D9
+        addr:            0x235
+        size:            372
+        offset:          0x6ED
         align:           0
         reloff:          0x0
         nreloc:          0
@@ -226,18 +244,34 @@ LoadCommands:
         reserved3:       0x0
       - sectname:        __debug_info
         segname:         __DWARF
-        addr:            0x388
-        size:            686
-        offset:          0x840
+        addr:            0x3A9
+        size:            747
+        offset:          0x861
         align:           0
-        reloff:          0xFE0
-        nreloc:          14
+        reloff:          0x1130
+        nreloc:          16
         flags:           0x2000000
         reserved1:       0x0
         reserved2:       0x0
         reserved3:       0x0
         relocations:
-          - address:         0x26A
+          - address:         0x2A7
+            symbolnum:       1
+            pcrel:           false
+            length:          3
+            extern:          false
+            type:            0
+            scattered:       false
+            value:           0
+          - address:         0x28E
+            symbolnum:       1
+            pcrel:           false
+            length:          3
+            extern:          false
+            type:            0
+            scattered:       false
+            value:           0
+          - address:         0x253
             symbolnum:       1
             pcrel:           false
             length:          3
@@ -245,7 +279,7 @@ LoadCommands:
             type:            0
             scattered:       false
             value:           0
-          - address:         0x251
+          - address:         0x1F5
             symbolnum:       1
             pcrel:           false
             length:          3
@@ -253,7 +287,7 @@ LoadCommands:
             type:            0
             scattered:       false
             value:           0
-          - address:         0x216
+          - address:         0x1E1
             symbolnum:       1
             pcrel:           false
             length:          3
@@ -261,7 +295,7 @@ LoadCommands:
             type:            0
             scattered:       false
             value:           0
-          - address:         0x1B8
+          - address:         0x1CE
             symbolnum:       1
             pcrel:           false
             length:          3
@@ -269,7 +303,7 @@ LoadCommands:
             type:            0
             scattered:       false
             value:           0
-          - address:         0x1A5
+          - address:         0x1BA
             symbolnum:       1
             pcrel:           false
             length:          3
@@ -277,7 +311,7 @@ LoadCommands:
             type:            0
             scattered:       false
             value:           0
-          - address:         0x191
+          - address:         0x1A7
             symbolnum:       1
             pcrel:           false
             length:          3
@@ -285,7 +319,7 @@ LoadCommands:
             type:            0
             scattered:       false
             value:           0
-          - address:         0x17E
+          - address:         0x169
             symbolnum:       1
             pcrel:           false
             length:          3
@@ -293,7 +327,7 @@ LoadCommands:
             type:            0
             scattered:       false
             value:           0
-          - address:         0x140
+          - address:         0x12D
             symbolnum:       1
             pcrel:           false
             length:          3
@@ -301,7 +335,7 @@ LoadCommands:
             type:            0
             scattered:       false
             value:           0
-          - address:         0x104
+          - address:         0xF1
             symbolnum:       1
             pcrel:           false
             length:          3
@@ -309,7 +343,7 @@ LoadCommands:
             type:            0
             scattered:       false
             value:           0
-          - address:         0xC8
+          - address:         0xC4
             symbolnum:       1
             pcrel:           false
             length:          3
@@ -317,7 +351,7 @@ LoadCommands:
             type:            0
             scattered:       false
             value:           0
-          - address:         0x9B
+          - address:         0x88
             symbolnum:       1
             pcrel:           false
             length:          3
@@ -351,9 +385,9 @@ LoadCommands:
             value:           0
       - sectname:        __debug_str
         segname:         __DWARF
-        addr:            0x636
-        size:            239
-        offset:          0xAEE
+        addr:            0x694
+        size:            400
+        offset:          0xB4C
         align:           0
         reloff:          0x0
         nreloc:          0
@@ -363,9 +397,9 @@ LoadCommands:
         reserved3:       0x0
       - sectname:        __apple_names
         segname:         __DWARF
-        addr:            0x725
-        size:            260
-        offset:          0xBDD
+        addr:            0x824
+        size:            288
+        offset:          0xCDC
         align:           0
         reloff:          0x0
         nreloc:          0
@@ -373,12 +407,12 @@ LoadCommands:
         reserved1:       0x0
         reserved2:       0x0
         reserved3:       0x0
-        content:         485341480100000008000000080000000C000000000000000100000001000600000000000200000005000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90D9F86F88CB36CF4908311CD1125E5389CB36CF4A08311C522B70536A7F9A7C8000000094000000A4000000B4000000C4000000D4000000E4000000F40000008A0000000200000015020000690200000000000055000000010000009A0000000000000045000000010000005E00000000000000A3000000010000001502000000000000750000000100000003010000000000006500000001000000C700000000000000BB00000001000000690200000000000085000000010000003F01000000000000
+        content:         485341480100000009000000090000000C00000000000000010000000100060000000000FFFFFFFFFFFFFFFF0100000003000000040000000600000007000000080000004A08311CC78E3C8288CB36CF89CB36CFD1125E53522B705390D9F86F6A7F9A7C4908311C8C0000009C000000AC000000BC000000CC000000DC000000EC00000000010000100100000601000001000000F000000000000000D6000000010000005E00000000000000F600000001000000C30000000000000016010000010000002C01000000000000440100000100000052020000000000005C01000001000000A6020000000000002B0100000200000052020000A60200000000000026010000010000006801000000000000E6000000010000008700000000000000
       - sectname:        __apple_objc
         segname:         __DWARF
-        addr:            0x829
+        addr:            0x944
         size:            36
-        offset:          0xCE1
+        offset:          0xDFC
         align:           0
         reloff:          0x0
         nreloc:          0
@@ -389,9 +423,9 @@ LoadCommands:
         content:         485341480100000001000000000000000C000000000000000100000001000600FFFFFFFF
       - sectname:        __apple_namespac
         segname:         __DWARF
-        addr:            0x84D
+        addr:            0x968
         size:            36
-        offset:          0xD05
+        offset:          0xE20
         align:           0
         reloff:          0x0
         nreloc:          0
@@ -402,9 +436,9 @@ LoadCommands:
         content:         485341480100000001000000000000000C000000000000000100000001000600FFFFFFFF
       - sectname:        __apple_types
         segname:         __DWARF
-        addr:            0x871
+        addr:            0x98C
         size:            195
-        offset:          0xD29
+        offset:          0xE44
         align:           0
         reloff:          0x0
         nreloc:          0
@@ -412,21 +446,29 @@ LoadCommands:
         reserved1:       0x0
         reserved2:       0x0
         reserved3:       0x0
-        content:         48534148010000000500000005000000140000000000000003000000010006000300050004000B000000000002000000FFFFFFFF03000000040000007CA8F05D90D9F86F5B738CDC3080880B6320957C64000000770000008A0000009D000000B00000009700000001000000EA010000130000000000008A00000001000000C80100001300000000000031000000010000005700000024000000000000D300000001000000A1020000240000000000002C000000010000005000000024000000000000
+        content:         48534148010000000500000005000000140000000000000003000000010006000300050004000B000000000002000000FFFFFFFF03000000040000007CA8F05D90D9F86F5B738CDC3080880B6320957C64000000770000008A0000009D000000B0000000380100000100000027020000130000000000002B010000010000000502000013000000000000C20000000100000057000000240000000000007401000001000000DE02000024000000000000BD000000010000005000000024000000000000
       - sectname:        __debug_frame
         segname:         __DWARF
-        addr:            0x938
-        size:            208
-        offset:          0xDF0
+        addr:            0xA50
+        size:            232
+        offset:          0xF08
         align:           3
-        reloff:          0x1050
-        nreloc:          7
+        reloff:          0x11B0
+        nreloc:          8
         flags:           0x2000000
         reserved1:       0x0
         reserved2:       0x0
         reserved3:       0x0
-        content:         14000000FFFFFFFF0400080001781E0C1F00000000000000140000000000000000000000000000000800000000000000140000000000000008000000000000000800000000000000140000000000000010000000000000000800000000000000140000000000000018000000000000000800000000000000240000000000000020000000000000005800000000000000500C1D109E019D02930394040000000014000000000000007800000000000000040000000000000014000000000000007C000000000000000400000000000000
+        content:         14000000FFFFFFFF0400080001781E0C1F00000000000000140000000000000000000000000000000800000000000000140000000000000008000000000000000800000000000000140000000000000010000000000000000800000000000000140000000000000018000000000000000800000000000000140000000000000020000000000000000800000000000000240000000000000028000000000000006400000000000000500C1D109E019D02930394040000000014000000000000008C000000000000000400000000000000140000000000000090000000000000000400000000000000
         relocations:
+          - address:         0xD8
+            symbolnum:       1
+            pcrel:           false
+            length:          3
+            extern:          false
+            type:            0
+            scattered:       false
+            value:           0
           - address:         0xC0
             symbolnum:       1
             pcrel:           false
@@ -435,7 +477,7 @@ LoadCommands:
             type:            0
             scattered:       false
             value:           0
-          - address:         0xA8
+          - address:         0x98
             symbolnum:       1
             pcrel:           false
             length:          3
@@ -485,18 +527,26 @@ LoadCommands:
             value:           0
       - sectname:        __debug_line
         segname:         __DWARF
-        addr:            0xA08
-        size:            225
-        offset:          0xEC0
+        addr:            0xB38
+        size:            253
+        offset:          0xFF0
         align:           0
-        reloff:          0x1088
-        nreloc:          7
+        reloff:          0x11F0
+        nreloc:          8
         flags:           0x2000000
         reserved1:       0x0
         reserved2:       0x0
         reserved3:       0x0
         relocations:
-          - address:         0xD1
+          - address:         0xED
+            symbolnum:       1
+            pcrel:           false
+            length:          3
+            extern:          false
+            type:            0
+            scattered:       false
+            value:           0
+          - address:         0xD9
             symbolnum:       1
             pcrel:           false
             length:          3
@@ -504,7 +554,7 @@ LoadCommands:
             type:            0
             scattered:       false
             value:           0
-          - address:         0xBD
+          - address:         0xAA
             symbolnum:       1
             pcrel:           false
             length:          3
@@ -512,7 +562,7 @@ LoadCommands:
             type:            0
             scattered:       false
             value:           0
-          - address:         0x92
+          - address:         0x96
             symbolnum:       1
             pcrel:           false
             length:          3
@@ -560,21 +610,21 @@ LoadCommands:
     ntools:          0
   - cmd:             LC_LINKER_OPTIMIZATION_HINT
     cmdsize:         16
-    dataoff:         4288
+    dataoff:         4656
     datasize:        8
   - cmd:             LC_SYMTAB
     cmdsize:         24
-    symoff:          4296
-    nsyms:           10
-    stroff:          4456
-    strsize:         144
+    symoff:          4664
+    nsyms:           11
+    stroff:          4840
+    strsize:         168
   - cmd:             LC_DYSYMTAB
     cmdsize:         80
     ilocalsym:       0
     nlocalsym:       3
     iextdefsym:      3
-    nextdefsym:      7
-    iundefsym:       10
+    nextdefsym:      8
+    iundefsym:       11
     nundefsym:       0
     tocoff:          0
     ntoc:            0
@@ -590,7 +640,7 @@ LoadCommands:
     nlocrel:         0
 LinkEditData:
   NameList:
-    - n_strx:          138
+    - n_strx:          155
       n_type:          0xE
       n_sect:          1
       n_desc:          0
@@ -599,47 +649,52 @@ LinkEditData:
       n_type:          0xE
       n_sect:          2
       n_desc:          0
-      n_value:         128
-    - n_strx:          132
+      n_value:         148
+    - n_strx:          149
       n_type:          0xE
       n_sect:          2
       n_desc:          0
-      n_value:         128
+      n_value:         148
     - n_strx:          39
       n_type:          0xF
       n_sect:          1
       n_desc:          192
-      n_value:         120
+      n_value:         140
     - n_strx:          14
       n_type:          0xF
       n_sect:          1
       n_desc:          192
-      n_value:         124
+      n_value:         144
+    - n_strx:          132
+      n_type:          0xF
+      n_sect:          1
+      n_desc:          0
+      n_value:         0
     - n_strx:          115
       n_type:          0xF
       n_sect:          1
       n_desc:          0
-      n_value:         8
+      n_value:         16
     - n_strx:          81
       n_type:          0xF
       n_sect:          1
       n_desc:          0
-      n_value:         24
+      n_value:         32
     - n_strx:          98
       n_type:          0xF
       n_sect:          1
       n_desc:          0
-      n_value:         0
+      n_value:         8
     - n_strx:          64
       n_type:          0xF
       n_sect:          1
       n_desc:          0
-      n_value:         16
+      n_value:         24
     - n_strx:          8
       n_type:          0xF
       n_sect:          1
       n_desc:          0
-      n_value:         32
+      n_value:         40
   StringTable:
     - ''
     - l_.str
@@ -650,16 +705,25 @@ LinkEditData:
     - _function2_copy2
     - _function3_copy1
     - _function2_copy1
+    - _function1_copy1
     - ltmp1
     - ltmp0
+    - ''
+    - ''
+    - ''
+    - ''
+    - ''
+    - ''
+    - ''
 DWARF:
   debug_str:
-    - ''
+    - 'Facebook clang version 19.1.5 (https://git.internal.tfbnw.net/repos/git/rw/osmeta/external/llvm-project b36c9ae1f8f2b39e4aafb9ca4700c608c3036365)'
     - stmt_seq_macho.cpp
     - '/'
     - '/private/tmp/stmt_seq'
     - char
     - __ARRAY_SIZE_TYPE__
+    - function1_copy1
     - function3_copy1
     - function2_copy1
     - function3_copy2
@@ -783,6 +847,18 @@ DWARF:
             - Attribute:       DW_AT_APPLE_optimized
               Form:            DW_FORM_flag_present
         - Code:            0x9
+          Tag:             DW_TAG_formal_parameter
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+            - Attribute:       DW_AT_decl_file
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_decl_line
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref4
+        - Code:            0xA
           Tag:             DW_TAG_formal_parameter
           Children:        DW_CHILDREN_no
           Attributes:
@@ -796,7 +872,7 @@ DWARF:
               Form:            DW_FORM_data1
             - Attribute:       DW_AT_type
               Form:            DW_FORM_ref4
-        - Code:            0xA
+        - Code:            0xB
           Tag:             DW_TAG_variable
           Children:        DW_CHILDREN_no
           Attributes:
@@ -810,7 +886,7 @@ DWARF:
               Form:            DW_FORM_data1
             - Attribute:       DW_AT_type
               Form:            DW_FORM_ref4
-        - Code:            0xB
+        - Code:            0xC
           Tag:             DW_TAG_subprogram
           Children:        DW_CHILDREN_yes
           Attributes:
@@ -836,7 +912,7 @@ DWARF:
               Form:            DW_FORM_flag_present
             - Attribute:       DW_AT_APPLE_optimized
               Form:            DW_FORM_flag_present
-        - Code:            0xC
+        - Code:            0xD
           Tag:             DW_TAG_variable
           Children:        DW_CHILDREN_no
           Attributes:
@@ -850,7 +926,7 @@ DWARF:
               Form:            DW_FORM_data1
             - Attribute:       DW_AT_type
               Form:            DW_FORM_ref4
-        - Code:            0xD
+        - Code:            0xE
           Tag:             DW_TAG_call_site
           Children:        DW_CHILDREN_yes
           Attributes:
@@ -858,7 +934,7 @@ DWARF:
               Form:            DW_FORM_ref4
             - Attribute:       DW_AT_call_return_pc
               Form:            DW_FORM_addr
-        - Code:            0xE
+        - Code:            0xF
           Tag:             DW_TAG_call_site_parameter
           Children:        DW_CHILDREN_no
           Attributes:
@@ -866,7 +942,7 @@ DWARF:
               Form:            DW_FORM_exprloc
             - Attribute:       DW_AT_call_value
               Form:            DW_FORM_exprloc
-        - Code:            0xF
+        - Code:            0x10
           Tag:             DW_TAG_structure_type
           Children:        DW_CHILDREN_yes
           Attributes:
@@ -880,7 +956,7 @@ DWARF:
               Form:            DW_FORM_data1
             - Attribute:       DW_AT_decl_line
               Form:            DW_FORM_data1
-        - Code:            0x10
+        - Code:            0x11
           Tag:             DW_TAG_inheritance
           Children:        DW_CHILDREN_no
           Attributes:
@@ -888,7 +964,7 @@ DWARF:
               Form:            DW_FORM_ref4
             - Attribute:       DW_AT_data_member_location
               Form:            DW_FORM_data1
-        - Code:            0x11
+        - Code:            0x12
           Tag:             DW_TAG_subprogram
           Children:        DW_CHILDREN_yes
           Attributes:
@@ -906,7 +982,7 @@ DWARF:
               Form:            DW_FORM_flag_present
             - Attribute:       DW_AT_explicit
               Form:            DW_FORM_flag_present
-        - Code:            0x12
+        - Code:            0x13
           Tag:             DW_TAG_formal_parameter
           Children:        DW_CHILDREN_no
           Attributes:
@@ -914,13 +990,13 @@ DWARF:
               Form:            DW_FORM_ref4
             - Attribute:       DW_AT_artificial
               Form:            DW_FORM_flag_present
-        - Code:            0x13
+        - Code:            0x14
           Tag:             DW_TAG_formal_parameter
           Children:        DW_CHILDREN_no
           Attributes:
             - Attribute:       DW_AT_type
               Form:            DW_FORM_ref4
-        - Code:            0x14
+        - Code:            0x15
           Tag:             DW_TAG_subprogram
           Children:        DW_CHILDREN_yes
           Attributes:
@@ -936,13 +1012,13 @@ DWARF:
               Form:            DW_FORM_flag_present
             - Attribute:       DW_AT_APPLE_optimized
               Form:            DW_FORM_flag_present
-        - Code:            0x15
+        - Code:            0x16
           Tag:             DW_TAG_pointer_type
           Children:        DW_CHILDREN_no
           Attributes:
             - Attribute:       DW_AT_type
               Form:            DW_FORM_ref4
-        - Code:            0x16
+        - Code:            0x17
           Tag:             DW_TAG_subprogram
           Children:        DW_CHILDREN_yes
           Attributes:
@@ -964,7 +1040,7 @@ DWARF:
               Form:            DW_FORM_strp
             - Attribute:       DW_AT_specification
               Form:            DW_FORM_ref4
-        - Code:            0x17
+        - Code:            0x18
           Tag:             DW_TAG_formal_parameter
           Children:        DW_CHILDREN_no
           Attributes:
@@ -976,7 +1052,7 @@ DWARF:
               Form:            DW_FORM_ref4
             - Attribute:       DW_AT_artificial
               Form:            DW_FORM_flag_present
-        - Code:            0x18
+        - Code:            0x19
           Tag:             DW_TAG_formal_parameter
           Children:        DW_CHILDREN_no
           Attributes:
@@ -990,7 +1066,7 @@ DWARF:
               Form:            DW_FORM_data1
             - Attribute:       DW_AT_type
               Form:            DW_FORM_ref4
-        - Code:            0x19
+        - Code:            0x1A
           Tag:             DW_TAG_call_site
           Children:        DW_CHILDREN_yes
           Attributes:
@@ -1001,7 +1077,7 @@ DWARF:
             - Attribute:       DW_AT_call_pc
               Form:            DW_FORM_addr
   debug_info:
-    - Length:          0x2AA
+    - Length:          0x2E7
       Version:         4
       AbbrevTableID:   0
       AbbrOffset:      0x0
@@ -1011,20 +1087,20 @@ DWARF:
           Values:
             - Value:           0x0
             - Value:           0x21
-            - Value:           0x1
-            - Value:           0x14
+            - Value:           0x92
+            - Value:           0xA5
             - Value:           0x0
-            - Value:           0x16
+            - Value:           0xA7
             - Value:           0x1
             - Value:           0x0
-            - Value:           0x80
+            - Value:           0x94
         - AbbrCode:        0x2
           Values:
             - Value:           0x3F
             - Value:           0x1
-            - Value:           0x23
+            - Value:           0x27
             - Value:           0x9
-              BlockData:       [ 0x3, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
+              BlockData:       [ 0x3, 0x94, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
                                  0x0 ]
         - AbbrCode:        0x3
           Values:
@@ -1039,12 +1115,12 @@ DWARF:
             - Value:           0x50
         - AbbrCode:        0x6
           Values:
-            - Value:           0x2C
+            - Value:           0xBD
             - Value:           0x6
             - Value:           0x1
         - AbbrCode:        0x7
           Values:
-            - Value:           0x31
+            - Value:           0xC2
             - Value:           0x8
             - Value:           0x7
         - AbbrCode:        0x8
@@ -1056,177 +1132,210 @@ DWARF:
             - Value:           0x1
               BlockData:       [ 0x6F ]
             - Value:           0x1
-            - Value:           0x45
+            - Value:           0xD6
             - Value:           0x1
-            - Value:           0x3
-            - Value:           0x2A1
+            - Value:           0x2
+            - Value:           0x2DE
             - Value:           0x1
             - Value:           0x1
         - AbbrCode:        0x9
           Values:
-            - Value:           0x0
-            - Value:           0xD7
+            - Value:           0x178
+            - Value:           0x1
+            - Value:           0x2
+            - Value:           0x2DE
+        - AbbrCode:        0x0
+        - AbbrCode:        0x8
+          Values:
+            - Value:           0x8
+            - Value:           0x8
+            - Value:           0x1
+            - Value:           0x4A
+            - Value:           0x1
+              BlockData:       [ 0x6F ]
+            - Value:           0x1
+            - Value:           0xE6
+            - Value:           0x1
+            - Value:           0x6
+            - Value:           0x2DE
+            - Value:           0x1
             - Value:           0x1
-            - Value:           0x3
-            - Value:           0x2A1
         - AbbrCode:        0xA
+          Values:
+            - Value:           0x0
+            - Value:           0x178
+            - Value:           0x1
+            - Value:           0x6
+            - Value:           0x2DE
+        - AbbrCode:        0xB
           Values:
             - Value:           0x39
-            - Value:           0xD9
+            - Value:           0x17A
             - Value:           0x1
-            - Value:           0x4
-            - Value:           0x2A1
+            - Value:           0x7
+            - Value:           0x2DE
         - AbbrCode:        0x0
         - AbbrCode:        0x8
           Values:
-            - Value:           0x8
+            - Value:           0x10
             - Value:           0x8
             - Value:           0x1
-            - Value:           0x4A
+            - Value:           0x60
             - Value:           0x1
               BlockData:       [ 0x6F ]
             - Value:           0x1
-            - Value:           0x55
+            - Value:           0xF6
             - Value:           0x1
-            - Value:           0x8
-            - Value:           0x2A1
+            - Value:           0xB
+            - Value:           0x2DE
             - Value:           0x1
             - Value:           0x1
-        - AbbrCode:        0x9
+        - AbbrCode:        0xA
           Values:
             - Value:           0x5E
-            - Value:           0xD7
+            - Value:           0x178
             - Value:           0x1
-            - Value:           0x8
-            - Value:           0x2A1
+            - Value:           0xB
+            - Value:           0x2DE
         - AbbrCode:        0x0
         - AbbrCode:        0x8
           Values:
-            - Value:           0x10
+            - Value:           0x18
             - Value:           0x8
             - Value:           0x1
-            - Value:           0x60
+            - Value:           0x78
             - Value:           0x1
               BlockData:       [ 0x6F ]
             - Value:           0x1
-            - Value:           0x65
+            - Value:           0x106
             - Value:           0x1
-            - Value:           0xC
-            - Value:           0x2A1
+            - Value:           0xF
+            - Value:           0x2DE
             - Value:           0x1
             - Value:           0x1
-        - AbbrCode:        0x9
+        - AbbrCode:        0xA
           Values:
             - Value:           0x97
-            - Value:           0xD7
+            - Value:           0x178
             - Value:           0x1
-            - Value:           0xC
-            - Value:           0x2A1
-        - AbbrCode:        0xA
+            - Value:           0xF
+            - Value:           0x2DE
+        - AbbrCode:        0xB
           Values:
             - Value:           0xD0
-            - Value:           0xD9
+            - Value:           0x17A
             - Value:           0x1
-            - Value:           0xD
-            - Value:           0x2A1
+            - Value:           0x10
+            - Value:           0x2DE
         - AbbrCode:        0x0
         - AbbrCode:        0x8
           Values:
-            - Value:           0x18
+            - Value:           0x20
             - Value:           0x8
             - Value:           0x1
-            - Value:           0x78
+            - Value:           0x90
             - Value:           0x1
               BlockData:       [ 0x6F ]
             - Value:           0x1
-            - Value:           0x75
+            - Value:           0x116
             - Value:           0x1
-            - Value:           0x11
-            - Value:           0x2A1
+            - Value:           0x14
+            - Value:           0x2DE
             - Value:           0x1
             - Value:           0x1
-        - AbbrCode:        0x9
+        - AbbrCode:        0xA
           Values:
             - Value:           0xF5
-            - Value:           0xD7
+            - Value:           0x178
             - Value:           0x1
-            - Value:           0x11
-            - Value:           0x2A1
-        - AbbrCode:        0xA
+            - Value:           0x14
+            - Value:           0x2DE
+        - AbbrCode:        0xB
           Values:
             - Value:           0x12E
-            - Value:           0xDB
+            - Value:           0x17C
             - Value:           0x1
-            - Value:           0x12
-            - Value:           0x2A1
+            - Value:           0x15
+            - Value:           0x2DE
         - AbbrCode:        0x0
-        - AbbrCode:        0xB
+        - AbbrCode:        0xC
           Values:
-            - Value:           0x20
-            - Value:           0x58
-            - Value:           0x8F
+            - Value:           0x28
+            - Value:           0x64
+            - Value:           0xA7
             - Value:           0x1
               BlockData:       [ 0x6D ]
             - Value:           0x1
-            - Value:           0x85
+            - Value:           0x126
             - Value:           0x1
-            - Value:           0x1E
-            - Value:           0x2A1
+            - Value:           0x21
+            - Value:           0x2DE
             - Value:           0x1
             - Value:           0x1
-        - AbbrCode:        0xC
+        - AbbrCode:        0xD
           Values:
             - Value:           0x2
               BlockData:       [ 0x8F, 0xF ]
-            - Value:           0xE2
+            - Value:           0x183
             - Value:           0x1
-            - Value:           0x23
-            - Value:           0x1C8
-        - AbbrCode:        0xA
+            - Value:           0x27
+            - Value:           0x205
+        - AbbrCode:        0xB
           Values:
             - Value:           0x151
-            - Value:           0xE4
+            - Value:           0x185
             - Value:           0x1
-            - Value:           0x1F
-            - Value:           0x2A1
-        - AbbrCode:        0xD
-          Values:
-            - Value:           0x103
-            - Value:           0x38
+            - Value:           0x22
+            - Value:           0x2DE
         - AbbrCode:        0xE
+          Values:
+            - Value:           0x12C
+            - Value:           0x40
+        - AbbrCode:        0xF
           Values:
             - Value:           0x1
               BlockData:       [ 0x50 ]
             - Value:           0x1
               BlockData:       [ 0x33 ]
         - AbbrCode:        0x0
-        - AbbrCode:        0xD
-          Values:
-            - Value:           0xC7
-            - Value:           0x44
         - AbbrCode:        0xE
+          Values:
+            - Value:           0xF0
+            - Value:           0x4C
+        - AbbrCode:        0xF
           Values:
             - Value:           0x1
               BlockData:       [ 0x50 ]
             - Value:           0x2
               BlockData:       [ 0x10, 0x29 ]
         - AbbrCode:        0x0
-        - AbbrCode:        0xD
-          Values:
-            - Value:           0x9A
-            - Value:           0x50
         - AbbrCode:        0xE
+          Values:
+            - Value:           0xC3
+            - Value:           0x58
+        - AbbrCode:        0xF
           Values:
             - Value:           0x1
               BlockData:       [ 0x50 ]
             - Value:           0x1
               BlockData:       [ 0x3B ]
         - AbbrCode:        0x0
-        - AbbrCode:        0xD
+        - AbbrCode:        0xE
           Values:
-            - Value:           0x215
+            - Value:           0x5E
             - Value:           0x64
+        - AbbrCode:        0xF
+          Values:
+            - Value:           0x1
+              BlockData:       [ 0x50 ]
+            - Value:           0x2
+              BlockData:       [ 0x10, 0x2A ]
+        - AbbrCode:        0x0
         - AbbrCode:        0xE
+          Values:
+            - Value:           0x252
+            - Value:           0x78
+        - AbbrCode:        0xF
           Values:
             - Value:           0x1
               BlockData:       [ 0x50 ]
@@ -1234,107 +1343,107 @@ DWARF:
               BlockData:       [ 0x8F, 0xF ]
         - AbbrCode:        0x0
         - AbbrCode:        0x0
-        - AbbrCode:        0xF
+        - AbbrCode:        0x10
           Values:
             - Value:           0x5
-            - Value:           0x8A
+            - Value:           0x12B
             - Value:           0x1
             - Value:           0x1
-            - Value:           0x1A
-        - AbbrCode:        0x10
+            - Value:           0x1D
+        - AbbrCode:        0x11
           Values:
-            - Value:           0x1EA
+            - Value:           0x227
             - Value:           0x0
-        - AbbrCode:        0x11
+        - AbbrCode:        0x12
           Values:
-            - Value:           0x8A
+            - Value:           0x12B
             - Value:           0x1
-            - Value:           0x1B
+            - Value:           0x1E
             - Value:           0x1
             - Value:           0x1
             - Value:           0x1
             - Value:           0x1
-        - AbbrCode:        0x12
+        - AbbrCode:        0x13
           Values:
-            - Value:           0x210
+            - Value:           0x24D
             - Value:           0x1
-        - AbbrCode:        0x13
+        - AbbrCode:        0x14
           Values:
-            - Value:           0x20B
+            - Value:           0x248
         - AbbrCode:        0x0
         - AbbrCode:        0x0
-        - AbbrCode:        0xF
+        - AbbrCode:        0x10
           Values:
             - Value:           0x5
-            - Value:           0x97
+            - Value:           0x138
             - Value:           0x1
             - Value:           0x1
-            - Value:           0x16
-        - AbbrCode:        0x14
+            - Value:           0x19
+        - AbbrCode:        0x15
           Values:
-            - Value:           0x97
+            - Value:           0x138
             - Value:           0x1
-            - Value:           0x17
+            - Value:           0x1A
             - Value:           0x1
             - Value:           0x1
             - Value:           0x1
-        - AbbrCode:        0x12
+        - AbbrCode:        0x13
           Values:
-            - Value:           0x206
+            - Value:           0x243
             - Value:           0x1
-        - AbbrCode:        0x13
+        - AbbrCode:        0x14
           Values:
-            - Value:           0x20B
+            - Value:           0x248
         - AbbrCode:        0x0
         - AbbrCode:        0x0
-        - AbbrCode:        0x15
+        - AbbrCode:        0x16
           Values:
-            - Value:           0x1EA
-        - AbbrCode:        0x15
+            - Value:           0x227
+        - AbbrCode:        0x16
           Values:
             - Value:           0x4B
-        - AbbrCode:        0x15
-          Values:
-            - Value:           0x1C8
         - AbbrCode:        0x16
           Values:
-            - Value:           0x78
+            - Value:           0x205
+        - AbbrCode:        0x17
+          Values:
+            - Value:           0x8C
             - Value:           0x4
             - Value:           0x1
-            - Value:           0xB7
+            - Value:           0xD3
             - Value:           0x1
               BlockData:       [ 0x6F ]
-            - Value:           0x234
+            - Value:           0x271
             - Value:           0x1
-            - Value:           0xA3
-            - Value:           0x1D7
-        - AbbrCode:        0x17
+            - Value:           0x144
+            - Value:           0x214
+        - AbbrCode:        0x18
           Values:
             - Value:           0x1
               BlockData:       [ 0x50 ]
-            - Value:           0xE8
-            - Value:           0x2A8
+            - Value:           0x189
+            - Value:           0x2E5
             - Value:           0x1
-        - AbbrCode:        0x18
+        - AbbrCode:        0x19
           Values:
             - Value:           0x1
               BlockData:       [ 0x51 ]
-            - Value:           0xED
+            - Value:           0x18E
             - Value:           0x1
-            - Value:           0x1B
-            - Value:           0x20B
-        - AbbrCode:        0x19
+            - Value:           0x1E
+            - Value:           0x248
+        - AbbrCode:        0x1A
           Values:
-            - Value:           0x269
+            - Value:           0x2A6
             - Value:           0x1
-            - Value:           0x78
-        - AbbrCode:        0xE
+            - Value:           0x8C
+        - AbbrCode:        0xF
           Values:
             - Value:           0x1
               BlockData:       [ 0x50 ]
             - Value:           0x3
               BlockData:       [ 0xA3, 0x1, 0x50 ]
-        - AbbrCode:        0xE
+        - AbbrCode:        0xF
           Values:
             - Value:           0x1
               BlockData:       [ 0x51 ]
@@ -1342,45 +1451,45 @@ DWARF:
               BlockData:       [ 0xA3, 0x1, 0x51 ]
         - AbbrCode:        0x0
         - AbbrCode:        0x0
-        - AbbrCode:        0x16
+        - AbbrCode:        0x17
           Values:
-            - Value:           0x7C
+            - Value:           0x90
             - Value:           0x4
             - Value:           0x1
-            - Value:           0xCB
+            - Value:           0xE7
             - Value:           0x1
               BlockData:       [ 0x6F ]
-            - Value:           0x288
+            - Value:           0x2C5
             - Value:           0x1
-            - Value:           0xBB
-            - Value:           0x1D7
-        - AbbrCode:        0x17
+            - Value:           0x15C
+            - Value:           0x214
+        - AbbrCode:        0x18
           Values:
             - Value:           0x1
               BlockData:       [ 0x50 ]
-            - Value:           0xE8
-            - Value:           0x2A8
+            - Value:           0x189
+            - Value:           0x2E5
             - Value:           0x1
-        - AbbrCode:        0x18
+        - AbbrCode:        0x19
           Values:
             - Value:           0x1
               BlockData:       [ 0x51 ]
-            - Value:           0xED
+            - Value:           0x18E
             - Value:           0x1
-            - Value:           0x1B
-            - Value:           0x20B
+            - Value:           0x1E
+            - Value:           0x248
         - AbbrCode:        0x0
         - AbbrCode:        0x6
           Values:
-            - Value:           0xD3
+            - Value:           0x174
             - Value:           0x5
             - Value:           0x4
-        - AbbrCode:        0x15
+        - AbbrCode:        0x16
           Values:
-            - Value:           0x1C8
+            - Value:           0x205
         - AbbrCode:        0x0
   debug_line:
-    - Length:          221
+    - Length:          249
       Version:         4
       PrologueLength:  42
       MinInstLength:   1
@@ -1397,17 +1506,17 @@ DWARF:
           Length:          0
       Opcodes:
         - Opcode:          DW_LNS_set_column
-          Data:            14
+          Data:            10
         - Opcode:          DW_LNS_set_prologue_end
           Data:            0
         - Opcode:          DW_LNS_extended_op
           ExtLen:          9
           SubOpcode:       DW_LNE_set_address
           Data:            0
-        - Opcode:          0x16
+        - Opcode:          0x14
           Data:            0
         - Opcode:          DW_LNS_set_column
-          Data:            5
+          Data:            3
         - Opcode:          DW_LNS_negate_stmt
           Data:            0
         - Opcode:          0x4A
@@ -1424,7 +1533,7 @@ DWARF:
           ExtLen:          9
           SubOpcode:       DW_LNE_set_address
           Data:            8
-        - Opcode:          0x1A
+        - Opcode:          0x19
           Data:            0
         - Opcode:          DW_LNS_set_column
           Data:            5
@@ -1445,7 +1554,7 @@ DWARF:
           SubOpcode:       DW_LNE_set_address
           Data:            16
         - Opcode:          DW_LNS_advance_line
-          SData:           13
+          SData:           11
           Data:            0
         - Opcode:          DW_LNS_copy
           Data:            0
@@ -1460,7 +1569,7 @@ DWARF:
           SubOpcode:       DW_LNE_end_sequence
           Data:            0
         - Opcode:          DW_LNS_set_column
-          Data:            20
+          Data:            14
         - Opcode:          DW_LNS_set_prologue_end
           Data:            0
         - Opcode:          DW_LNS_extended_op
@@ -1468,24 +1577,47 @@ DWARF:
           SubOpcode:       DW_LNE_set_address
           Data:            24
         - Opcode:          DW_LNS_advance_line
-          SData:           17
+          SData:           16
           Data:            0
         - Opcode:          DW_LNS_copy
           Data:            0
         - Opcode:          DW_LNS_set_column
           Data:            5
-        - Opcode:          0x4B
+        - Opcode:          DW_LNS_negate_stmt
+          Data:            0
+        - Opcode:          0x4A
           Data:            0
         - Opcode:          DW_LNS_extended_op
           ExtLen:          1
           SubOpcode:       DW_LNE_end_sequence
           Data:            0
+        - Opcode:          DW_LNS_set_column
+          Data:            20
+        - Opcode:          DW_LNS_set_prologue_end
+          Data:            0
         - Opcode:          DW_LNS_extended_op
           ExtLen:          9
           SubOpcode:       DW_LNE_set_address
           Data:            32
         - Opcode:          DW_LNS_advance_line
-          SData:           29
+          SData:           20
+          Data:            0
+        - Opcode:          DW_LNS_copy
+          Data:            0
+        - Opcode:          DW_LNS_set_column
+          Data:            5
+        - Opcode:          0x4B
+          Data:            0
+        - Opcode:          DW_LNS_extended_op
+          ExtLen:          1
+          SubOpcode:       DW_LNE_end_sequence
+          Data:            0
+        - Opcode:          DW_LNS_extended_op
+          ExtLen:          9
+          SubOpcode:       DW_LNE_set_address
+          Data:            40
+        - Opcode:          DW_LNS_advance_line
+          SData:           32
           Data:            0
         - Opcode:          DW_LNS_copy
           Data:            0
@@ -1509,9 +1641,15 @@ DWARF:
           Data:            0
         - Opcode:          0x4B
           Data:            0
+        - Opcode:          0xBB
+          Data:            0
+        - Opcode:          DW_LNS_set_column
+          Data:            9
+        - Opcode:          0x81
+          Data:            0
         - Opcode:          DW_LNS_set_column
           Data:            18
-        - Opcode:          0xBB
+        - Opcode:          0x4C
           Data:            0
         - Opcode:          DW_LNS_set_column
           Data:            9
@@ -1534,9 +1672,9 @@ DWARF:
         - Opcode:          DW_LNS_extended_op
           ExtLen:          9
           SubOpcode:       DW_LNE_set_address
-          Data:            120
+          Data:            140
         - Opcode:          DW_LNS_advance_line
-          SData:           26
+          SData:           29
           Data:            0
         - Opcode:          DW_LNS_copy
           Data:            0
@@ -1551,9 +1689,9 @@ DWARF:
         - Opcode:          DW_LNS_extended_op
           ExtLen:          9
           SubOpcode:       DW_LNE_set_address
-          Data:            124
+          Data:            144
         - Opcode:          DW_LNS_advance_line
-          SData:           26
+          SData:           29
           Data:            0
         - Opcode:          DW_LNS_copy
           Data:            0
@@ -1604,7 +1742,7 @@ LoadCommands:
       - sectname:        __text
         segname:         __TEXT
         addr:            0x1000002F0
-        size:            112
+        size:            132
         offset:          0x2F0
         align:           2
         reloff:          0x0
@@ -1613,12 +1751,12 @@ LoadCommands:
         reserved1:       0x0
         reserved2:       0x0
         reserved3:       0x0
-        content:         00580051C0035FD600100011C0035FD6FFC300D1F44F01A9FD7B02A9FD83009160008052F7FFFF97F30300AA20058052F6FFFF971400130B60018052F1FFFF97F30300AA610100101F2003D5E03F0091060000948002130BFD7B42A9F44F41A9FFC30091C0035FD601000014C0035FD6
+        content:         00040011C0035FD600580051C0035FD600100011C0035FD6FFC300D1F44F01A9FD7B02A9FD83009160008052F7FFFF97F30300AA20058052F6FFFF971400130B60018052F1FFFF97F30300AA40058052ECFFFF977302000B610100101F2003D5E03F0091060000948002130BFD7B42A9F44F41A9FFC30091C0035FD601000014C0035FD6
       - sectname:        __cstring
         segname:         __TEXT
-        addr:            0x100000360
+        addr:            0x100000374
         size:            5
-        offset:          0x360
+        offset:          0x374
         align:           0
         reloff:          0x0
         nreloc:          0
@@ -1631,9 +1769,9 @@ LoadCommands:
     cmdsize:         72
     segname:         __LINKEDIT
     vmaddr:          4294983680
-    vmsize:          960
+    vmsize:          1040
     fileoff:         16384
-    filesize:        960
+    filesize:        1040
     maxprot:         1
     initprot:        1
     nsects:          0
@@ -1649,20 +1787,20 @@ LoadCommands:
     lazy_bind_off:   0
     lazy_bind_size:  0
     export_off:      16384
-    export_size:     96
+    export_size:     112
   - cmd:             LC_SYMTAB
     cmdsize:         24
-    symoff:          16488
-    nsyms:           22
-    stroff:          16840
-    strsize:         192
+    symoff:          16504
+    nsyms:           25
+    stroff:          16904
+    strsize:         208
   - cmd:             LC_DYSYMTAB
     cmdsize:         80
     ilocalsym:       0
-    nlocalsym:       17
-    iextdefsym:      17
-    nextdefsym:      5
-    iundefsym:       22
+    nlocalsym:       19
+    iextdefsym:      19
+    nextdefsym:      6
+    iundefsym:       25
     nundefsym:       0
     tocoff:          0
     ntoc:            0
@@ -1683,7 +1821,7 @@ LoadCommands:
     ZeroPadBytes:    7
   - cmd:             LC_UUID
     cmdsize:         24
-    uuid:            4C4C4480-5555-3144-A138-E5DA50CC68DB
+    uuid:            4C4C443F-5555-3144-A15F-DE084AB2A15B
   - cmd:             LC_BUILD_VERSION
     cmdsize:         32
     platform:        1
@@ -1692,22 +1830,22 @@ LoadCommands:
     ntools:          1
     Tools:
       - tool:            4
-        version:         1376256
+        version:         1245445
   - cmd:             LC_MAIN
     cmdsize:         24
-    entryoff:        768
+    entryoff:        776
     stacksize:       0
   - cmd:             LC_FUNCTION_STARTS
     cmdsize:         16
-    dataoff:         16480
+    dataoff:         16496
     datasize:        8
   - cmd:             LC_DATA_IN_CODE
     cmdsize:         16
-    dataoff:         16488
+    dataoff:         16504
     datasize:        0
   - cmd:             LC_CODE_SIGNATURE
     cmdsize:         16
-    dataoff:         17040
+    dataoff:         17120
     datasize:        304
 LinkEditData:
   ExportTrie:
@@ -1738,7 +1876,7 @@ LinkEditData:
             NodeOffset:      47
             Name:            main
             Flags:           0x0
-            Address:         0x300
+            Address:         0x308
             Other:           0x0
             ImportName:      ''
           - TerminalSize:    0
@@ -1749,8 +1887,15 @@ LinkEditData:
             Other:           0x0
             ImportName:      ''
             Children:
+              - TerminalSize:    3
+                NodeOffset:      80
+                Name:            1_copy1
+                Flags:           0x0
+                Address:         0x2F0
+                Other:           0x0
+                ImportName:      ''
               - TerminalSize:    0
-                NodeOffset:      71
+                NodeOffset:      85
                 Name:            2_copy
                 Flags:           0x0
                 Address:         0x0
@@ -1758,52 +1903,52 @@ LinkEditData:
                 ImportName:      ''
                 Children:
                   - TerminalSize:    3
-                    NodeOffset:      79
+                    NodeOffset:      93
                     Name:            '1'
                     Flags:           0x0
-                    Address:         0x2F0
+                    Address:         0x2F8
                     Other:           0x0
                     ImportName:      ''
                   - TerminalSize:    3
-                    NodeOffset:      84
+                    NodeOffset:      98
                     Name:            '2'
                     Flags:           0x0
-                    Address:         0x2F0
+                    Address:         0x2F8
                     Other:           0x0
                     ImportName:      ''
               - TerminalSize:    3
-                NodeOffset:      89
+                NodeOffset:      103
                 Name:            3_copy2
                 Flags:           0x0
-                Address:         0x2F8
+                Address:         0x300
                 Other:           0x0
                 ImportName:      ''
   NameList:
-    - n_strx:          129
+    - n_strx:          146
       n_type:          0x64
       n_sect:          0
       n_desc:          0
       n_value:         0
-    - n_strx:          170
+    - n_strx:          187
       n_type:          0x66
       n_sect:          0
       n_desc:          1
       n_value:         0
-    - n_strx:          59
+    - n_strx:          76
       n_type:          0x24
       n_sect:          1
       n_desc:          0
-      n_value:         4294968152
+      n_value:         4294968172
     - n_strx:          1
       n_type:          0x24
       n_sect:          0
       n_desc:          0
       n_value:         4
-    - n_strx:          84
+    - n_strx:          101
       n_type:          0x24
       n_sect:          1
       n_desc:          0
-      n_value:         4294968156
+      n_value:         4294968176
     - n_strx:          1
       n_type:          0x24
       n_sect:          0
@@ -1813,12 +1958,12 @@ LinkEditData:
       n_type:          0x24
       n_sect:          1
       n_desc:          0
-      n_value:         4294968064
+      n_value:         4294968072
     - n_strx:          1
       n_type:          0x24
       n_sect:          0
       n_desc:          0
-      n_value:         88
+      n_value:         100
     - n_strx:          8
       n_type:          0x24
       n_sect:          1
@@ -1843,7 +1988,17 @@ LinkEditData:
       n_type:          0x24
       n_sect:          1
       n_desc:          0
-      n_value:         4294968048
+      n_value:         4294968064
+    - n_strx:          1
+      n_type:          0x24
+      n_sect:          0
+      n_desc:          0
+      n_value:         8
+    - n_strx:          59
+      n_type:          0x24
+      n_sect:          1
+      n_desc:          0
+      n_value:         4294968056
     - n_strx:          1
       n_type:          0x24
       n_sect:          0
@@ -1854,21 +2009,21 @@ LinkEditData:
       n_sect:          1
       n_desc:          0
       n_value:         0
-    - n_strx:          59
+    - n_strx:          76
       n_type:          0x1E
       n_sect:          1
       n_desc:          0
-      n_value:         4294968152
-    - n_strx:          84
+      n_value:         4294968172
+    - n_strx:          101
       n_type:          0x1E
       n_sect:          1
       n_desc:          0
-      n_value:         4294968156
+      n_value:         4294968176
     - n_strx:          2
       n_type:          0xF
       n_sect:          1
       n_desc:          0
-      n_value:         4294968064
+      n_value:         4294968072
     - n_strx:          8
       n_type:          0xF
       n_sect:          1
@@ -1883,8 +2038,13 @@ LinkEditData:
       n_type:          0xF
       n_sect:          1
       n_desc:          0
-      n_value:         4294968048
-    - n_strx:          109
+      n_value:         4294968064
+    - n_strx:          59
+      n_type:          0xF
+      n_sect:          1
+      n_desc:          0
+      n_value:         4294968056
+    - n_strx:          126
       n_type:          0xF
       n_sect:          1
       n_desc:          16
@@ -1892,6 +2052,7 @@ LinkEditData:
   StringTable:
     - ' '
     - _main
+    - _function1_copy1
     - _function2_copy1
     - _function3_copy2
     - _function2_copy2
@@ -1904,6 +2065,5 @@ LinkEditData:
     - ''
     - ''
     - ''
-    - ''
-  FunctionStarts:  [ 0x2F0, 0x2F8, 0x300, 0x358, 0x35C ]
+  FunctionStarts:  [ 0x2F0, 0x2F8, 0x300, 0x308, 0x36C, 0x370 ]
 ...

>From b799fc451dfba106a3f400b46916300a785bf8c2 Mon Sep 17 00:00:00 2001
From: Peter Rong <PeterRong at meta.com>
Date: Fri, 18 Jul 2025 10:41:01 -0700
Subject: [PATCH 2/8] Remove debug/comment

---
 llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 27 --------------------
 1 file changed, 27 deletions(-)

diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index 5c2d15da5d315..b6b661f9c1981 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -36,7 +36,6 @@
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/ThreadPool.h"
-#include <iostream>
 #include <vector>
 
 namespace llvm {
@@ -2360,16 +2359,6 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
           LineTableMapping[DummyKey] = DummyVal;
           SmallVector<uint64_t> SortedLineTableKeys(LineTableMapping.keys());
           llvm::sort(SortedLineTableKeys);
-          for (auto Key : SortedLineTableKeys) {
-            std::cout << std::hex << Key << " " << LineTableMapping[Key]
-                      << "\n";
-          }
-          for (auto StmtAttr : StmtAttrs) {
-            std::cout << std::hex << StmtAttr.get() << "\n";
-          }
-          for (auto Row : SeqStartRows) {
-            std::cout << std::hex << Row << "\n";
-          }
 
           size_t StmtAttrIdx = 0, SeqStartIdx = 0;
           size_t NextSeqOff = 0;
@@ -2410,22 +2399,6 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
             // on.
             SeqOffToOrigRow[NextSeqOff] = NextRow;
           }
-          // size_t i = 0, j = 0;
-          // while (i < StmtAttrs.size() && j < SeqStartRows.size()) {
-          //   auto It = SeqOffToOrigRow.find(StmtAttrs[i].get());
-          //   // The match is not set, use current result.
-          //   if (It == SeqOffToOrigRow.end()) {
-          //     SeqOffToOrigRow.try_emplace(StmtAttrs[i].get(),
-          //     SeqStartRows[j]);
-          //   } else {
-          //     while (It->second != SeqStartRows[j] && j <
-          //     SeqStartRows.size()) {
-          //       ++j;
-          //     }
-          //   }
-          //   ++i;
-          //   ++j;
-          // }
         }
 
         // Create a map of original row indices to new row indices.

>From 07c0c080ca351ff43e24e647a469b57e0c029fd1 Mon Sep 17 00:00:00 2001
From: Peter Rong <PeterRong at meta.com>
Date: Fri, 18 Jul 2025 15:10:46 -0700
Subject: [PATCH 3/8] Patch corner case

---
 llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 145 ++++++++++++++++++-
 1 file changed, 142 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index b6b661f9c1981..e470d44e6a1e1 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -36,6 +36,7 @@
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/ThreadPool.h"
+#include <iostream>
 #include <vector>
 
 namespace llvm {
@@ -2182,6 +2183,10 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
 
   if (const DWARFDebugLine::LineTable *LT =
           ObjFile.Dwarf->getLineTableForUnit(&Unit.getOrigUnit())) {
+    // Search through Prologue
+    StringRef ObjName = ObjFile.FileName;
+    llvm::outs() << "ObjName: " << ObjName << "\n";
+    bool ShouldDebug = ObjName.contains("METAAppGroup.m");
 
     DWARFDebugLine::LineTable LineTable;
 
@@ -2207,6 +2212,18 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
       for (size_t i = 0; i < LT->Rows.size(); i++)
         InputRows.emplace_back(TrackedRow{LT->Rows[i], i, false});
 
+      if (ShouldDebug) {
+        llvm::outs() << "DEBUG: InputRows setup:\n";
+        for (size_t i = 0; i < InputRows.size(); i++) {
+          llvm::outs() << "  [" << i << "] OriginalRowIndex: "
+                       << InputRows[i].OriginalRowIndex << ", Address: 0x"
+                       << llvm::format_hex(InputRows[i].Row.Address.Address, 16)
+                       << ", Line: " << InputRows[i].Row.Line
+                       << ", EndSequence: " << InputRows[i].Row.EndSequence
+                       << "\n";
+        }
+      }
+
       // This vector is the output line table (still in TrackedRow form).
       std::vector<TrackedRow> OutputRows;
       OutputRows.reserve(InputRows.size());
@@ -2274,6 +2291,20 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
           insertLineSequence(Seq, OutputRows);
       }
 
+      if (ShouldDebug) {
+        llvm::outs() << "DEBUG: OutputRows after processing:\n";
+        for (size_t i = 0; i < OutputRows.size(); i++) {
+          llvm::outs() << "  [" << i << "] OriginalRowIndex: "
+                       << OutputRows[i].OriginalRowIndex << ", Address: 0x"
+                       << llvm::format_hex(OutputRows[i].Row.Address.Address,
+                                           16)
+                       << ", Line: " << OutputRows[i].Row.Line
+                       << ", EndSequence: " << OutputRows[i].Row.EndSequence
+                       << ", isStartSeqInOutput: "
+                       << OutputRows[i].isStartSeqInOutput << "\n";
+        }
+      }
+
       // Materialize the tracked rows into final DWARFDebugLine::Row objects.
       LineTable.Rows.clear();
       LineTable.Rows.reserve(OutputRows.size());
@@ -2308,6 +2339,15 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
             LineTableMapping[Seq.StmtSeqOffset] = Seq.FirstRowIndex;
           }
 
+          if (ShouldDebug) {
+            llvm::outs() << "DEBUG: LineTableMapping from parser:\n";
+            for (const auto &Entry : LineTableMapping) {
+              llvm::outs() << "  StmtSeqOffset: 0x"
+                           << llvm::format_hex(Entry.first, 8)
+                           << " -> FirstRowIndex: " << Entry.second << "\n";
+            }
+          }
+
           // Second, manually find sequence boundaries and match them to the
           // sorted attributes to handle sequences the parser might have missed.
           auto StmtAttrs = Unit.getStmtSeqListAttributes();
@@ -2316,12 +2356,27 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
                        return A.get() < B.get();
                      });
 
+          if (ShouldDebug) {
+            llvm::outs() << "DEBUG: Sorted StmtAttrs:\n";
+            for (const auto &Attr : StmtAttrs) {
+              llvm::outs() << "  StmtSeqOffset: 0x"
+                           << llvm::format_hex(Attr.get(), 8) << "\n";
+            }
+          }
+
           std::vector<size_t> SeqStartRows;
           SeqStartRows.push_back(0);
           for (size_t i = 0; i < LT->Rows.size() - 1; ++i)
             if (LT->Rows[i].EndSequence)
               SeqStartRows.push_back(i + 1);
 
+          if (ShouldDebug) {
+            llvm::outs() << "DEBUG: SeqStartRows:\n";
+            for (size_t i = 0; i < SeqStartRows.size(); ++i) {
+              llvm::outs() << "  [" << i << "]: " << SeqStartRows[i] << "\n";
+            }
+          }
+
           // While SeqOffToOrigRow parsed from CU could be the ground truth,
           // e.g.
           //
@@ -2383,6 +2438,12 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
                    SeqStartIdxValidAndSmallerThanNext()) {
               SeqOffToOrigRow[StmtAttrs[StmtAttrIdx].get()] =
                   SeqStartRows[SeqStartIdx];
+              if (ShouldDebug) {
+                llvm::outs()
+                    << "DEBUG: Adding dummy mapping: StmtSeqOffset 0x"
+                    << llvm::format_hex(StmtAttrs[StmtAttrIdx].get(), 8)
+                    << " -> OrigRowIndex " << SeqStartRows[SeqStartIdx] << "\n";
+              }
               ++StmtAttrIdx;
               ++SeqStartIdx;
             }
@@ -2390,14 +2451,59 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
             // LineTableMapping, We move the pointer to re-align with the
             // LineTableMapping
             while (StmtIdxValidAndSmallerThanNext()) {
+              if (ShouldDebug) {
+                llvm::outs()
+                    << "DEBUG: Skipping StmtAttr: 0x"
+                    << llvm::format_hex(StmtAttrs[StmtAttrIdx].get(), 8)
+                    << "\n";
+              }
               ++StmtAttrIdx;
             }
             while (SeqStartIdxValidAndSmallerThanNext()) {
+              if (ShouldDebug) {
+                llvm::outs() << "DEBUG: Skipping SeqStartRow: "
+                             << SeqStartRows[SeqStartIdx] << "\n";
+              }
               ++SeqStartIdx;
             }
             // Use the LineTableMapping's result as the ground truth and move
             // on.
-            SeqOffToOrigRow[NextSeqOff] = NextRow;
+            if (NextSeqOff != DummyKey) {
+              SeqOffToOrigRow[NextSeqOff] = NextRow;
+              if (ShouldDebug) {
+                llvm::outs()
+                    << "DEBUG: Adding ground truth mapping: StmtSeqOffset 0x"
+                    << llvm::format_hex(NextSeqOff, 8) << " -> OrigRowIndex "
+                    << NextRow << "\n";
+              }
+            }
+            // It is possible that the first StmtAttrIdx/SeqStartIdx point to
+            // later entries in LineTableMapping. Therefore we only increment
+            // the pointers after we validate they are pointing to the `Next`
+            // entry. e.g. LineTableMapping SeqOff     Row 0x08        9    <-
+            // NextSeqOff/NextRow 0x14       15
+            //
+            // StmtAttrs  SeqStartRows
+            // 0x14       13    <- StmtAttrIdx/SeqStartIdx
+            // 0x16       15
+            //  --        17
+            if (StmtAttrIdx < StmtAttrs.size() &&
+                StmtAttrs[StmtAttrIdx].get() == NextSeqOff) {
+              ++StmtAttrIdx;
+            }
+            if (SeqStartIdx < SeqStartRows.size() &&
+                SeqStartRows[SeqStartIdx] == NextRow) {
+              ++SeqStartIdx;
+            }
+          }
+        }
+
+        if (ShouldDebug) {
+          llvm::outs() << "DEBUG: Final SeqOffToOrigRow map:\n";
+          for (const auto &Entry : SeqOffToOrigRow) {
+            llvm::outs() << "  StmtSeqOffset: 0x"
+                         << llvm::format_hex(Entry.first, 8)
+                         << " -> OrigRowIndex: " << Entry.second << "\n";
           }
         }
 
@@ -2406,27 +2512,55 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
         for (size_t i = 0; i < OutputRows.size(); ++i)
           OrigRowToNewRow[OutputRows[i].OriginalRowIndex] = i;
 
+        if (ShouldDebug) {
+          llvm::outs() << "DEBUG: OrigRowToNewRow map:\n";
+          for (const auto &Entry : OrigRowToNewRow) {
+            llvm::outs() << "  OrigRowIndex: " << Entry.first
+                         << " -> NewRowIndex: " << Entry.second << "\n";
+          }
+        }
+
         // Patch DW_AT_LLVM_stmt_sequence attributes in the compile unit DIE
         // with the correct offset into the .debug_line section.
         for (const auto &StmtSeq : Unit.getStmtSeqListAttributes()) {
           uint64_t OrigStmtSeq = StmtSeq.get();
+          if (ShouldDebug) {
+            llvm::outs() << "DEBUG: Processing StmtSeq attribute with offset 0x"
+                         << llvm::format_hex(OrigStmtSeq, 8) << "\n";
+          }
+
           // 1. Get the original row index from the stmt list offset.
           auto OrigRowIter = SeqOffToOrigRow.find(OrigStmtSeq);
           // Check whether we have an output sequence for the StmtSeq offset.
           // Some sequences are discarded by the DWARFLinker if they are invalid
           // (empty).
           if (OrigRowIter == SeqOffToOrigRow.end()) {
-            StmtSeq.set(UINT64_MAX);
+            if (ShouldDebug) {
+              llvm::outs() << "DEBUG: StmtSeq 0x"
+                           << llvm::format_hex(OrigStmtSeq, 8)
+                           << " not found in SeqOffToOrigRow, setting to "
+                              "OrigOffsetMissing\n";
+            }
+            StmtSeq.set(OrigOffsetMissing);
             continue;
           }
           size_t OrigRowIndex = OrigRowIter->second;
+          if (ShouldDebug) {
+            llvm::outs() << "DEBUG: Found OrigRowIndex: " << OrigRowIndex
+                         << "\n";
+          }
 
           // 2. Get the new row index from the original row index.
           auto NewRowIter = OrigRowToNewRow.find(OrigRowIndex);
           if (NewRowIter == OrigRowToNewRow.end()) {
             // If the original row index is not found in the map, update the
             // stmt_sequence attribute to the 'invalid offset' magic value.
-            StmtSeq.set(UINT64_MAX);
+            if (ShouldDebug) {
+              llvm::outs() << "DEBUG: OrigRowIndex " << OrigRowIndex
+                           << " not found in OrigRowToNewRow, setting to "
+                              "NewOffsetMissing\n";
+            }
+            StmtSeq.set(NewOffsetMissing);
             continue;
           }
 
@@ -2434,6 +2568,11 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
           assert(NewRowIter->second < OutputRowOffsets.size() &&
                  "New row index out of bounds");
           uint64_t NewStmtSeqOffset = OutputRowOffsets[NewRowIter->second];
+          if (ShouldDebug) {
+            llvm::outs() << "DEBUG: Found NewRowIndex: " << NewRowIter->second
+                         << ", setting to new offset 0x"
+                         << llvm::format_hex(NewStmtSeqOffset, 8) << "\n";
+          }
 
           // 4. Patch the stmt_list attribute with the new offset.
           StmtSeq.set(NewStmtSeqOffset);

>From 3370cdb2d37f89d4e930f6d4cf86b8a7856bdeb5 Mon Sep 17 00:00:00 2001
From: Peter Rong <PeterRong at meta.com>
Date: Fri, 18 Jul 2025 16:33:55 -0700
Subject: [PATCH 4/8] Remove Debug

Signed-off-by: Peter Rong <PeterRong at meta.com>
---
 llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 124 +------------------
 1 file changed, 2 insertions(+), 122 deletions(-)

diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index e470d44e6a1e1..71e0b79fcb158 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -36,7 +36,6 @@
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/ThreadPool.h"
-#include <iostream>
 #include <vector>
 
 namespace llvm {
@@ -2184,9 +2183,6 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
   if (const DWARFDebugLine::LineTable *LT =
           ObjFile.Dwarf->getLineTableForUnit(&Unit.getOrigUnit())) {
     // Search through Prologue
-    StringRef ObjName = ObjFile.FileName;
-    llvm::outs() << "ObjName: " << ObjName << "\n";
-    bool ShouldDebug = ObjName.contains("METAAppGroup.m");
 
     DWARFDebugLine::LineTable LineTable;
 
@@ -2212,18 +2208,6 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
       for (size_t i = 0; i < LT->Rows.size(); i++)
         InputRows.emplace_back(TrackedRow{LT->Rows[i], i, false});
 
-      if (ShouldDebug) {
-        llvm::outs() << "DEBUG: InputRows setup:\n";
-        for (size_t i = 0; i < InputRows.size(); i++) {
-          llvm::outs() << "  [" << i << "] OriginalRowIndex: "
-                       << InputRows[i].OriginalRowIndex << ", Address: 0x"
-                       << llvm::format_hex(InputRows[i].Row.Address.Address, 16)
-                       << ", Line: " << InputRows[i].Row.Line
-                       << ", EndSequence: " << InputRows[i].Row.EndSequence
-                       << "\n";
-        }
-      }
-
       // This vector is the output line table (still in TrackedRow form).
       std::vector<TrackedRow> OutputRows;
       OutputRows.reserve(InputRows.size());
@@ -2291,20 +2275,6 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
           insertLineSequence(Seq, OutputRows);
       }
 
-      if (ShouldDebug) {
-        llvm::outs() << "DEBUG: OutputRows after processing:\n";
-        for (size_t i = 0; i < OutputRows.size(); i++) {
-          llvm::outs() << "  [" << i << "] OriginalRowIndex: "
-                       << OutputRows[i].OriginalRowIndex << ", Address: 0x"
-                       << llvm::format_hex(OutputRows[i].Row.Address.Address,
-                                           16)
-                       << ", Line: " << OutputRows[i].Row.Line
-                       << ", EndSequence: " << OutputRows[i].Row.EndSequence
-                       << ", isStartSeqInOutput: "
-                       << OutputRows[i].isStartSeqInOutput << "\n";
-        }
-      }
-
       // Materialize the tracked rows into final DWARFDebugLine::Row objects.
       LineTable.Rows.clear();
       LineTable.Rows.reserve(OutputRows.size());
@@ -2339,15 +2309,6 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
             LineTableMapping[Seq.StmtSeqOffset] = Seq.FirstRowIndex;
           }
 
-          if (ShouldDebug) {
-            llvm::outs() << "DEBUG: LineTableMapping from parser:\n";
-            for (const auto &Entry : LineTableMapping) {
-              llvm::outs() << "  StmtSeqOffset: 0x"
-                           << llvm::format_hex(Entry.first, 8)
-                           << " -> FirstRowIndex: " << Entry.second << "\n";
-            }
-          }
-
           // Second, manually find sequence boundaries and match them to the
           // sorted attributes to handle sequences the parser might have missed.
           auto StmtAttrs = Unit.getStmtSeqListAttributes();
@@ -2356,27 +2317,12 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
                        return A.get() < B.get();
                      });
 
-          if (ShouldDebug) {
-            llvm::outs() << "DEBUG: Sorted StmtAttrs:\n";
-            for (const auto &Attr : StmtAttrs) {
-              llvm::outs() << "  StmtSeqOffset: 0x"
-                           << llvm::format_hex(Attr.get(), 8) << "\n";
-            }
-          }
-
           std::vector<size_t> SeqStartRows;
           SeqStartRows.push_back(0);
           for (size_t i = 0; i < LT->Rows.size() - 1; ++i)
             if (LT->Rows[i].EndSequence)
               SeqStartRows.push_back(i + 1);
 
-          if (ShouldDebug) {
-            llvm::outs() << "DEBUG: SeqStartRows:\n";
-            for (size_t i = 0; i < SeqStartRows.size(); ++i) {
-              llvm::outs() << "  [" << i << "]: " << SeqStartRows[i] << "\n";
-            }
-          }
-
           // While SeqOffToOrigRow parsed from CU could be the ground truth,
           // e.g.
           //
@@ -2438,12 +2384,6 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
                    SeqStartIdxValidAndSmallerThanNext()) {
               SeqOffToOrigRow[StmtAttrs[StmtAttrIdx].get()] =
                   SeqStartRows[SeqStartIdx];
-              if (ShouldDebug) {
-                llvm::outs()
-                    << "DEBUG: Adding dummy mapping: StmtSeqOffset 0x"
-                    << llvm::format_hex(StmtAttrs[StmtAttrIdx].get(), 8)
-                    << " -> OrigRowIndex " << SeqStartRows[SeqStartIdx] << "\n";
-              }
               ++StmtAttrIdx;
               ++SeqStartIdx;
             }
@@ -2451,31 +2391,15 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
             // LineTableMapping, We move the pointer to re-align with the
             // LineTableMapping
             while (StmtIdxValidAndSmallerThanNext()) {
-              if (ShouldDebug) {
-                llvm::outs()
-                    << "DEBUG: Skipping StmtAttr: 0x"
-                    << llvm::format_hex(StmtAttrs[StmtAttrIdx].get(), 8)
-                    << "\n";
-              }
               ++StmtAttrIdx;
             }
             while (SeqStartIdxValidAndSmallerThanNext()) {
-              if (ShouldDebug) {
-                llvm::outs() << "DEBUG: Skipping SeqStartRow: "
-                             << SeqStartRows[SeqStartIdx] << "\n";
-              }
               ++SeqStartIdx;
             }
             // Use the LineTableMapping's result as the ground truth and move
             // on.
             if (NextSeqOff != DummyKey) {
               SeqOffToOrigRow[NextSeqOff] = NextRow;
-              if (ShouldDebug) {
-                llvm::outs()
-                    << "DEBUG: Adding ground truth mapping: StmtSeqOffset 0x"
-                    << llvm::format_hex(NextSeqOff, 8) << " -> OrigRowIndex "
-                    << NextRow << "\n";
-              }
             }
             // It is possible that the first StmtAttrIdx/SeqStartIdx point to
             // later entries in LineTableMapping. Therefore we only increment
@@ -2498,69 +2422,31 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
           }
         }
 
-        if (ShouldDebug) {
-          llvm::outs() << "DEBUG: Final SeqOffToOrigRow map:\n";
-          for (const auto &Entry : SeqOffToOrigRow) {
-            llvm::outs() << "  StmtSeqOffset: 0x"
-                         << llvm::format_hex(Entry.first, 8)
-                         << " -> OrigRowIndex: " << Entry.second << "\n";
-          }
-        }
-
         // Create a map of original row indices to new row indices.
         DenseMap<size_t, size_t> OrigRowToNewRow;
         for (size_t i = 0; i < OutputRows.size(); ++i)
           OrigRowToNewRow[OutputRows[i].OriginalRowIndex] = i;
 
-        if (ShouldDebug) {
-          llvm::outs() << "DEBUG: OrigRowToNewRow map:\n";
-          for (const auto &Entry : OrigRowToNewRow) {
-            llvm::outs() << "  OrigRowIndex: " << Entry.first
-                         << " -> NewRowIndex: " << Entry.second << "\n";
-          }
-        }
-
         // Patch DW_AT_LLVM_stmt_sequence attributes in the compile unit DIE
         // with the correct offset into the .debug_line section.
         for (const auto &StmtSeq : Unit.getStmtSeqListAttributes()) {
           uint64_t OrigStmtSeq = StmtSeq.get();
-          if (ShouldDebug) {
-            llvm::outs() << "DEBUG: Processing StmtSeq attribute with offset 0x"
-                         << llvm::format_hex(OrigStmtSeq, 8) << "\n";
-          }
-
           // 1. Get the original row index from the stmt list offset.
           auto OrigRowIter = SeqOffToOrigRow.find(OrigStmtSeq);
           // Check whether we have an output sequence for the StmtSeq offset.
           // Some sequences are discarded by the DWARFLinker if they are invalid
           // (empty).
           if (OrigRowIter == SeqOffToOrigRow.end()) {
-            if (ShouldDebug) {
-              llvm::outs() << "DEBUG: StmtSeq 0x"
-                           << llvm::format_hex(OrigStmtSeq, 8)
-                           << " not found in SeqOffToOrigRow, setting to "
-                              "OrigOffsetMissing\n";
-            }
-            StmtSeq.set(OrigOffsetMissing);
+            StmtSeq.set(UINT64_MAX);
             continue;
           }
           size_t OrigRowIndex = OrigRowIter->second;
-          if (ShouldDebug) {
-            llvm::outs() << "DEBUG: Found OrigRowIndex: " << OrigRowIndex
-                         << "\n";
-          }
-
           // 2. Get the new row index from the original row index.
           auto NewRowIter = OrigRowToNewRow.find(OrigRowIndex);
           if (NewRowIter == OrigRowToNewRow.end()) {
             // If the original row index is not found in the map, update the
             // stmt_sequence attribute to the 'invalid offset' magic value.
-            if (ShouldDebug) {
-              llvm::outs() << "DEBUG: OrigRowIndex " << OrigRowIndex
-                           << " not found in OrigRowToNewRow, setting to "
-                              "NewOffsetMissing\n";
-            }
-            StmtSeq.set(NewOffsetMissing);
+            StmtSeq.set(UINT64_MAX);
             continue;
           }
 
@@ -2568,12 +2454,6 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
           assert(NewRowIter->second < OutputRowOffsets.size() &&
                  "New row index out of bounds");
           uint64_t NewStmtSeqOffset = OutputRowOffsets[NewRowIter->second];
-          if (ShouldDebug) {
-            llvm::outs() << "DEBUG: Found NewRowIndex: " << NewRowIter->second
-                         << ", setting to new offset 0x"
-                         << llvm::format_hex(NewStmtSeqOffset, 8) << "\n";
-          }
-
           // 4. Patch the stmt_list attribute with the new offset.
           StmtSeq.set(NewStmtSeqOffset);
         }

>From e3d98fd4c2465c7793e2ca2ae18e37becd806d0d Mon Sep 17 00:00:00 2001
From: Peter Rong <PeterRong at meta.com>
Date: Fri, 18 Jul 2025 16:37:10 -0700
Subject: [PATCH 5/8] fix format

---
 llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index 71e0b79fcb158..572b2a252afc5 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -2182,7 +2182,6 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
 
   if (const DWARFDebugLine::LineTable *LT =
           ObjFile.Dwarf->getLineTableForUnit(&Unit.getOrigUnit())) {
-    // Search through Prologue
 
     DWARFDebugLine::LineTable LineTable;
 
@@ -2441,6 +2440,7 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
             continue;
           }
           size_t OrigRowIndex = OrigRowIter->second;
+
           // 2. Get the new row index from the original row index.
           auto NewRowIter = OrigRowToNewRow.find(OrigRowIndex);
           if (NewRowIter == OrigRowToNewRow.end()) {
@@ -2454,6 +2454,7 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
           assert(NewRowIter->second < OutputRowOffsets.size() &&
                  "New row index out of bounds");
           uint64_t NewStmtSeqOffset = OutputRowOffsets[NewRowIter->second];
+
           // 4. Patch the stmt_list attribute with the new offset.
           StmtSeq.set(NewStmtSeqOffset);
         }

>From 54a86d7cbbb39942956d348f470ed136af762793 Mon Sep 17 00:00:00 2001
From: Peter Rong <PeterRong at meta.com>
Date: Mon, 21 Jul 2025 14:01:10 -0700
Subject: [PATCH 6/8] Reformat comments

---
 llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index 572b2a252afc5..09df2aa0760a3 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -2403,8 +2403,12 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
             // It is possible that the first StmtAttrIdx/SeqStartIdx point to
             // later entries in LineTableMapping. Therefore we only increment
             // the pointers after we validate they are pointing to the `Next`
-            // entry. e.g. LineTableMapping SeqOff     Row 0x08        9    <-
-            // NextSeqOff/NextRow 0x14       15
+            // entry. e.g.
+            //
+            // LineTableMapping
+            // SeqOff      Row
+            // 0x08         9    <- NextSeqOff/NextRow
+            // 0x14        15
             //
             // StmtAttrs  SeqStartRows
             // 0x14       13    <- StmtAttrIdx/SeqStartIdx

>From aa89b8433e56059ca15428607a09a7d21216c948 Mon Sep 17 00:00:00 2001
From: Peter Rong <PeterRong at meta.com>
Date: Mon, 21 Jul 2025 16:40:20 -0700
Subject: [PATCH 7/8] Address reviewer's comment

---
 llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 251 ++++++++++---------
 1 file changed, 128 insertions(+), 123 deletions(-)

diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index 09df2aa0760a3..807f76b1e985c 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -413,6 +413,132 @@ static bool isTlsAddressCode(uint8_t DW_OP_Code) {
          DW_OP_Code == dwarf::DW_OP_GNU_push_tls_address;
 }
 
+static void constructSeqOffsettoOrigRowMapping(
+    CompileUnit &Unit, const DWARFDebugLine::LineTable *LT,
+    DenseMap<size_t, unsigned> &SeqOffToOrigRow) {
+
+  assert(LT && "Line table is null");
+
+  // Use std::map for ordered iteration.
+  std::map<uint64_t, unsigned> LineTableMapping;
+
+  // First, trust the sequences that the DWARF parser did identify.
+  for (const DWARFDebugLine::Sequence &Seq : LT->Sequences)
+    LineTableMapping[Seq.StmtSeqOffset] = Seq.FirstRowIndex;
+
+  // Second, manually find sequence boundaries and match them to the
+  // sorted attributes to handle sequences the parser might have missed.
+  auto StmtAttrs = Unit.getStmtSeqListAttributes();
+  llvm::sort(StmtAttrs, [](const PatchLocation &A, const PatchLocation &B) {
+    return A.get() < B.get();
+  });
+
+  std::vector<size_t> SeqStartRows;
+  SeqStartRows.push_back(0);
+  for (size_t I = 0; I < LT->Rows.size() - 1; ++I)
+    if (LT->Rows[I].EndSequence)
+      SeqStartRows.push_back(I + 1);
+
+  // While SeqOffToOrigRow parsed from CU could be the ground truth,
+  // e.g.
+  //
+  // SeqOff     Row
+  // 0x08        9
+  // 0x14       15
+  //
+  // The StmtAttrs and SeqStartRows may not match perfectly, e.g.
+  //
+  // StmtAttrs  SeqStartRows
+  // 0x04        3
+  // 0x08        5
+  // 0x10        9
+  // 0x12       11
+  // 0x14       15
+  //
+  // In this case, we don't want to assign 5 to 0x08, since we know 0x08
+  // maps to 9. If we do a dummy 1:1 mapping 0x10 will be mapped to 9
+  // which is incorrect. The expected behavior is ignore 5, realign the
+  // table based on the result from the line table:
+  //
+  // StmtAttrs  SeqStartRows
+  // 0x04        3
+  //   --        5
+  // 0x08        9 <- LineTableMapping ground truth
+  // 0x10       11
+  // 0x12       --
+  // 0x14       15 <- LineTableMapping ground truth
+
+  // Dummy last element to make sure StmtAttrIdx and SeqStartIdx always
+  // run out first.
+  constexpr size_t DummyKey = UINT64_MAX;
+  constexpr unsigned DummyVal = UINT32_MAX;
+  LineTableMapping[DummyKey] = DummyVal;
+
+  size_t StmtAttrIdx = 0, SeqStartIdx = 0;
+  size_t NextSeqOff = 0;
+  unsigned NextRow = 0;
+
+  auto StmtIdxValidAndSmallerThanNext = [&]() {
+    return StmtAttrIdx < StmtAttrs.size() &&
+           StmtAttrs[StmtAttrIdx].get() < NextSeqOff;
+  };
+
+  auto SeqStartIdxValidAndSmallerThanNext = [&]() {
+    return SeqStartIdx < SeqStartRows.size() &&
+           SeqStartRows[SeqStartIdx] < NextRow;
+  };
+
+  for (auto It : LineTableMapping) {
+    // More verbosed setup to make sure closure capture works.
+    NextSeqOff = It.first;
+    NextRow = It.second;
+
+    // If both StmtAttrs and SeqStartRows points to value not in
+    // the LineTableMapping yet, we do a dummy one to one mapping and
+    // move the pointer.
+    while (StmtIdxValidAndSmallerThanNext() &&
+           SeqStartIdxValidAndSmallerThanNext()) {
+      SeqOffToOrigRow[StmtAttrs[StmtAttrIdx].get()] = SeqStartRows[SeqStartIdx];
+      ++StmtAttrIdx;
+      ++SeqStartIdx;
+    }
+    // One of the pointer points to the value at or past Next in the
+    // LineTableMapping, We move the pointer to re-align with the
+    // LineTableMapping
+    while (StmtIdxValidAndSmallerThanNext()) {
+      ++StmtAttrIdx;
+    }
+    while (SeqStartIdxValidAndSmallerThanNext()) {
+      ++SeqStartIdx;
+    }
+    // Use the LineTableMapping's result as the ground truth and move
+    // on.
+    if (NextSeqOff != DummyKey) {
+      SeqOffToOrigRow[NextSeqOff] = NextRow;
+    }
+    // It is possible that the first StmtAttrIdx/SeqStartIdx point to
+    // later entries in LineTableMapping. Therefore we only increment
+    // the pointers after we validate they are pointing to the `Next`
+    // entry. e.g.
+    //
+    // LineTableMapping
+    // SeqOff      Row
+    // 0x08         9    <- NextSeqOff/NextRow
+    // 0x14        15
+    //
+    // StmtAttrs  SeqStartRows
+    // 0x14       13    <- StmtAttrIdx/SeqStartIdx
+    // 0x16       15
+    //  --        17
+    if (StmtAttrIdx < StmtAttrs.size() &&
+        StmtAttrs[StmtAttrIdx].get() == NextSeqOff)
+      ++StmtAttrIdx;
+    if (SeqStartIdx < SeqStartRows.size() &&
+        SeqStartRows[SeqStartIdx] == NextRow)
+      ++SeqStartIdx;
+  }
+}
+
 std::pair<bool, std::optional<int64_t>>
 DWARFLinker::getVariableRelocAdjustment(AddressesMap &RelocMgr,
                                         const DWARFDie &DIE) {
@@ -2297,133 +2423,12 @@ void DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
 
         // Create a map of stmt sequence offsets to original row indices.
         DenseMap<uint64_t, unsigned> SeqOffToOrigRow;
-        DenseMap<uint64_t, unsigned> LineTableMapping;
         // The DWARF parser's discovery of sequences can be incomplete. To
         // ensure all DW_AT_LLVM_stmt_sequence attributes can be patched, we
         // build a map from both the parser's results and a manual
         // reconstruction.
-        if (!LT->Rows.empty()) {
-          // First, trust the sequences that the DWARF parser did identify.
-          for (const DWARFDebugLine::Sequence &Seq : LT->Sequences) {
-            LineTableMapping[Seq.StmtSeqOffset] = Seq.FirstRowIndex;
-          }
-
-          // Second, manually find sequence boundaries and match them to the
-          // sorted attributes to handle sequences the parser might have missed.
-          auto StmtAttrs = Unit.getStmtSeqListAttributes();
-          llvm::sort(StmtAttrs,
-                     [](const PatchLocation &A, const PatchLocation &B) {
-                       return A.get() < B.get();
-                     });
-
-          std::vector<size_t> SeqStartRows;
-          SeqStartRows.push_back(0);
-          for (size_t i = 0; i < LT->Rows.size() - 1; ++i)
-            if (LT->Rows[i].EndSequence)
-              SeqStartRows.push_back(i + 1);
-
-          // While SeqOffToOrigRow parsed from CU could be the ground truth,
-          // e.g.
-          //
-          // SeqOff     Row
-          // 0x08        9
-          // 0x14       15
-          //
-          // The StmtAttrs and SeqStartRows may not match perfectly, e.g.
-          //
-          // StmtAttrs  SeqStartRows
-          // 0x04        3
-          // 0x08        5
-          // 0x10        9
-          // 0x12       11
-          // 0x14       15
-          //
-          // In this case, we don't want to assign 5 to 0x08, since we know 0x08
-          // maps to 9. If we do a dummy 1:1 mapping 0x10 will be mapped to 9
-          // which is incorrect. The expected behavior is ignore 5, realign the
-          // table based on the result from the line table:
-          //
-          // StmtAttrs  SeqStartRows
-          // 0x04        3
-          //   --        5
-          // 0x08        9 <- LineTableMapping ground truth
-          // 0x10       11
-          // 0x12       --
-          // 0x14       15 <- LineTableMapping ground truth
-
-          // Dummy last element to make sure StmtAttrIdx and SeqStartIdx always
-          // run out first. Can't directly use TombstoneKey/TombstoneVal, that's
-          // preserved.
-          constexpr size_t DummyKey = UINT64_MAX - 2;
-          constexpr unsigned DummyVal = UINT32_MAX - 2;
-          LineTableMapping[DummyKey] = DummyVal;
-          SmallVector<uint64_t> SortedLineTableKeys(LineTableMapping.keys());
-          llvm::sort(SortedLineTableKeys);
-
-          size_t StmtAttrIdx = 0, SeqStartIdx = 0;
-          size_t NextSeqOff = 0;
-          unsigned NextRow = 0;
-
-          auto StmtIdxValidAndSmallerThanNext = [&]() {
-            return StmtAttrIdx < StmtAttrs.size() &&
-                   StmtAttrs[StmtAttrIdx].get() < NextSeqOff;
-          };
-
-          auto SeqStartIdxValidAndSmallerThanNext = [&]() {
-            return SeqStartIdx < SeqStartRows.size() &&
-                   SeqStartRows[SeqStartIdx] < NextRow;
-          };
-          for (size_t i = 0; i < SortedLineTableKeys.size(); ++i) {
-            NextSeqOff = SortedLineTableKeys[i];
-            NextRow = LineTableMapping[NextSeqOff];
-            // If both StmtAttrs and SeqStartRows points to value not in
-            // the LineTableMapping yet, we do a dummy one to one mapping and
-            // move the pointer.
-            while (StmtIdxValidAndSmallerThanNext() &&
-                   SeqStartIdxValidAndSmallerThanNext()) {
-              SeqOffToOrigRow[StmtAttrs[StmtAttrIdx].get()] =
-                  SeqStartRows[SeqStartIdx];
-              ++StmtAttrIdx;
-              ++SeqStartIdx;
-            }
-            // One of the pointer points to the value at or past Next in the
-            // LineTableMapping, We move the pointer to re-align with the
-            // LineTableMapping
-            while (StmtIdxValidAndSmallerThanNext()) {
-              ++StmtAttrIdx;
-            }
-            while (SeqStartIdxValidAndSmallerThanNext()) {
-              ++SeqStartIdx;
-            }
-            // Use the LineTableMapping's result as the ground truth and move
-            // on.
-            if (NextSeqOff != DummyKey) {
-              SeqOffToOrigRow[NextSeqOff] = NextRow;
-            }
-            // It is possible that the first StmtAttrIdx/SeqStartIdx point to
-            // later entries in LineTableMapping. Therefore we only increment
-            // the pointers after we validate they are pointing to the `Next`
-            // entry. e.g.
-            //
-            // LineTableMapping
-            // SeqOff      Row
-            // 0x08         9    <- NextSeqOff/NextRow
-            // 0x14        15
-            //
-            // StmtAttrs  SeqStartRows
-            // 0x14       13    <- StmtAttrIdx/SeqStartIdx
-            // 0x16       15
-            //  --        17
-            if (StmtAttrIdx < StmtAttrs.size() &&
-                StmtAttrs[StmtAttrIdx].get() == NextSeqOff) {
-              ++StmtAttrIdx;
-            }
-            if (SeqStartIdx < SeqStartRows.size() &&
-                SeqStartRows[SeqStartIdx] == NextRow) {
-              ++SeqStartIdx;
-            }
-          }
-        }
+        if (!LT->Rows.empty())
+          constructSeqOffsettoOrigRowMapping(Unit, LT, SeqOffToOrigRow);
 
         // Create a map of original row indices to new row indices.
         DenseMap<size_t, size_t> OrigRowToNewRow;

>From 94774f0905eaf810df4f5f8e7c99f83634b6677c Mon Sep 17 00:00:00 2001
From: Peter Rong <PeterRong at meta.com>
Date: Tue, 22 Jul 2025 13:49:53 -0700
Subject: [PATCH 8/8] Resolve reviewers comment

---
 llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 72 ++++++++------------
 1 file changed, 29 insertions(+), 43 deletions(-)

diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index 807f76b1e985c..196af7115ea72 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -435,8 +435,8 @@ static void constructSeqOffsettoOrigRowMapping(
 
   std::vector<size_t> SeqStartRows;
   SeqStartRows.push_back(0);
-  for (size_t I = 0; I < LT->Rows.size() - 1; ++I)
-    if (LT->Rows[I].EndSequence)
+  for (auto [I, Row] : llvm::enumerate(ArrayRef(LT->Rows).drop_back()))
+    if (Row.EndSequence)
       SeqStartRows.push_back(I + 1);
 
   // While SeqOffToOrigRow parsed from CU could be the ground truth,
@@ -468,58 +468,46 @@ static void constructSeqOffsettoOrigRowMapping(
   // 0x12       --
   // 0x14       15 <- LineTableMapping ground truth
 
-  // Dummy last element to make sure StmtAttrIdx and SeqStartIdx always
+  ArrayRef StmtAttrsRef(StmtAttrs);
+  ArrayRef SeqStartRowsRef(SeqStartRows);
+
+  // Dummy last element to make sure StmtAttrsRef and SeqStartRowsRef always
   // run out first.
   constexpr size_t DummyKey = UINT64_MAX;
   constexpr unsigned DummyVal = UINT32_MAX;
   LineTableMapping[DummyKey] = DummyVal;
 
-  size_t StmtAttrIdx = 0, SeqStartIdx = 0;
-  size_t NextSeqOff = 0;
-  unsigned NextRow = 0;
-
-  auto StmtIdxValidAndSmallerThanNext = [&]() {
-    return StmtAttrIdx < StmtAttrs.size() &&
-           StmtAttrs[StmtAttrIdx].get() < NextSeqOff;
-  };
-
-  auto SeqStartIdxValidAndSmallerThanNext = [&]() {
-    return SeqStartIdx < SeqStartRows.size() &&
-           SeqStartRows[SeqStartIdx] < NextRow;
-  };
-
-  for (auto It : LineTableMapping) {
-    // More verbosed setup to make sure closure capture works.
-    NextSeqOff = It.first;
-    NextRow = It.second;
+  for (auto [NextSeqOff, NextRow] : LineTableMapping) {
+    auto StmtAttrSmallerThanNext = [NextSeqOff](const PatchLocation &SA) {
+      return SA.get() < NextSeqOff;
+    };
+    auto SeqStartSmallerThanNext = [NextRow](const size_t &Row) {
+      return Row < NextRow;
+    };
 
     // If both StmtAttrs and SeqStartRows points to value not in
     // the LineTableMapping yet, we do a dummy one to one mapping and
     // move the pointer.
-    while (StmtIdxValidAndSmallerThanNext() &&
-           SeqStartIdxValidAndSmallerThanNext()) {
-      SeqOffToOrigRow[StmtAttrs[StmtAttrIdx].get()] = SeqStartRows[SeqStartIdx];
-      ++StmtAttrIdx;
-      ++SeqStartIdx;
+    while (!StmtAttrsRef.empty() && !SeqStartRowsRef.empty() &&
+           StmtAttrSmallerThanNext(StmtAttrsRef.front()) &&
+           SeqStartSmallerThanNext(SeqStartRowsRef.front())) {
+      SeqOffToOrigRow[StmtAttrsRef.consume_front().get()] =
+          SeqStartRowsRef.consume_front();
     }
     // One of the pointer points to the value at or past Next in the
     // LineTableMapping, We move the pointer to re-align with the
     // LineTableMapping
-    while (StmtIdxValidAndSmallerThanNext()) {
-      ++StmtAttrIdx;
-    }
-    while (SeqStartIdxValidAndSmallerThanNext()) {
-      ++SeqStartIdx;
-    }
+    StmtAttrsRef = StmtAttrsRef.drop_while(StmtAttrSmallerThanNext);
+    SeqStartRowsRef = SeqStartRowsRef.drop_while(SeqStartSmallerThanNext);
     // Use the LineTableMapping's result as the ground truth and move
     // on.
     if (NextSeqOff != DummyKey) {
       SeqOffToOrigRow[NextSeqOff] = NextRow;
     }
-    // It is possible that the first StmtAttrIdx/SeqStartIdx point to
-    // later entries in LineTableMapping. Therefore we only increment
-    // the pointers after we validate they are pointing to the `Next`
-    // entry. e.g.
+    // Move the pointers if they are pointed at Next.
+    // It is possible that they point to later entries in LineTableMapping.
+    // Therefore we only increment the pointers after we validate they are
+    // pointing to the `Next` entry. e.g.
     //
     // LineTableMapping
     // SeqOff      Row
@@ -527,15 +515,13 @@ static void constructSeqOffsettoOrigRowMapping(
     // 0x14        15
     //
     // StmtAttrs  SeqStartRows
-    // 0x14       13    <- StmtAttrIdx/SeqStartIdx
+    // 0x14       13    <- StmtAttrsRef.front() / SeqStartRowsRef.front()
     // 0x16       15
     //  --        17
-    if (StmtAttrIdx < StmtAttrs.size() &&
-        StmtAttrs[StmtAttrIdx].get() == NextSeqOff)
-      ++StmtAttrIdx;
-    if (SeqStartIdx < SeqStartRows.size() &&
-        SeqStartRows[SeqStartIdx] == NextRow)
-      ++SeqStartIdx;
+    if (!StmtAttrsRef.empty() && StmtAttrsRef.front().get() == NextSeqOff)
+      StmtAttrsRef.consume_front();
+    if (!SeqStartRowsRef.empty() && SeqStartRowsRef.front() == NextRow)
+      SeqStartRowsRef.consume_front();
   }
 }
 



More information about the llvm-commits mailing list