diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 348470bd7687..0853c7a34354 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -682,9 +682,10 @@ calcUniqueIDUpdateFlagsAndSize(const GlobalObject *GO, StringRef SectionName, } if (Retain) { - if ((Ctx.getAsmInfo()->useIntegratedAssembler() || - Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36)) && - !TM.getTargetTriple().isOSSolaris()) + if (TM.getTargetTriple().isOSSolaris()) + Flags |= ELF::SHF_SUNW_NODISCARD; + else if (Ctx.getAsmInfo()->useIntegratedAssembler() || + Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36)) Flags |= ELF::SHF_GNU_RETAIN; return NextUniqueID++; } @@ -861,12 +862,15 @@ static MCSection *selectELFSectionForGlobal( EmitUniqueSection = true; Flags |= ELF::SHF_LINK_ORDER; } - if (Retain && - (Ctx.getAsmInfo()->useIntegratedAssembler() || - Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36)) && - !TM.getTargetTriple().isOSSolaris()) { - EmitUniqueSection = true; - Flags |= ELF::SHF_GNU_RETAIN; + if (Retain) { + if (TM.getTargetTriple().isOSSolaris()) { + EmitUniqueSection = true; + Flags |= ELF::SHF_SUNW_NODISCARD; + } else if (Ctx.getAsmInfo()->useIntegratedAssembler() || + Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36)) { + EmitUniqueSection = true; + Flags |= ELF::SHF_GNU_RETAIN; + } } MCSectionELF *Section = selectELFSectionForGlobal( diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp index 2d76b1c12c95..34f11eb25dbe 100644 --- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -282,7 +282,8 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) { return false; } -static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) { +static unsigned parseSectionFlags(const Triple &TT, StringRef flagsStr, + bool *UseLastGroup) { unsigned flags = 0; // If a valid numerical value is set for the section flag, use it verbatim @@ -331,7 +332,10 @@ static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) { flags |= ELF::SHF_GROUP; break; case 'R': - flags |= ELF::SHF_GNU_RETAIN; + if (TT.isOSSolaris()) + flags |= ELF::SHF_SUNW_NODISCARD; + else + flags |= ELF::SHF_GNU_RETAIN; break; case '?': *UseLastGroup = true; @@ -569,7 +573,8 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { } else { StringRef FlagsStr = getTok().getStringContents(); Lex(); - extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup); + extraFlags = parseSectionFlags(getContext().getTargetTriple(), FlagsStr, + &UseLastGroup); } if (extraFlags == -1U) diff --git a/llvm/lib/MC/MCSectionELF.cpp b/llvm/lib/MC/MCSectionELF.cpp index d18876507cd7..7480a68be8ec 100644 --- a/llvm/lib/MC/MCSectionELF.cpp +++ b/llvm/lib/MC/MCSectionELF.cpp @@ -105,6 +105,11 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, if (Flags & ELF::SHF_GNU_RETAIN) OS << 'R'; + // If there are os-specific flags, print them. + if (T.isOSSolaris()) + if (Flags & ELF::SHF_SUNW_NODISCARD) + OS << 'R'; + // If there are target-specific flags, print them. Triple::ArchType Arch = T.getArch(); if (Arch == Triple::xcore) { diff --git a/llvm/test/CodeGen/X86/elf-retain.ll b/llvm/test/CodeGen/X86/elf-retain.ll index 95d0414f36ed..fface61e6b82 100644 --- a/llvm/test/CodeGen/X86/elf-retain.ll +++ b/llvm/test/CodeGen/X86/elf-retain.ll @@ -3,6 +3,8 @@ ; RUN: llc -mtriple=x86_64 -data-sections=1 < %s | FileCheck %s ; RUN: llc -mtriple=x86_64 -no-integrated-as -binutils-version=2.36 < %s | FileCheck %s ; RUN: llc -mtriple=x86_64 -no-integrated-as -binutils-version=2.35 < %s | FileCheck %s --check-prefix=OLDGAS +;; Solaris uses the equivalent SHF_SUNW_NODISCARD flag, also represented as "R". +; RUN: llc -mtriple=x86_64-solaris < %s | FileCheck %s ; RUN: llc -mtriple=x86_64 -data-sections=1 -unique-section-names=0 < %s | FileCheck %s --check-prefix=NOUNIQUE diff --git a/llvm/test/MC/ELF/section-gnu.s b/llvm/test/MC/ELF/section-gnu.s index cb4fc9d3d2b5..573153bf7f4e 100644 --- a/llvm/test/MC/ELF/section-gnu.s +++ b/llvm/test/MC/ELF/section-gnu.s @@ -1,19 +1,22 @@ # REQUIRES: aarch64-registered-target # RUN: llvm-mc -triple=x86_64 %s | FileCheck %s --check-prefix=ASM -# RUN: llvm-mc -filetype=obj -triple=x86_64 %s | llvm-readobj -hS - | FileCheck %s --check-prefixes=GNU,OBJ -# RUN: llvm-mc -filetype=obj -triple=aarch64-freebsd %s | llvm-readobj -hS - | FileCheck %s --check-prefixes=FREEBSD,OBJ +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s | llvm-readobj -hS - | FileCheck %s --check-prefixes=GNU,OBJ,OBJ-GNU +# RUN: llvm-mc -filetype=obj -triple=aarch64-freebsd %s | llvm-readobj -hS - | FileCheck %s --check-prefixes=FREEBSD,OBJ,OBJ-GNU +# RUN: llvm-mc -filetype=obj -triple=x86_64-solaris %s | llvm-readobj -hS - | FileCheck %s --check-prefixes=SOLARIS,OBJ,OBJ-SOLARIS # ASM: .section retain,"aR",@progbits ## ELFOSABI_NONE is changed to ELFOSABI_GNU. Other OSABI values are unchanged. # GNU: OS/ABI: GNU/Linux # FREEBSD: OS/ABI: FreeBSD +# SOLARIS: OS/ABI: Solaris -# OBJ: Name: retain -# OBJ-NEXT: Type: SHT_PROGBITS -# OBJ-NEXT: Flags [ -# OBJ-NEXT: SHF_ALLOC -# OBJ-NEXT: SHF_GNU_RETAIN -# OBJ-NEXT: ] +# OBJ: Name: retain +# OBJ-NEXT: Type: SHT_PROGBITS +# OBJ-NEXT: Flags [ +# OBJ-NEXT: SHF_ALLOC +# OBJ-GNU-NEXT: SHF_GNU_RETAIN +# OBJ-SOLARIS-NEXT: SHF_SUNW_NODISCARD +# OBJ-NEXT: ] .section retain,"aR",@progbits