From patchwork Fri Sep 5 18:40:23 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Metcalf X-Patchwork-Id: 386499 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 9D3FF1400F0 for ; Sat, 6 Sep 2014 04:55:02 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:from:date:subject:to; q=dns; s= default; b=tCYd3Y8R/mKXxz+m3KtYmm867dB8qJA6g+SjGDiH3U+mJVlxLfJII 2RdOoqAiKqgrxmCNlbR97K1PxCLo38zmG3B5ua4IR9NuG03k6Awi2mmd3sDYxILf fgJyoQOgm4+uYcL31mN2R0w6SSgqSssK/odg40li6lFZbcCCHQLaQI= 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:message-id:from:date:subject:to; s=default; bh=W00/hcBAlZFerG4MWD2M6UtExw4=; b=fa3otI9xEXwLTeJBMyQLwp43aMca 4bfyqQyhkQgW+mUznAdOa98W8VvVQ17kNuknWPaArar9VdeazBd9N29+Y34d1snr J/H5oNiv4r5wUq63iUPxI9U+T0o/nsoAQfV5E6/Y368VTFuwHoXgMXoa+nb37LWP qSmsFmyLJlrjAJ4= Received: (qmail 5963 invoked by alias); 5 Sep 2014 18:54:48 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 5929 invoked by uid 89); 5 Sep 2014 18:54:46 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.1 required=5.0 tests=AWL, BAYES_00, NO_DNS_FOR_FROM, RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: gx-1.internal.tilera.com Message-Id: <201409051854.s85IsfM0024659@gx-1.internal.tilera.com> From: Chris Metcalf Date: Fri, 5 Sep 2014 14:40:23 -0400 Subject: [PATCH] tile: Fix up corner cases with signed relocations To: libc-alpha@sourceware.org Some types of relocations technically need to be signed rather than unsigned: in particular ones that are used with moveli or movei, or for jump and branch. This is almost never a problem. Jump and branch opcodes are pretty much uniformly resolved by the static linker (unless you omit -fpic for a shared library, which is not recommended). The moveli and movei opcodes that need to be sign-extended generally are for positive displacements, like the construction of the address of main() from _start(). However, tst-pie1 ends up with main below _start (in a different module) and the test failed due to signedness issues in relocation handling. This commit treats the value as signed when shifting (to preserve the high bit) and also sign-extends the value generated from the updated bundle when comparing with the desired bundle, which we do to make sure no overflow occurred. As a result, the tst-pie1 test now passes. --- sysdeps/tile/dl-machine.h | 40 ++++++++++++++++++++++------------------ 1 files changed, 22 insertions(+), 18 deletions(-) This is the change I wanted to push before 2.20 froze. It turns out not to be a regression, so arguably the conservative thing may to wait until after 2.21 opens. I've done reasonable internal testing (and will have more results by Saturday morning after a full rebuild and test suite run) but could easily be swayed one way or the other. diff --git a/sysdeps/tile/dl-machine.h b/sysdeps/tile/dl-machine.h index 8be6758..ecd1eff 100644 --- a/sysdeps/tile/dl-machine.h +++ b/sysdeps/tile/dl-machine.h @@ -657,7 +657,7 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, value += 0x8000; #endif - value >>= h->right_shift; + value = ((long) value) >> h->right_shift; switch (h->byte_size) { @@ -686,13 +686,17 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, tile_bundle_bits *p = (tile_bundle_bits *) reloc_addr; tile_bundle_bits bits = *p; -#define MUNGE(func) do { \ +#define MUNGE_SIGNED(func, length) do { \ bits = ((bits & ~create_##func (-1)) | create_##func (value)); \ - if (get_##func (bits) != value) \ + ElfW(Addr) result = (long) get_##func (bits) \ + << (__WORDSIZE - length) >> (__WORDSIZE - length); \ + if (result != value) \ _dl_signal_error (0, map->l_name, NULL, \ "relocation value too large for " #func); \ } while (0) +#define MUNGE(func) MUNGE_SIGNED(func, __WORDSIZE) + #define MUNGE_NOCHECK(func) \ bits = ((bits & ~create_##func (-1)) | create_##func (value)) @@ -700,23 +704,23 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, { #ifdef __tilegx__ case R_TILEGX_BROFF_X1: - MUNGE (BrOff_X1); + MUNGE_SIGNED (BrOff_X1, 17); break; case R_TILEGX_JUMPOFF_X1: case R_TILEGX_JUMPOFF_X1_PLT: - MUNGE (JumpOff_X1); + MUNGE_SIGNED (JumpOff_X1, 27); break; case R_TILEGX_IMM8_X0: - MUNGE (Imm8_X0); + MUNGE_SIGNED (Imm8_X0, 8); break; case R_TILEGX_IMM8_Y0: - MUNGE (Imm8_Y0); + MUNGE_SIGNED (Imm8_Y0, 8); break; case R_TILEGX_IMM8_X1: - MUNGE (Imm8_X1); + MUNGE_SIGNED (Imm8_X1, 8); break; case R_TILEGX_IMM8_Y1: - MUNGE (Imm8_Y1); + MUNGE_SIGNED (Imm8_Y1, 8); break; case R_TILEGX_MT_IMM14_X1: MUNGE (MT_Imm14_X1); @@ -746,7 +750,7 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: - MUNGE (Imm16_X0); + MUNGE_SIGNED (Imm16_X0, 16); break; case R_TILEGX_IMM16_X1_HW0: case R_TILEGX_IMM16_X1_HW1: @@ -770,7 +774,7 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: - MUNGE (Imm16_X1); + MUNGE_SIGNED (Imm16_X1, 16); break; case R_TILEGX_MMSTART_X0: MUNGE (BFStart_X0); @@ -792,23 +796,23 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, break; #else case R_TILEPRO_BROFF_X1: - MUNGE (BrOff_X1); + MUNGE_SIGNED (BrOff_X1, 17); break; case R_TILEPRO_JOFFLONG_X1: case R_TILEPRO_JOFFLONG_X1_PLT: MUNGE_NOCHECK (JOffLong_X1); /* holds full 32-bit value */ break; case R_TILEPRO_IMM8_X0: - MUNGE (Imm8_X0); + MUNGE_SIGNED (Imm8_X0, 8); break; case R_TILEPRO_IMM8_Y0: - MUNGE (Imm8_Y0); + MUNGE_SIGNED (Imm8_Y0, 8); break; case R_TILEPRO_IMM8_X1: - MUNGE (Imm8_X1); + MUNGE_SIGNED (Imm8_X1, 8); break; case R_TILEPRO_IMM8_Y1: - MUNGE (Imm8_Y1); + MUNGE_SIGNED (Imm8_Y1, 8); break; case R_TILEPRO_MT_IMM15_X1: MUNGE (MT_Imm15_X1); @@ -834,7 +838,7 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, case R_TILEPRO_IMM16_X0_PCREL: case R_TILEPRO_IMM16_X0_TLS_GD: case R_TILEPRO_IMM16_X0_TLS_IE: - MUNGE (Imm16_X0); + MUNGE_SIGNED (Imm16_X0, 16); break; case R_TILEPRO_IMM16_X1_LO: case R_TILEPRO_IMM16_X1_HI: @@ -854,7 +858,7 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, case R_TILEPRO_IMM16_X1_PCREL: case R_TILEPRO_IMM16_X1_TLS_GD: case R_TILEPRO_IMM16_X1_TLS_IE: - MUNGE (Imm16_X1); + MUNGE_SIGNED (Imm16_X1, 16); break; case R_TILEPRO_MMSTART_X0: MUNGE (MMStart_X0);