llvm-project/lld/test/ELF/linkerscript/discard-group.s

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

34 lines
1.1 KiB
ArmAsm
Raw Normal View History

[ELF] Improve --gc-sections compatibility with GNU ld regarding section groups Based on D70020 by serge-sans-paille. The ELF spec says: > Furthermore, there may be internal references among these sections that would not make sense if one of the sections were removed or replaced by a duplicate from another object. Therefore, such groups must be included or omitted from the linked object as a unit. A section cannot be a member of more than one group. GNU ld has 2 behaviors that we don't have: - Group members (nextInSectionGroup != nullptr) are subject to garbage collection. This includes non-SHF_ALLOC SHT_NOTE sections. In particular, discarding non-SHF_ALLOC SHT_NOTE sections is an expected behavior by the Annobin project. See https://developers.redhat.com/blog/2018/02/20/annobin-storing-information-binaries/ for more information. - Groups members are retained or discarded as a unit. Members may have internal references that are not expressed as SHF_LINK_ORDER, relocations, etc. It seems that we should be more conservative here: if a section is marked live, mark all the other member within the group. Both behaviors are reasonable. This patch implements them. A new field InputSectionBase::nextInSectionGroup tracks the next member within a group. on ELF64, this increases sizeof(InputSectionBase) froms 144 to 152. InputSectionBase::dependentSections tracks section dependencies, which is used by both --gc-sections and /DISCARD/. We can't overload it for the "next member" semantic, because we should allow /DISCARD/ to discard sections independent of --gc-sections (GNU ld behavior). This behavior may be reasonably used by `/DISCARD/ : { *(.ARM.exidx*) }` or `/DISCARD/ : { *(.note*) }` (new test `linkerscript/discard-group.s`). Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D70146
2019-11-19 13:56:58 +08:00
# REQUIRES: arm
## For --gc-sections, group members are retained or discarded as a unit.
## However, discarding a section via /DISCARD/ should not discard other members
## within the group. This is compatible with GNU ld.
# RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
## We can discard .ARM.exidx* in a group.
# RUN: echo 'SECTIONS { /DISCARD/ : { *(.ARM.exidx*) }}' > %t.noarm.script
# RUN: ld.lld %t.o --gc-sections -T %t.noarm.script -o %t.noarm
# RUN: llvm-readobj -S %t.noarm | FileCheck %s --check-prefix=NOARM --implicit-check-not='Name: .ARM.exidx'
# NOARM: Name: .text
# NOARM: Name: .note._start
## Another example, we can discard SHT_NOTE in a group.
# RUN: echo 'SECTIONS { /DISCARD/ : { *(.note*) }}' > %t.nonote.script
# RUN: ld.lld %t.o --gc-sections -T %t.nonote.script -o %t.nonote
# RUN: llvm-readobj -S %t.nonote | FileCheck %s --check-prefix=NONOTE --implicit-check-not='Name: .note'
# NONOTE: Name: .ARM.exidx
# NONOTE: Name: .text
.section .text._start,"axG",%progbits,_start,comdat
.globl _start
_start:
.fnstart
.cantunwind
bx lr
.fnend
.section .note._start,"G",%note,_start,comdat
.byte 0