From patchwork Thu Mar 22 14:38:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Christophe Lyon X-Patchwork-Id: 132298 Delivered-To: patch@linaro.org Received: by 10.46.84.29 with SMTP id i29csp931617ljb; Thu, 22 Mar 2018 07:41:09 -0700 (PDT) X-Google-Smtp-Source: AG47ELvCdTCmmsAGf0eYTmyPrukmS9KJ1s706xZW06xWYvU0hUVu3QfuZvIlbPopgYI4yuu6VcN+ X-Received: by 10.99.96.130 with SMTP id u124mr18323827pgb.252.1521729669050; Thu, 22 Mar 2018 07:41:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521729669; cv=none; d=google.com; s=arc-20160816; b=hChwB1dLHcVobiWy5qhBzGA2m5MOwYKUlNMsvjunRSAUMNvmVKgJDRaDVEewOmDqgI r9fx5OxYWoq/UMwdTNVS0QDk9lZsmVjRBgey62gemXsB3FYrVxkrLQ/lyahg2WPiSFxK b0iu/DFqCkEMPrCHObcEPd6w8w7MUmA63SitlFX3G8C4vf+bOCRi1DFiH5qmP8KNagKx FNqtONxgAytChgAadtdawkC0N0hLQ7VfjKtC/3TJ2OgL20T+b7O+r3K+Us/wg7JBCvYl K87qYYBh5CXih5TuSdg/hmMx/6/jvAwqGtwOqsoXcWV7FCRUkQVWTXA0IW8zniRoQYha n0OA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:delivered-to:sender:list-help :list-post:list-archive:list-subscribe:list-unsubscribe:list-id :precedence:mailing-list:dkim-signature:domainkey-signature :arc-authentication-results; bh=ac3XfSeXKlgH/X5Dc7pJdc2TInh2uwru/P8LOM6W4uQ=; b=sK6pWU5FLNBUTanVK8jnigyOlkankXlOtA5R+FrMaGOYurCpqAOa+3Ji+1qfs3M30l ZaeScOqkozosBc1cYXiUUT1jM3/UC8YUSz7fo2ZtUnAxdXiz1teqsdU1zzwYqIf9RS0S 1FRHeu3iKTuhW68Q39LpQd0OWNvLHLAiyt+JfsGmiquaVa/4OoOCQ0J3I14o9nTbSg7T CqlSBVEZwdIhH+LAFDKU8X8igzpkh2xHe6ZjEImteR1iWcR49IZX5CKOX6DXC1l5kqXw XkhTuffWnvukFXwooqIffF+/RDJexlCwnkw2T6vqSr4i4eBJuF8FdTRsXuyFXeyZV0Xl B1jw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=cJ+bT+rl; spf=pass (google.com: domain of binutils-return-101084-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=binutils-return-101084-patch=linaro.org@sourceware.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id 204si4438744pgf.771.2018.03.22.07.41.08 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 22 Mar 2018 07:41:09 -0700 (PDT) Received-SPF: pass (google.com: domain of binutils-return-101084-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=cJ+bT+rl; spf=pass (google.com: domain of binutils-return-101084-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=binutils-return-101084-patch=linaro.org@sourceware.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; q=dns; s=default; b=sAJkW2ZLOWeIrSJT9788Qrofq0KXW8iJfb57+GwSv3R 0GY8vGNnon+6UZjcDLa9n8IWIZQiT6685gMGm3gP9wJ0QyQ5aOJ8QOmY0CjDRuXu XrpEVGav3VlDMxXNawAiApa5JBcN8VRXuACPZqYiuf8PoO6TZNZe+3R2FhgW9WFg = DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; s=default; bh=/hx2rUKeNvubSUuvLvDCs+Z3u8w=; b=cJ+bT+rlirG+naO7g usj8GL3rPn6c6Gaf1rmoVJ4T+OtdudK7VQ4wIlhvnLrkoHa7U29htVSZDqzwqcc0 +c3YhZmvcE/6/nzRwOQbWF6hA8rPfAuP/CJ0P5bF4yI7b+DOBaWN4pp8eQiVo0Tc /UOfLVuDhtKnVxE0wjFM+qfcrE= Received: (qmail 76254 invoked by alias); 22 Mar 2018 14:40:43 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Delivered-To: mailing list binutils@sourceware.org Received: (qmail 76191 invoked by uid 89); 22 Mar 2018 14:40:42 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-27.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mx07-00178001.pphosted.com Received: from mx07-00178001.pphosted.com (HELO mx07-00178001.pphosted.com) (62.209.51.94) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 22 Mar 2018 14:40:39 +0000 Received: from pps.filterd (m0046668.ppops.net [127.0.0.1]) by mx07-.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id w2MEcfnu001270 for ; Thu, 22 Mar 2018 15:40:37 +0100 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 2gv9sx1fh8-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT) for ; Thu, 22 Mar 2018 15:40:37 +0100 Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 5B7C241 for ; Thu, 22 Mar 2018 14:40:36 +0000 (GMT) Received: from Webmail-eu.st.com (sfhdag5node1.st.com [10.75.127.13]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 29FE72B0F for ; Thu, 22 Mar 2018 14:40:36 +0000 (GMT) Received: from gnx2104.gnb.st.com (10.75.127.51) by SFHDAG5NODE1.st.com (10.75.127.13) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Thu, 22 Mar 2018 15:40:35 +0100 From: Christophe Lyon To: Subject: [ARM-FDPIC 05/12] [ARM] Implement PLT for FDPIC. Date: Thu, 22 Mar 2018 15:38:23 +0100 Message-ID: <20180322143850.1766-6-christophe.lyon@st.com> In-Reply-To: <20180322143850.1766-1-christophe.lyon@st.com> References: <20180322143850.1766-1-christophe.lyon@st.com> MIME-Version: 1.0 X-ClientProxiedBy: SFHDAG4NODE1.st.com (10.75.127.10) To SFHDAG5NODE1.st.com (10.75.127.13) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-03-22_07:, , signatures=0 X-IsSubscribed: yes FDPIC requires special PLT entries, defined in this patch. Note that lazy binding is not supported because of a race condition for lack of an atomic 64-bits load instruction. 2018-XX-XX Christophe Lyon Mickaël Guêné * elf32-arm.c (elf32_arm_fdpic_plt_entry): New. (elf32_arm_create_dynamic_sections): Handle FDPIC. (elf32_arm_allocate_plt_entry): Likewise. (elf32_arm_populate_plt_entry): Likewise. (elf32_arm_output_plt_map_1): Likewise. --- bfd/elf32-arm.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 143 insertions(+), 9 deletions(-) -- 2.6.3 diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 5892255..d84edb1 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -2229,6 +2229,22 @@ static const unsigned long dl_tlsdesc_lazy_trampoline [] = 0x00000018, /* 4: .word _GLOBAL_OFFSET_TABLE_ - 2b - 8 */ }; +/* ARM FDPIC PLT entry. */ +/* The last 5 words contain PLT lazy fragment code and data. */ +static const bfd_vma elf32_arm_fdpic_plt_entry [] = + { + 0xe59fc008, /* ldr r12, .L1 */ + 0xe08cc009, /* add r12, r12, r9 */ + 0xe59c9004, /* ldr r9, [r12, #4] */ + 0xe59cf000, /* ldr pc, [r12] */ + 0x00000000, /* L1. .word foo(GOTOFFFUNCDESC) */ + 0x00000000, /* L1. .word foo(funcdesc_value_reloc_offset) */ + 0xe51fc00c, /* ldr r12, [pc, #-12] */ + 0xe92d1000, /* push {r12} */ + 0xe599c004, /* ldr r12, [r9, #4] */ + 0xe599f000, /* ldr pc, [r9] */ + }; + #ifdef FOUR_WORD_PLT /* The first entry in a procedure linkage table looks like @@ -3856,6 +3872,14 @@ elf32_arm_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info) htab->obfd = saved_obfd; } + if (htab->fdpic_p) { + htab->plt_header_size = 0; + if (info->flags & DF_BIND_NOW) + htab->plt_entry_size = 4 * (ARRAY_SIZE(elf32_arm_fdpic_plt_entry) - 5); + else + htab->plt_entry_size = 4 * ARRAY_SIZE(elf32_arm_fdpic_plt_entry); + } + if (!htab->root.splt || !htab->root.srelplt || !htab->root.sdynbss @@ -9392,8 +9416,22 @@ elf32_arm_allocate_plt_entry (struct bfd_link_info *info, splt = htab->root.splt; sgotplt = htab->root.sgotplt; - /* Allocate room for an R_JUMP_SLOT relocation in .rel.plt. */ - elf32_arm_allocate_dynrelocs (info, htab->root.srelplt, 1); + if (htab->fdpic_p) + { + /* Allocate room for R_ARM_FUNCDESC_VALUE. */ + /* For lazy binding, relocations will be put into .rel.plt, in + .rel.got otherwise. */ + /* FIXME: today we don't support lazy binding so put it in .rel.got */ + if (info->flags & DF_BIND_NOW) + elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1); + else + elf32_arm_allocate_dynrelocs (info, htab->root.srelplt, 1); + } + else + { + /* Allocate room for an R_JUMP_SLOT relocation in .rel.plt. */ + elf32_arm_allocate_dynrelocs (info, htab->root.srelplt, 1); + } /* If this is the first .plt entry, make room for the special first entry. */ @@ -9417,7 +9455,11 @@ elf32_arm_allocate_plt_entry (struct bfd_link_info *info, arm_plt->got_offset = sgotplt->size; else arm_plt->got_offset = sgotplt->size - 8 * htab->num_tls_desc; - sgotplt->size += 4; + if (htab->fdpic_p) + /* Function descriptor takes 64 bits in GOT. */ + sgotplt->size += 8; + else + sgotplt->size += 4; } } @@ -9526,7 +9568,11 @@ elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info, in all the symbols for which we are making plt entries. After the reserved .got.plt entries, all symbols appear in the same order as in .plt. */ - plt_index = (got_offset - got_header_size) / 4; + if (htab->fdpic_p) + /* Function descriptor takes 8 bytes. */ + plt_index = (got_offset - got_header_size) / 8; + else + plt_index = (got_offset - got_header_size) / 4; /* Calculate the address of the GOT entry. */ got_address = (sgot->output_section->vma @@ -9634,6 +9680,42 @@ elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info, | (tail_displacement & 0x00ffffff), ptr + 12); } + else if (htab->fdpic_p) + { + /* Fill-up Thumb stub if needed. */ + if (elf32_arm_plt_needs_thumb_stub_p (info, arm_plt)) + { + put_thumb_insn (htab, output_bfd, + elf32_arm_plt_thumb_stub[0], ptr - 4); + put_thumb_insn (htab, output_bfd, + elf32_arm_plt_thumb_stub[1], ptr - 2); + } + put_arm_insn(htab, output_bfd, + elf32_arm_fdpic_plt_entry[0], ptr + 0); + put_arm_insn(htab, output_bfd, + elf32_arm_fdpic_plt_entry[1], ptr + 4); + put_arm_insn(htab, output_bfd, + elf32_arm_fdpic_plt_entry[2], ptr + 8); + put_arm_insn(htab, output_bfd, + elf32_arm_fdpic_plt_entry[3], ptr + 12); + bfd_put_32 (output_bfd, got_offset, ptr + 16); + + if (!(info->flags & DF_BIND_NOW)) + { + /* funcdesc_value_reloc_offset. */ + bfd_put_32 (output_bfd, + htab->root.srelplt->reloc_count * RELOC_SIZE (htab), + ptr + 20); + put_arm_insn(htab, output_bfd, + elf32_arm_fdpic_plt_entry[6], ptr + 24); + put_arm_insn(htab, output_bfd, + elf32_arm_fdpic_plt_entry[7], ptr + 28); + put_arm_insn(htab, output_bfd, + elf32_arm_fdpic_plt_entry[8], ptr + 32); + put_arm_insn(htab, output_bfd, + elf32_arm_fdpic_plt_entry[9], ptr + 36); + } + } else if (using_thumb_only (htab)) { /* PR ld/16017: Generate thumb only PLT entries. */ @@ -9744,22 +9826,61 @@ elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info, } else { - rel.r_info = ELF32_R_INFO (dynindx, R_ARM_JUMP_SLOT); - initial_got_entry = (splt->output_section->vma - + splt->output_offset); + /* For FDPIC we will have to resolve a R_ARM_FUNCDESC_VALUE + used by PLT entry. */ + if (htab->fdpic_p) + { + rel.r_info = ELF32_R_INFO (dynindx, R_ARM_FUNCDESC_VALUE); + initial_got_entry = 0; + } + else + { + rel.r_info = ELF32_R_INFO (dynindx, R_ARM_JUMP_SLOT); + initial_got_entry = (splt->output_section->vma + + splt->output_offset); + } } /* Fill in the entry in the global offset table. */ bfd_put_32 (output_bfd, initial_got_entry, sgot->contents + got_offset); + + if (htab->fdpic_p && !(info->flags & DF_BIND_NOW)) + { + /* Setup initial funcdesc value. */ + /* FIXME: we don't support lazy binding because there is a + race condition between both words getting written and + some other thread attempting to read them. The ARM + architecture does not have an atomic 64 bit load/store + instruction that could be used to prevent it; it is + recommended that threaded FDPIC applications run with the + LD_BIND_NOW environment variable set. */ + bfd_put_32(output_bfd, plt_address + 0x18, + sgot->contents + got_offset); + bfd_put_32(output_bfd, -1 /*TODO*/, + sgot->contents + got_offset + 4); + } } if (dynindx == -1) elf32_arm_add_dynreloc (output_bfd, info, srel, &rel); else { - loc = srel->contents + plt_index * RELOC_SIZE (htab); - SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc); + if (htab->fdpic_p) + { + /* For FDPIC we put PLT relocationss into .rel.got when not + lazy binding otherwise we put them in .rel.plt. For now, + we don't support lazy binding so put it in .rel.got. */ + if (info->flags & DF_BIND_NOW) + elf32_arm_add_dynreloc(output_bfd, info, htab->root.srelgot, &rel); + else + elf32_arm_add_dynreloc(output_bfd, info, htab->root.srelplt, &rel); + } + else + { + loc = srel->contents + plt_index * RELOC_SIZE (htab); + SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc); + } } return TRUE; @@ -17577,6 +17698,19 @@ elf32_arm_output_plt_map_1 (output_arch_syminfo *osi, if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr)) return FALSE; } + else if (htab->fdpic_p) + { + if (elf32_arm_plt_needs_thumb_stub_p (osi->info, arm_plt)) + if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr - 4)) + return FALSE; + if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr)) + return FALSE; + if (!elf32_arm_output_map_sym (osi, ARM_MAP_DATA, addr + 16)) + return FALSE; + if (htab->plt_entry_size == 4 * ARRAY_SIZE(elf32_arm_fdpic_plt_entry)) + if (!elf32_arm_output_map_sym (osi, ARM_MAP_ARM, addr + 24)) + return FALSE; + } else if (using_thumb_only (htab)) { if (!elf32_arm_output_map_sym (osi, ARM_MAP_THUMB, addr))