This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] rl78: add %code() pseudo-op


The RL78 has a 20-bit address space.  Symbols in certain pages can be
accessed with 16-bit relocs and the page offset is "assumed".
However, the default for data is different than the default for code.
This patch adds a %code() pseudo-op that tells the linker that the
symbol's default page is the code page, not the data page, so that the
16-bit PLT jump tables can be properly created.  The failure case was
when a code label happened to be in the data page - the linker would
truncate the value to 16-bits but the chip would access that offset in
the code page instead, causing a fault.

Committed.

	* reloc.c (BFD_RELOC_RL78_CODE): Add.
	* libbfd.h: Regenerate.
	* bfd-in2.h: Regenerate.
	* elf32-rl78.c (rl78_elf_relocate_section): Handle weak code
	references in compuated relocs.

	* config/tc-rl78.c (reloc_function): Add %code -> BFD_RELOC_RL78_CODE.
	(rl78_op): Handle %code().
	(rl78_cons_fix_new): Likewise, but ignore for 20-bit operands.
	(tc_gen_reloc): Likwise; convert to a computed reloc.
	(md_apply_fix): Likewise.

Index: bfd/bfd-in2.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in2.h,v
retrieving revision 1.598
diff -p -U5 -r1.598 bfd-in2.h
--- bfd/bfd-in2.h	6 Feb 2013 23:22:07 -0000	1.598
+++ bfd/bfd-in2.h	27 Feb 2013 21:08:15 -0000
@@ -4237,10 +4237,11 @@ in .byte hlo8(symbol)  */
   BFD_RELOC_RL78_ABS16UL,
   BFD_RELOC_RL78_RELAX,
   BFD_RELOC_RL78_HI16,
   BFD_RELOC_RL78_HI8,
   BFD_RELOC_RL78_LO16,
+  BFD_RELOC_RL78_CODE,
 
 /* Renesas RX Relocations.  */
   BFD_RELOC_RX_NEG8,
   BFD_RELOC_RX_NEG16,
   BFD_RELOC_RX_NEG24,
Index: bfd/elf32-rl78.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-rl78.c,v
retrieving revision 1.11
diff -p -U5 -r1.11 elf32-rl78.c
--- bfd/elf32-rl78.c	10 Jan 2013 20:03:53 -0000	1.11
+++ bfd/elf32-rl78.c	27 Feb 2013 21:08:15 -0000
@@ -776,10 +776,12 @@ rl78_elf_relocate_section
 		      || h->root.type == bfd_link_hash_defweak))
 		RL78_STACK_PUSH (h->root.u.def.value
 			       + sec->output_section->vma
 			       + sec->output_offset
 			       + rel->r_addend);
+	      else if (h->root.type == bfd_link_hash_undefweak)
+		RL78_STACK_PUSH (0);
 	      else
 		_bfd_error_handler (_("Warning: RL78_SYM reloc with an unknown symbol"));
 	    }
 	  break;
 
Index: bfd/libbfd.h
===================================================================
RCS file: /cvs/src/src/bfd/libbfd.h,v
retrieving revision 1.292
diff -p -U5 -r1.292 libbfd.h
--- bfd/libbfd.h	11 Feb 2013 05:30:53 -0000	1.292
+++ bfd/libbfd.h	27 Feb 2013 21:08:16 -0000
@@ -1968,10 +1968,11 @@ static const char *const bfd_reloc_code_
   "BFD_RELOC_RL78_ABS16UL",
   "BFD_RELOC_RL78_RELAX",
   "BFD_RELOC_RL78_HI16",
   "BFD_RELOC_RL78_HI8",
   "BFD_RELOC_RL78_LO16",
+  "BFD_RELOC_RL78_CODE",
   "BFD_RELOC_RX_NEG8",
   "BFD_RELOC_RX_NEG16",
   "BFD_RELOC_RX_NEG24",
   "BFD_RELOC_RX_NEG32",
   "BFD_RELOC_RX_16_OP",
Index: bfd/reloc.c
===================================================================
RCS file: /cvs/src/src/bfd/reloc.c,v
retrieving revision 1.242
diff -p -U5 -r1.242 reloc.c
--- bfd/reloc.c	6 Feb 2013 23:22:08 -0000	1.242
+++ bfd/reloc.c	27 Feb 2013 21:08:17 -0000
@@ -4558,10 +4558,12 @@ ENUMX
   BFD_RELOC_RL78_HI16
 ENUMX
   BFD_RELOC_RL78_HI8
 ENUMX
   BFD_RELOC_RL78_LO16
+ENUMX
+  BFD_RELOC_RL78_CODE
 ENUMDOC
   Renesas RL78 Relocations.
 
 ENUM
   BFD_RELOC_RX_NEG8
Index: gas/config/tc-rl78.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-rl78.c,v
retrieving revision 1.5
diff -p -U5 -r1.5 tc-rl78.c
--- gas/config/tc-rl78.c	29 Jan 2013 22:17:53 -0000	1.5
+++ gas/config/tc-rl78.c	27 Feb 2013 21:08:18 -0000
@@ -192,10 +192,13 @@ rl78_op (expressionS exp, int nbytes, in
 	    }
 	}
     }
   else
     {
+      if (nbytes > 2
+	  && exp.X_md == BFD_RELOC_RL78_CODE)
+	exp.X_md = 0;
       rl78_op_fixup (exp, rl78_bytes.n_ops * 8, nbytes * 8, type);
       memset (rl78_bytes.ops + rl78_bytes.n_ops, 0, nbytes);
       rl78_bytes.n_ops += nbytes;
     }
 }
@@ -335,10 +338,11 @@ static struct
   char * fname;
   int    reloc;
 }
 reloc_functions[] =
 {
+  { "code", BFD_RELOC_RL78_CODE },
   { "lo16", BFD_RELOC_RL78_LO16 },
   { "hi16", BFD_RELOC_RL78_HI16 },
   { "hi8",  BFD_RELOC_RL78_HI8 },
   { 0, 0 }
 };
@@ -554,10 +558,14 @@ rl78_cons_fix_new (fragS *	frag,
       return;
     }
 
   switch (exp->X_md)
     {
+    case BFD_RELOC_RL78_CODE:
+      if (size == 2)
+	type = exp->X_md;
+      break;
     case BFD_RELOC_RL78_LO16:
     case BFD_RELOC_RL78_HI16:
       if (size != 2)
 	as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
       type = exp->X_md;
@@ -663,10 +671,15 @@ tc_gen_reloc (asection * seg ATTRIBUTE_U
       SYM0 ();
       OP (OP_NEG);
       OP (ABS32);
       break;
 
+    case BFD_RELOC_RL78_CODE:
+      SYM0 ();
+      OP (ABS16);
+      break;
+
     case BFD_RELOC_RL78_LO16:
       SYM0 ();
       OPIMM (0xffff);
       OP (OP_AND);
       OP (ABS16);
@@ -769,10 +782,11 @@ md_apply_fix (struct fix * f ATTRIBUTE_U
       op[0] = val;
       break;
 
     case BFD_RELOC_16:
     case BFD_RELOC_16_PCREL:
+    case BFD_RELOC_RL78_CODE:
       op[0] = val;
       op[1] = val >> 8;
       break;
 
     case BFD_RELOC_24:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]