[lld] 241f62d - [lld-macho] Fix assertion when two symbols at same addr have unwind info

Jez Ng via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 21 06:46:46 PDT 2022


Author: Jez Ng
Date: 2022-07-21T09:44:49-04:00
New Revision: 241f62d8d30f0d846cbb5ec4ec65f1476ebc63fe

URL: https://github.com/llvm/llvm-project/commit/241f62d8d30f0d846cbb5ec4ec65f1476ebc63fe
DIFF: https://github.com/llvm/llvm-project/commit/241f62d8d30f0d846cbb5ec4ec65f1476ebc63fe.diff

LOG: [lld-macho] Fix assertion when two symbols at same addr have unwind info

If there are multiple symbols at the same address, our unwind info
implementation assumes that we always register unwind entries to a
single canonical symbol.

This assumption was violated by the `registerEhFrame` code.

Fixes #56570.

Reviewed By: #lld-macho, thakis

Differential Revision: https://reviews.llvm.org/D130208

Added: 
    lld/test/MachO/Inputs/double-unwind-info.yaml
    lld/test/MachO/double-unwind-info.s

Modified: 
    lld/MachO/InputFiles.cpp
    lld/MachO/UnwindInfoSection.cpp

Removed: 
    


################################################################################
diff  --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index 5bc333f57db55..a2c27f1fd9f30 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -1528,6 +1528,13 @@ void ObjFile::registerEhFrames(Section &ehFrameSection) {
     Defined *funcSym;
     if (funcAddrRelocIt != isec->relocs.end()) {
       funcSym = targetSymFromCanonicalSubtractor(isec, funcAddrRelocIt);
+      // Canonicalize the symbol. If there are multiple symbols at the same
+      // address, we want both `registerEhFrame` and `registerCompactUnwind`
+      // to register the unwind entry under same symbol.
+      // This is not particularly efficient, but we should run into this case
+      // infrequently (only when handling the output of `ld -r`).
+      funcSym = findSymbolAtOffset(cast<ConcatInputSection>(funcSym->isec),
+                                   funcSym->value);
     } else {
       funcSym = findSymbolAtAddress(sections, funcAddr);
       ehRelocator.makePcRel(funcAddrOff, funcSym, target->p2WordSize);

diff  --git a/lld/MachO/UnwindInfoSection.cpp b/lld/MachO/UnwindInfoSection.cpp
index 8c3425a174595..322057947a3d2 100644
--- a/lld/MachO/UnwindInfoSection.cpp
+++ b/lld/MachO/UnwindInfoSection.cpp
@@ -211,7 +211,7 @@ void UnwindInfoSection::addSymbol(const Defined *d) {
   // we use that as the key here.
   auto p = symbols.insert({{d->isec, d->value}, d});
   // If we have multiple symbols at the same address, only one of them can have
-  // an associated CUE.
+  // an associated unwind entry.
   if (!p.second && d->unwindEntry) {
     assert(!p.first->second->unwindEntry);
     p.first->second = d;

diff  --git a/lld/test/MachO/Inputs/double-unwind-info.yaml b/lld/test/MachO/Inputs/double-unwind-info.yaml
new file mode 100644
index 0000000000000..077f334343ba4
--- /dev/null
+++ b/lld/test/MachO/Inputs/double-unwind-info.yaml
@@ -0,0 +1,159 @@
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x1000007
+  cpusubtype:      0x3
+  filetype:        0x1
+  ncmds:           4
+  sizeofcmds:      384
+  flags:           0x2000
+  reserved:        0x0
+LoadCommands:
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         312
+    segname:         ''
+    vmaddr:          0
+    vmsize:          96
+    fileoff:         448
+    filesize:        96
+    maxprot:         7
+    initprot:        7
+    nsects:          3
+    flags:           0
+    Sections:
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x0
+        size:            2
+        offset:          0x1C0
+        align:           0
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         '9090'
+      - sectname:        __eh_frame
+        segname:         __TEXT
+        addr:            0x8
+        size:            56
+        offset:          0x1C8
+        align:           3
+        reloff:          0x220
+        nreloc:          4
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         1400000000000000017A520001781001100C0708900100001C00000004000000F8FFFFFFFFFFFFFF0100000000000000000E080000000000
+        relocations:
+          - address:         0x1C
+            symbolnum:       3
+            pcrel:           false
+            length:          2
+            extern:          true
+            type:            5
+            scattered:       false
+            value:           0
+          - address:         0x1C
+            symbolnum:       4
+            pcrel:           false
+            length:          2
+            extern:          true
+            type:            0
+            scattered:       false
+            value:           0
+          - address:         0x20
+            symbolnum:       4
+            pcrel:           false
+            length:          3
+            extern:          true
+            type:            5
+            scattered:       false
+            value:           0
+          - address:         0x20
+            symbolnum:       2
+            pcrel:           false
+            length:          3
+            extern:          true
+            type:            0
+            scattered:       false
+            value:           0
+      - sectname:        __compact_unwind
+        segname:         __LD
+        addr:            0x40
+        size:            32
+        offset:          0x200
+        align:           3
+        reloff:          0x240
+        nreloc:          1
+        flags:           0x2000000
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         '0000000000000000010000000000010200000000000000000000000000000000'
+        relocations:
+          - address:         0x0
+            symbolnum:       2
+            pcrel:           false
+            length:          3
+            extern:          true
+            type:            0
+            scattered:       false
+            value:           0
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          584
+    nsyms:           5
+    stroff:          664
+    strsize:         40
+  - cmd:             LC_BUILD_VERSION
+    cmdsize:         32
+    platform:        1
+    minos:           659200
+    sdk:             0
+    ntools:          1
+    Tools:
+      - tool:            3
+        version:         50069504
+  - cmd:             LC_DATA_IN_CODE
+    cmdsize:         16
+    dataoff:         584
+    datasize:        0
+LinkEditData:
+  NameList:
+    - n_strx:          2
+      n_type:          0xE
+      n_sect:          1
+      n_desc:          0
+      n_value:         0
+    - n_strx:          10
+      n_type:          0xE
+      n_sect:          1
+      n_desc:          0
+      n_value:         1
+    - n_strx:          16
+      n_type:          0xE
+      n_sect:          1
+      n_desc:          0
+      n_value:         1
+    - n_strx:          21
+      n_type:          0xE
+      n_sect:          2
+      n_desc:          0
+      n_value:         8
+    - n_strx:          31
+      n_type:          0xE
+      n_sect:          2
+      n_desc:          0
+      n_value:         32
+  StringTable:
+    - ' '
+    - _spacer
+    - ltmp1
+    - _foo
+    - EH_Frame1
+    - func.eh
+    - ''
+...

diff  --git a/lld/test/MachO/double-unwind-info.s b/lld/test/MachO/double-unwind-info.s
new file mode 100644
index 0000000000000..d1301cb744207
--- /dev/null
+++ b/lld/test/MachO/double-unwind-info.s
@@ -0,0 +1,26 @@
+## When changing the assembly input, uncomment these lines to re-generate the
+## YAML.
+# COM: llvm-mc --emit-dwarf-unwind=always -filetype=obj -triple=x86_64-apple-macos10.15 %s -o %t.o
+# COM: ld -r %t.o -o %t-r.o
+# COM: obj2yaml %t-r.o > %S/Inputs/double-unwind-info.yaml
+
+# RUN: yaml2obj %S/Inputs/double-unwind-info.yaml > %t-r.o
+# RUN: %lld -dylib -lSystem %t-r.o -o /dev/null
+
+.text
+## eh_frame function address relocations are only emitted if the function isn't
+## at address 0x0.
+_spacer:
+  nop
+
+## Check that we perform unwind info registration correctly when there are
+## multiple symbols at the same address. This would previously hit an assertion
+## error (PR56570).
+_foo:
+ltmp1:
+  .cfi_startproc
+  .cfi_def_cfa_offset 8
+  nop
+  .cfi_endproc
+
+.subsections_via_symbols


        


More information about the llvm-commits mailing list