diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -1023,16 +1023,20 @@ break; } - if (Section.getFlags() & ELF::SHF_LINK_ORDER) { + unsigned Flags = Section.getFlags(); + if (Flags & ELF::SHF_LINK_ORDER) { const MCSymbol *Sym = Section.getAssociatedSymbol(); - const MCSectionELF *Sec = cast(&Sym->getSection()); - sh_link = SectionIndexMap.lookup(Sec); + if (Sym->isInSection()) { + const MCSectionELF *Sec = cast(&Sym->getSection()); + sh_link = SectionIndexMap.lookup(Sec); + } else { + Flags &= ~ELF::SHF_LINK_ORDER; + } } WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getSectionName()), - Section.getType(), Section.getFlags(), 0, Offset, Size, - sh_link, sh_info, Section.getAlignment(), - Section.getEntrySize()); + Section.getType(), Flags, 0, Offset, Size, sh_link, sh_info, + Section.getAlignment(), Section.getEntrySize()); } void ELFWriter::writeSectionHeader( diff --git a/llvm/test/CodeGen/X86/elf-associated-discarded.ll b/llvm/test/CodeGen/X86/elf-associated-discarded.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/elf-associated-discarded.ll @@ -0,0 +1,23 @@ +;; Test that we drop SHF_LINK_ORDER and reset sh_link to 0 if the associated +;; symbol is not defined. +; RUN: llc -mtriple=x86_64 -data-sections=1 < %s | FileCheck %s +; RUN: llc -filetype=obj -mtriple=x86_64 -data-sections=1 < %s | llvm-readelf -S | FileCheck --check-prefix=SEC %s + +;; FIXME The assembly output cannot be assembled because foo is not defined. +;; This is difficult to fix because we allow loops (see elf-associated.ll +;; .data.c and .data.d). +; CHECK: .section .data.a,"awo",@progbits,foo +; CHECK: .section .data.b,"awo",@progbits,foo + +;; No 'L' (SHF_LINK_ORDER). sh_link=0. +; SEC; Name {{.*}} Flg Lk Inf +; SEC: .data.a {{.*}} WA 0 0 +; SEC: .data.b {{.*}} WA 0 0 + +;; The definition may be discarded by LTO. +declare void @foo() + +@a = global i32 1, !associated !0 +@b = global i32 1, !associated !0 + +!0 = !{void ()* @foo}