From 95441c43cc0a8f30a27fe9bfc7f42f63f80b95c5 Mon Sep 17 00:00:00 2001 From: Sandra Loosemore Date: Fri, 31 Jan 2020 10:32:48 -0800 Subject: nios2: recognize %gotoff relocation in assembler 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 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 + + * config/tc-nios2.c (nios2_cons): Handle %gotoff as well as + %tls_ldo. + 2020-01-31 Andre Vieira 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. */ -- cgit v1.1