This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Commit: RL78: Fix handling of immediate values in complex relocs
- From: Nick Clifton <nickc at redhat dot com>
- To: binutils at sourceware dot org
- Date: Fri, 24 Jul 2015 16:42:54 +0100
- Subject: Commit: RL78: Fix handling of immediate values in complex relocs
- Authentication-results: sourceware.org; auth=none
Hi Guys,
The RL78 target uses complex relocs to achieve various different
effects. As part of their operation these relocs use an evaluation
stack to hold temporary values. Unfortunately it turns out that it is
not possible to push an immediate value onto this evaluation stack
because the code in bfd_perform_relocation() and
bfd_install_relocation() prevent it. They processes any relocs
against the absolute section symbol immediately rather than passing
them to the special relocation handler function (if it exists).
The attached patch fixes this problem by creating a new RL78 specific
absolute symbol and changing any immediate value in a complex
relocation sequence to be against this new symbol. This avoids
changing the generic code in bfd/reloc.c, but unfortunately means that
the new symbol has to be PROVIDED by rl78 linker scripts. This in
turn means that a few tests have to be tweaked to allow for this new
symbol.
Tested with no regressions on an rl78-elf toolchain.
Cheers
Nick
gas/ChangeLog
2015-07-24 Nick Clifton <nickc@redhat.com>
* config/tc-rl78.c (rl78_abs_sym): New local variable.
(md_begin): Initialise the new symbol.
(OPIMM): Define the value to be relative to the new symbol and not
the absolute section symbol.
ld/ChangeLog
2015-07-24 Nick Clifton <nickc@redhat.com>
* emulparams/elf32rl78.sh (OTHER_SECTIONS): Provide a value for
the _-rl78_abs__ symbol.
gas/testsuite/ChangeLog
2015-07-24 Nick Clifton <nickc@redhat.com>
* gas/all/struct.d: Allow for extra symbols in the output.
* gas/macros/test1.d: Likewise.
* gas/elf/elf.exp: Add an rl78 machine.
* gas/elf/sections2e-rl78: New file.
binutils/testsuite/ChangeLog
2015-07-24 Nick Clifton <nickc@redhat.com>
* binutils-all/localize-hidden-1.d: Allow for extra symbols in the
output.
* binutils-all/strip-11.d: Skip for the RL78.
diff --git a/binutils/testsuite/binutils-all/localize-hidden-1.d b/binutils/testsuite/binutils-all/localize-hidden-1.d
index a5286ed..60dc556 100644
--- a/binutils/testsuite/binutils-all/localize-hidden-1.d
+++ b/binutils/testsuite/binutils-all/localize-hidden-1.d
@@ -12,6 +12,7 @@
0+2300 l .*\*ABS\* 0+ \.internal Ginternal
0+3200 l .*\*ABS\* 0+ \.hidden Whidden
0+3300 l .*\*ABS\* 0+ \.internal Winternal
+#...
0+2100 g .*\*ABS\* 0+ Gdefault
0+2400 g .*\*ABS\* 0+ \.protected Gprotected
0+3100 w.*\*ABS\* 0+ Wdefault
diff --git a/binutils/testsuite/binutils-all/strip-11.d b/binutils/testsuite/binutils-all/strip-11.d
index 04c47ab..92a6b6b 100644
--- a/binutils/testsuite/binutils-all/strip-11.d
+++ b/binutils/testsuite/binutils-all/strip-11.d
@@ -3,6 +3,8 @@
#strip: -g
#readelf: -S --wide
#name: strip -g empty file
+# The RL78 linker scripts always PROVIDE a __rl78_abs__ symbol so the stripped symbol table is never empty.
+#not-target: rl78-*-*
#...
\[ 0\] +NULL +0+ .*
diff --git a/gas/config/tc-rl78.c b/gas/config/tc-rl78.c
index 3a14fc0..c9d5c97 100644
--- a/gas/config/tc-rl78.c
+++ b/gas/config/tc-rl78.c
@@ -402,9 +402,12 @@ const pseudo_typeS md_pseudo_table[] =
{ NULL, NULL, 0 }
};
+static symbolS * rl78_abs_sym = NULL;
+
void
md_begin (void)
{
+ rl78_abs_sym = symbol_make ("__rl78_abs__");
}
void
@@ -1240,7 +1243,17 @@ tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
reloc[rp]->address = fixp->fx_frag->fr_address + fixp->fx_where; \
reloc[++rp] = NULL
#define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0)
-#define OPIMM(IMM) OPX(BFD_RELOC_RL78_SYM, abs_symbol.bsym, IMM)
+
+ /* FIXME: We cannot do the normal thing for an immediate value reloc,
+ ie creating a RL78_SYM reloc in the *ABS* section with an offset
+ equal to the immediate value we want to store. This fails because
+ the reloc processing in bfd_perform_relocation and bfd_install_relocation
+ will short circuit such relocs and never pass them on to the special
+ reloc processing code. So instead we create a RL78_SYM reloc against
+ the __rl78_abs__ symbol and arrange for the linker scripts to place
+ this symbol at address 0. */
+#define OPIMM(IMM) OPX (BFD_RELOC_RL78_SYM, symbol_get_bfdsym (rl78_abs_sym), IMM)
+
#define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
#define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
diff --git a/gas/testsuite/gas/all/struct.d b/gas/testsuite/gas/all/struct.d
index 8dc5dd4..d59a8dd 100644
--- a/gas/testsuite/gas/all/struct.d
+++ b/gas/testsuite/gas/all/struct.d
@@ -2,7 +2,7 @@
#name: struct
# Test the .struct pseudo-op.
-
+#...
0+00 A w1
0+02 A w2
0+04 A w3
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index ff19bad..496e01a 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -79,6 +79,9 @@ if { [is_elf_format] } then {
if {[istarget "v850*-*-*"]} then {
set target_machine -v850
}
+ if {[istarget "rl78-*-*"]} then {
+ set target_machine -rl78
+ }
if {[istarget "arm*-*-*"]} {
set target_machine -arm
}
diff --git a/gas/testsuite/gas/macros/test1.d b/gas/testsuite/gas/macros/test1.d
index f6d7fa4..fe16434 100644
--- a/gas/testsuite/gas/macros/test1.d
+++ b/gas/testsuite/gas/macros/test1.d
@@ -1,5 +1,6 @@
#nm: --extern-only
#name: macro test 1
+#...
0+01 A s_not_a_reg_1
0+02 A s_not_a_reg_2
diff --git a/ld/emulparams/elf32rl78.sh b/ld/emulparams/elf32rl78.sh
index e305aa1..7073efb 100644
--- a/ld/emulparams/elf32rl78.sh
+++ b/ld/emulparams/elf32rl78.sh
@@ -8,7 +8,7 @@ ENTRY=_start
EMBEDDED=yes
TEMPLATE_NAME=elf32
ELFSIZE=32
-EXTRA_EM_FILE=needrelax
+# EXTRA_EM_FILE=needrelax
MAXPAGESIZE=256
# This is like setting STACK_ADDR to 0xffedc, except that the setting can
# be overridden, e.g. --defsym _stack=0x0f00, and that we put an extra
@@ -21,6 +21,7 @@ test -z "$CREATE_SHLIB" && OTHER_SECTIONS=" .stack ${RELOCATING-0}${RELO
${RELOCATING+__stack = .;}
*(.stack)
LONG(0xdead)
- }"
+ }
+ ${RELOCATING+PROVIDE (__rl78_abs__ = 0);}"
# We do not need .stack for shared library.
test -n "$CREATE_SHLIB" && OTHER_SECTIONS=""
--- /dev/null 2015-07-24 08:10:00.220964865 +0100
+++ gas/testsuite/gas/elf/section2.e-rl78 2015-07-24 15:55:23.428997995 +0100
@@ -0,0 +1,9 @@
+
+Symbol table '.symtab' contains 6 entries:
+ +Num: +Value +Size +Type +Bind +Vis +Ndx +Name
+ +0: 0+0 +0 +NOTYPE +LOCAL +DEFAULT +UND
+ +1: 0+0 +0 +SECTION +LOCAL +DEFAULT +1
+ +2: 0+0 +0 +SECTION +LOCAL +DEFAULT +2
+ +3: 0+0 +0 +SECTION +LOCAL +DEFAULT +3
+ +4: 0+0 +0 +SECTION +LOCAL +DEFAULT +4
+ +5: 0+0 +0 +NOTYPE +GLOBAL +DEFAULT +UND __rl78_abs__