In lld, SECTIONS { /DISCARD/ : { *(.symtab) *(.strtab) } } can discard the synthesized .symtab and .strtab (probably since https://reviews.llvm.org/D27040 ). Discarding .shstrtab is not allowed: % ld.lld -T =(printf 'SECTIONS { /DISCARD/ : { *(.shstrtab) }}') a.o -o a ld.lld: error: discarding .shstrtab section is not allowed Discarding *(*) triggers a similar error: % ld.lld -T =(printf 'SECTIONS { /DISCARD/ : { *(*) }}') a.o -o a ld.lld: error: discarding .shstrtab section is not allowed GNU ld keeps .symtab, .strtab and .shstrtab
ld.lld giving errors on "/DISCARD/ : { *(*) }" is just a lld bug. There is no way we will want to copy the lld behaviour of allowing a discard of .symtab and/or .strtab either. What exactly does *(.symtab) mean anyway? It ought to mean discard all input .symtab sections, which doesn't make any sort of sense.
SECTIONS { /DISCARD/ : { *(.symtab) } } deletes .symtab SECTIONS { /DISCARD/ : { *(.strtab) } } deletes .strtab When combined, it is like --strip-all (normally there is no need for .symtab_shndx) /DISCARD/ : { *(.shstrtab) } is not allowed by lld. /DISCARD/ : { *(*) } matches .shstrtab, and thus is not allowed by lld. *(*) is likely a user error. /DISCARD/ : { INPUT_SECTION_FLAGS(SHF_ALLOC) *(*) }
SECTIONS { .pltfoo : { a.o(.plt) }} can rename the synthetic section .plt, so I don't see a problem allowing an input section description to match a synthetic section.