From 329a9a8a331ef87a1807e6d9d45d448338cc6224 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Tue, 22 Oct 2013 23:41:52 +0000 Subject: [PATCH] MC: Support multiple sections with the same name in the same comdat group Code review by Eric Christopher and Rafael Espindola. llvm-svn: 193209 --- lib/MC/ELFObjectWriter.cpp | 19 +++++++------ lib/MC/MCContext.cpp | 18 ++++++++----- test/MC/ELF/comdat-dup-group-name.s | 41 +++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 test/MC/ELF/comdat-dup-group-name.s diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index c5f7287bc22..eb197f2cec7 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -1298,10 +1298,12 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm, // Remove ".rel" and ".rela" prefixes. unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5; StringRef SectionName = Section.getSectionName().substr(SecNameLen); + StringRef GroupName = + Section.getGroup() ? Section.getGroup()->getName() : ""; - InfoSection = Asm.getContext().getELFSection(SectionName, - ELF::SHT_PROGBITS, 0, - SectionKind::getReadOnly()); + InfoSection = Asm.getContext().getELFSection(SectionName, ELF::SHT_PROGBITS, + 0, SectionKind::getReadOnly(), + 0, GroupName); sh_info = SectionIndexMap.lookup(InfoSection); break; } @@ -1351,11 +1353,12 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC, SectionKind::getText())); } else if (SecName.startswith(".ARM.exidx")) { - sh_link = SectionIndexMap.lookup( - Asm.getContext().getELFSection(SecName.substr(sizeof(".ARM.exidx") - 1), - ELF::SHT_PROGBITS, - ELF::SHF_EXECINSTR | ELF::SHF_ALLOC, - SectionKind::getText())); + StringRef GroupName = + Section.getGroup() ? Section.getGroup()->getName() : ""; + sh_link = SectionIndexMap.lookup(Asm.getContext().getELFSection( + SecName.substr(sizeof(".ARM.exidx") - 1), ELF::SHT_PROGBITS, + ELF::SHF_EXECINSTR | ELF::SHF_ALLOC, SectionKind::getText(), 0, + GroupName)); } } diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index 6e4d82b6e76..67904f6f74b 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -25,10 +25,15 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Signals.h" #include "llvm/Support/SourceMgr.h" + +#include + using namespace llvm; +typedef std::pair SectionGroupPair; + typedef StringMap MachOUniqueMapTy; -typedef StringMap ELFUniqueMapTy; +typedef std::map ELFUniqueMapTy; typedef StringMap COFFUniqueMapTy; @@ -249,8 +254,9 @@ getELFSection(StringRef Section, unsigned Type, unsigned Flags, ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)ELFUniquingMap; // Do the lookup, if we have a hit, return it. - StringMapEntry &Entry = Map.GetOrCreateValue(Section); - if (Entry.getValue()) return Entry.getValue(); + std::pair Entry = Map.insert( + std::make_pair(SectionGroupPair(Section, Group), (MCSectionELF *)0)); + if (!Entry.second) return Entry.first->second; // Possibly refine the entry size first. if (!EntrySize) { @@ -261,9 +267,9 @@ getELFSection(StringRef Section, unsigned Type, unsigned Flags, if (!Group.empty()) GroupSym = GetOrCreateSymbol(Group); - MCSectionELF *Result = new (*this) MCSectionELF(Entry.getKey(), Type, Flags, - Kind, EntrySize, GroupSym); - Entry.setValue(Result); + MCSectionELF *Result = new (*this) MCSectionELF( + Entry.first->first.first, Type, Flags, Kind, EntrySize, GroupSym); + Entry.first->second = Result; return Result; } diff --git a/test/MC/ELF/comdat-dup-group-name.s b/test/MC/ELF/comdat-dup-group-name.s new file mode 100644 index 00000000000..1181e2eab02 --- /dev/null +++ b/test/MC/ELF/comdat-dup-group-name.s @@ -0,0 +1,41 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -s -t | FileCheck %s + +// Test that we produce two foo sections, each in separate groups + +// CHECK: Index: 1 +// CHECK-NEXT: Name: .group + +// CHECK: Index: 2 +// CHECK-NEXT: Name: .group + +// CHECK: Index: 6 +// CHECK-NEXT: Name: .foo + +// CHECK: Index: 7 +// CHECK-NEXT: Name: .foo + +// CHECK: Symbols [ + +// CHECK: Name: f1 +// CHECK-NOT: } +// CHECK: Section: .group (0x1) + +// CHECK: Name: f2 +// CHECK-NOT: } +// CHECK: Section: .group (0x2) + +// CHECK: Name: .foo +// CHECK-NOT: } +// CHECK: Section: .foo (0x6) + +// CHECK: Name: .foo +// CHECK-NOT: } +// CHECK: Section: .foo (0x7) + + + .section .foo,"axG",@progbits,f1,comdat + nop + + .section .foo,"axG",@progbits,f2,comdat + nop +