[lld] b428c3e - [lld-macho] Ignore local personality symbols if non-local with the same name exisst, to avoid "too many personalities" error.

Vy Nguyen via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 17 10:01:33 PDT 2021


Author: Vy Nguyen
Date: 2021-09-17T12:59:42-04:00
New Revision: b428c3e8c19293506a55e389f025a9a9572aa03a

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

LOG:     [lld-macho] Ignore local personality symbols if non-local with the same name exisst,  to avoid "too many personalities" error.

    Sometimes people intentionally re-define a dylib personlity symbol as a local defined symbol as a workaround to a ld -r bug.
    As a result, we could see "too many personalities" to encode. This patch tries to handle this case by ignoring the local symbols entirely.

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

Added: 
    lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s

Modified: 
    lld/MachO/UnwindInfoSection.cpp

Removed: 
    


################################################################################
diff  --git a/lld/MachO/UnwindInfoSection.cpp b/lld/MachO/UnwindInfoSection.cpp
index 95a5f57ded43e..04463ca65ef2c 100644
--- a/lld/MachO/UnwindInfoSection.cpp
+++ b/lld/MachO/UnwindInfoSection.cpp
@@ -184,12 +184,26 @@ void UnwindInfoSectionImpl<Ptr>::prepareRelocations(ConcatInputSection *isec) {
       continue;
 
     if (auto *s = r.referent.dyn_cast<Symbol *>()) {
+      if (auto *defined = dyn_cast<Defined>(s)) {
+        // XXX(vyng) This is a a special case for handling duplicate personality
+        // symbols. Note that LD64's behavior is a bit 
diff erent and it is
+        // inconsistent with how symbol resolution usually work
+        //
+        // So we've decided not to follow it. Instead, simply pick the symbol
+        // with the same name from the symbol table to replace the local one.
+        //
+        // (See discussions/alternatives already considered on D107533)
+        if (!defined->isExternal())
+          if (const Symbol *sym = symtab->find(defined->getName()))
+            r.referent = s = const_cast<Symbol *>(sym);
+      }
       if (auto *undefined = dyn_cast<Undefined>(s)) {
         treatUndefinedSymbol(*undefined);
         // treatUndefinedSymbol() can replace s with a DylibSymbol; re-check.
         if (isa<Undefined>(s))
           continue;
       }
+
       if (auto *defined = dyn_cast<Defined>(s)) {
         // Check if we have created a synthetic symbol at the same address.
         Symbol *&personality =

diff  --git a/lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s b/lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s
new file mode 100644
index 0000000000000..a4ef172d7f7c0
--- /dev/null
+++ b/lld/test/MachO/compact-unwind-both-local-and-dylib-personality.s
@@ -0,0 +1,295 @@
+## Tests that lld-macho can handle the case where personality symbols with the same name
+## are both from a dylib and locally defined in an object file.
+
+# REQUIRES: x86
+# RUN: rm -rf %t; split-file %s %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/user_2.s -o %t/user_2.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/user_3.s -o %t/user_3.o
+# RUN: yaml2obj %t/combined.yaml > %t/combined.o
+
+## Pre-condition: check that ___gxx_personality_v0 really is locally defined in combined.o before we proceed.
+# RUN: llvm-nm %t/combined.o | grep '___gxx_personality_v0'  | FileCheck %s --check-prefix=PRECHECK
+# PRECHECK: {{.*}} t ___gxx_personality_v0
+# PRECHECK-NOT: {{.*}} U ___gxx_personality_v0
+# PRECHECK-NOT: {{.*}} T ___gxx_personality_v0
+
+## check that we can link with 4 personalities without crashing:
+## ___gxx_personality_v0 (libc++.tbd), ___gxx_personality_v0(local), _personality_1, and _personality_2
+# RUN: %lld -lSystem -lc++ %t/user_2.o %t/combined.o -o %t/a.out
+## ___gxx_personality_v0 (global), ___gxx_personality_v0(libc++.tbd), _personality_1, and _personality_2
+# RUN: %lld -lSystem -lc++ %t/user_3.o %t/user_2.o -o %t/b.out
+## ___gxx_personality_v0 (global), ___gxx_personality_v0(local), _personality_1, and _personality_2
+# RUN: %lld -lSystem -dylib %t/user_3.o %t/combined.o %t/user_2.o -o %t/c.out
+
+## Postlink checks.
+# RUN: llvm-nm %t/a.out | FileCheck %s --check-prefix=POSTCHECK
+# POSTCHECK: {{.*}} U ___gxx_personality_v0
+# POSTCHECK: {{.*}} t ___gxx_personality_v0	
+
+# RUN: llvm-objdump --macho --unwind-info --syms --indirect-symbols --bind %t/a.out | FileCheck %s --check-prefixes=A,CHECK -D#%x,OFF=0x100000000
+# RUN: llvm-objdump --macho --unwind-info --syms --indirect-symbols --bind %t/b.out | FileCheck %s --check-prefixes=BC,CHECK -D#%x,OFF=0x100000000
+# RUN: llvm-objdump --macho --unwind-info --syms --indirect-symbols --bind %t/c.out | FileCheck %s --check-prefixes=BC,CHECK -D#%x,OFF=0
+
+# A:      Indirect symbols for (__DATA_CONST,__got)
+# A-NEXT: address                    index name
+# A-DAG:  0x[[#%x,GXX_PERSONALITY_LO:]] [[#]] ___gxx_personality_v0
+# A-DAG:  0x[[#%x,GXX_PERSONALITY_HI:]] [[#]] ___gxx_personality_v0        
+# A-DAG:  0x[[#%x,PERSONALITY_1:]]  LOCAL
+# A-DAG:  0x[[#%x,PERSONALITY_2:]]  LOCAL
+
+# BC:      Indirect symbols for (__DATA_CONST,__got)
+# BC-NEXT: address                    index name
+# BC-DAG:  0x[[#%x,GXX_PERSONALITY_LO:]] LOCAL
+# BC-DAG:  0x[[#%x,PERSONALITY_1:]]  LOCAL
+# BC-DAG:  0x[[#%x,PERSONALITY_2:]]  LOCAL
+
+# CHECK:        Personality functions: (count = 3)
+# CHECK-DAG:     personality[{{[0-9]+}}]: 0x{{0*}}[[#GXX_PERSONALITY_LO-OFF]]
+# CHECK-DAG:     personality[{{[0-9]+}}]: 0x{{0*}}[[#PERSONALITY_1-OFF]]
+# CHECK-DAG:     personality[{{[0-9]+}}]: 0x{{0*}}[[#PERSONALITY_2-OFF]]
+
+# A: Bind table
+# A-NEXT: segment  section          address      type       addend dylib            symbol
+# A-NEXT: __DATA_CONST __got        0x[[#GXX_PERSONALITY_LO-0]] pointer         0 libc++abi        ___gxx_personality_v0
+
+## Error cases.
+## Check that dylib symbols are picked (which means without libc++, we'd get an undefined symbol error.
+# RUN:  not %lld -lSystem %t/user_2.o %t/combined.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERRORCHECK
+# ERRORCHECK: {{.*}} undefined symbol: ___gxx_personality_v0
+
+#--- user_3.s
+.globl _baz3
+.private_extern ___gxx_personality_v0
+
+.text
+_baz3:
+  .cfi_startproc
+  .cfi_personality 155, ___gxx_personality_v0
+  .cfi_def_cfa_offset 16
+  retq
+  .cfi_endproc
+
+.text
+.no_dead_strip ___gxx_personality_v0	
+___gxx_personality_v0:	
+  nop
+
+.subsections_via_symbols
+
+
+#--- user_2.s
+.globl _main, _personality_1, _personality_2
+
+.text
+
+_bar:
+  .cfi_startproc
+  .cfi_personality 155, _personality_1
+  .cfi_def_cfa_offset 16
+  retq
+  .cfi_endproc
+
+_baz:
+  .cfi_startproc
+  .cfi_personality 155, _personality_2
+  .cfi_def_cfa_offset 16
+  retq
+  .cfi_endproc
+
+_main:
+  .cfi_startproc
+  .cfi_personality 155, ___gxx_personality_v0
+  .cfi_def_cfa_offset 16
+  retq
+  .cfi_endproc
+
+_personality_1:
+  retq
+_personality_2:
+  retq
+  
+## This yaml was created from the combined.o object file described in this comment:
+## https://reviews.llvm.org/D107533#2935217
+#--- combined.yaml
+--- !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:          152
+    fileoff:         448
+    filesize:        152
+    maxprot:         7
+    initprot:        7
+    nsects:          3
+    flags:           0
+    Sections:
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x0
+        size:            5
+        offset:          0x1C0
+        align:           2
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         90909090C3
+      - sectname:        __eh_frame
+        segname:         __TEXT
+        addr:            0x8
+        size:            80
+        offset:          0x1C8
+        align:           3
+        reloff:          0x258
+        nreloc:          5
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         1400000000000000017A520001781001100C0708900100001800000000000000017A505200017810069B04000000100C070890011800000004000000F8FFFFFFFFFFFFFF0100000000000000000E1000
+        relocations:
+          - address:         0x2A
+            symbolnum:       0
+            pcrel:           true
+            length:          2
+            extern:          true
+            type:            4
+            scattered:       false
+            value:           0
+          - address:         0x38
+            symbolnum:       2
+            pcrel:           false
+            length:          2
+            extern:          true
+            type:            5
+            scattered:       false
+            value:           0
+          - address:         0x38
+            symbolnum:       3
+            pcrel:           false
+            length:          2
+            extern:          true
+            type:            0
+            scattered:       false
+            value:           0
+          - address:         0x3C
+            symbolnum:       3
+            pcrel:           false
+            length:          3
+            extern:          true
+            type:            5
+            scattered:       false
+            value:           0
+          - address:         0x3C
+            symbolnum:       4
+            pcrel:           false
+            length:          3
+            extern:          true
+            type:            0
+            scattered:       false
+            value:           0
+      - sectname:        __compact_unwind
+        segname:         __LD
+        addr:            0x58
+        size:            64
+        offset:          0x218
+        align:           3
+        reloff:          0x280
+        nreloc:          3
+        flags:           0x2000000
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         '00000000000000000100000000000202000000000000000000000000000000000000000000000000010000000000020200000000000000000000000000000000'
+        relocations:
+          - address:         0x0
+            symbolnum:       0
+            pcrel:           false
+            length:          3
+            extern:          true
+            type:            0
+            scattered:       false
+            value:           0
+          - address:         0x20
+            symbolnum:       4
+            pcrel:           false
+            length:          3
+            extern:          true
+            type:            0
+            scattered:       false
+            value:           0
+          - address:         0x30
+            symbolnum:       0
+            pcrel:           false
+            length:          3
+            extern:          true
+            type:            0
+            scattered:       false
+            value:           0
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          664
+    nsyms:           5
+    stroff:          744
+    strsize:         48
+  - cmd:             LC_BUILD_VERSION
+    cmdsize:         32
+    platform:        1
+    minos:           659200
+    sdk:             720896
+    ntools:          1
+    Tools:
+      - tool:            3
+        version:         39913472    
+  - cmd:             LC_DATA_IN_CODE
+    cmdsize:         16
+    dataoff:         664
+    datasize:        0
+LinkEditData:
+  NameList:
+    - n_strx:          7
+      n_type:          0x1E
+      n_sect:          1
+      n_desc:          32
+      n_value:         0
+    - n_strx:          29
+      n_type:          0xE
+      n_sect:          2
+      n_desc:          0
+      n_value:         8
+    - n_strx:          29
+      n_type:          0xE
+      n_sect:          2
+      n_desc:          0
+      n_value:         32
+    - n_strx:          39
+      n_type:          0xE
+      n_sect:          2
+      n_desc:          0
+      n_value:         60
+    - n_strx:          2
+      n_type:          0xF
+      n_sect:          1
+      n_desc:          0
+      n_value:         4
+  StringTable:
+    - ' '
+    - _foo
+    - ___gxx_personality_v0
+    - EH_Frame1
+    - func.eh
+    - ''
+...


        


More information about the llvm-commits mailing list