[llvm] 11bb7c2 - [MC] Set sh_link to 0 if the associated symbol is undefined
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 3 13:43:59 PDT 2020
Author: Fangrui Song
Date: 2020-08-03T13:43:48-07:00
New Revision: 11bb7c220ccdff1ffec4780ff92fb5acec8f6f0b
URL: https://github.com/llvm/llvm-project/commit/11bb7c220ccdff1ffec4780ff92fb5acec8f6f0b
DIFF: https://github.com/llvm/llvm-project/commit/11bb7c220ccdff1ffec4780ff92fb5acec8f6f0b.diff
LOG: [MC] Set sh_link to 0 if the associated symbol is undefined
Part of https://bugs.llvm.org/show_bug.cgi?id=41734
LTO can drop externally available definitions. Such AssociatedSymbol is
not associated with a symbol. ELFWriter::writeSection() will assert.
Allow a SHF_LINK_ORDER section to have sh_link=0.
We need to give sh_link a syntax, a literal zero in the linked-to symbol
position, e.g. `.section name,"ao", at progbits,0`
Reviewed By: pcc
Differential Revision: https://reviews.llvm.org/D72899
Added:
llvm/test/CodeGen/X86/elf-associated-discarded.ll
llvm/test/MC/ELF/section-linkorder.s
Modified:
llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
llvm/lib/MC/ELFObjectWriter.cpp
llvm/lib/MC/MCParser/ELFAsmParser.cpp
llvm/lib/MC/MCSectionELF.cpp
llvm/test/CodeGen/X86/elf-associated.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 48599199626c..8ef91250423f 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -680,7 +680,7 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
// MD_associated in a unique section.
unsigned UniqueID = MCContext::GenericSectionID;
const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM);
- if (LinkedToSym) {
+ if (GO->getMetadata(LLVMContext::MD_associated)) {
UniqueID = NextUniqueID++;
Flags |= ELF::SHF_LINK_ORDER;
} else {
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index 5a5692c0cb63..b44a36b9713e 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -1024,9 +1024,13 @@ void ELFWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
}
if (Section.getFlags() & ELF::SHF_LINK_ORDER) {
+ // If the value in the associated metadata is not a definition, Sym will be
+ // undefined. Represent this with sh_link=0.
const MCSymbol *Sym = Section.getLinkedToSymbol();
- const MCSectionELF *Sec = cast<MCSectionELF>(&Sym->getSection());
- sh_link = SectionIndexMap.lookup(Sec);
+ if (Sym && Sym->isInSection()) {
+ const MCSectionELF *Sec = cast<MCSectionELF>(&Sym->getSection());
+ sh_link = SectionIndexMap.lookup(Sec);
+ }
}
WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getName()),
diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
index e5ab13bc719d..41779d023a5d 100644
--- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -450,8 +450,14 @@ bool ELFAsmParser::parseLinkedToSym(MCSymbolELF *&LinkedToSym) {
Lex();
StringRef Name;
SMLoc StartLoc = L.getLoc();
- if (getParser().parseIdentifier(Name))
+ if (getParser().parseIdentifier(Name)) {
+ if (getParser().getTok().getString() == "0") {
+ getParser().Lex();
+ LinkedToSym = nullptr;
+ return false;
+ }
return TokError("invalid linked-to symbol");
+ }
LinkedToSym = dyn_cast_or_null<MCSymbolELF>(getContext().lookupSymbol(Name));
if (!LinkedToSym || !LinkedToSym->isInSection())
return Error(StartLoc, "linked-to symbol is not in a section: " + Name);
diff --git a/llvm/lib/MC/MCSectionELF.cpp b/llvm/lib/MC/MCSectionELF.cpp
index 77c259c27a04..7a1555618265 100644
--- a/llvm/lib/MC/MCSectionELF.cpp
+++ b/llvm/lib/MC/MCSectionELF.cpp
@@ -172,9 +172,11 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
}
if (Flags & ELF::SHF_LINK_ORDER) {
- assert(LinkedToSym);
OS << ",";
- printName(OS, LinkedToSym->getName());
+ if (LinkedToSym)
+ printName(OS, LinkedToSym->getName());
+ else
+ OS << '0';
}
if (isUnique())
diff --git a/llvm/test/CodeGen/X86/elf-associated-discarded.ll b/llvm/test/CodeGen/X86/elf-associated-discarded.ll
new file mode 100644
index 000000000000..5a4fad4ebb7d
--- /dev/null
+++ b/llvm/test/CodeGen/X86/elf-associated-discarded.ll
@@ -0,0 +1,23 @@
+;; Test that we keep SHF_LINK_ORDER but 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
diff icult to fix because we allow loops (see elf-associated.ll
+;; .data.c and .data.d).
+; CHECK: .section .data.a,"awo", at progbits,foo
+; CHECK: .section .data.b,"awo", at progbits,foo
+
+;; No 'L' (SHF_LINK_ORDER). sh_link=0.
+; SEC; Name {{.*}} Flg Lk Inf
+; SEC: .data.a {{.*}} WAL 0 0
+; SEC: .data.b {{.*}} WAL 0 0
+
+;; The definition may be discarded by LTO.
+declare void @foo()
+
+ at a = global i32 1, !associated !0
+ at b = global i32 1, !associated !0
+
+!0 = !{void ()* @foo}
diff --git a/llvm/test/CodeGen/X86/elf-associated.ll b/llvm/test/CodeGen/X86/elf-associated.ll
index e0e9e0058289..14a4b5b85b0c 100644
--- a/llvm/test/CodeGen/X86/elf-associated.ll
+++ b/llvm/test/CodeGen/X86/elf-associated.ll
@@ -36,15 +36,15 @@
; Non-GlobalValue metadata.
@l = global i32 1, section "ccc", !associated !5
!5 = !{i32* null}
-; CHECK-DAG: .section ccc,"aw", at progbits
+; CHECK-DAG: .section ccc,"awo", at progbits,0,unique,3
; Null metadata.
@m = global i32 1, section "ddd", !associated !6
!6 = distinct !{null}
-; CHECK-DAG: .section ddd,"aw", at progbits
+; CHECK-DAG: .section ddd,"awo", at progbits,0,unique,4
; Aliases are OK.
@n = alias i32, i32* inttoptr (i64 add (i64 ptrtoint (i32* @a to i64), i64 1297036692682702848) to i32*)
@o = global i32 1, section "eee", !associated !7
!7 = !{i32* @n}
-; CHECK-DAG: .section eee,"awo", at progbits,n,unique,3
+; CHECK-DAG: .section eee,"awo", at progbits,n,unique,5
diff --git a/llvm/test/MC/ELF/section-linkorder.s b/llvm/test/MC/ELF/section-linkorder.s
new file mode 100644
index 000000000000..a0f6357e52cb
--- /dev/null
+++ b/llvm/test/MC/ELF/section-linkorder.s
@@ -0,0 +1,8 @@
+# RUN: llvm-mc -triple x86_64 %s | FileCheck %s --check-prefix=ASM
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t
+# RUN: llvm-readelf -S %t | FileCheck %s
+
+# ASM: .section .linkorder,"ao", at progbits,0
+# CHECK: Name Type {{.*}} Flg Lk
+# CHECK: .linkorder PROGBITS {{.*}} AL 0
+.section .linkorder,"ao", at progbits,0
More information about the llvm-commits
mailing list