From dcba4828a9ead5f5b1fa27f0853823618075d0e0 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 4 Jun 2019 13:41:29 +0000 Subject: [PATCH] [ELF] Suppress "STT_SECTION symbol should be defined" on .eh_frame, .debug*, .zdebug* and .gcc_except_table Summary: With -r or --emit-relocs, we warn `STT_SECTION symbol should be defined` on relocations to discarded section symbol. This was added as an error in rLLD319404, but was not so effective before D61583 (it turned the error to a warning). Relocations from .eh_frame .debug* .zdebug* .gcc_except_table to discarded .text are very common and somewhat expected. Don't warn/error on them. As a reference, ld.bfd has a similar logic in _bfd_elf_default_action_discarded() to allow these cases. Delete invalid-undef-section-symbol.test because what it intended to check is now covered by the updated comdat-discarded-reloc.s Delete relocatable-eh-frame.s because we allow relocations from .eh_frame as a special case now. Reviewers: grimar, phosek, ruiu, espindola Reviewed By: ruiu Subscribers: emaste, arichardson, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D62840 llvm-svn: 362497 --- lld/ELF/InputSection.cpp | 17 ++++++-- lld/test/ELF/Inputs/comdat-discarded-reloc.s | 12 +++--- lld/test/ELF/comdat-discarded-reloc.s | 39 +++++++++++++++---- .../ELF/invalid-undef-section-symbol.test | 26 ------------- lld/test/ELF/relocatable-eh-frame.s | 21 ---------- 5 files changed, 53 insertions(+), 62 deletions(-) delete mode 100644 lld/test/ELF/invalid-undef-section-symbol.test delete mode 100644 lld/test/ELF/relocatable-eh-frame.s diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 74a8028e229b..cb1072505638 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -412,7 +412,8 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef Rels) { for (const RelTy &Rel : Rels) { RelType Type = Rel.getType(Config->IsMips64EL); - Symbol &Sym = getFile()->getRelocTargetSym(Rel); + const ObjFile *File = getFile(); + Symbol &Sym = File->getRelocTargetSym(Rel); auto *P = reinterpret_cast(Buf); Buf += sizeof(RelTy); @@ -435,10 +436,20 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef Rels) { // .eh_frame is horribly special and can reference discarded sections. To // avoid having to parse and recreate .eh_frame, we just replace any // relocation in it pointing to discarded sections with R_*_NONE, which - // hopefully creates a frame that is ignored at runtime. + // hopefully creates a frame that is ignored at runtime. Also, don't warn + // on .gcc_except_table and debug sections. auto *D = dyn_cast(&Sym); if (!D) { - warn("STT_SECTION symbol should be defined"); + if (!Sec->Name.startswith(".debug") && + !Sec->Name.startswith(".zdebug") && Sec->Name != ".eh_frame" && + Sec->Name != ".gcc_except_table") { + uint32_t SecIdx = cast(Sym).DiscardedSecIdx; + Elf_Shdr_Impl Sec = + CHECK(File->getObj().sections(), File)[SecIdx]; + warn("relocation refers to a discarded section: " + + CHECK(File->getObj().getSectionName(&Sec), File) + + "\n>>> referenced by " + getObjMsg(P->r_offset)); + } P->setSymbolAndType(0, 0, false); continue; } diff --git a/lld/test/ELF/Inputs/comdat-discarded-reloc.s b/lld/test/ELF/Inputs/comdat-discarded-reloc.s index 9526f5ac95c0..d89575f27e94 100644 --- a/lld/test/ELF/Inputs/comdat-discarded-reloc.s +++ b/lld/test/ELF/Inputs/comdat-discarded-reloc.s @@ -1,6 +1,8 @@ -.section .text.bar1,"aG",@progbits,group,comdat +.global bar, _start -.section .text.bar2 -.global bar -bar: - .quad .text.bar1 +.section .text.foo,"aG",@progbits,group,comdat + +.section .text +_start: + .quad .text.foo + .quad bar diff --git a/lld/test/ELF/comdat-discarded-reloc.s b/lld/test/ELF/comdat-discarded-reloc.s index d12732cd3569..4d50ab10e512 100644 --- a/lld/test/ELF/comdat-discarded-reloc.s +++ b/lld/test/ELF/comdat-discarded-reloc.s @@ -1,17 +1,42 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/comdat-discarded-reloc.s -o %t2.o -# RUN: ld.lld -gc-sections --noinhibit-exec %t.o %t2.o -o /dev/null +# RUN: ld.lld -gc-sections --noinhibit-exec %t2.o %t.o -o /dev/null +# RUN: ld.lld -r %t2.o %t.o -o %t 2>&1 | FileCheck --check-prefix=WARN %s +# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s ## ELF spec doesn't allow a relocation to point to a deduplicated ## COMDAT section. Unfortunately this happens in practice (e.g. .eh_frame) ## Test case checks we do not crash. -.global bar, _start +# WARN: warning: relocation refers to a discarded section: .text.bar1 +# WARN-NEXT: >>> referenced by {{.*}}.o:(.rela.text.bar2+0x0) +# WARN-NOT: warning -.section .text.foo,"aG",@progbits,group,comdat +# RELOC: .rela.eh_frame { +# RELOC-NEXT: R_X86_64_NONE +# RELOC-NEXT: } +# RELOC-NEXT: .rela.debug_foo { +# RELOC-NEXT: R_X86_64_NONE +# RELOC-NEXT: } +# RELOC-NEXT: .rela.gcc_except_table { +# RELOC-NEXT: R_X86_64_NONE +# RELOC-NEXT: } -.section .text -_start: - .quad .text.foo - .quad bar +.section .text.bar1,"aG",@progbits,group,comdat + +## .text.bar1 in this file is discarded. Warn on the relocation. +.section .text.bar2,"ax" +.globl bar +bar: + .quad .text.bar1 + +## Don't warn on .eh_frame, .debug*, .zdebug*, or .gcc_except_table +.section .eh_frame,"a" + .quad .text.bar1 + +.section .debug_foo + .quad .text.bar1 + +.section .gcc_except_table,"a" + .quad .text.bar1 diff --git a/lld/test/ELF/invalid-undef-section-symbol.test b/lld/test/ELF/invalid-undef-section-symbol.test deleted file mode 100644 index 80e5a1464d74..000000000000 --- a/lld/test/ELF/invalid-undef-section-symbol.test +++ /dev/null @@ -1,26 +0,0 @@ -# RUN: yaml2obj %s -o %t.o -# RUN: not ld.lld -r --fatal-warnings %t.o -o /dev/null 2>&1 | FileCheck %s - -# We used to crash at this. -# CHECK: STT_SECTION symbol should be defined - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 -Sections: - - Name: .text - Type: SHT_PROGBITS - - Name: .rela.text - Type: SHT_RELA - AddressAlign: 0x0000000000000008 - Info: .text - Relocations: - - Offset: 0x0000000000000000 - Symbol: .text - Type: R_X86_64_NONE -Symbols: - - Name: .text - Type: STT_SECTION diff --git a/lld/test/ELF/relocatable-eh-frame.s b/lld/test/ELF/relocatable-eh-frame.s deleted file mode 100644 index 6172dd355db4..000000000000 --- a/lld/test/ELF/relocatable-eh-frame.s +++ /dev/null @@ -1,21 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: ld.lld -r %t.o %t.o -o %t 2>&1 | FileCheck --check-prefix=WARN %s -# RUN: llvm-readobj -r %t | FileCheck %s -# RUN: ld.lld %t -o %t.so -shared -# RUN: llvm-objdump -h %t.so | FileCheck --check-prefix=DSO %s - -# WARN: STT_SECTION symbol should be defined - -# DSO: .eh_frame 00000034 - -# CHECK: Relocations [ -# CHECK-NEXT: Section ({{.*}}) .rela.eh_frame { -# CHECK-NEXT: 0x20 R_X86_64_PC32 .foo 0x0 -# CHECK-NEXT: 0x50 R_X86_64_NONE - 0x0 -# CHECK-NEXT: } -# CHECK-NEXT: ] - -.section .foo,"aG",@progbits,bar,comdat -.cfi_startproc -.cfi_endproc