mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:43:36 +01:00
[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",@progbits,0` Reviewed By: pcc Differential Revision: https://reviews.llvm.org/D72899
This commit is contained in:
parent
040e0990b8
commit
6fcac4f990
@ -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 {
|
||||
|
@ -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()),
|
||||
|
@ -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);
|
||||
|
@ -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())
|
||||
|
23
test/CodeGen/X86/elf-associated-discarded.ll
Normal file
23
test/CodeGen/X86/elf-associated-discarded.ll
Normal file
@ -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 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 {{.*}} WAL 0 0
|
||||
; SEC: .data.b {{.*}} WAL 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}
|
@ -36,15 +36,15 @@
|
||||
; Non-GlobalValue metadata.
|
||||
@l = global i32 1, section "ccc", !associated !5
|
||||
!5 = !{i32* null}
|
||||
; CHECK-DAG: .section ccc,"aw",@progbits
|
||||
; CHECK-DAG: .section ccc,"awo",@progbits,0,unique,3
|
||||
|
||||
; Null metadata.
|
||||
@m = global i32 1, section "ddd", !associated !6
|
||||
!6 = distinct !{null}
|
||||
; CHECK-DAG: .section ddd,"aw",@progbits
|
||||
; CHECK-DAG: .section ddd,"awo",@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",@progbits,n,unique,3
|
||||
; CHECK-DAG: .section eee,"awo",@progbits,n,unique,5
|
||||
|
8
test/MC/ELF/section-linkorder.s
Normal file
8
test/MC/ELF/section-linkorder.s
Normal file
@ -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",@progbits,0
|
||||
# CHECK: Name Type {{.*}} Flg Lk
|
||||
# CHECK: .linkorder PROGBITS {{.*}} AL 0
|
||||
.section .linkorder,"ao",@progbits,0
|
Loading…
Reference in New Issue
Block a user