[llvm] 165321b - [MC][ELF] Emit unique sections for different flags

Tomas Matheson via llvm-commits llvm-commits at lists.llvm.org
Wed May 26 03:52:26 PDT 2021


Author: Tomas Matheson
Date: 2021-05-26T11:51:29+01:00
New Revision: 165321b3d27de5349520b5fdb7e08cbd238c880f

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

LOG: [MC][ELF] Emit unique sections for different flags

Global values imply flags such as readable, writable, executable for the
sections that they will be placed in. Currently MC places all such
entries into the same section, using the first set of flags seen. This
can lead to situations in LTO where a writable global is placed in the
same named section as a readable global from another file, and the
section may not be marked writable.

D72194 ensures that mergeable globals with explicit sections are placed
in separate sections with compatible entry size, by emitting the
`unique` assembly syntax where appropriate. This change extends that
approach to include section flags, so that globals with different
section flags are emitted in separate unique sections.

Differential revision: https://reviews.llvm.org/D100944

Added: 
    llvm/test/CodeGen/Generic/elf-unique-sections-by-flags.ll

Modified: 
    llvm/include/llvm/MC/MCContext.h
    llvm/lib/MC/MCContext.cpp
    llvm/test/CodeGen/Mips/gpopt-explict-section.ll
    llvm/test/CodeGen/X86/explicit-section-mergeable.ll
    llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 1bd567d9dea6c..d0edad8f02c24 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -371,17 +371,17 @@ namespace llvm {
       bool operator<(const ELFEntrySizeKey &Other) const {
         if (SectionName != Other.SectionName)
           return SectionName < Other.SectionName;
-        if ((Flags & ELF::SHF_STRINGS) != (Other.Flags & ELF::SHF_STRINGS))
-          return Other.Flags & ELF::SHF_STRINGS;
+        if (Flags != Other.Flags)
+          return Flags < Other.Flags;
         return EntrySize < Other.EntrySize;
       }
     };
 
-    // Symbols must be assigned to a section with a compatible entry
-    // size. This map is used to assign unique IDs to sections to
-    // distinguish between sections with identical names but incompatible entry
-    // sizes. This can occur when a symbol is explicitly assigned to a
-    // section, e.g. via __attribute__((section("myname"))).
+    // Symbols must be assigned to a section with a compatible entry size and
+    // flags. This map is used to assign unique IDs to sections to distinguish
+    // between sections with identical names but incompatible entry sizes and/or
+    // flags. This can occur when a symbol is explicitly assigned to a section,
+    // e.g. via __attribute__((section("myname"))).
     std::map<ELFEntrySizeKey, unsigned> ELFEntrySizeMap;
 
     // This set is used to record the generic mergeable section names seen.
@@ -589,6 +589,8 @@ namespace llvm {
 
     bool isELFGenericMergeableSection(StringRef Name);
 
+    /// Return the unique ID of the section with the given name, flags and entry
+    /// size, if it exists.
     Optional<unsigned> getELFUniqueIDForEntsize(StringRef SectionName,
                                                 unsigned Flags,
                                                 unsigned EntrySize);

diff  --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 72171488e93f3..906588a1a169e 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -580,7 +580,7 @@ void MCContext::recordELFMergeableSectionInfo(StringRef SectionName,
                                               unsigned Flags, unsigned UniqueID,
                                               unsigned EntrySize) {
   bool IsMergeable = Flags & ELF::SHF_MERGE;
-  if (IsMergeable && (UniqueID == GenericSectionID))
+  if (UniqueID == GenericSectionID)
     ELFSeenGenericMergeableSections.insert(SectionName);
 
   // For mergeable sections or non-mergeable sections with a generic mergeable

diff  --git a/llvm/test/CodeGen/Generic/elf-unique-sections-by-flags.ll b/llvm/test/CodeGen/Generic/elf-unique-sections-by-flags.ll
new file mode 100644
index 0000000000000..0ca08d4b3fead
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/elf-unique-sections-by-flags.ll
@@ -0,0 +1,140 @@
+; Test that global values with the same specified section produces multiple
+; sections with 
diff erent sets of flags, depending on the properties (mutable,
+; executable) of the global value.
+
+; RUN: llc < %s | FileCheck %s
+; RUN: llc -function-sections < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FNSECTIONS
+target triple="x86_64-unknown-unknown-elf"
+
+; Normal function goes in .text, or in it's own named section with -function-sections.
+define i32 @fn_text() {
+    entry:
+    ret i32 0
+}
+; CHECK:        .text{{$}}
+; CHECK-NEXT:   .file
+; FNSECTIONS:   .section	.text.fn_text,"ax", at progbits{{$}}
+; CHECK-NEXT:   .globl fn_text
+; CHECK:        fn_text:
+
+; A second function placed in .text, to check the behaviour with -function-sections.
+; It should be emitted to a new section with a new name, not expected to require unique.
+define i32 @fn_text2() {
+    entry:
+    ret i32 0
+}
+; FNSECTIONS:   .section	.text.fn_text2,"ax", at progbits{{$}}
+; CHECK:        .globl fn_text2
+; CHECK:        fn_text2:
+
+; Functions in user defined executable sections
+define i32 @fn_s1() section "s1" {
+    entry:
+    ret i32 0
+}
+; CHECK:        .section s1,"ax", at progbits{{$}}
+; CHECK-NEXT:   .globl fn_s1
+; CHECK:        fn_s1:
+
+define i32 @fn_s2() section "s2" {
+    entry:
+    ret i32 0
+}
+; CHECK:        .section s2,"ax", at progbits{{$}}
+; CHECK-NEXT:   .globl fn_s2
+; CHECK:        fn_s2:
+
+; A second function in s2 should share the same .section
+define i32 @fn2_s2() section "s2" {
+    entry:
+    ret i32 0
+}
+; CHECK-NOT:    .section
+; CHECK:        .globl fn2_s2
+; CHECK:        fn2_s2:
+
+; Values that share a section name with a function are placed in 
diff erent sections without executable flag
+ at rw_s1 = global i32 10, section "s1", align 4
+ at ro_s2 = constant i32 10, section "s2", align 4
+; CHECK:        .section s1,"aw", at progbits,unique,[[#UNIQUE_S1_aw:]]
+; CHECK-NEXT:   .globl rw_s1
+; CHECK:        rw_s1:
+; CHECK:        .section s2,"a", at progbits,unique,[[#UNIQUE_S2_a:]]
+; CHECK-NEXT:   .globl ro_s2
+; CHECK:        ro_s2:
+
+; Placing another value in the same section with the same flags uses the same unique ID
+ at rw2_s1 = global i32 10, section "s1", align 4
+ at ro2_s2 = constant i32 10, section "s2", align 4
+; CHECK:        .section s1,"aw", at progbits,unique,[[#UNIQUE_S1_aw]]
+; CHECK-NEXT:   .globl rw2_s1
+; CHECK:        rw2_s1:
+; CHECK:        .section s2,"a", at progbits,unique,[[#UNIQUE_S2_a]]
+; CHECK-NEXT:   .globl ro2_s2
+; CHECK:        ro2_s2:
+
+; Normal user defined section, first is the generic section, second should be unique
+ at ro_s3 = constant i32 10, section "s3", align 4
+ at rw_s3 = global i32 10, section "s3", align 4
+; CHECK:        .section s3,"a", at progbits{{$}}
+; CHECK-NEXT:   .globl ro_s3
+; CHECK:        ro_s3:
+; CHECK:        .section s3,"aw", at progbits,unique,[[#U:]]
+; CHECK-NEXT:   .globl rw_s3
+; CHECK:        rw_s3:
+
+; Values declared without explicit sections go into compatible default sections and don't require unique
+ at rw_nosec = global i32 10, align 4
+ at ro_nosec = constant i32 10, align 4
+; CHECK:        .data{{$}}
+; CHECK-NEXT:   .globl rw_nosec
+; CHECK:        rw_nosec:
+; CHECK:        .section .rodata,"a", at progbits{{$}}
+; CHECK-NEXT:   .globl ro_nosec
+; CHECK:        ro_nosec:
+
+; Explicitly placed in .rodata with writeable set. The writable section should be uniqued, not the default ro section, even if it comes first.
+ at rw_rodata = global [2 x i32] zeroinitializer, section ".rodata", align 4
+ at ro_rodata = constant [2 x i32] zeroinitializer, section ".rodata", align 4
+; CHECK:        .section .rodata,"aw", at progbits,unique,[[#U+1]]{{$}}
+; CHECK-NEXT:   .globl rw_rodata{{$}}
+; CHECK:        rw_rodata:
+; CHECK:        .section .rodata,"a", at progbits{{$}}
+; CHECK-NEXT:   .globl ro_rodata{{$}}
+; CHECK:        ro_rodata:
+
+; Writable symbols in writable default sections; no need to unique
+ at w_sdata = global [4 x i32] zeroinitializer, section ".sdata", align 4
+ at w_sbss = global [4 x i32] zeroinitializer, section ".sbss", align 4
+; CHECK:        .section .sdata,"aw", at progbits{{$}}
+; CHECK-NEXT:   .globl w_sdata{{$}}
+; CHECK:        w_sdata:
+; CHECK:        .section .sbss,"aw", at nobits{{$}}
+; CHECK-NEXT:   .globl w_sbss{{$}}
+; CHECK:        w_sbss:
+
+; Multiple .text sections are emitted for read-only and read-write sections using .text name.
+ at rw_text = global i32 10, section ".text", align 4
+ at ro_text = constant i32 10, section ".text", align 4
+; CHECK:        .section .text,"aw", at progbits,unique,[[#U+2]]
+; CHECK-NEXT:   .globl rw_text
+; CHECK:        rw_text:
+; CHECK:        .section .text,"a", at progbits,unique,[[#U+3]]
+; CHECK-NEXT:   .globl ro_text
+; CHECK:        ro_text:
+
+; A read-only .data section is emitted
+ at ro_data = constant i32 10, section ".data", align 4
+; CHECK:        .section .data,"a", at progbits,unique,[[#U+4]]
+; CHECK-NEXT:   .globl ro_data
+; CHECK:        ro_data:
+
+; TLS and non-TLS symbols cannot live in the same section
+ at tls_var = thread_local global i32 10, section "s4", align 4
+ at non_tls_var = global i32 10, section "s4", align 4
+; CHECK:        .section s4,"awT", at progbits{{$}}
+; CHECK-NEXT:   .globl tls_var
+; CHECK:        tls_var:
+; CHECK:        .section s4,"aw", at progbits,unique,[[#U+5]]
+; CHECK-NEXT:   .globl non_tls_var
+; CHECK:        non_tls_var:

diff  --git a/llvm/test/CodeGen/Mips/gpopt-explict-section.ll b/llvm/test/CodeGen/Mips/gpopt-explict-section.ll
index f1518ba562c73..d546895749caa 100644
--- a/llvm/test/CodeGen/Mips/gpopt-explict-section.ll
+++ b/llvm/test/CodeGen/Mips/gpopt-explict-section.ll
@@ -7,7 +7,7 @@
 ; small data section. Also test that explicitly placing something in the small
 ; data section uses %gp_rel addressing mode.
 
- at a = global [2 x i32] zeroinitializer, section ".rodata", align 4
+ at a = constant [2 x i32] zeroinitializer, section ".rodata", align 4
 @b = global [4 x i32] zeroinitializer, section ".sdata", align 4
 @c = global [4 x i32] zeroinitializer, section ".sbss", align 4
 

diff  --git a/llvm/test/CodeGen/X86/explicit-section-mergeable.ll b/llvm/test/CodeGen/X86/explicit-section-mergeable.ll
index 8c274821185a8..c721f7e807d39 100644
--- a/llvm/test/CodeGen/X86/explicit-section-mergeable.ll
+++ b/llvm/test/CodeGen/X86/explicit-section-mergeable.ll
@@ -4,10 +4,10 @@
 ;; Several sections are created via inline assembly. We add checks
 ;; for these lines as we want to use --implicit-check-not to reduce the
 ;; number of checks in this file.
-; CHECK: .section .asm_mergeable1,"aMS", at progbits,2
-; CHECK-NEXT: .section .asm_nonmergeable1,"a", at progbits
-; CHECK-NEXT: .section .asm_mergeable2,"aMS", at progbits,2
-; CHECK-NEXT: .section .asm_nonmergeable2,"a", at progbits
+; CHECK: .section .asm_mergeable1,"aMS", at progbits,2{{$}}
+; CHECK-NEXT: .section .asm_nonmergeable1,"a", at progbits{{$}}
+; CHECK-NEXT: .section .asm_mergeable2,"aMS", at progbits,2{{$}}
+; CHECK-NEXT: .section .asm_nonmergeable2,"a", at progbits{{$}}
 
 ;; Test implicit section assignment for symbols
 ; CHECK: .section .data,"aw", at progbits,unique,1
@@ -21,11 +21,11 @@
 ;; have the expected properties.
 ; CHECK: .section .rodata,"a", at progbits,unique,2
 ; CHECK: implicit_nonmergeable:
-; CHECK: .section .rodata.cst4,"aM", at progbits,4
+; CHECK: .section .rodata.cst4,"aM", at progbits,4{{$}}
 ; CHECK: implicit_rodata_cst4:
-; CHECK: .section .rodata.cst8,"aM", at progbits,8
+; CHECK: .section .rodata.cst8,"aM", at progbits,8{{$}}
 ; CHECK: implicit_rodata_cst8:
-; CHECK: .section .rodata.str4.4,"aMS", at progbits,4
+; CHECK: .section .rodata.str4.4,"aMS", at progbits,4{{$}}
 ; CHECK: implicit_rodata_str4_4:
 
 @implicit_nonmergeable  =              constant [2 x i16] [i16 1, i16 1]
@@ -63,13 +63,13 @@
 ;; Assign a compatible mergeable global to the previous section.
 @explicit_basic_6 = unnamed_addr constant [2 x i32] [i32 1, i32 0], section ".explicit_basic"
 
-; CHECK: .section .explicit_basic,"a", at progbits
+; CHECK: .section .explicit_basic,"a", at progbits{{$}}
 ; CHECK: explicit_basic_7:
 
 ;; Assign a symbol with an incompatible entsize (non-mergeable) to a mergeable section created explicitly.
 @explicit_basic_7 = constant [2 x i16] [i16 1, i16 1], section ".explicit_basic"
 
-; CHECK: .section .explicit_initially_nonmergeable,"a", at progbits
+; CHECK: .section .explicit_initially_nonmergeable,"a", at progbits{{$}}
 ; CHECK: explicit_basic_8:
 ; CHECK: .section .explicit_initially_nonmergeable,"aM", at progbits,4,unique,6
 ; CHECK: explicit_basic_9:
@@ -78,7 +78,7 @@
 @explicit_basic_8 = constant [2 x i16] [i16 1, i16 1], section ".explicit_initially_nonmergeable"
 @explicit_basic_9 = unnamed_addr constant [2 x i16] [i16 1, i16 1], section ".explicit_initially_nonmergeable"
 
-; CHECK: .section .explicit_initially_nonmergeable,"a", at progbits
+; CHECK: .section .explicit_initially_nonmergeable,"a", at progbits{{$}}
 ; CHECK: explicit_basic_10:
 ; CHECK: .section .explicit_initially_nonmergeable,"aM", at progbits,4,unique,6
 ; CHECK: explicit_basic_11:
@@ -95,28 +95,28 @@
 ;; Assign an incompatible (non-mergeable) symbol to a "default" mergeable section.
 @explicit_default_1 = constant [2 x i64] [i64 1, i64 1], section ".rodata.cst16"
 
-; CHECK: .section .rodata.cst16,"aM", at progbits,16
+; CHECK: .section .rodata.cst16,"aM", at progbits,16{{$}}
 ; CHECK: explicit_default_2:
 
 ;; Assign a compatible global to a "default" mergeable section.
 @explicit_default_2 = unnamed_addr constant [2 x i64] [i64 1, i64 1], section ".rodata.cst16"
 
-; CHECK: .section .debug_str,"MS", at progbits,1
+; CHECK: .section .debug_str,"aMS", at progbits,1,unique,[[#U:8]]
 ; CHECK: explicit_default_3:
 
-;; Non-allocatable "default" sections can have allocatable mergeable symbols with compatible entry sizes assigned to them.
+;; Non-allocatable "default" sections can be re-emitted with allocatable flag and uniqued
 @explicit_default_3 = unnamed_addr constant [2 x i8] [i8 1, i8 0], section ".debug_str"
 
-; CHECK: .section .debug_str,"a", at progbits,unique,8
+; CHECK: .section .debug_str,"a", at progbits,unique,[[#U+1]]
 ; CHECK: explicit_default_4:
 
 ;; Non-allocatable "default" sections cannot have allocatable mergeable symbols with incompatible (non-mergeable) entry sizes assigned to them.
 @explicit_default_4 = constant [2 x i16] [i16 1, i16 1], section ".debug_str"
 
 ;; Test implicit section assignment for globals with associated globals.
-; CHECK: .section .rodata.cst4,"aMo", at progbits,4,implicit_rodata_cst4,unique,9
+; CHECK: .section .rodata.cst4,"aMo", at progbits,4,implicit_rodata_cst4,unique,[[#U+2]]
 ; CHECK: implicit_rodata_cst4_assoc:
-; CHECK: .section .rodata.cst8,"aMo", at progbits,8,implicit_rodata_cst4,unique,10
+; CHECK: .section .rodata.cst8,"aMo", at progbits,8,implicit_rodata_cst4,unique,[[#U+3]]
 ; CHECK: implicit_rodata_cst8_assoc:
 
 @implicit_rodata_cst4_assoc = unnamed_addr constant [2 x i16] [i16 1, i16 1], !associated !4
@@ -125,11 +125,11 @@
 ;; Check that globals with associated globals that are explicitly assigned
 ;; to a section have been placed into distinct sections with the same name, but
 ;; 
diff erent entry sizes.
-; CHECK: .section .explicit,"aMo", at progbits,4,implicit_rodata_cst4,unique,11
+; CHECK: .section .explicit,"aMo", at progbits,4,implicit_rodata_cst4,unique,[[#U+4]]
 ; CHECK: explicit_assoc_1:
-; CHECK: .section .explicit,"aMo", at progbits,4,implicit_rodata_cst4,unique,12
+; CHECK: .section .explicit,"aMo", at progbits,4,implicit_rodata_cst4,unique,[[#U+5]]
 ; CHECK: explicit_assoc_2:
-; CHECK: .section .explicit,"aMo", at progbits,8,implicit_rodata_cst4,unique,13
+; CHECK: .section .explicit,"aMo", at progbits,8,implicit_rodata_cst4,unique,[[#U+6]]
 ; CHECK: explicit_assoc_3:
 
 @explicit_assoc_1 = unnamed_addr constant [2 x i16] [i16 1, i16 1], section ".explicit", !associated !4
@@ -139,9 +139,9 @@
 !4 = !{[2 x i16]* @implicit_rodata_cst4}
 
 ;; Test implicit section assignment for globals in distinct comdat groups.
-; CHECK: .section .rodata.cst4,"aGM", at progbits,4,f,comdat,unique,14
+; CHECK: .section .rodata.cst4,"aGM", at progbits,4,f,comdat,unique,[[#U+7]]
 ; CHECK: implicit_rodata_cst4_comdat:
-; CHECK: .section .rodata.cst8,"aGM", at progbits,8,g,comdat,unique,15
+; CHECK: .section .rodata.cst8,"aGM", at progbits,8,g,comdat,unique,[[#U+8]]
 ; CHECK: implicit_rodata_cst8_comdat:
 
 ;; Check that globals in distinct comdat groups that are explicitly assigned
@@ -151,13 +151,13 @@
 ;; appear incorrect as comdats are not taken into account when looking up the unique ID
 ;; for a mergeable section. However, as they have no effect it doesn't matter that they
 ;; are incorrect.
-; CHECK: .section .explicit_comdat_distinct,"aM", at progbits,4,unique,16
+; CHECK: .section .explicit_comdat_distinct,"aM", at progbits,4,unique,[[#U+9]]
 ; CHECK: explicit_comdat_distinct_supply_uid:
-; CHECK: .section .explicit_comdat_distinct,"aGM", at progbits,4,f,comdat,unique,16
+; CHECK: .section .explicit_comdat_distinct,"aGM", at progbits,4,f,comdat,unique,[[#U+10]]
 ; CHECK: explicit_comdat_distinct1:
-; CHECK: .section .explicit_comdat_distinct,"aGM", at progbits,4,g,comdat,unique,16
+; CHECK: .section .explicit_comdat_distinct,"aGM", at progbits,4,g,comdat,unique,[[#U+10]]
 ; CHECK: explicit_comdat_distinct2:
-; CHECK: .section .explicit_comdat_distinct,"aGM", at progbits,8,h,comdat,unique,17
+; CHECK: .section .explicit_comdat_distinct,"aGM", at progbits,8,h,comdat,unique,[[#U+11]]
 ; CHECK: explicit_comdat_distinct3:
 
 $f = comdat any
@@ -173,9 +173,9 @@ $h = comdat any
 @explicit_comdat_distinct3 = unnamed_addr constant [2 x i32] [i32 1, i32 1], section ".explicit_comdat_distinct", comdat($h)
 
 ;; Test implicit section assignment for globals in the same comdat group.
-; CHECK: .section .rodata.cst4,"aGM", at progbits,4,i,comdat,unique,18
+; CHECK: .section .rodata.cst4,"aGM", at progbits,4,i,comdat,unique,[[#U+12]]
 ; CHECK: implicit_rodata_cst4_same_comdat:
-; CHECK: .section .rodata.cst8,"aGM", at progbits,8,i,comdat,unique,19
+; CHECK: .section .rodata.cst8,"aGM", at progbits,8,i,comdat,unique,[[#U+13]]
 ; CHECK: implicit_rodata_cst8_same_comdat:
 
 ;; Check that globals in the same comdat group that are explicitly assigned
@@ -185,12 +185,12 @@ $h = comdat any
 ;; appear incorrect as comdats are not taken into account when looking up the unique ID
 ;; for a mergeable section. However, as they have no effect it doesn't matter that they
 ;; are incorrect.
-; CHECK: .section .explicit_comdat_same,"aM", at progbits,4,unique,20
+; CHECK: .section .explicit_comdat_same,"aM", at progbits,4,unique,[[#U+14]]
 ; CHECK: explicit_comdat_same_supply_uid:
-; CHECK: .section .explicit_comdat_same,"aGM", at progbits,4,i,comdat,unique,20
+; CHECK: .section .explicit_comdat_same,"aGM", at progbits,4,i,comdat,unique,[[#U+15]]
 ; CHECK: explicit_comdat_same1:
 ; CHECK: explicit_comdat_same2:
-; CHECK: .section .explicit_comdat_same,"aGM", at progbits,8,i,comdat,unique,21
+; CHECK: .section .explicit_comdat_same,"aGM", at progbits,8,i,comdat,unique,[[#U+16]]
 ; CHECK: explicit_comdat_same3:
 
 $i = comdat any
@@ -206,7 +206,7 @@ $i = comdat any
 ;; Check interaction between symbols that are explicitly assigned
 ;; to a section and implicitly assigned symbols.
 
-; CHECK: .section .rodata.str1.1,"aMS", at progbits,1
+; CHECK: .section .rodata.str1.1,"aMS", at progbits,1{{$}}
 ; CHECK: implicit_rodata_str1_1:
 ; CHECK: explicit_implicit_1:
 
@@ -214,22 +214,22 @@ $i = comdat any
 @implicit_rodata_str1_1 = unnamed_addr constant [2 x i8] [i8 1, i8 0]
 @explicit_implicit_1 = unnamed_addr constant [2 x i8] [i8 1, i8 0], section ".rodata.str1.1"
 
-; CHECK: .section .rodata.str1.1,"a", at progbits,unique,22
+; CHECK: .section .rodata.str1.1,"a", at progbits,unique,[[#U+17]]
 ; CHECK: explicit_implicit_2:
 
 ;; Assign an incompatible symbol (non-mergeable) to an existing mergeable section created implicitly.
 @explicit_implicit_2 = constant [2 x i16] [i16 1, i16 1], section ".rodata.str1.1"
 
-; CHECK: .section .rodata.str1.1,"aMS", at progbits,1
+; CHECK: .section .rodata.str1.1,"aMS", at progbits,1{{$}}
 ; CHECK: explicit_implicit_3:
-; CHECK: .section .rodata.str1.1,"a", at progbits,unique,22
+; CHECK: .section .rodata.str1.1,"a", at progbits,unique,[[#U+17]]
 ; CHECK: explicit_implicit_4:
 
 ;; Assign compatible globals to the previously created sections.
 @explicit_implicit_3 = unnamed_addr constant [2 x i8] [i8 1, i8 0], section ".rodata.str1.1"
 @explicit_implicit_4 = constant [2 x i16] [i16 1, i16 1], section ".rodata.str1.1"
 
-; CHECK: .section .rodata.str2.2,"aMS", at progbits,2
+; CHECK: .section .rodata.str2.2,"aMS", at progbits,2{{$}}
 ; CHECK: explicit_implicit_5:
 ; CHECK: implicit_rodata_str2_2:
 
@@ -239,21 +239,21 @@ $i = comdat any
 
 ;; Check the interaction with inline asm.
 
-; CHECK: .section .asm_mergeable1,"aMS", at progbits,2
+; CHECK: .section .asm_mergeable1,"aMS", at progbits,2{{$}}
 ; CHECK: explicit_asm_1:
-; CHECK: .section .asm_nonmergeable1,"a", at progbits
+; CHECK: .section .asm_nonmergeable1,"a", at progbits{{$}}
 ; CHECK: explicit_asm_2:
-; CHECK: .section .asm_mergeable1,"aM", at progbits,4,unique,23
+; CHECK: .section .asm_mergeable1,"aM", at progbits,4,unique,[[#U+18]]
 ; CHECK: explicit_asm_3:
-; CHECK: .section .asm_nonmergeable1,"aMS", at progbits,2,unique,24
+; CHECK: .section .asm_nonmergeable1,"aMS", at progbits,2,unique,[[#U+19]]
 ; CHECK: explicit_asm_4:
-; CHECK: .section .asm_mergeable2,"aM", at progbits,4,unique,25
+; CHECK: .section .asm_mergeable2,"aM", at progbits,4,unique,[[#U+20]]
 ; CHECK: explicit_asm_5:
-; CHECK: .section .asm_nonmergeable2,"aMS", at progbits,2,unique,26
+; CHECK: .section .asm_nonmergeable2,"aMS", at progbits,2,unique,[[#U+21]]
 ; CHECK: explicit_asm_6:
-; CHECK: .section .asm_mergeable2,"aMS", at progbits,2
+; CHECK: .section .asm_mergeable2,"aMS", at progbits,2{{$}}
 ; CHECK: explicit_asm_7:
-; CHECK: .section .asm_nonmergeable2,"a", at progbits
+; CHECK: .section .asm_nonmergeable2,"a", at progbits{{$}}
 ; CHECK: explicit_asm_8:
 
 module asm ".section .asm_mergeable1,\22aMS\22, at progbits,2"
@@ -277,7 +277,7 @@ module asm ".section .asm_nonmergeable2,\22a\22, at progbits"
 
 ;; A .note.GNU-stack section is created implicitly. We add a check for this as we want to use
 ;; --implicit-check-not to reduce the number of checks in this file.
-; CHECK: .section ".note.GNU-stack","", at progbits
+; CHECK: .section ".note.GNU-stack","", at progbits{{$}}
 
 ;; --no-integrated-as avoids the use of ",unique," for compatibility with older binutils.
 
@@ -294,7 +294,7 @@ module asm ".section .asm_nonmergeable2,\22a\22, at progbits"
 ; RUN: echo '@explicit = unnamed_addr constant [2 x i16] [i16 1, i16 1], section ".explicit"' > %t.no_i_as.ll
 ; RUN: llc < %t.no_i_as.ll -mtriple=x86_64 --no-integrated-as -binutils-version=2.34 2>&1 \
 ; RUN:     | FileCheck %s --check-prefix=NO-I-AS-OLD
-; NO-I-AS-OLD: .section .explicit,"a", at progbits
+; NO-I-AS-OLD: .section .explicit,"a", at progbits{{$}}
 ; RUN: llc < %t.no_i_as.ll -mtriple=x86_64 --no-integrated-as -binutils-version=2.35 2>&1 \
 ; RUN:     | FileCheck %s --check-prefix=NO-I-AS-NEW
 ; RUN: llc < %t.no_i_as.ll -mtriple=x86_64 --no-integrated-as -binutils-version=none 2>&1 \

diff  --git a/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp b/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
index 0d34b99484d23..000a44953a0d1 100644
--- a/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/RTDyldObjectLinkingLayerTest.cpp
@@ -21,34 +21,36 @@ using namespace llvm::orc;
 
 namespace {
 
-// Adds an object with a debug section to RuntimeDyld and then returns whether
-// the debug section was passed to the memory manager.
+// Returns whether a non-alloc section was passed to the memory manager.
 static bool testSetProcessAllSections(std::unique_ptr<MemoryBuffer> Obj,
                                       bool ProcessAllSections) {
   class MemoryManagerWrapper : public SectionMemoryManager {
   public:
-    MemoryManagerWrapper(bool &DebugSeen) : DebugSeen(DebugSeen) {}
+    MemoryManagerWrapper(bool &NonAllocSeen) : NonAllocSeen(NonAllocSeen) {}
     uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
                                  unsigned SectionID, StringRef SectionName,
                                  bool IsReadOnly) override {
-      if (SectionName == ".debug_str")
-        DebugSeen = true;
+      // We check for ".note.GNU-stack" here because it is currently the only
+      // non-alloc section seen in the module. If this changes in future any
+      // other non-alloc section would do here.
+      if (SectionName == ".note.GNU-stack")
+        NonAllocSeen = true;
       return SectionMemoryManager::allocateDataSection(
           Size, Alignment, SectionID, SectionName, IsReadOnly);
     }
 
   private:
-    bool &DebugSeen;
+    bool &NonAllocSeen;
   };
 
-  bool DebugSectionSeen = false;
+  bool NonAllocSectionSeen = false;
 
   ExecutionSession ES;
   auto &JD = ES.createBareJITDylib("main");
   auto Foo = ES.intern("foo");
 
-  RTDyldObjectLinkingLayer ObjLayer(ES, [&DebugSectionSeen]() {
-    return std::make_unique<MemoryManagerWrapper>(DebugSectionSeen);
+  RTDyldObjectLinkingLayer ObjLayer(ES, [&NonAllocSectionSeen]() {
+    return std::make_unique<MemoryManagerWrapper>(NonAllocSectionSeen);
   });
 
   auto OnResolveDoNothing = [](Expected<SymbolMap> R) {
@@ -64,13 +66,16 @@ static bool testSetProcessAllSections(std::unique_ptr<MemoryBuffer> Obj,
   if (auto Err = ES.endSession())
     ES.reportError(std::move(Err));
 
-  return DebugSectionSeen;
+  return NonAllocSectionSeen;
 }
 
 TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
   LLVMContext Context;
   auto M = std::make_unique<Module>("", Context);
   M->setTargetTriple("x86_64-unknown-linux-gnu");
+
+  // These values are only here to ensure that the module is non-empty.
+  // They are no longer relevant to the test.
   Constant *StrConstant = ConstantDataArray::getString(Context, "forty-two");
   auto *GV =
       new GlobalVariable(*M, StrConstant->getType(), true,
@@ -78,8 +83,6 @@ TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
   GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
   GV->setAlignment(Align(1));
 
-  GV->setSection(".debug_str");
-
   // Initialize the native target in case this is the first unit test
   // to try to build a TM.
   OrcNativeTarget::initialize();
@@ -92,9 +95,9 @@ TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
 
   EXPECT_FALSE(testSetProcessAllSections(
       MemoryBuffer::getMemBufferCopy(Obj->getBuffer()), false))
-      << "Debug section seen despite ProcessAllSections being false";
+      << "Non-alloc section seen despite ProcessAllSections being false";
   EXPECT_TRUE(testSetProcessAllSections(std::move(Obj), true))
-      << "Expected to see debug section when ProcessAllSections is true";
+      << "Expected to see non-alloc section when ProcessAllSections is true";
 }
 
 TEST(RTDyldObjectLinkingLayerTest, TestOverrideObjectFlags) {


        


More information about the llvm-commits mailing list