Index: include/llvm/MC/MCObjectFileInfo.h =================================================================== --- include/llvm/MC/MCObjectFileInfo.h +++ include/llvm/MC/MCObjectFileInfo.h @@ -299,7 +299,7 @@ MCSection *getStackMapSection() const { return StackMapSection; } MCSection *getFaultMapSection() const { return FaultMapSection; } - MCSection *getStackSizesSection() const { return StackSizesSection; } + MCSection *getStackSizesSection(const MCSection &TextSec, unsigned ID) const; // ELF specific sections. MCSection *getDataRelROSection() const { return DataRelROSection; } Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -989,7 +989,13 @@ if (!MF.getTarget().Options.EmitStackSizeSection) return; - MCSection *StackSizeSection = getObjFileLowering().getStackSizesSection(); + // If -ffunction-section is specified, we want to emit .stack_sizes section + // for each .text.X section. Here we select the unique ID based on a unique + // function number. + unsigned UniqueID = + MF.getTarget().Options.FunctionSections ? MF.getFunctionNumber() : ~0; + MCSection *StackSizeSection = + getObjFileLowering().getStackSizesSection(*getCurrentSection(), UniqueID); if (!StackSizeSection) return; Index: lib/MC/MCObjectFileInfo.cpp =================================================================== --- lib/MC/MCObjectFileInfo.cpp +++ lib/MC/MCObjectFileInfo.cpp @@ -948,3 +948,22 @@ return Ctx->getELFSection(".debug_types", ELF::SHT_PROGBITS, ELF::SHF_GROUP, 0, utostr(Hash)); } + +MCSection *MCObjectFileInfo::getStackSizesSection(const MCSection &TextSec, + unsigned ID) const { + if (Env != IsELF) + return StackSizesSection; + + unsigned Flags = ELF::SHF_LINK_ORDER; + + StringRef GroupName; + const MCSectionELF &ElfSec = static_cast(TextSec); + if (const MCSymbol *Group = ElfSec.getGroup()) { + GroupName = Group->getName(); + Flags |= ELF::SHF_GROUP; + } + + const MCSymbolELF *Link = cast(TextSec.getBeginSymbol()); + return Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, Flags, 0, + GroupName, ID, Link); +} Index: test/CodeGen/X86/stack-size-section-function-sections.ll =================================================================== --- test/CodeGen/X86/stack-size-section-function-sections.ll +++ test/CodeGen/X86/stack-size-section-function-sections.ll @@ -0,0 +1,29 @@ +; RUN: llc < %s -mtriple=x86_64-linux -stack-size-section -function-sections | FileCheck %s + +; Check we add SHF_LINK_ORDER for .stack_sizes and link it with the corresponding .text sections. + +; CHECK: .section .text._Z3barv,"ax",@progbits +; CHECK: .section .stack_sizes,"o",@progbits,.text._Z3barv,unique,0 + +; CHECK: .section .text._Z3foov,"ax",@progbits +; CHECK: .section .stack_sizes,"o",@progbits,.text._Z3foov,unique,1 + +; Check we add .stack_size section to COMDAT with the corresponding .text section if such COMDAT exists. + +; CHECK: .section .text._Z4fooTIiET_v,"axG",@progbits,_Z4fooTIiET_v,comdat +; CHECK: .section .stack_sizes,"Go",@progbits,_Z4fooTIiET_v,comdat,.text._Z4fooTIiET_v,unique,2 + +$_Z4fooTIiET_v = comdat any + +define dso_local i32 @_Z3barv() { + ret i32 0 +} + +define dso_local i32 @_Z3foov() { + %1 = call i32 @_Z4fooTIiET_v() + ret i32 %1 +} + +define linkonce_odr dso_local i32 @_Z4fooTIiET_v() comdat { + ret i32 0 +} Index: test/CodeGen/X86/stack-size-section.ll =================================================================== --- test/CodeGen/X86/stack-size-section.ll +++ test/CodeGen/X86/stack-size-section.ll @@ -22,6 +22,14 @@ ret void } +; Check that we still put .stack_sizes into the corresponding COMDAT group if any. +; CHECK: .section .text._Z4fooTIiET_v,"axG",@progbits,_Z4fooTIiET_v,comdat +; CHECK: .section .stack_sizes,"Go",@progbits,_Z4fooTIiET_v,comdat,.text._Z4fooTIiET_v +$_Z4fooTIiET_v = comdat any +define linkonce_odr dso_local i32 @_Z4fooTIiET_v() comdat { + ret i32 0 +} + ; CHECK-LABEL: dynalloc: ; CHECK-NOT: .section .stack_sizes define void @dynalloc(i32 %N) #0 {