Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -1491,15 +1491,15 @@ } void RelocationBaseSection::finalizeContents() { - // If all relocations are R_*_{,I}RELATIVE they don't refer to any dynamic - // symbol and we don't need a dynamic symbol table. If that is the case, use - // the index of the regular symbol table section (if exists) or 0. - if (In.DynSymTab) - getParent()->Link = In.DynSymTab->getParent()->SectionIndex; - else if (In.SymTab) - getParent()->Link = In.SymTab->getParent()->SectionIndex; - else - getParent()->Link = 0; + // When linking glibc statically, .rela?.plt contains R_*_IRELATIVE + // relocations due to IFUNC (e.g. strcpy). Just set sh_link to 0 as there is + // no .dynsym. We cannot set it to .symtab as otherwise GNU strip (as of + // 2018-10) will change the address of .rela.plt (and rename it to + // .rela.got.plt) and break __rela_iplt_{start,end} used in + // glibc/csu/libc-start.c:apply_irel. Note, GNU readelf will warn "Link field + // (0) should index a symtab section", but we can live with that. + getParent()->Link = + In.DynSymTab ? In.DynSymTab->getParent()->SectionIndex : 0; if (In.RelaIplt == this || In.RelaPlt == this) getParent()->Info = In.GotPlt->getParent()->SectionIndex; Index: test/ELF/aarch64-gnu-ifunc.s =================================================================== --- test/ELF/aarch64-gnu-ifunc.s +++ test/ELF/aarch64-gnu-ifunc.s @@ -15,7 +15,7 @@ // CHECK-NEXT: Address: [[RELA:.*]] // CHECK-NEXT: Offset: 0x158 // CHECK-NEXT: Size: 48 -// CHECK-NEXT: Link: 6 +// CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 4 // CHECK-NEXT: AddressAlignment: 8 // CHECK-NEXT: EntrySize: 24 Index: test/ELF/gnu-ifunc-i386.s =================================================================== --- test/ELF/gnu-ifunc-i386.s +++ test/ELF/gnu-ifunc-i386.s @@ -15,7 +15,7 @@ // CHECK-NEXT: Address: [[RELA:.*]] // CHECK-NEXT: Offset: 0xD4 // CHECK-NEXT: Size: 16 -// CHECK-NEXT: Link: 6 +// CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 4 // CHECK-NEXT: AddressAlignment: 4 // CHECK-NEXT: EntrySize: 8 Index: test/ELF/gnu-ifunc.s =================================================================== --- test/ELF/gnu-ifunc.s +++ test/ELF/gnu-ifunc.s @@ -15,16 +15,13 @@ // CHECK-NEXT: Address: [[RELA:.*]] // CHECK-NEXT: Offset: 0x158 // CHECK-NEXT: Size: 48 -// CHECK-NEXT: Link: [[SYMTAB:.*]] +// CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: [[GOTPLT:.*]] // CHECK-NEXT: AddressAlignment: 8 // CHECK-NEXT: EntrySize: 24 // CHECK-NEXT: } // CHECK: Index: [[GOTPLT]] // CHECK-NEXT: Name: .got.plt -// CHECK: Index: [[SYMTAB]] -// CHECK-NEXT: Name: .symtab -// CHECK-NEXT: Type: SHT_SYMTAB // CHECK: Relocations [ // CHECK-NEXT: Section ({{.*}}) .rela.plt { // CHECK-NEXT: 0x202000 R_X86_64_IRELATIVE