Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -380,6 +380,14 @@ S == InX::DynStrTab) error("discarding " + S->Name + " section is not allowed"); + // You can discard .hash and .gnu.hash sections by linker scripts. Since + // they are synthesized sections, we need to handle them differently than + // other regular sections. + if (S == InX::GnuHashTab) + InX::GnuHashTab = nullptr; + if (S == InX::HashTab) + InX::HashTab = nullptr; + S->Assigned = false; S->Live = false; discard(S->DependentSections); Index: lld/trunk/test/ELF/linkerscript/discard-gnu-hash.s =================================================================== --- lld/trunk/test/ELF/linkerscript/discard-gnu-hash.s +++ lld/trunk/test/ELF/linkerscript/discard-gnu-hash.s @@ -0,0 +1,23 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: ld.lld --hash-style both -shared -o %t1 %t +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s +# CHECK: .gnu.hash +# CHECK: .hash + +# RUN: echo "SECTIONS { /DISCARD/ : { *(.hash) } }" > %t.script +# RUN: ld.lld --hash-style both -shared -o %t1 --script %t.script %t +# RUN: llvm-objdump -section-headers %t1 \ +# RUN: | FileCheck %s --check-prefix=HASH +# HASH-NOT: .hash +# HASH: .gnu.hash +# HASH-NOT: .hash + +# RUN: echo "SECTIONS { /DISCARD/ : { *(.gnu.hash) } }" > %t.script +# RUN: ld.lld --hash-style both -shared -o %t1 --script %t.script %t +# RUN: llvm-objdump -section-headers %t1 \ +# RUN: | FileCheck %s --check-prefix=GNUHASH +# GNUHASH-NOT: .gnu.hash +# GNUHASH: .hash +# GNUHASH-NOT: .gnu.hash