[llvm] 792c206 - [llvm-objcopy] Drop GRP_COMDAT if the group signature is localized

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 26 09:05:24 PDT 2021


Author: Fangrui Song
Date: 2021-07-26T09:05:18-07:00
New Revision: 792c206e2b63c16075d759d3abc3eb5399ed74fe

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

LOG: [llvm-objcopy] Drop GRP_COMDAT if the group signature is localized

See [GRP_COMDAT group with STB_LOCAL signature](https://groups.google.com/g/generic-abi/c/2X6mR-s2zoc)
objcopy PR: https://sourceware.org/bugzilla/show_bug.cgi?id=27931

GRP_COMDAT deduplication is purely based on the signature symbol name in
ld.lld/GNU ld/gold. The local/global status is not part of the equation.

If the signature symbol is localized by --localize-hidden or
--keep-global-symbol, the intention is likely to make the group fully
localized. Drop GRP_COMDAT to suppress deduplication.

Reviewed By: jhenderson

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

Added: 
    

Modified: 
    llvm/test/tools/llvm-objcopy/ELF/group-reorder.test
    llvm/test/tools/llvm-objcopy/ELF/group.test
    llvm/test/tools/llvm-objcopy/ELF/remove-section-in-group.test
    llvm/test/tools/llvm-objcopy/ELF/strip-dwo-groups.test
    llvm/tools/llvm-objcopy/ELF/Object.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-objcopy/ELF/group-reorder.test b/llvm/test/tools/llvm-objcopy/ELF/group-reorder.test
index ce163da90c105..db2f733fbf8a1 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/group-reorder.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/group-reorder.test
@@ -61,4 +61,5 @@ Symbols:
     Section:         .bar
   - Name:            bar
     Type:            STT_FUNC
+    Binding:         STB_GLOBAL
     Section:         .foo

diff  --git a/llvm/test/tools/llvm-objcopy/ELF/group.test b/llvm/test/tools/llvm-objcopy/ELF/group.test
index 806653d644404..64c97b17d1850 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/group.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/group.test
@@ -78,3 +78,52 @@ Symbols:
 ## sh_info fields.
 # RUN: llvm-objcopy --allow-broken-links -R .symtab %t3 %t4
 # RUN: cmp %t3 %t4
+
+## The signature symbol becomes local. Assume the intention is to localize the group.
+## Drop GRP_COMDAT so that the linker will suppress deduplication.
+# RUN: llvm-objcopy --keep-global-symbol=bar %t %t5
+# RUN: llvm-readelf -s --section-groups %t5 | FileCheck %s --check-prefix=LOCAL-SIG
+
+# LOCAL-SIG:  LOCAL  DEFAULT [[#]] foo
+# LOCAL-SIG:  (unknown) group section [ 1] `.group' [foo] contains 1 sections:
+
+## The signature symbol remains non-local. Keep GRP_COMDAT.
+# RUN: llvm-readelf -s --section-groups %t1 | FileCheck %s --check-prefix=WEAK-SIG
+
+# WEAK-SIG:   WEAK   DEFAULT [[#]] foo
+# WEAK-SIG:   COMDAT group section [ 1] `.group' [foo] contains 1 sections:
+
+# RUN: llvm-objcopy --globalize-symbol=foo %t %t6
+# RUN: llvm-readelf -s --section-groups %t6 | FileCheck %s --check-prefix=GLOBAL-SIG
+
+# GLOBAL-SIG: GLOBAL DEFAULT [[#]] foo
+# GLOBAL-SIG: COMDAT group section [ 1] `.group' [foo] contains 1 sections:
+
+## If the signature is initially local and no operation has been performed to
+## specifically localize it, it isn't clear whether we should drop GRP_COMDAT.
+## The current convention is that compilers should not produce such input, so
+## our choice does not matter.
+# RUN: yaml2obj --docnum=2 %s -o %t.localsig
+# RUN: llvm-objcopy %t.localsig %t.localsig.out
+# RUN: llvm-readelf -s --section-groups %t.localsig.out | FileCheck %s --check-prefix=LOCAL-SIG
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:  .group
+    Type:  SHT_GROUP
+    Info:  foo
+    Members:
+      - SectionOrType: GRP_COMDAT
+      - SectionOrType: .text.foo
+  - Name:  .text.foo
+    Type:  SHT_PROGBITS
+    Flags: [ SHF_GROUP ]
+Symbols:
+  - Name:    foo
+    Type:    STT_FUNC
+    Section: .text.foo

diff  --git a/llvm/test/tools/llvm-objcopy/ELF/remove-section-in-group.test b/llvm/test/tools/llvm-objcopy/ELF/remove-section-in-group.test
index 6b2e43d680339..9e683b9f68c93 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/remove-section-in-group.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/remove-section-in-group.test
@@ -34,3 +34,4 @@ Sections:
 Symbols:
   - Name:     foo_bar_grp
     Section:  .group
+    Binding:  STB_GLOBAL

diff  --git a/llvm/test/tools/llvm-objcopy/ELF/strip-dwo-groups.test b/llvm/test/tools/llvm-objcopy/ELF/strip-dwo-groups.test
index 77727ca942220..93c35117fa8f8 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/strip-dwo-groups.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/strip-dwo-groups.test
@@ -75,9 +75,11 @@ Sections:
 Symbols:
   - Name:    debug_before
     Section: .debug_before.dwo
+  - Name:    debug_after
+    Section: .debug_after.dwo
   - Name:    group2
     Section: .text.group2
+    Binding: STB_WEAK
   - Name:    group1
     Section: .text.group1
-  - Name:    debug_after
-    Section: .debug_after.dwo
+    Binding: STB_WEAK

diff  --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/tools/llvm-objcopy/ELF/Object.cpp
index 0255fdaec5d46..91a73f2111ae0 100644
--- a/llvm/tools/llvm-objcopy/ELF/Object.cpp
+++ b/llvm/tools/llvm-objcopy/ELF/Object.cpp
@@ -1069,6 +1069,12 @@ Error Section::removeSectionReferences(
 void GroupSection::finalize() {
   this->Info = Sym ? Sym->Index : 0;
   this->Link = SymTab ? SymTab->Index : 0;
+  // Linker deduplication for GRP_COMDAT is based on Sym->Name. The local/global
+  // status is not part of the equation. If Sym is localized, the intention is
+  // likely to make the group fully localized. Drop GRP_COMDAT to suppress
+  // deduplication. See https://groups.google.com/g/generic-abi/c/2X6mR-s2zoc
+  if ((FlagWord & GRP_COMDAT) && Sym && Sym->Binding == STB_LOCAL)
+    this->FlagWord &= ~GRP_COMDAT;
 }
 
 Error GroupSection::removeSectionReferences(


        


More information about the llvm-commits mailing list