Index: include/llvm/Target/TargetLoweringObjectFile.h =================================================================== --- include/llvm/Target/TargetLoweringObjectFile.h +++ include/llvm/Target/TargetLoweringObjectFile.h @@ -89,6 +89,11 @@ static SectionKind getKindForGlobal(const GlobalObject *GO, const TargetMachine &TM); + virtual SectionKind getSectionKindForGlobal(const GlobalObject *GO, + const TargetMachine &TM) const { + return TargetLoweringObjectFile::getKindForGlobal(GO, TM); + } + /// This method computes the appropriate section to emit the specified global /// variable or function definition. This should not be passed external (or /// available externally) globals. Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -388,7 +388,8 @@ if (MAI->hasDotTypeDotSizeDirective()) OutStreamer->EmitSymbolAttribute(EmittedSym, MCSA_ELF_TypeObject); - SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM); + const TargetLoweringObjectFile &TLOF = getObjFileLowering(); + SectionKind GVKind = TLOF.getSectionKindForGlobal(GV, TM); const DataLayout &DL = GV->getParent()->getDataLayout(); uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType()); Index: lib/Target/PowerPC/PPCTargetObjectFile.h =================================================================== --- lib/Target/PowerPC/PPCTargetObjectFile.h +++ lib/Target/PowerPC/PPCTargetObjectFile.h @@ -25,6 +25,10 @@ MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override; + SectionKind getSectionKindForGlobal(const GlobalObject *GO, + const TargetMachine &TM) const override; + + /// \brief Describe a TLS variable address within debug info. const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const override; }; Index: lib/Target/PowerPC/PPCTargetObjectFile.cpp =================================================================== --- lib/Target/PowerPC/PPCTargetObjectFile.cpp +++ lib/Target/PowerPC/PPCTargetObjectFile.cpp @@ -48,6 +48,22 @@ return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM); } +SectionKind PPC64LinuxTargetObjectFile::getSectionKindForGlobal( + const GlobalObject *GO, const TargetMachine &TM) const { + auto Kind = TargetLoweringObjectFileELF::getSectionKindForGlobal(GO, TM); + + // See in PPC64LinuxTargetObjectFile::SelectSectionForGlobal above. + if (Kind.isReadOnly()) { + const auto *GVar = dyn_cast(GO); + + if (GVar && GVar->isConstant() && GVar->getInitializer()->needsRelocation()) + Kind = SectionKind::getReadOnlyWithRel(); + } + + return Kind; +} + + const MCExpr *PPC64LinuxTargetObjectFile:: getDebugThreadLocalSymbol(const MCSymbol *Sym) const { const MCExpr *Expr = Index: test/CodeGen/PowerPC/func-addr-consts.ll =================================================================== --- test/CodeGen/PowerPC/func-addr-consts.ll +++ test/CodeGen/PowerPC/func-addr-consts.ll @@ -0,0 +1,16 @@ +; RUN: llc < %s | FileCheck %s +target datalayout = "E-m:e-i64:64-n32:64" +target triple = "powerpc64--linux" + +@g = internal constant i8* bitcast (void ()* @f to i8*), section "gsection", align 8 +@h = constant i8* bitcast (void ()* @f to i8*), section "hsection", align 8 +@llvm.used = appending global [2 x i8*] [i8* bitcast (i8** @g to i8*), i8* bitcast (i8** @h to i8*)], section "llvm.metadata" + +; Function Attrs: nounwind uwtable +define internal void @f() { +entry: + ret void +} + +; CHECK: .section gsection,"aw",@progbits +; CHECK: .section hsection,"aw",@progbits