From c135a68d426fd69d26454658bfa62102993f12a7 Mon Sep 17 00:00:00 2001 From: Georgii Rymar Date: Mon, 10 Aug 2020 17:00:53 +0300 Subject: [PATCH] [LLD][ELF] - Do not produce an invalid dynamic relocation order with --shuffle-sections. Normally (when not on android with android relocation packing enabled), we put IRelative relocations to ".rel[a].dyn", after other relocations, to ensure that IRelatives are processed last by the dynamic loader. To achieve that we add the `in.relaIplt` after the `part.relaDyn`: https://github.com/llvm/llvm-project/blob/master/lld/ELF/Writer.cpp#L540 The problem is that `--shuffle-sections` might break the sections order. This patch fixes it. Fixes https://bugs.llvm.org/show_bug.cgi?id=47056. Differential revision: https://reviews.llvm.org/D85651 --- lld/ELF/Writer.cpp | 8 ++++++++ lld/test/ELF/gnu-ifunc-plt.s | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 1bd6fb6..2cb508c 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1437,6 +1437,14 @@ static void sortSection(OutputSection *sec, if (name == ".init" || name == ".fini") return; + // IRelative relocations that usually live in the .rel[a].dyn section should + // be proccessed last by the dynamic loader. To achieve that we add synthetic + // sections in the required order from the begining so that the in.relaIplt + // section is placed last in an output section. Here we just do not apply + // sorting for an output section which holds the in.relaIplt section. + if (in.relaIplt->getParent() == sec) + return; + // Sort input sections by priority using the list provided by // --symbol-ordering-file or --shuffle-sections=. This is a least significant // digit radix sort. The sections may be sorted stably again by a more diff --git a/lld/test/ELF/gnu-ifunc-plt.s b/lld/test/ELF/gnu-ifunc-plt.s index 1ac31b8..540bfbc 100644 --- a/lld/test/ELF/gnu-ifunc-plt.s +++ b/lld/test/ELF/gnu-ifunc-plt.s @@ -77,6 +77,20 @@ // DISASM-NEXT: 201386: pushq $0x1 // DISASM-NEXT: 20138b: jmp 0x201340 <.plt> +// Test that --shuffle-sections does not affect the order of relocations and that +// we still place IRELATIVE relocations last. Check both random seed (0) and an +// arbitrary seed that was known to break the order of relocations previously (3). +// RUN: ld.lld --shuffle-sections=3 %t.so %t.o -o %tout2 +// RUN: llvm-readobj --relocations %tout2 | FileCheck %s --check-prefix=SHUFFLE +// RUN: ld.lld --shuffle-sections=0 %t.so %t.o -o %tout3 +// RUN: llvm-readobj --relocations %tout3 | FileCheck %s --check-prefix=SHUFFLE + +// SHUFFLE: Section {{.*}} .rela.dyn { +// SHUFFLE-NEXT: R_X86_64_GLOB_DAT +// SHUFFLE-NEXT: R_X86_64_IRELATIVE +// SHUFFLE-NEXT: R_X86_64_IRELATIVE +// SHUFFLE-NEXT: } + .text .type foo STT_GNU_IFUNC .globl foo -- 2.7.4