This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 2/2][ARC] Emit BFD_RELOC_ARC_32_PCREL relocation
- From: Claudiu Zissulescu <Claudiu dot Zissulescu at synopsys dot com>
- To: <binutils at sourceware dot org>
- Cc: <cupertino dot miranda at synopsys dot com>, <Francois dot Bedard at synopsys dot com>
- Date: Tue, 20 Oct 2015 14:11:18 +0200
- Subject: [PATCH 2/2][ARC] Emit BFD_RELOC_ARC_32_PCREL relocation
- Authentication-results: sourceware.org; auth=none
- References: <1445343078-8199-1-git-send-email-claziss at synopsys dot com>
These patches are fixing the observed ARC backend's GAS dejagnu errors.
Please review,
Claudiu
ChangeLog GAS:
2015-10-20 Claudiu Zissulescu <claziss@synopsys.com>
* config/tc-arc.c (tokenize_arguments): Avoid creating unused
symbols when parsing relocation types.
(md_apply_fix): Handle TLS relocations. Fix BFD_RELOC_ARC_32_PCREL
relocation.
(arc_check_reloc): Emit BFD_RELOC_ARC_32_PCREL relocation.
Signed-off-by: Claudiu Zissulescu <claziss@synopsys.com>
---
gas/config/tc-arc.c | 158 +++++++++++++++++++++++++++++---------------------
1 files changed, 92 insertions(+), 66 deletions(-)
diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c
index cc56797..d35a1c2 100644
--- a/gas/config/tc-arc.c
+++ b/gas/config/tc-arc.c
@@ -623,11 +623,11 @@ tokenize_arguments (char *str,
bfd_boolean saw_arg = FALSE;
int brk_lvl = 0;
int num_args = 0;
- const char *p;
int i;
size_t len;
const struct arc_reloc_op_tag *r;
expressionS tmpE;
+ char *reloc_name, c;
memset (tok, 0, sizeof (*tok) * ntok);
@@ -685,6 +685,8 @@ tokenize_arguments (char *str,
if (*input_line_pointer != '@')
goto normalsymbol; /* This is not a relocation. */
+ relocationsym:
+
/* A relocation opernad has the following form
@identifier@relocation_type. The identifier is already
in tok! */
@@ -695,37 +697,29 @@ tokenize_arguments (char *str,
}
/* Parse @relocation_type. */
- memset (&tmpE, 0, sizeof (tmpE));
- tmpE.X_op = O_symbol;
- expression (&tmpE);
-
- if (tmpE.X_op != O_symbol)
+ input_line_pointer++;
+ c = get_symbol_name (&reloc_name);
+ len = input_line_pointer - reloc_name;
+ if (len == 0)
{
as_bad (_("No relocation operand"));
goto err;
}
- p = S_GET_NAME (tmpE.X_add_symbol);
- len = strlen (p);
/* Go through known relocation and try to find a match. */
r = &arc_reloc_op[0];
for (i = arc_num_reloc_op - 1; i >= 0; i--, r++)
- if (len == r->length && memcmp (p, r->name, len) == 0)
+ if (len == r->length
+ && memcmp (reloc_name, r->name, len) == 0)
break;
-
if (i < 0)
{
- as_bad (_("Unknown relocation operand: @%s"), p);
- goto err;
- }
- tok->X_md = r->op;
- tok->X_add_number = tmpE.X_add_number;
- if (tmpE.X_add_number && !r->complex_expr)
- {
- as_bad (_("Complex relocation operand."));
+ as_bad (_("Unknown relocation operand: @%s"), reloc_name);
goto err;
}
+ *input_line_pointer = c;
+ SKIP_WHITESPACE_AFTER_NAME ();
/* Extra check for TLS: base. */
if (*input_line_pointer == '@')
{
@@ -733,17 +727,44 @@ tokenize_arguments (char *str,
if (tok->X_op_symbol != NULL
|| tok->X_op != O_symbol)
{
- as_bad (_("Unable to parse this reloc"));
+ as_bad (_("Unable to parse TLS base: %s"),
+ input_line_pointer);
goto err;
}
input_line_pointer++;
char *sym_name;
- char c = get_symbol_name (&sym_name);
+ c = get_symbol_name (&sym_name);
base = symbol_find_or_make (sym_name);
tok->X_op = O_subtract;
tok->X_op_symbol = base;
restore_line_pointer (c);
+ tmpE.X_add_number = 0;
+ }
+ else if ((*input_line_pointer != '+')
+ && (*input_line_pointer != '-'))
+ {
+ tmpE.X_add_number = 0;
}
+ else
+ {
+ /* Parse the constant of a complex relocation expression
+ like @identifier@reloc +/- const. */
+ if (! r->complex_expr)
+ {
+ as_bad (_("@%s is not a complex relocation."), r->name);
+ goto err;
+ }
+ expression (&tmpE);
+ if (tmpE.X_op != O_constant)
+ {
+ as_bad (_("Bad expression: @%s + %s."),
+ r->name, input_line_pointer);
+ goto err;
+ }
+ }
+
+ tok->X_md = r->op;
+ tok->X_add_number = tmpE.X_add_number;
debug_exp (tok);
@@ -763,8 +784,15 @@ tokenize_arguments (char *str,
goto err;
tok->X_op = O_absent;
+ tok->X_md = O_absent;
expression (tok);
+ /* Legacy: There are cases when we have
+ identifier@relocation_type, if it is the case parse the
+ relocation type as well. */
+ if (*input_line_pointer == '@')
+ goto relocationsym;
+
normalsymbol:
debug_exp (tok);
@@ -1234,6 +1262,7 @@ md_apply_fix (fixS *fixP,
fixP->fx_r_type = BFD_RELOC_ARC_PC32;
/* Fall through. */
case BFD_RELOC_ARC_PC32:
+ /* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
break;
default:
if ((int) fixP->fx_r_type < 0)
@@ -1249,8 +1278,48 @@ md_apply_fix (fixS *fixP,
bfd_get_reloc_code_name (fixP->fx_r_type), value,
fixP->fx_offset);
+
+ /* Now check for TLS relocations. */
+ reloc = fixP->fx_r_type;
+ switch (reloc)
+ {
+ case BFD_RELOC_ARC_TLS_DTPOFF:
+ case BFD_RELOC_ARC_TLS_LE_32:
+ fixP->fx_offset = 0;
+ /* Fall through. */
+ case BFD_RELOC_ARC_TLS_GD_GOT:
+ case BFD_RELOC_ARC_TLS_IE_GOT:
+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
+ break;
+
+ case BFD_RELOC_ARC_TLS_GD_LD:
+ gas_assert (!fixP->fx_offset);
+ if (fixP->fx_subsy)
+ fixP->fx_offset
+ = (S_GET_VALUE (fixP->fx_subsy)
+ - fixP->fx_frag->fr_address- fixP->fx_where);
+ fixP->fx_subsy = NULL;
+ /* Fall through. */
+ case BFD_RELOC_ARC_TLS_GD_CALL:
+ /* These two relocs are there just to allow ld to change the tls
+ model for this symbol, by patching the code. The offset -
+ and scale, if any - will be installed by the linker. */
+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
+ break;
+
+ case BFD_RELOC_ARC_TLS_LE_S9:
+ case BFD_RELOC_ARC_TLS_DTPOFF_S9:
+ as_bad (_("TLS_*_S9 relocs are not supported yet"));
+ break;
+
+ default:
+ break;
+ }
+
if (!fixP->fx_done)
- return;
+ {
+ return;
+ }
/* Addjust the value if we have a constant. */
value += fx_offset;
@@ -1269,6 +1338,7 @@ md_apply_fix (fixS *fixP,
case BFD_RELOC_24:
case BFD_RELOC_32:
case BFD_RELOC_64:
+ case BFD_RELOC_ARC_32_PCREL:
md_number_to_chars (fixpos, value, fixP->fx_size);
return;
@@ -1312,50 +1382,6 @@ md_apply_fix (fixS *fixP,
gas_assert (operand);
break;
- case BFD_RELOC_ARC_TLS_DTPOFF:
- case BFD_RELOC_ARC_TLS_LE_32:
- if (fixP->fx_done)
- {
- gas_assert (!fixP->fx_addsy);
- gas_assert (!fixP->fx_subsy);
- md_number_to_chars_midend (fixpos, value, fixP->fx_size);
- return;
- }
- else
- {
- value = fixP->fx_offset;
- fixP->fx_offset = 0;
- }
- /* Fall through. */
- case BFD_RELOC_ARC_TLS_GD_GOT:
- case BFD_RELOC_ARC_TLS_IE_GOT:
- S_SET_THREAD_LOCAL (fixP->fx_addsy);
- md_number_to_chars_midend (fixpos, value, fixP->fx_size);
- return;
-
- case BFD_RELOC_ARC_TLS_GD_LD:
- gas_assert (!fixP->fx_offset);
- if (fixP->fx_subsy)
- fixP->fx_offset
- = (S_GET_VALUE (fixP->fx_subsy)
- - fixP->fx_frag->fr_address- fixP->fx_where);
- fixP->fx_subsy = NULL;
- /* Fall through. */
- case BFD_RELOC_ARC_TLS_GD_CALL:
- /* These two relocs are there just to allow ld to change the tls
- model for this symbol, by patching the code. */
- /* Fall through. */
- /* The offset - and scale, if any - will be installed by the
- linker. */
- gas_assert (!fixP->fx_done);
- S_SET_THREAD_LOCAL (fixP->fx_addsy);
- return;
-
- case BFD_RELOC_ARC_TLS_LE_S9:
- case BFD_RELOC_ARC_TLS_DTPOFF_S9:
- as_bad (_("TLS_*_S9 relocs are not supported yet"));
- break;
-
default:
{
if ((int) fixP->fx_r_type >= 0)
@@ -3046,7 +3072,7 @@ arc_check_reloc (expressionS *exp,
&& exp->X_op == O_subtract
&& exp->X_op_symbol != NULL
&& exp->X_op_symbol->bsym->section == now_seg)
- *r_type_p = BFD_RELOC_ARC_PC32;
+ *r_type_p = BFD_RELOC_ARC_32_PCREL;
}
--
1.7.0.4