1From 362a20108782b87cd780a989c0dbd014fc2def8b Mon Sep 17 00:00:00 2001
2From: Stafford Horne <shorne@gmail.com>
3Date: Sun, 2 Jan 2022 09:03:28 +0900
4Subject: [PATCH] or1k: Avoid R_OR1K_GOT16 signed overflow by using special
5 howto
6
7Previously when fixing PR 21464 we masked out upper bits of the
8relocation value in order to avoid overflow complaints when acceptable.
9It turns out this does not work when the relocation value ends up being
10signed.
11
12To fix this this patch introduces a special howto with
13complain_on_overflow set to complain_overflow_dont.  This is used in
14place of the normal R_OR1K_GOT16 howto when we detect R_OR1K_GOT_AHI16
15relocations.
16
17bfd/ChangeLog:
18
19	PR 28735
20	* elf32-or1k.c (or1k_elf_got16_no_overflow_howto): Define.
21	(or1k_elf_relocate_section): Use new howto instead of trying to
22	mask out relocation bits.
23
24Signed-off-by: Giulio Benetti <giulio.benetti@benettiengineering.com>
25---
26 bfd/elf32-or1k.c | 24 ++++++++++++++++++++----
27 1 file changed, 20 insertions(+), 4 deletions(-)
28
29diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
30index 4ae7f324d33..7fd88d72442 100644
31--- a/bfd/elf32-or1k.c
32+++ b/bfd/elf32-or1k.c
33@@ -828,6 +828,23 @@ static reloc_howto_type or1k_elf_howto_table[] =
34 	 false),		/* pcrel_offset */
35 };
36
37+/* A copy of the R_OR1K_GOT16 used in the presense of R_OR1K_GOT_AHI16
38+   relocations when we know we can ignore overflows.  */
39+static reloc_howto_type or1k_elf_got16_no_overflow_howto =
40+  HOWTO (R_OR1K_GOT16,		/* type */
41+	 0,			/* rightshift */
42+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
43+	 16,			/* bitsize */
44+	 false,			/* pc_relative */
45+	 0,			/* bitpos */
46+	 complain_overflow_dont, /* complain_on_overflow */
47+	 bfd_elf_generic_reloc, /* special_function */
48+	 "R_OR1K_GOT16",	/* name */
49+	 false,			/* partial_inplace */
50+	 0,			/* src_mask */
51+	 0xffff,		/* dst_mask */
52+	 false);		/* pcrel_offset */
53+
54 /* Map BFD reloc types to Or1k ELF reloc types.  */
55
56 struct or1k_reloc_map
57@@ -1506,12 +1523,11 @@ or1k_elf_relocate_section (bfd *output_bfd,
58 	    if (r_type == R_OR1K_GOT_AHI16)
59 	      saw_gotha = true;
60
61-	    /* If we have a R_OR1K_GOT16 followed by a R_OR1K_GOT_AHI16
62+	    /* If we have a R_OR1K_GOT16 following a R_OR1K_GOT_AHI16
63 	       relocation we assume the code is doing the right thing to avoid
64-	       overflows.  Here we mask the lower 16-bit of the relocation to
65-	       avoid overflow validation failures.  */
66+	       overflows.  */
67 	    if (r_type == R_OR1K_GOT16 && saw_gotha)
68-	      relocation &= 0xffff;
69+	      howto = &or1k_elf_got16_no_overflow_howto;
70
71 	  /* Addend should be zero.  */
72 	  if (rel->r_addend != 0)
73--
742.25.1
75
76