/// The Compile Unit ID that we are currently processing.
unsigned DwarfCompileUnitID = 0;
+ // Sections are differentiated by the quadruple (section_name, group_name,
+ // unique_id, link_to_symbol_name). Sections sharing the same quadruple are
+ // combined into one section.
struct ELFSectionKey {
std::string SectionName;
StringRef GroupName;
+ StringRef LinkedToName;
unsigned UniqueID;
ELFSectionKey(StringRef SectionName, StringRef GroupName,
- unsigned UniqueID)
- : SectionName(SectionName), GroupName(GroupName), UniqueID(UniqueID) {
- }
+ StringRef LinkedToName, unsigned UniqueID)
+ : SectionName(SectionName), GroupName(GroupName),
+ LinkedToName(LinkedToName), UniqueID(UniqueID) {}
bool operator<(const ELFSectionKey &Other) const {
if (SectionName != Other.SectionName)
return SectionName < Other.SectionName;
if (GroupName != Other.GroupName)
return GroupName < Other.GroupName;
+ if (int O = LinkedToName.compare(Other.LinkedToName))
+ return O < 0;
return UniqueID < Other.UniqueID;
}
};
if (const MCSymbol *Group = Section->getGroup())
GroupName = Group->getName();
+ // This function is only used by .debug*, which should not have the
+ // SHF_LINK_ORDER flag.
unsigned UniqueID = Section->getUniqueID();
ELFUniquingMap.erase(
- ELFSectionKey{Section->getSectionName(), GroupName, UniqueID});
- auto I = ELFUniquingMap.insert(std::make_pair(
- ELFSectionKey{Name, GroupName, UniqueID},
- Section))
+ ELFSectionKey{Section->getSectionName(), GroupName, "", UniqueID});
+ auto I = ELFUniquingMap
+ .insert(std::make_pair(
+ ELFSectionKey{Name, GroupName, "", UniqueID}, Section))
.first;
StringRef CachedName = I->first.SectionName;
const_cast<MCSectionELF *>(Section)->setSectionName(CachedName);
if (GroupSym)
Group = GroupSym->getName();
// Do the lookup, if we have a hit, return it.
- auto IterBool = ELFUniquingMap.insert(
- std::make_pair(ELFSectionKey{Section.str(), Group, UniqueID}, nullptr));
+ auto IterBool = ELFUniquingMap.insert(std::make_pair(
+ ELFSectionKey{Section.str(), Group,
+ LinkedToSym ? LinkedToSym->getName() : "", UniqueID},
+ nullptr));
auto &Entry = *IterBool.first;
if (!IterBool.second)
return Entry.second;
; CHECK-NEXT: ret
; CHECK: .Lfunc_end2:
; CHECK-NEXT: .size f2_1, .Lfunc_end2-f2_1
-; CHECK: .section __patchable_function_entries,"awo",@progbits,f1,unique,0
+; CHECK: .section __patchable_function_entries,"awo",@progbits,f2_1,unique,0
; CHECK-NEXT: .p2align 3
; CHECK-NEXT: .xword .Ltmp0
ret void
;; Other basic blocks have BTI, but they don't affect our decision to not create .Lpatch0
; CHECK: .LBB{{.+}} // %sw.bb1
; CHECK-NEXT: hint #36
-; CHECK: .section __patchable_function_entries,"awo",@progbits,f1,unique,0
+; CHECK: .section __patchable_function_entries,"awo",@progbits,f1i,unique,0
; CHECK-NEXT: .p2align 3
; CHECK-NEXT: .xword .Lfunc_begin3
entry:
; CHECK-NEXT: .Lfunc_begin2:
; CHECK-COUNT-2: nop
; CHECK-NEXT: ret
-; NOFSECT: .section __patchable_function_entries,"awo",@progbits,f1,unique,0
+; NOFSECT: .section __patchable_function_entries,"awo",@progbits,f2,unique,0
; FSECT: .section __patchable_function_entries,"awo",@progbits,f2,unique,1
; CHECK-NEXT: .p2align 3
; CHECK-NEXT: .xword .Lfunc_begin2
;; .size does not include the prefix.
; CHECK: .Lfunc_end5:
; CHECK-NEXT: .size f3_2, .Lfunc_end5-f3_2
-; NOFSECT .section __patchable_function_entries,"awo",@progbits,f1,unique,0
+; NOFSECT: .section __patchable_function_entries,"awo",@progbits,f3_2,unique,0
; FSECT: .section __patchable_function_entries,"awo",@progbits,f3_2,unique,4
; CHECK: .p2align 3
; CHECK-NEXT: .xword .Ltmp1
; CHECK-NEXT: ret
; CHECK: .Lfunc_end2:
; CHECK-NEXT: .size f2_1, .Lfunc_end2-f2_1
-; CHECK: .section __patchable_function_entries,"awo",@progbits,f1,unique,0
+; CHECK: .section __patchable_function_entries,"awo",@progbits,f2_1,unique,0
; 32-NEXT: .p2align 2
; 32-NEXT: .long .Ltmp0
; 64-NEXT: .p2align 3
; CHECK-NOT: .Lpatch0:
;; Another basic block has ENDBR, but it doesn't affect our decision to not create .Lpatch0
; CHECK: endbr
-; CHECK: .section __patchable_function_entries,"awo",@progbits,f1,unique,0
+; CHECK: .section __patchable_function_entries,"awo",@progbits,f1i,unique,0
; 32-NEXT: .p2align 2
; 32-NEXT: .long .Lfunc_begin3
; 64-NEXT: .p2align 3
; 32-COUNT-2: nop
; 64: xchgw %ax, %ax
; CHECK-NEXT: ret
-; NOFSECT: .section __patchable_function_entries,"awo",@progbits,f1,unique,0
+; NOFSECT: .section __patchable_function_entries,"awo",@progbits,f2,unique,0
; FSECT: .section __patchable_function_entries,"awo",@progbits,f2,unique,1
; 32: .p2align 2
; 32-NEXT: .long .Lfunc_begin2
;; .size does not include the prefix.
; CHECK: .Lfunc_end5:
; CHECK-NEXT: .size f3_2, .Lfunc_end5-f3_2
-; NOFSECT .section __patchable_function_entries,"awo",@progbits,f0,unique,0
+; NOFSECT: .section __patchable_function_entries,"awo",@progbits,f3_2,unique,0
; FSECT: .section __patchable_function_entries,"awo",@progbits,f3_2,unique,4
; 32: .p2align 2
; 32-NEXT: .long .Ltmp0
+++ /dev/null
-// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -S --symbols | FileCheck %s
-
-// Test that we produce two foo sections, each in separate groups
-
-// CHECK: Index: 3
-// CHECK-NEXT: Name: .group
-
-// CHECK: Index: 4
-// CHECK-NEXT: Name: .foo
-
-// CHECK: Index: 5
-// CHECK-NEXT: Name: .group
-
-// CHECK: Index: 6
-// CHECK-NEXT: Name: .foo
-
-// CHECK: Symbols [
-
-// CHECK: Name: f1
-// CHECK-NOT: }
-// CHECK: Section: .group (0x3)
-
-// CHECK: Name: f2
-// CHECK-NOT: }
-// CHECK: Section: .group (0x5)
-
- .section .foo,"axG",@progbits,f1,comdat
- nop
-
- .section .foo,"axG",@progbits,f2,comdat
- nop
-
--- /dev/null
+## Sections are differentiated by the quadruple
+## (section_name, group_name, unique_id, link_to_symbol_name).
+## Sections sharing the same quadruple are combined into one section.
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t
+# RUN: llvm-readelf -x .foo %t | FileCheck %s
+
+# CHECK: Hex dump of section '.foo':
+# CHECK-NEXT: 0x00000000 00
+# CHECK: Hex dump of section '.foo':
+# CHECK-NEXT: 0x00000000 0102
+# CHECK: Hex dump of section '.foo':
+# CHECK-NEXT: 0x00000000 03
+# CHECK: Hex dump of section '.foo':
+# CHECK-NEXT: 0x00000000 0405
+# CHECK: Hex dump of section '.foo':
+# CHECK-NEXT: 0x00000000 06
+# CHECK: Hex dump of section '.foo':
+# CHECK-NEXT: 0x00000000 0708
+
+foo:
+bar:
+
+## foo and bar are in the same section. However, a section referencing foo
+## is considered different from a section referencing bar.
+.section .foo,"o",@progbits,foo
+.byte 0
+
+.section .foo,"o",@progbits,bar
+.byte 1
+.section .foo,"o",@progbits,bar
+.byte 2
+
+.section .foo,"o",@progbits,bar,unique,0
+.byte 3
+
+.section .foo,"o",@progbits,bar,unique,1
+.byte 4
+.section .foo,"o",@progbits,bar,unique,1
+.byte 5
+
+.section .foo,"Go",@progbits,comdat0,comdat,bar,unique,1
+.byte 6
+
+.section .foo,"Go",@progbits,comdat1,comdat,bar,unique,1
+.byte 7
+.section .foo,"Go",@progbits,comdat1,comdat,bar,unique,1
+.byte 8