[committed] nios2: recognize %gotoff relocation in assembler

Sandra Loosemore sandra@codesourcery.com
Fri Jan 31 18:40:00 GMT 2020


The nios2 ABI documentation lists %gotoff as assembler syntax for the
R_NIOS2_GOTOFF relocation, used to represent a 32-bit GOT-relative offset
in data sections.  This was previously unimplemented in GAS.

2020-01-31  Sandra Loosemore  <sandra@codesourcery.com>

	gas/
	* config/tc-nios2.c (nios2_cons): Handle %gotoff as well as
	%tls_ldo.
---
 gas/ChangeLog         |  5 +++++
 gas/config/tc-nios2.c | 40 ++++++++++++++++++++++++++++++----------
 2 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 9e2458a..bc149c1 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2020-01-31  Sandra Loosemore  <sandra@codesourcery.com>
+
+	* config/tc-nios2.c (nios2_cons): Handle %gotoff as well as
+	%tls_ldo.
+
 2020-01-31  Andre Vieira  <andre.simoesdiasvieira@arm.com>
 
 	PR gas/25472
diff --git a/gas/config/tc-nios2.c b/gas/config/tc-nios2.c
index a87f249..a7039e4 100644
--- a/gas/config/tc-nios2.c
+++ b/gas/config/tc-nios2.c
@@ -4011,31 +4011,48 @@ nios2_elf_section_flags (flagword flags, int attr, int type ATTRIBUTE_UNUSED)
   return flags;
 }
 
-/* Implement TC_PARSE_CONS_EXPRESSION to handle %tls_ldo(...) */
+/* Implement TC_PARSE_CONS_EXPRESSION to handle %tls_ldo(...) and
+   %gotoff(...).  */
 bfd_reloc_code_real_type
 nios2_cons (expressionS *exp, int size)
 {
-  bfd_reloc_code_real_type nios2_tls_ldo_reloc = BFD_RELOC_NONE;
+  bfd_reloc_code_real_type explicit_reloc = BFD_RELOC_NONE;
+  const char *reloc_name = NULL;
 
   SKIP_WHITESPACE ();
   if (input_line_pointer[0] == '%')
     {
       if (strprefix (input_line_pointer + 1, "tls_ldo"))
 	{
+	  reloc_name = "%tls_ldo";
 	  if (size != 4)
 	    as_bad (_("Illegal operands: %%tls_ldo in %d-byte data field"),
 		    size);
 	  else
 	    {
 	      input_line_pointer += 8;
-	      nios2_tls_ldo_reloc = BFD_RELOC_NIOS2_TLS_DTPREL;
+	      explicit_reloc = BFD_RELOC_NIOS2_TLS_DTPREL;
 	    }
 	}
-      if (nios2_tls_ldo_reloc != BFD_RELOC_NONE)
+      else if (strprefix (input_line_pointer + 1, "gotoff"))
+	{
+	  reloc_name = "%gotoff";
+	  if (size != 4)
+	    as_bad (_("Illegal operands: %%gotoff in %d-byte data field"),
+		    size);
+	  else
+	    {
+	      input_line_pointer += 7;
+	      explicit_reloc = BFD_RELOC_NIOS2_GOTOFF;
+	    }
+	}
+
+      if (explicit_reloc != BFD_RELOC_NONE)
 	{
 	  SKIP_WHITESPACE ();
 	  if (input_line_pointer[0] != '(')
-	    as_bad (_("Illegal operands: %%tls_ldo requires arguments in ()"));
+	    as_bad (_("Illegal operands: %s requires arguments in ()"),
+		    reloc_name);
 	  else
 	    {
 	      int c;
@@ -4053,29 +4070,32 @@ nios2_cons (expressionS *exp, int size)
 		  }
 
 	      if (c != ')')
-		as_bad (_("Illegal operands: %%tls_ldo requires arguments in ()"));
+		as_bad (_("Illegal operands: %s requires arguments in ()"),
+			reloc_name);
 	      else
 		{
 		  *end = '\0';
 		  expression (exp);
 		  *end = c;
 		  if (input_line_pointer != end)
-		    as_bad (_("Illegal operands: %%tls_ldo requires arguments in ()"));
+		    as_bad (_("Illegal operands: %s requires arguments in ()"),
+			    reloc_name);
 		  else
 		    {
 		      input_line_pointer++;
 		      SKIP_WHITESPACE ();
 		      c = *input_line_pointer;
 		      if (! is_end_of_line[c] && c != ',')
-			as_bad (_("Illegal operands: garbage after %%tls_ldo()"));
+			as_bad (_("Illegal operands: garbage after %s()"),
+				reloc_name);
 		    }
 		}
 	    }
 	}
     }
-  if (nios2_tls_ldo_reloc == BFD_RELOC_NONE)
+  if (explicit_reloc == BFD_RELOC_NONE)
     expression (exp);
-  return nios2_tls_ldo_reloc;
+  return explicit_reloc;
 }
 
 /* Implement HANDLE_ALIGN.  */
-- 
2.8.1



More information about the Binutils mailing list