Fix errors in the gas testsuite for the ARC target.

bfd	* reloc.c (BFD_RELOC_ARC_32_PCREL): New entry.
	(ARC_TLS_DTPOFF): Arrange it in order.
	* elf32-arc.c (arc_elf_howto_ini): Update formula.
	(get_middle_endian_relocation): New function.
	(PDATA): Define.
	* bfd-in2.h: Regenerate.
	* libbfd.h: Likewise.

elf	* arc-reloc.def (ARC_32_PCREL): New definition.

gas	* 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.
This commit is contained in:
Cupertino Miranda 2015-10-28 13:48:00 +00:00 committed by Nick Clifton
parent 7963511fbf
commit 6f4b1afcdc
9 changed files with 266 additions and 193 deletions

View File

@ -1,3 +1,12 @@
2015-10-28 Cupertino Miranda <cmiranda@synopsys.com>
* reloc.c (BFD_RELOC_ARC_32_PCREL): New entry.
* elf32-arc.c (arc_elf_howto_ini): Update formula.
(get_middle_endian_relocation): New function.
(PDATA): Define.
* bfd-in2.h: Regenerate.
* libbfd.h: Likewise.
2015-10-28 Alan Modra <amodra@gmail.com>
PR ld/19162

View File

@ -3684,6 +3684,7 @@ pc-relative or some form of GOT-indirect relocation. */
BFD_RELOC_ARC_SECTOFF_1,
BFD_RELOC_ARC_SECTOFF_2,
BFD_RELOC_ARC_SDA16_ST2,
BFD_RELOC_ARC_32_PCREL,
BFD_RELOC_ARC_PC32,
BFD_RELOC_ARC_GOT32,
BFD_RELOC_ARC_GOTPC32,

View File

@ -229,7 +229,8 @@ static struct reloc_howto_struct elf_arc_howto_table[] =
static void arc_elf_howto_init (void)
{
#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
elf_arc_howto_table[TYPE].pc_relative = (strstr (#FORMULA, " P ") != NULL);
elf_arc_howto_table[TYPE].pc_relative = \
(strstr (#FORMULA, " P ") != NULL || strstr (#FORMULA, " PDATA ") != NULL);
#include "elf/arc-reloc.def"
}
@ -473,6 +474,17 @@ debug_arc_reloc (struct arc_relocation_data reloc_data)
fprintf (stderr, " input section is NULL\n");
}
static ATTRIBUTE_UNUSED bfd_vma
get_middle_endian_relocation (bfd_vma reloc)
{
bfd_vma ret =
((reloc & 0xffff0000) >> 16) |
((reloc & 0xffff) << 16);
return ret;
}
#define ME(RELOC) (get_middle_endian_reloction(RELOC))
#define S (reloc_data.sym_value \
+ reloc_data.sym_section->output_offset \
+ reloc_data.sym_section->output_section->vma)
@ -491,6 +503,11 @@ debug_arc_reloc (struct arc_relocation_data reloc_data)
+ reloc_data.input_section->output_offset \
+ (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0)) \
) & ~0x3)
#define PDATA ( \
(reloc_data.input_section->output_section->vma \
+ reloc_data.input_section->output_offset \
+ (reloc_data.reloc_offset) \
) & ~0x3)
#define SECTSTAR (reloc_data.input_section->output_offset)
#define SECTSTART (reloc_data.input_section->output_offset)
#define _SDA_BASE_ (reloc_data.sdata_begin_symbol_vma)

View File

@ -1707,6 +1707,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_ARC_SECTOFF_1",
"BFD_RELOC_ARC_SECTOFF_2",
"BFD_RELOC_ARC_SDA16_ST2",
"BFD_RELOC_ARC_32_PCREL",
"BFD_RELOC_ARC_PC32",
"BFD_RELOC_ARC_GOT32",
"BFD_RELOC_ARC_GOTPC32",

View File

@ -3602,6 +3602,8 @@ ENUMX
BFD_RELOC_ARC_SECTOFF_2
ENUMX
BFD_RELOC_ARC_SDA16_ST2
ENUMX
BFD_RELOC_ARC_32_PCREL
ENUMX
BFD_RELOC_ARC_PC32
ENUMX

View File

@ -1,3 +1,11 @@
2015-10-28 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.
2015-10-27 Jim Wilson <jim.wilson@linaro.org>
* config/tc-arm.c (selected_cpu_name): Increase length of array to

View File

@ -91,7 +91,7 @@ static void arc_option (int);
static void arc_extra_reloc (int);
const pseudo_typeS md_pseudo_table[] =
{
{
/* Make sure that .word is 32 bits. */
{ "word", cons, 4 },
@ -104,12 +104,12 @@ const pseudo_typeS md_pseudo_table[] =
{ "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL },
{ NULL, NULL, 0 }
};
};
const char *md_shortopts = "";
enum options
{
{
OPTION_EB = OPTION_MD_BASE,
OPTION_EL,
@ -147,10 +147,10 @@ enum options
OPTION_SWAPE,
OPTION_RTSC,
OPTION_FPUDA
};
};
struct option md_longopts[] =
{
{
{ "EB", no_argument, NULL, OPTION_EB },
{ "EL", no_argument, NULL, OPTION_EL },
{ "mcpu", required_argument, NULL, OPTION_MCPU },
@ -206,7 +206,7 @@ struct option md_longopts[] =
{ "mfpuda", no_argument, NULL, OPTION_FPUDA},
{ NULL, no_argument, NULL, 0 }
};
};
size_t md_longopts_size = sizeof (md_longopts);
@ -354,7 +354,7 @@ static const struct arc_reloc_op_tag
unsigned int complex_expr : 1;
}
arc_reloc_op[] =
{
{
DEF (gotoff, BFD_RELOC_ARC_GOTOFF, 1),
DEF (gotpc, BFD_RELOC_ARC_GOTPC32, 0),
DEF (plt, BFD_RELOC_ARC_PLT32, 0),
@ -366,7 +366,7 @@ static const struct arc_reloc_op_tag
DEF (tpoff, BFD_RELOC_ARC_TLS_LE_32, 0),
DEF (dtpoff9, BFD_RELOC_ARC_TLS_DTPOFF_S9, 0),
DEF (dtpoff, BFD_RELOC_ARC_TLS_DTPOFF, 0),
};
};
static const int arc_num_reloc_op
= sizeof (arc_reloc_op) / sizeof (*arc_reloc_op);
@ -414,9 +414,7 @@ static const struct arc_opcode *find_special_case_pseudo (const char *,
this function is used for regular 4 byte instructions as well. */
static void
md_number_to_chars_midend (char *buf,
valueT val,
int n)
md_number_to_chars_midend (char *buf, valueT val, int n)
{
if (n == 4)
{
@ -623,11 +621,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 +683,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 +695,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 +725,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 +782,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 +1260,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 +1276,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;
}
/* Addjust the value if we have a constant. */
value += fx_offset;
@ -1269,6 +1336,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 +1380,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 +3070,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;
}

View File

@ -1,3 +1,8 @@
2015-10-28 Cupertino Miranda <cmiranda@synopsys.com>
* arc-reloc.def (ARC_32_PCREL): New definition.
(ARC_TLS_DTPOFF): Arrange it in order.
2015-10-27 Stephen Fisher <sfisher@panix.com>
* common.h (NT_NETBSD_MARCH): Define.

View File

@ -1,4 +1,3 @@
ARC_RELOC_HOWTO(ARC_NONE, 0, \
2, \
32, \
@ -286,6 +285,13 @@ ARC_RELOC_HOWTO(ARC_SDA16_ST2, 48, \
signed, \
( ( ( S + A ) - _SDA_BASE_ ) >> 2 ))
ARC_RELOC_HOWTO(ARC_32_PCREL, 49, \
2, \
32, \
replace_word32, \
signed, \
( ( S + A ) - PDATA ))
ARC_RELOC_HOWTO(ARC_PC32, 50, \
2, \
32, \
@ -377,13 +383,6 @@ ARC_RELOC_HOWTO(ARC_TLS_DTPMOD, 66, \
dont, \
0)
ARC_RELOC_HOWTO(ARC_TLS_DTPOFF, 67, \
2, \
32, \
replace_word32, \
dont, \
0)
ARC_RELOC_HOWTO(ARC_TLS_TPOFF, 68, \
2, \
32, \
@ -419,6 +418,13 @@ ARC_RELOC_HOWTO(ARC_TLS_IE_GOT, 72, \
dont, \
0)
ARC_RELOC_HOWTO(ARC_TLS_DTPOFF, 67, \
2, \
32, \
replace_word32, \
dont, \
0)
ARC_RELOC_HOWTO(ARC_TLS_DTPOFF_S9, 73, \
2, \
32, \