mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Revert [MC][ELF] Emit separate unique sections for different flags
Commit Message from @MaskRay:
Rust has a fragile embed-bitcode implementation
(bddb59cf07/compiler/rustc_codegen_llvm/src/back/write.rs (L970-L1017)
)
which relied on the previous LLVM MC behavior. Rust's LLVM fork
has carried a revert. This commit made the similar revert to help
distributions since they would otherwise probably carry a similar patch
(as they ship rust linked against system LLVM).
Fixes https://bugs.llvm.org/show_bug.cgi?id=51207.
Differential Revision: https://reviews.llvm.org/D107216
This commit is contained in:
parent
a967752a95
commit
b6614b2353
@ -374,17 +374,17 @@ namespace llvm {
|
||||
bool operator<(const ELFEntrySizeKey &Other) const {
|
||||
if (SectionName != Other.SectionName)
|
||||
return SectionName < Other.SectionName;
|
||||
if (Flags != Other.Flags)
|
||||
return Flags < Other.Flags;
|
||||
if ((Flags & ELF::SHF_STRINGS) != (Other.Flags & ELF::SHF_STRINGS))
|
||||
return Other.Flags & ELF::SHF_STRINGS;
|
||||
return EntrySize < Other.EntrySize;
|
||||
}
|
||||
};
|
||||
|
||||
// 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"))).
|
||||
// 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"))).
|
||||
std::map<ELFEntrySizeKey, unsigned> ELFEntrySizeMap;
|
||||
|
||||
// This set is used to record the generic mergeable section names seen.
|
||||
@ -592,8 +592,6 @@ 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);
|
||||
|
@ -586,7 +586,7 @@ void MCContext::recordELFMergeableSectionInfo(StringRef SectionName,
|
||||
unsigned Flags, unsigned UniqueID,
|
||||
unsigned EntrySize) {
|
||||
bool IsMergeable = Flags & ELF::SHF_MERGE;
|
||||
if (UniqueID == GenericSectionID)
|
||||
if (IsMergeable && (UniqueID == GenericSectionID))
|
||||
ELFSeenGenericMergeableSections.insert(SectionName);
|
||||
|
||||
// For mergeable sections or non-mergeable sections with a generic mergeable
|
||||
|
@ -7,7 +7,7 @@
|
||||
; small data section. Also test that explicitly placing something in the small
|
||||
; data section uses %gp_rel addressing mode.
|
||||
|
||||
@a = constant [2 x i32] zeroinitializer, section ".rodata", align 4
|
||||
@a = global [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
|
||||
|
||||
|
@ -1,140 +0,0 @@
|
||||
; Test that global values with the same specified section produces multiple
|
||||
; sections with different 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",@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",@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",@progbits{{$}}
|
||||
; CHECK-NEXT: .globl fn_s1
|
||||
; CHECK: fn_s1:
|
||||
|
||||
define i32 @fn_s2() section "s2" {
|
||||
entry:
|
||||
ret i32 0
|
||||
}
|
||||
; CHECK: .section s2,"ax",@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 different sections without executable flag
|
||||
@rw_s1 = global i32 10, section "s1", align 4
|
||||
@ro_s2 = constant i32 10, section "s2", align 4
|
||||
; CHECK: .section s1,"aw",@progbits,unique,[[#UNIQUE_S1_aw:]]
|
||||
; CHECK-NEXT: .globl rw_s1
|
||||
; CHECK: rw_s1:
|
||||
; CHECK: .section s2,"a",@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
|
||||
@rw2_s1 = global i32 10, section "s1", align 4
|
||||
@ro2_s2 = constant i32 10, section "s2", align 4
|
||||
; CHECK: .section s1,"aw",@progbits,unique,[[#UNIQUE_S1_aw]]
|
||||
; CHECK-NEXT: .globl rw2_s1
|
||||
; CHECK: rw2_s1:
|
||||
; CHECK: .section s2,"a",@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
|
||||
@ro_s3 = constant i32 10, section "s3", align 4
|
||||
@rw_s3 = global i32 10, section "s3", align 4
|
||||
; CHECK: .section s3,"a",@progbits{{$}}
|
||||
; CHECK-NEXT: .globl ro_s3
|
||||
; CHECK: ro_s3:
|
||||
; CHECK: .section s3,"aw",@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
|
||||
@rw_nosec = global i32 10, align 4
|
||||
@ro_nosec = constant i32 10, align 4
|
||||
; CHECK: .data{{$}}
|
||||
; CHECK-NEXT: .globl rw_nosec
|
||||
; CHECK: rw_nosec:
|
||||
; CHECK: .section .rodata,"a",@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.
|
||||
@rw_rodata = global [2 x i32] zeroinitializer, section ".rodata", align 4
|
||||
@ro_rodata = constant [2 x i32] zeroinitializer, section ".rodata", align 4
|
||||
; CHECK: .section .rodata,"aw",@progbits,unique,[[#U+1]]{{$}}
|
||||
; CHECK-NEXT: .globl rw_rodata{{$}}
|
||||
; CHECK: rw_rodata:
|
||||
; CHECK: .section .rodata,"a",@progbits{{$}}
|
||||
; CHECK-NEXT: .globl ro_rodata{{$}}
|
||||
; CHECK: ro_rodata:
|
||||
|
||||
; Writable symbols in writable default sections; no need to unique
|
||||
@w_sdata = global [4 x i32] zeroinitializer, section ".sdata", align 4
|
||||
@w_sbss = global [4 x i32] zeroinitializer, section ".sbss", align 4
|
||||
; CHECK: .section .sdata,"aw",@progbits{{$}}
|
||||
; CHECK-NEXT: .globl w_sdata{{$}}
|
||||
; CHECK: w_sdata:
|
||||
; CHECK: .section .sbss,"aw",@nobits{{$}}
|
||||
; CHECK-NEXT: .globl w_sbss{{$}}
|
||||
; CHECK: w_sbss:
|
||||
|
||||
; Multiple .text sections are emitted for read-only and read-write sections using .text name.
|
||||
@rw_text = global i32 10, section ".text", align 4
|
||||
@ro_text = constant i32 10, section ".text", align 4
|
||||
; CHECK: .section .text,"aw",@progbits,unique,[[#U+2]]
|
||||
; CHECK-NEXT: .globl rw_text
|
||||
; CHECK: rw_text:
|
||||
; CHECK: .section .text,"a",@progbits,unique,[[#U+3]]
|
||||
; CHECK-NEXT: .globl ro_text
|
||||
; CHECK: ro_text:
|
||||
|
||||
; A read-only .data section is emitted
|
||||
@ro_data = constant i32 10, section ".data", align 4
|
||||
; CHECK: .section .data,"a",@progbits,unique,[[#U+4]]
|
||||
; CHECK-NEXT: .globl ro_data
|
||||
; CHECK: ro_data:
|
||||
|
||||
; TLS and non-TLS symbols cannot live in the same section
|
||||
@tls_var = thread_local global i32 10, section "s4", align 4
|
||||
@non_tls_var = global i32 10, section "s4", align 4
|
||||
; CHECK: .section s4,"awT",@progbits{{$}}
|
||||
; CHECK-NEXT: .globl tls_var
|
||||
; CHECK: tls_var:
|
||||
; CHECK: .section s4,"aw",@progbits,unique,[[#U+5]]
|
||||
; CHECK-NEXT: .globl non_tls_var
|
||||
; CHECK: non_tls_var:
|
@ -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",@progbits,2{{$}}
|
||||
; CHECK-NEXT: .section .asm_nonmergeable1,"a",@progbits{{$}}
|
||||
; CHECK-NEXT: .section .asm_mergeable2,"aMS",@progbits,2{{$}}
|
||||
; CHECK-NEXT: .section .asm_nonmergeable2,"a",@progbits{{$}}
|
||||
; CHECK: .section .asm_mergeable1,"aMS",@progbits,2
|
||||
; CHECK-NEXT: .section .asm_nonmergeable1,"a",@progbits
|
||||
; CHECK-NEXT: .section .asm_mergeable2,"aMS",@progbits,2
|
||||
; CHECK-NEXT: .section .asm_nonmergeable2,"a",@progbits
|
||||
|
||||
;; Test implicit section assignment for symbols
|
||||
; CHECK: .section .data,"aw",@progbits,unique,1
|
||||
@ -21,11 +21,11 @@
|
||||
;; have the expected properties.
|
||||
; CHECK: .section .rodata,"a",@progbits,unique,2
|
||||
; CHECK: implicit_nonmergeable:
|
||||
; CHECK: .section .rodata.cst4,"aM",@progbits,4{{$}}
|
||||
; CHECK: .section .rodata.cst4,"aM",@progbits,4
|
||||
; CHECK: implicit_rodata_cst4:
|
||||
; CHECK: .section .rodata.cst8,"aM",@progbits,8{{$}}
|
||||
; CHECK: .section .rodata.cst8,"aM",@progbits,8
|
||||
; CHECK: implicit_rodata_cst8:
|
||||
; CHECK: .section .rodata.str4.4,"aMS",@progbits,4{{$}}
|
||||
; CHECK: .section .rodata.str4.4,"aMS",@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",@progbits{{$}}
|
||||
; CHECK: .section .explicit_basic,"a",@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",@progbits{{$}}
|
||||
; CHECK: .section .explicit_initially_nonmergeable,"a",@progbits
|
||||
; CHECK: explicit_basic_8:
|
||||
; CHECK: .section .explicit_initially_nonmergeable,"aM",@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",@progbits{{$}}
|
||||
; CHECK: .section .explicit_initially_nonmergeable,"a",@progbits
|
||||
; CHECK: explicit_basic_10:
|
||||
; CHECK: .section .explicit_initially_nonmergeable,"aM",@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",@progbits,16{{$}}
|
||||
; CHECK: .section .rodata.cst16,"aM",@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,"aMS",@progbits,1,unique,[[#U:8]]
|
||||
; CHECK: .section .debug_str,"MS",@progbits,1
|
||||
; CHECK: explicit_default_3:
|
||||
|
||||
;; Non-allocatable "default" sections can be re-emitted with allocatable flag and uniqued
|
||||
;; Non-allocatable "default" sections can have allocatable mergeable symbols with compatible entry sizes assigned to them.
|
||||
@explicit_default_3 = unnamed_addr constant [2 x i8] [i8 1, i8 0], section ".debug_str"
|
||||
|
||||
; CHECK: .section .debug_str,"a",@progbits,unique,[[#U+1]]
|
||||
; CHECK: .section .debug_str,"a",@progbits,unique,8
|
||||
; 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",@progbits,4,implicit_rodata_cst4,unique,[[#U+2]]
|
||||
; CHECK: .section .rodata.cst4,"aMo",@progbits,4,implicit_rodata_cst4,unique,9
|
||||
; CHECK: implicit_rodata_cst4_assoc:
|
||||
; CHECK: .section .rodata.cst8,"aMo",@progbits,8,implicit_rodata_cst4,unique,[[#U+3]]
|
||||
; CHECK: .section .rodata.cst8,"aMo",@progbits,8,implicit_rodata_cst4,unique,10
|
||||
; 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
|
||||
;; different entry sizes.
|
||||
; CHECK: .section .explicit,"aMo",@progbits,4,implicit_rodata_cst4,unique,[[#U+4]]
|
||||
; CHECK: .section .explicit,"aMo",@progbits,4,implicit_rodata_cst4,unique,11
|
||||
; CHECK: explicit_assoc_1:
|
||||
; CHECK: .section .explicit,"aMo",@progbits,4,implicit_rodata_cst4,unique,[[#U+5]]
|
||||
; CHECK: .section .explicit,"aMo",@progbits,4,implicit_rodata_cst4,unique,12
|
||||
; CHECK: explicit_assoc_2:
|
||||
; CHECK: .section .explicit,"aMo",@progbits,8,implicit_rodata_cst4,unique,[[#U+6]]
|
||||
; CHECK: .section .explicit,"aMo",@progbits,8,implicit_rodata_cst4,unique,13
|
||||
; 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",@progbits,4,f,comdat,unique,[[#U+7]]
|
||||
; CHECK: .section .rodata.cst4,"aGM",@progbits,4,f,comdat,unique,14
|
||||
; CHECK: implicit_rodata_cst4_comdat:
|
||||
; CHECK: .section .rodata.cst8,"aGM",@progbits,8,g,comdat,unique,[[#U+8]]
|
||||
; CHECK: .section .rodata.cst8,"aGM",@progbits,8,g,comdat,unique,15
|
||||
; 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",@progbits,4,unique,[[#U+9]]
|
||||
; CHECK: .section .explicit_comdat_distinct,"aM",@progbits,4,unique,16
|
||||
; CHECK: explicit_comdat_distinct_supply_uid:
|
||||
; CHECK: .section .explicit_comdat_distinct,"aGM",@progbits,4,f,comdat,unique,[[#U+10]]
|
||||
; CHECK: .section .explicit_comdat_distinct,"aGM",@progbits,4,f,comdat,unique,16
|
||||
; CHECK: explicit_comdat_distinct1:
|
||||
; CHECK: .section .explicit_comdat_distinct,"aGM",@progbits,4,g,comdat,unique,[[#U+10]]
|
||||
; CHECK: .section .explicit_comdat_distinct,"aGM",@progbits,4,g,comdat,unique,16
|
||||
; CHECK: explicit_comdat_distinct2:
|
||||
; CHECK: .section .explicit_comdat_distinct,"aGM",@progbits,8,h,comdat,unique,[[#U+11]]
|
||||
; CHECK: .section .explicit_comdat_distinct,"aGM",@progbits,8,h,comdat,unique,17
|
||||
; 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",@progbits,4,i,comdat,unique,[[#U+12]]
|
||||
; CHECK: .section .rodata.cst4,"aGM",@progbits,4,i,comdat,unique,18
|
||||
; CHECK: implicit_rodata_cst4_same_comdat:
|
||||
; CHECK: .section .rodata.cst8,"aGM",@progbits,8,i,comdat,unique,[[#U+13]]
|
||||
; CHECK: .section .rodata.cst8,"aGM",@progbits,8,i,comdat,unique,19
|
||||
; 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",@progbits,4,unique,[[#U+14]]
|
||||
; CHECK: .section .explicit_comdat_same,"aM",@progbits,4,unique,20
|
||||
; CHECK: explicit_comdat_same_supply_uid:
|
||||
; CHECK: .section .explicit_comdat_same,"aGM",@progbits,4,i,comdat,unique,[[#U+15]]
|
||||
; CHECK: .section .explicit_comdat_same,"aGM",@progbits,4,i,comdat,unique,20
|
||||
; CHECK: explicit_comdat_same1:
|
||||
; CHECK: explicit_comdat_same2:
|
||||
; CHECK: .section .explicit_comdat_same,"aGM",@progbits,8,i,comdat,unique,[[#U+16]]
|
||||
; CHECK: .section .explicit_comdat_same,"aGM",@progbits,8,i,comdat,unique,21
|
||||
; 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",@progbits,1{{$}}
|
||||
; CHECK: .section .rodata.str1.1,"aMS",@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",@progbits,unique,[[#U+17]]
|
||||
; CHECK: .section .rodata.str1.1,"a",@progbits,unique,22
|
||||
; 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",@progbits,1{{$}}
|
||||
; CHECK: .section .rodata.str1.1,"aMS",@progbits,1
|
||||
; CHECK: explicit_implicit_3:
|
||||
; CHECK: .section .rodata.str1.1,"a",@progbits,unique,[[#U+17]]
|
||||
; CHECK: .section .rodata.str1.1,"a",@progbits,unique,22
|
||||
; 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",@progbits,2{{$}}
|
||||
; CHECK: .section .rodata.str2.2,"aMS",@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",@progbits,2{{$}}
|
||||
; CHECK: .section .asm_mergeable1,"aMS",@progbits,2
|
||||
; CHECK: explicit_asm_1:
|
||||
; CHECK: .section .asm_nonmergeable1,"a",@progbits{{$}}
|
||||
; CHECK: .section .asm_nonmergeable1,"a",@progbits
|
||||
; CHECK: explicit_asm_2:
|
||||
; CHECK: .section .asm_mergeable1,"aM",@progbits,4,unique,[[#U+18]]
|
||||
; CHECK: .section .asm_mergeable1,"aM",@progbits,4,unique,23
|
||||
; CHECK: explicit_asm_3:
|
||||
; CHECK: .section .asm_nonmergeable1,"aMS",@progbits,2,unique,[[#U+19]]
|
||||
; CHECK: .section .asm_nonmergeable1,"aMS",@progbits,2,unique,24
|
||||
; CHECK: explicit_asm_4:
|
||||
; CHECK: .section .asm_mergeable2,"aM",@progbits,4,unique,[[#U+20]]
|
||||
; CHECK: .section .asm_mergeable2,"aM",@progbits,4,unique,25
|
||||
; CHECK: explicit_asm_5:
|
||||
; CHECK: .section .asm_nonmergeable2,"aMS",@progbits,2,unique,[[#U+21]]
|
||||
; CHECK: .section .asm_nonmergeable2,"aMS",@progbits,2,unique,26
|
||||
; CHECK: explicit_asm_6:
|
||||
; CHECK: .section .asm_mergeable2,"aMS",@progbits,2{{$}}
|
||||
; CHECK: .section .asm_mergeable2,"aMS",@progbits,2
|
||||
; CHECK: explicit_asm_7:
|
||||
; CHECK: .section .asm_nonmergeable2,"a",@progbits{{$}}
|
||||
; CHECK: .section .asm_nonmergeable2,"a",@progbits
|
||||
; CHECK: explicit_asm_8:
|
||||
|
||||
module asm ".section .asm_mergeable1,\22aMS\22,@progbits,2"
|
||||
@ -277,7 +277,7 @@ module asm ".section .asm_nonmergeable2,\22a\22,@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","",@progbits{{$}}
|
||||
; CHECK: .section ".note.GNU-stack","",@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,@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",@progbits{{$}}
|
||||
; NO-I-AS-OLD: .section .explicit,"a",@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 \
|
||||
|
@ -22,36 +22,34 @@ using namespace llvm::orc;
|
||||
|
||||
namespace {
|
||||
|
||||
// Returns whether a non-alloc section was passed to the memory manager.
|
||||
// Adds an object with a debug section to RuntimeDyld and then returns whether
|
||||
// the debug section was passed to the memory manager.
|
||||
static bool testSetProcessAllSections(std::unique_ptr<MemoryBuffer> Obj,
|
||||
bool ProcessAllSections) {
|
||||
class MemoryManagerWrapper : public SectionMemoryManager {
|
||||
public:
|
||||
MemoryManagerWrapper(bool &NonAllocSeen) : NonAllocSeen(NonAllocSeen) {}
|
||||
MemoryManagerWrapper(bool &DebugSeen) : DebugSeen(DebugSeen) {}
|
||||
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
|
||||
unsigned SectionID, StringRef SectionName,
|
||||
bool IsReadOnly) override {
|
||||
// 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;
|
||||
if (SectionName == ".debug_str")
|
||||
DebugSeen = true;
|
||||
return SectionMemoryManager::allocateDataSection(
|
||||
Size, Alignment, SectionID, SectionName, IsReadOnly);
|
||||
}
|
||||
|
||||
private:
|
||||
bool &NonAllocSeen;
|
||||
bool &DebugSeen;
|
||||
};
|
||||
|
||||
bool NonAllocSectionSeen = false;
|
||||
bool DebugSectionSeen = false;
|
||||
|
||||
ExecutionSession ES(std::make_unique<UnsupportedExecutorProcessControl>());
|
||||
auto &JD = ES.createBareJITDylib("main");
|
||||
auto Foo = ES.intern("foo");
|
||||
|
||||
RTDyldObjectLinkingLayer ObjLayer(ES, [&NonAllocSectionSeen]() {
|
||||
return std::make_unique<MemoryManagerWrapper>(NonAllocSectionSeen);
|
||||
RTDyldObjectLinkingLayer ObjLayer(ES, [&DebugSectionSeen]() {
|
||||
return std::make_unique<MemoryManagerWrapper>(DebugSectionSeen);
|
||||
});
|
||||
|
||||
auto OnResolveDoNothing = [](Expected<SymbolMap> R) {
|
||||
@ -67,16 +65,13 @@ static bool testSetProcessAllSections(std::unique_ptr<MemoryBuffer> Obj,
|
||||
if (auto Err = ES.endSession())
|
||||
ES.reportError(std::move(Err));
|
||||
|
||||
return NonAllocSectionSeen;
|
||||
return DebugSectionSeen;
|
||||
}
|
||||
|
||||
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,
|
||||
@ -84,6 +79,8 @@ 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();
|
||||
@ -96,9 +93,9 @@ TEST(RTDyldObjectLinkingLayerTest, TestSetProcessAllSections) {
|
||||
|
||||
EXPECT_FALSE(testSetProcessAllSections(
|
||||
MemoryBuffer::getMemBufferCopy(Obj->getBuffer()), false))
|
||||
<< "Non-alloc section seen despite ProcessAllSections being false";
|
||||
<< "Debug section seen despite ProcessAllSections being false";
|
||||
EXPECT_TRUE(testSetProcessAllSections(std::move(Obj), true))
|
||||
<< "Expected to see non-alloc section when ProcessAllSections is true";
|
||||
<< "Expected to see debug section when ProcessAllSections is true";
|
||||
}
|
||||
|
||||
TEST(RTDyldObjectLinkingLayerTest, TestOverrideObjectFlags) {
|
||||
|
Loading…
Reference in New Issue
Block a user