Extend .reloc to accept some BFD_RELOCs
authorAlan Modra <amodra@gmail.com>
Mon, 19 Jan 2015 08:27:04 +0000 (18:57 +1030)
committerAlan Modra <amodra@gmail.com>
Mon, 19 Jan 2015 09:07:46 +0000 (19:37 +1030)
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.

gas/ChangeLog
gas/read.c
gas/testsuite/ChangeLog
gas/testsuite/gas/all/gas.exp
gas/testsuite/gas/all/none.d [new file with mode: 0644]
gas/testsuite/gas/all/none.s [new file with mode: 0644]
gas/write.c

index abb6d67b08cb59c4af4765b34d3563eb6916b9c7..6da11bb6f4a1cf5e803f45da0abc7aaf3b554560 100644 (file)
@@ -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.
index b2d50272d7fde8ba2af87a29c905c8dd245e08ae..2224c0ed241845eb2e73f59b807dedd617f2a0e0 100644 (file)
@@ -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)
     {
index 37c3e8687b44dd7fb1ff9bcec72388b894aee838..1feb27fdaeb01a43a23e900b9cb76d8578e554a3 100644 (file)
@@ -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.
index 0f76bf24bc474a4725fb7fe03583ce4f554acdf6..67be05016b80c04025776d47098d0865ac3bd069 100644 (file)
@@ -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 (file)
index 0000000..82e495b
--- /dev/null
@@ -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 (file)
index 0000000..1a82f06
--- /dev/null
@@ -0,0 +1,2 @@
+ .text
+ .reloc 0, BFD_RELOC_NONE, 0
index 15dc1c58f22d4b1becbba268207e9142f723b27d..aefed29ba3382075287f651cad95e474659f8851 100644 (file)
@@ -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;