aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-04-14 16:23:33 +0100
committerNick Clifton <nickc@redhat.com>2015-04-14 16:23:33 +0100
commit6ff71e768112317de1236a429e7c88c9d3e32116 (patch)
tree3d24e09232efe594ec6a32482a95b2f161250e4e /gas
parent9e811bc379ef78f0e2beadda9ed3ce6679ded7ea (diff)
downloadbinutils-6ff71e768112317de1236a429e7c88c9d3e32116.zip
binutils-6ff71e768112317de1236a429e7c88c9d3e32116.tar.gz
binutils-6ff71e768112317de1236a429e7c88c9d3e32116.tar.bz2
Adds support to the RL78 port for linker relaxation affecting .debug sections.
gas * config/tc-rl78.h (TC_LINKRELAX_FIXUP): Define. (TC_FORCE_RELOCATION_SUB_SAME): Define. (DWARF2_USE_FIXED_ADVANCE_PC): Define. * gas/lns/lns.exp: Add RL78 to list of targets using DW_LNS_fixed_advance_pc. bfd * elf32-rl78.c (RL78_OP_REL): New macro. (rl78_elf_howto_table): Use it for complex relocs. (get_symbol_value): Handle the cases when the info or status arguments are NULL. (get_romstart): Cache the status returned by get_symbol_value. (get_ramstart): Likewise. (RL78_STACK_PUSH): Generate an error message if the stack overflows. (RL78_STACK_POP): Likewise for underflows. (rl78_compute_complex_reloc): New function. Contains the basic processing code for all RL78 complex relocs. (rl78_special_reloc): New function. Provides special reloc handling for complex relocs. (rl78_elf_relocate_section): Use rl78_compute_complex_reloc. (rl78_offset_for_reloc): Likewise. binutils* readelf.c (target_specific_reloc_handling): Add code to handle RL78 complex relocs.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog6
-rw-r--r--gas/config/tc-rl78.c29
-rw-r--r--gas/config/tc-rl78.h14
-rw-r--r--gas/testsuite/ChangeLog5
-rw-r--r--gas/testsuite/gas/lns/lns.exp7
5 files changed, 49 insertions, 12 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 636ef3c..c90f98c 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,9 @@
+2015-04-14 Nick Clifton <nickc@redhat.com>
+
+ * config/tc-rl78.h (TC_LINKRELAX_FIXUP): Define.
+ (TC_FORCE_RELOCATION_SUB_SAME): Define.
+ (DWARF2_USE_FIXED_ADVANCE_PC): Define.
+
2015-04-10 Nick Clifton <nickc@redhat.com>
PR binutils/18198
diff --git a/gas/config/tc-rl78.c b/gas/config/tc-rl78.c
index 337b819..b5f0563 100644
--- a/gas/config/tc-rl78.c
+++ b/gas/config/tc-rl78.c
@@ -340,15 +340,16 @@ md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
}
void
-md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
+md_show_usage (FILE * stream)
{
fprintf (stream, _(" RL78 specific command line options:\n"));
+ fprintf (stream, _(" --mrelax Enable link time relaxation\n"));
fprintf (stream, _(" --mg10 Enable support for G10 variant\n"));
fprintf (stream, _(" --mg13 Selects the G13 core.\n"));
fprintf (stream, _(" --mg14 Selects the G14 core [default]\n"));
fprintf (stream, _(" --mrl78 Alias for --mg14\n"));
fprintf (stream, _(" --m32bit-doubles [default]\n"));
- fprintf (stream, _(" --m64bit-doubles\n"));
+ fprintf (stream, _(" --m64bit-doubles Source code uses 64-bit doubles\n"));
}
static void
@@ -662,13 +663,23 @@ rl78_cons_fix_new (fragS * frag,
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;
+ {
+ /* Fixups to assembler generated expressions do not use %hi or %lo. */
+ if (frag->fr_file)
+ as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
+ }
+ else
+ type = exp->X_md;
break;
case BFD_RELOC_RL78_HI8:
if (size != 1)
- as_bad (_("%%hi8 only applies to .byte"));
- type = exp->X_md;
+ {
+ /* Fixups to assembler generated expressions do not use %hi or %lo. */
+ if (frag->fr_file)
+ as_bad (_("%%hi8 only applies to .byte"));
+ }
+ else
+ type = exp->X_md;
break;
default:
break;
@@ -823,7 +834,7 @@ rl78_frag_fix_value (fragS * fragP,
/* Estimate how big the opcode is after this relax pass. The return
value is the difference between fr_fix and the actual size. We
compute the total size in rl78_relax_frag and store it in fr_subtype,
- sowe only need to subtract fx_fix and return it. */
+ so we only need to subtract fx_fix and return it. */
int
md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
@@ -960,8 +971,8 @@ rl78_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
fragP->fr_subtype = newsize;
tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
return newsize - oldsize;
- }
-
+}
+
/* This lets us test for the opcode type and the desired size in a
switch statement. */
#define OPCODE(type,size) ((type) * 16 + (size))
diff --git a/gas/config/tc-rl78.h b/gas/config/tc-rl78.h
index e2b9699..b9ede61 100644
--- a/gas/config/tc-rl78.h
+++ b/gas/config/tc-rl78.h
@@ -85,3 +85,17 @@ extern void rl78_elf_final_processing (void);
#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
((EXP)->X_md = 0, expression (EXP), TC_PARSE_CONS_RETURN_NONE)
+
+#define TC_LINKRELAX_FIXUP(seg) ((seg->flags & SEC_CODE) || (seg->flags & SEC_DEBUGGING))
+
+/* Do not adjust relocations involving symbols in code sections,
+ because it breaks linker relaxations. This could be fixed in the
+ linker, but this fix is simpler, and it pretty much only affects
+ object size a little bit. */
+#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEC) \
+ ( ((SEC)->flags & SEC_CODE) != 0 \
+ || ((SEC)->flags & SEC_DEBUGGING) != 0 \
+ || ! SEG_NORMAL (SEC) \
+ || TC_FORCE_RELOCATION (FIX))
+
+#define DWARF2_USE_FIXED_ADVANCE_PC 1
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index fc2b934..6076b89 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-04-14 Nick Clifton <nickc@redhat.com>
+
+ * gas/lns/lns.exp: Add RL78 to list of targets using
+ DW_LNS_fixed_advance_pc.
+
2015-04-08 H.J. Lu <hongjiu.lu@intel.com>
* gas/i386/dw2-compressed-1.d: New file.
diff --git a/gas/testsuite/gas/lns/lns.exp b/gas/testsuite/gas/lns/lns.exp
index b72c536..96aaffd 100644
--- a/gas/testsuite/gas/lns/lns.exp
+++ b/gas/testsuite/gas/lns/lns.exp
@@ -32,13 +32,14 @@ if {
&& ![istarget s390*-*-*]
} {
# Use alternate file for targets using DW_LNS_fixed_advance_pc opcodes.
- if { [istarget xtensa*-*-*]
- || [istarget am3*-*-*]
+ if { [istarget am3*-*-*]
|| [istarget cr16-*-*]
|| [istarget crx-*-*]
+ || [istarget mn10*-*-*]
|| [istarget msp430-*-*]
|| [istarget nds32*-*-*]
- || [istarget mn10*-*-*] } {
+ || [istarget rl78-*-*]
+ || [istarget xtensa*-*-*] } {
run_dump_test "lns-common-1-alt"
run_dump_test "lns-big-delta"
} elseif { [istarget ia64*-*-*] } {