From 54634f19907efa692681e80f3b134808c10b2e35 Mon Sep 17 00:00:00 2001 From: George Rimar Date: Fri, 23 Mar 2018 09:18:31 +0000 Subject: [PATCH] [ELF] - Another fix for "LLD crashes with --emit-relocs when trying to proccess .eh_frame" This fixes PR36367 which is about segfault when --emit-relocs is used together with .eh_frame sections which happens because of reordering of regular and .rel[a] sections. Path changes loop that iterates over input sections to create relocation target sections first. Differential revision: https://reviews.llvm.org/D44679 llvm-svn: 328299 --- lld/ELF/LinkerScript.cpp | 21 +++++++++++++++++---- lld/test/ELF/emit-relocs-eh-frame.s | 16 ++++++++++++++++ lld/test/ELF/emit-relocs-shared.s | 4 ++-- lld/test/ELF/emit-relocs.s | 2 +- lld/test/ELF/linkerscript/eh-frame-emit-relocs.s | 13 +++++++++++++ 5 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 lld/test/ELF/emit-relocs-eh-frame.s create mode 100644 lld/test/ELF/linkerscript/eh-frame-emit-relocs.s diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 133f3e8..e16b49e 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -629,11 +629,11 @@ static OutputSection *addInputSec(StringMap &Map, void LinkerScript::addOrphanSections() { unsigned End = SectionCommands.size(); StringMap Map; - std::vector V; - for (InputSectionBase *S : InputSections) { + + auto Add = [&](InputSectionBase *S) { if (!S->Live || S->Parent) - continue; + return; StringRef Name = getOutputSectionName(S); @@ -645,12 +645,25 @@ void LinkerScript::addOrphanSections() { if (OutputSection *Sec = findByName(makeArrayRef(SectionCommands).slice(0, End), Name)) { Sec->addSection(cast(S)); - continue; + return; } if (OutputSection *OS = addInputSec(Map, S, Name)) V.push_back(OS); assert(S->getOutputSection()->SectionIndex == UINT32_MAX); + }; + + // For futher --emit-reloc handling code we need target output section + // to be created before we create relocation output section, so we want + // to create target sections first. We do not want priority handling + // for synthetic sections because them are special. + for (InputSectionBase *IS : InputSections) { + if ((IS->Type == SHT_REL || IS->Type == SHT_RELA) && + !isa(IS)) + if (auto *Rel = cast(IS)->getRelocatedSection()) + if (auto *RelIS = dyn_cast_or_null(Rel->Parent)) + Add(RelIS); + Add(IS); } // If no SECTIONS command was given, we should insert sections commands diff --git a/lld/test/ELF/emit-relocs-eh-frame.s b/lld/test/ELF/emit-relocs-eh-frame.s new file mode 100644 index 0000000..4df8858 --- /dev/null +++ b/lld/test/ELF/emit-relocs-eh-frame.s @@ -0,0 +1,16 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o +# RUN: ld.lld --emit-relocs %t1.o -o %t +# RUN: llvm-readobj -r %t | FileCheck %s + +# CHECK: Relocations [ +# CHECK-NEXT: Section {{.*}} .rela.eh_frame { +# CHECK-NEXT: 0x{{.*}} R_X86_64_PC32 .text 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] + +.text +.globl foo +foo: + .cfi_startproc + .cfi_endproc diff --git a/lld/test/ELF/emit-relocs-shared.s b/lld/test/ELF/emit-relocs-shared.s index 65a12c1..cb87d9f 100644 --- a/lld/test/ELF/emit-relocs-shared.s +++ b/lld/test/ELF/emit-relocs-shared.s @@ -7,10 +7,10 @@ .quad foo # CHECK: Relocations [ -# CHECK-NEXT: Section (4) .rela.dyn { +# CHECK-NEXT: Section {{.*}} .rela.dyn { # CHECK-NEXT: 0x1000 R_X86_64_64 foo 0x0 # CHECK-NEXT: } -# CHECK-NEXT: Section (8) .rela.data { +# CHECK-NEXT: Section {{.*}} .rela.data { # CHECK-NEXT: 0x1000 R_X86_64_64 foo 0x0 # CHECK-NEXT: } # CHECK-NEXT: ] diff --git a/lld/test/ELF/emit-relocs.s b/lld/test/ELF/emit-relocs.s index 95e70d8..b91bb9a 100644 --- a/lld/test/ELF/emit-relocs.s +++ b/lld/test/ELF/emit-relocs.s @@ -13,7 +13,7 @@ # CHECK: Section { # CHECK: Index: 2 -# CHECK-NEXT: Name: .rela.text +# CHECK: Name: .rela.text # CHECK-NEXT: Type: SHT_RELA # CHECK-NEXT: Flags [ # CHECK-NEXT: SHF_INFO_LINK diff --git a/lld/test/ELF/linkerscript/eh-frame-emit-relocs.s b/lld/test/ELF/linkerscript/eh-frame-emit-relocs.s new file mode 100644 index 0000000..d951cbc --- /dev/null +++ b/lld/test/ELF/linkerscript/eh-frame-emit-relocs.s @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: echo "SECTIONS { .foo : { *(.eh_frame) } }" > %t.script +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld --emit-relocs %t.o -T %t.script -o %t +# RUN: llvm-objdump -section-headers %t | FileCheck %s + +# CHECK-NOT: eh_frame +# CHECK: .rela.foo +# CHECK-NOT: eh_frame + +.text + .cfi_startproc + .cfi_endproc -- 2.7.4