summaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2015-01-19 18:57:04 +1030
committerAlan Modra <amodra@gmail.com>2015-01-19 19:37:46 +1030
commit740bdc67c057ee8012327420848eb134e1db4211 (patch)
tree5b62be60b72fb242cfe55b497abc9894afb6218e /gas
parent0ba38529f27a815a576bc07c85ceb65f6498ef5a (diff)
downloadbinutils-gdb-740bdc67c057ee8012327420848eb134e1db4211.tar.gz
Extend .reloc to accept some BFD_RELOCs
Tests that bfd_perform_reloc doesn't freak over a NONE reloc at end of section. gas/ * read.c (s_reloc): Match BFD_RELOC_NONE, BFD_RELOC{8,16,32,64}. * write.c (get_frag_for_reloc): Allow match just past end of frag. gas/testsuite/ * gas/all/none.s, * gas/all/none.d: New test. * gas/all/gas.exp: Run it.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog5
-rw-r--r--gas/read.c23
-rw-r--r--gas/testsuite/ChangeLog6
-rw-r--r--gas/testsuite/gas/all/gas.exp3
-rw-r--r--gas/testsuite/gas/all/none.d4
-rw-r--r--gas/testsuite/gas/all/none.s2
-rw-r--r--gas/write.c5
7 files changed, 47 insertions, 1 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index abb6d67b08c..6da11bb6f4a 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2015-01-19 Alan Modra <amodra@gmail.com>
+
+ * read.c (s_reloc): Match BFD_RELOC_NONE, BFD_RELOC{8,16,32,64}.
+ * write.c (get_frag_for_reloc): Allow match just past end of frag.
+
2015-01-16 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* config/tc-s390.c (struct pd_reg): Remove.
diff --git a/gas/read.c b/gas/read.c
index b2d50272d7f..2224c0ed241 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -3993,6 +3993,14 @@ s_reloc (int ignore ATTRIBUTE_UNUSED)
char *r_name;
int c;
struct reloc_list *reloc;
+ struct _bfd_rel { char *name; bfd_reloc_code_real_type code; };
+ static struct _bfd_rel bfd_relocs[] = {
+ { "NONE", BFD_RELOC_NONE },
+ { "8", BFD_RELOC_8 },
+ { "16", BFD_RELOC_16 },
+ { "32", BFD_RELOC_32 },
+ { "64", BFD_RELOC_64 }
+ };
reloc = (struct reloc_list *) xmalloc (sizeof (*reloc));
@@ -4035,7 +4043,20 @@ s_reloc (int ignore ATTRIBUTE_UNUSED)
SKIP_WHITESPACE ();
r_name = input_line_pointer;
c = get_symbol_end ();
- reloc->u.a.howto = bfd_reloc_name_lookup (stdoutput, r_name);
+ if (strncasecmp (r_name, "BFD_RELOC_", 10) == 0)
+ {
+ unsigned int i;
+
+ for (reloc->u.a.howto = NULL, i = 0; i < ARRAY_SIZE (bfd_relocs); i++)
+ if (strcasecmp (r_name + 10, bfd_relocs[i].name) == 0)
+ {
+ reloc->u.a.howto = bfd_reloc_type_lookup (stdoutput,
+ bfd_relocs[i].code);
+ break;
+ }
+ }
+ else
+ reloc->u.a.howto = bfd_reloc_name_lookup (stdoutput, r_name);
*input_line_pointer = c;
if (reloc->u.a.howto == NULL)
{
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 37c3e8687b4..1feb27fdaeb 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2015-01-19 Alan Modra <amodra@gmail.com>
+
+ * gas/all/none.s,
+ * gas/all/none.d: New test.
+ * gas/all/gas.exp: Run it.
+
2015-01-16 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* gas/s390/esa-g5.d: Add a variant without the optional operand.
diff --git a/gas/testsuite/gas/all/gas.exp b/gas/testsuite/gas/all/gas.exp
index 0f76bf24bc4..67be05016b8 100644
--- a/gas/testsuite/gas/all/gas.exp
+++ b/gas/testsuite/gas/all/gas.exp
@@ -430,6 +430,9 @@ gas_test_error "weakref3.s" "" "a: would close weakref loop: a => b => c => d =>
gas_test_error "weakref4.s" "" "is already defined"
run_dump_test string
+if [is_elf_format] {
+ run_dump_test none
+}
load_lib gas-dg.exp
dg-init
diff --git a/gas/testsuite/gas/all/none.d b/gas/testsuite/gas/all/none.d
new file mode 100644
index 00000000000..82e495ba050
--- /dev/null
+++ b/gas/testsuite/gas/all/none.d
@@ -0,0 +1,4 @@
+#objdump: -r -w
+
+#...
+0+ .*(NONE|NULL|UNUSED0) +\*ABS\*
diff --git a/gas/testsuite/gas/all/none.s b/gas/testsuite/gas/all/none.s
new file mode 100644
index 00000000000..1a82f063beb
--- /dev/null
+++ b/gas/testsuite/gas/all/none.s
@@ -0,0 +1,2 @@
+ .text
+ .reloc 0, BFD_RELOC_NONE, 0
diff --git a/gas/write.c b/gas/write.c
index 15dc1c58f22..aefed29ba33 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -1184,6 +1184,11 @@ get_frag_for_reloc (fragS *last_frag,
&& r->u.b.r.address < f->fr_address + f->fr_fix)
return f;
+ for (f = seginfo->frchainP->frch_root; f != NULL; f = f->fr_next)
+ if (f->fr_address <= r->u.b.r.address
+ && r->u.b.r.address <= f->fr_address + f->fr_fix)
+ return f;
+
as_bad_where (r->file, r->line,
_("reloc not within (fixed part of) section"));
return NULL;