From 83be4429b2807ac1568507d2bee657c9ba713966 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 6 Apr 2015 04:25:18 +0000 Subject: [PATCH] Store the sh_link of ARM_EXIDX directly in MCSectionELF. This avoids some pretty horrible and broken name based section handling. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234142 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCContext.h | 6 ++ lib/MC/ELFObjectWriter.cpp | 15 +--- lib/MC/MCContext.cpp | 19 +++- .../ARM/MCTargetDesc/ARMELFStreamer.cpp | 15 ++-- test/MC/ARM/eh-link.s | 90 +++++++++++++++++++ 5 files changed, 120 insertions(+), 25 deletions(-) create mode 100644 test/MC/ARM/eh-link.s diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index d6d6c255d28..8ac2047b43b 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -334,6 +334,12 @@ namespace llvm { StringRef Group, unsigned UniqueID, const char *BeginSymName); + const MCSectionELF *getELFSection(StringRef Section, unsigned Type, + unsigned Flags, unsigned EntrySize, + const MCSymbol *Group, unsigned UniqueID, + const char *BeginSymName, + const MCSectionELF *Associated); + const MCSectionELF *createELFRelSection(StringRef Name, unsigned Type, unsigned Flags, unsigned EntrySize, const MCSymbol *Group, diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 807a2ce35e0..2004b1b8a2d 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -1546,19 +1546,8 @@ void ELFObjectWriter::writeSection(MCAssembler &Asm, } if (TargetObjectWriter->getEMachine() == ELF::EM_ARM && - Section.getType() == ELF::SHT_ARM_EXIDX) { - StringRef SecName(Section.getSectionName()); - if (SecName == ".ARM.exidx") { - sh_link = SectionIndexMap.lookup(Asm.getContext().getELFSection( - ".text", ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC)); - } else if (SecName.startswith(".ARM.exidx")) { - 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, 0, GroupName)); - } - } + Section.getType() == ELF::SHT_ARM_EXIDX) + sh_link = SectionIndexMap.lookup(Section.getAssociatedSection()); WriteSecHdrEntry(ShStrTabBuilder.getOffset(Section.getSectionName()), Section.getType(), diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index 211f1640652..5f8e3c11de3 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -295,11 +295,22 @@ const MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type, StringRef Group, unsigned UniqueID, const char *BeginSymName) { MCSymbol *GroupSym = nullptr; - if (!Group.empty()) { + if (!Group.empty()) GroupSym = GetOrCreateSymbol(Group); - Group = GroupSym->getName(); - } + return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID, + BeginSymName, nullptr); +} + +const MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type, + unsigned Flags, unsigned EntrySize, + const MCSymbol *GroupSym, + unsigned UniqueID, + const char *BeginSymName, + const MCSectionELF *Associated) { + StringRef Group = ""; + if (GroupSym) + Group = GroupSym->getName(); // Do the lookup, if we have a hit, return it. auto IterBool = ELFUniquingMap.insert( std::make_pair(ELFSectionKey{Section, Group, UniqueID}, nullptr)); @@ -321,7 +332,7 @@ const MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type, MCSectionELF *Result = new (*this) MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, - GroupSym, UniqueID, Begin, nullptr); + GroupSym, UniqueID, Begin, Associated); Entry.second = Result; return Result; } diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index 9648ffafed8..b116cb80137 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -1083,14 +1083,13 @@ inline void ARMELFStreamer::SwitchToEHSection(const char *Prefix, } // Get .ARM.extab or .ARM.exidx section - const MCSectionELF *EHSection = nullptr; - if (const MCSymbol *Group = FnSection.getGroup()) { - EHSection = - getContext().getELFSection(EHSecName, Type, Flags | ELF::SHF_GROUP, - FnSection.getEntrySize(), Group->getName()); - } else { - EHSection = getContext().getELFSection(EHSecName, Type, Flags); - } + const MCSymbol *Group = FnSection.getGroup(); + if (Group) + Flags |= ELF::SHF_GROUP; + const MCSectionELF *EHSection = + getContext().getELFSection(EHSecName, Type, Flags, 0, Group, + FnSection.getUniqueID(), nullptr, &FnSection); + assert(EHSection && "Failed to get the required EH section"); // Switch to .ARM.extab or .ARM.exidx section diff --git a/test/MC/ARM/eh-link.s b/test/MC/ARM/eh-link.s new file mode 100644 index 00000000000..b7bed61bd44 --- /dev/null +++ b/test/MC/ARM/eh-link.s @@ -0,0 +1,90 @@ +@ RUN: llvm-mc %s -triple=armv7-unknown-linux-gnueabi -filetype=obj -o - \ +@ RUN: | llvm-readobj -s | FileCheck %s + +@ Test that the ARM_EXIDX sections point (Link) to the corresponding text +@ sections. + +@ FIXME: The section numbers are not important. If llvm-readobj printed the +@ name first we could use a FileCheck variable. + +@ CHECK: Section { +@ CHECK: Index: 6 +@ CHECK-NEXT: Name: .text +@ CHECK-NEXT: Type: SHT_PROGBITS +@ CHECK-NEXT: Flags [ +@ CHECK-NEXT: SHF_ALLOC +@ CHECK-NEXT: SHF_EXECINSTR +@ CHECK-NEXT: SHF_GROUP +@ CHECK-NEXT: ] +@ CHECK-NEXT: Address: 0x0 +@ CHECK-NEXT: Offset: 0x54 +@ CHECK-NEXT: Size: 4 +@ CHECK-NEXT: Link: 0 +@ CHECK-NEXT: Info: 0 +@ CHECK-NEXT: AddressAlignment: 1 +@ CHECK-NEXT: EntrySize: 0 +@ CHECK-NEXT: } +@ CHECK-NEXT: Section { +@ CHECK-NEXT: Index: 7 +@ CHECK-NEXT: Name: .ARM.exidx +@ CHECK-NEXT: Type: SHT_ARM_EXIDX +@ CHECK-NEXT: Flags [ +@ CHECK-NEXT: SHF_ALLOC +@ CHECK-NEXT: SHF_GROUP +@ CHECK-NEXT: SHF_LINK_ORDER +@ CHECK-NEXT: ] +@ CHECK-NEXT: Address: 0x0 +@ CHECK-NEXT: Offset: 0x58 +@ CHECK-NEXT: Size: 8 +@ CHECK-NEXT: Link: 6 +@ CHECK-NEXT: Info: 0 +@ CHECK-NEXT: AddressAlignment: 4 +@ CHECK-NEXT: EntrySize: 0 +@ CHECK-NEXT: } + +@ CHECK: Section { +@ CHECK: Index: 9 +@ CHECK-NEXT: Name: .text +@ CHECK-NEXT: Type: SHT_PROGBITS +@ CHECK-NEXT: Flags [ +@ CHECK-NEXT: SHF_ALLOC +@ CHECK-NEXT: SHF_EXECINSTR +@ CHECK-NEXT: SHF_GROUP +@ CHECK-NEXT: ] +@ CHECK-NEXT: Address: 0x0 +@ CHECK-NEXT: Offset: 0x60 +@ CHECK-NEXT: Size: 4 +@ CHECK-NEXT: Link: 0 +@ CHECK-NEXT: Info: 0 +@ CHECK-NEXT: AddressAlignment: 1 +@ CHECK-NEXT: EntrySize: 0 +@ CHECK-NEXT: } +@ CHECK-NEXT: Section { +@ CHECK-NEXT: Index: 10 +@ CHECK-NEXT: Name: .ARM.exidx +@ CHECK-NEXT: Type: SHT_ARM_EXIDX +@ CHECK-NEXT: Flags [ +@ CHECK-NEXT: SHF_ALLOC +@ CHECK-NEXT: SHF_GROUP +@ CHECK-NEXT: SHF_LINK_ORDER +@ CHECK-NEXT: ] +@ CHECK-NEXT: Address: 0x0 +@ CHECK-NEXT: Offset: 0x64 +@ CHECK-NEXT: Size: 8 +@ CHECK-NEXT: Link: 9 +@ CHECK-NEXT: Info: 0 +@ CHECK-NEXT: AddressAlignment: 4 +@ CHECK-NEXT: EntrySize: 0 +@ CHECK-NEXT: } + + .section .text,"axG",%progbits,f,comdat +f: + .fnstart + mov pc, lr + .fnend + + .section .text,"axG",%progbits,g,comdat +g: + .fnstart + mov pc, lr + .fnend -- 2.34.1