public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Alexey Brodkin <Alexey.Brodkin@synopsys.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2] ARC: Improve relocation fix-ups
Date: Wed, 30 May 2018 19:28:29 +0300	[thread overview]
Message-ID: <20180530162829.9340-1-abrodkin@synopsys.com> (raw)

We used to have the one and only linker script for all ARC boards
and so we relied on a particular order of symbols there.

Because of that we used __ivt_end as the marker of the end of all the
code which won't be true any longer if we move .ivt section to any other
place. That said we'd better check for each section separately.

A couple of other improvements:
 1. There's no point to include the marker of section end in interested
    range because its address is beyond the section, i.e. we should
    compare with "<" but not "<=".

 2. .ivt section for ARCv2 cores is just an array of 32-bit ints and
    they are not swapped even on little-endia cores while in case of
    ARCompact cores .ivt contains valid code so swapping is required.

 3. Just in case add check for ARC600 which is also ARCompact
    and its .ivt is normal code.

Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
---

Changes v1 -> v2:

 * Fixed build failure for ARcompact, see
   https://travis-ci.org/abrodkin/u-boot/jobs/385682085

 arch/arc/lib/relocate.c | 76 +++++++++++++++++++++++++++++------------
 1 file changed, 54 insertions(+), 22 deletions(-)

diff --git a/arch/arc/lib/relocate.c b/arch/arc/lib/relocate.c
index a3b7428d8519..4ffba84eeb3e 100644
--- a/arch/arc/lib/relocate.c
+++ b/arch/arc/lib/relocate.c
@@ -8,7 +8,9 @@
 #include <asm-generic/sections.h>
 
 extern ulong __image_copy_start;
+extern ulong __ivt_start;
 extern ulong __ivt_end;
+extern ulong __text_end;
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -48,7 +50,7 @@ int do_elf_reloc_fixups(void)
 	debug("Section .rela.dyn is located at %08x-%08x\n",
 	      (unsigned int)re_src, (unsigned int)re_end);
 
-	Elf32_Addr *offset_ptr_rom, *last_offset = NULL;
+	Elf32_Addr *offset_ptr_rom;
 	Elf32_Addr *offset_ptr_ram;
 
 	do {
@@ -57,15 +59,28 @@ int do_elf_reloc_fixups(void)
 
 		/* Check that the location of the relocation is in .text */
 		if (offset_ptr_rom >= (Elf32_Addr *)&__image_copy_start &&
-		    offset_ptr_rom > last_offset) {
-			unsigned int val;
+		    offset_ptr_rom < (Elf32_Addr *)&__image_copy_end) {
+			unsigned int val, do_swap = 0;
 			/* Switch to the in-RAM version */
 			offset_ptr_ram = (Elf32_Addr *)((ulong)offset_ptr_rom +
 							gd->reloc_off);
 
-			debug("Patching value @ %08x (relocated to %08x)\n",
+#ifdef __LITTLE_ENDIAN__
+			/* If location in ".text" section swap value */
+			if (((u32)offset_ptr_rom >= (u32)&__text_start &&
+			     (u32)offset_ptr_rom <= (u32)&__text_end)
+#if defined(__ARC700__) || defined(__ARC600__)
+			    || ((u32)offset_ptr_rom >= (u32)&__ivt_start &&
+				(u32)offset_ptr_rom <= (u32)&__ivt_end)
+#endif
+			   )
+				do_swap = 1;
+#endif
+
+			debug("Patching value @ %08x (relocated to %08x)%s\n",
 			      (unsigned int)offset_ptr_rom,
-			      (unsigned int)offset_ptr_ram);
+			      (unsigned int)offset_ptr_ram,
+			      do_swap ? ", middle-endian encoded" : "");
 
 			/*
 			 * Use "memcpy" because target location might be
@@ -75,28 +90,45 @@ int do_elf_reloc_fixups(void)
 			 */
 			memcpy(&val, offset_ptr_ram, sizeof(int));
 
-#ifdef __LITTLE_ENDIAN__
-			/* If location in ".text" section swap value */
-			if ((unsigned int)offset_ptr_rom <
-			    (unsigned int)&__ivt_end)
+			if (do_swap)
 				val = (val << 16) | (val >> 16);
-#endif
 
 			/* Check that the target points into executable */
-			if (val >= (unsigned int)&__image_copy_start && val <=
-			    (unsigned int)&__image_copy_end) {
-				val += gd->reloc_off;
-#ifdef __LITTLE_ENDIAN__
-				/* If location in ".text" section swap value */
-				if ((unsigned int)offset_ptr_rom <
-				    (unsigned int)&__ivt_end)
-					val = (val << 16) | (val >> 16);
-#endif
-				memcpy(offset_ptr_ram, &val, sizeof(int));
+			if (val < (unsigned int)&__image_copy_start ||
+			    val > (unsigned int)&__image_copy_end) {
+				/* TODO: Use panic() instead of debug()
+				 *
+				 * For some reason GCC might generate
+				 * fake relocation even for LD/SC of constant
+				 * inderectly. See an example below:
+				 * ----------------------->8--------------------
+				 * static int setup_mon_len(void)
+				 * {
+				 *         gd->mon_len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE;
+				 *         return 0;
+				 * }
+				 * ----------------------->8--------------------
+				 *
+				 * And that's what we get in the binary:
+				 * ----------------------->8--------------------
+				 * 10005cb4 <setup_mon_len>:
+				 * 10005cb4:       193c 3f80 0003 2f80     st      0x32f80,[r25,60]
+				 *                         10005cb8: R_ARC_RELATIVE        *ABS*-0x10000000
+				 * 10005cbc:       7fe0                    j_s.d   [blink]
+				 * 10005cbe:       700c                    mov_s   r0,0
+				 * ----------------------->8--------------------
+				 */
+				debug("Relocation target %08x points outside of image\n",
+				      val);
 			}
-		}
-		last_offset = offset_ptr_rom;
 
+			val += gd->reloc_off;
+
+			if (do_swap)
+				val = (val << 16) | (val >> 16);
+
+			memcpy(offset_ptr_ram, &val, sizeof(int));
+		}
 	} while (++re_src < re_end);
 
 	return 0;
-- 
2.17.0

                 reply	other threads:[~2018-05-30 16:28 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180530162829.9340-1-abrodkin@synopsys.com \
    --to=alexey.brodkin@synopsys.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox