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> 2015-10-28 Alan Modra <amodra@gmail.com>
PR ld/19162 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_1,
BFD_RELOC_ARC_SECTOFF_2, BFD_RELOC_ARC_SECTOFF_2,
BFD_RELOC_ARC_SDA16_ST2, BFD_RELOC_ARC_SDA16_ST2,
BFD_RELOC_ARC_32_PCREL,
BFD_RELOC_ARC_PC32, BFD_RELOC_ARC_PC32,
BFD_RELOC_ARC_GOT32, BFD_RELOC_ARC_GOT32,
BFD_RELOC_ARC_GOTPC32, 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) static void arc_elf_howto_init (void)
{ {
#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \ #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" #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"); 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 \ #define S (reloc_data.sym_value \
+ reloc_data.sym_section->output_offset \ + reloc_data.sym_section->output_offset \
+ reloc_data.sym_section->output_section->vma) + 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.input_section->output_offset \
+ (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0)) \ + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0)) \
) & ~0x3) ) & ~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 SECTSTAR (reloc_data.input_section->output_offset)
#define SECTSTART (reloc_data.input_section->output_offset) #define SECTSTART (reloc_data.input_section->output_offset)
#define _SDA_BASE_ (reloc_data.sdata_begin_symbol_vma) #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_1",
"BFD_RELOC_ARC_SECTOFF_2", "BFD_RELOC_ARC_SECTOFF_2",
"BFD_RELOC_ARC_SDA16_ST2", "BFD_RELOC_ARC_SDA16_ST2",
"BFD_RELOC_ARC_32_PCREL",
"BFD_RELOC_ARC_PC32", "BFD_RELOC_ARC_PC32",
"BFD_RELOC_ARC_GOT32", "BFD_RELOC_ARC_GOT32",
"BFD_RELOC_ARC_GOTPC32", "BFD_RELOC_ARC_GOTPC32",

View File

@ -3602,6 +3602,8 @@ ENUMX
BFD_RELOC_ARC_SECTOFF_2 BFD_RELOC_ARC_SECTOFF_2
ENUMX ENUMX
BFD_RELOC_ARC_SDA16_ST2 BFD_RELOC_ARC_SDA16_ST2
ENUMX
BFD_RELOC_ARC_32_PCREL
ENUMX ENUMX
BFD_RELOC_ARC_PC32 BFD_RELOC_ARC_PC32
ENUMX 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> 2015-10-27 Jim Wilson <jim.wilson@linaro.org>
* config/tc-arm.c (selected_cpu_name): Increase length of array to * 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); static void arc_extra_reloc (int);
const pseudo_typeS md_pseudo_table[] = const pseudo_typeS md_pseudo_table[] =
{ {
/* Make sure that .word is 32 bits. */ /* Make sure that .word is 32 bits. */
{ "word", cons, 4 }, { "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 }, { "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL },
{ NULL, NULL, 0 } { NULL, NULL, 0 }
}; };
const char *md_shortopts = ""; const char *md_shortopts = "";
enum options enum options
{ {
OPTION_EB = OPTION_MD_BASE, OPTION_EB = OPTION_MD_BASE,
OPTION_EL, OPTION_EL,
@ -147,10 +147,10 @@ enum options
OPTION_SWAPE, OPTION_SWAPE,
OPTION_RTSC, OPTION_RTSC,
OPTION_FPUDA OPTION_FPUDA
}; };
struct option md_longopts[] = struct option md_longopts[] =
{ {
{ "EB", no_argument, NULL, OPTION_EB }, { "EB", no_argument, NULL, OPTION_EB },
{ "EL", no_argument, NULL, OPTION_EL }, { "EL", no_argument, NULL, OPTION_EL },
{ "mcpu", required_argument, NULL, OPTION_MCPU }, { "mcpu", required_argument, NULL, OPTION_MCPU },
@ -206,7 +206,7 @@ struct option md_longopts[] =
{ "mfpuda", no_argument, NULL, OPTION_FPUDA}, { "mfpuda", no_argument, NULL, OPTION_FPUDA},
{ NULL, no_argument, NULL, 0 } { NULL, no_argument, NULL, 0 }
}; };
size_t md_longopts_size = sizeof (md_longopts); size_t md_longopts_size = sizeof (md_longopts);
@ -354,7 +354,7 @@ static const struct arc_reloc_op_tag
unsigned int complex_expr : 1; unsigned int complex_expr : 1;
} }
arc_reloc_op[] = arc_reloc_op[] =
{ {
DEF (gotoff, BFD_RELOC_ARC_GOTOFF, 1), DEF (gotoff, BFD_RELOC_ARC_GOTOFF, 1),
DEF (gotpc, BFD_RELOC_ARC_GOTPC32, 0), DEF (gotpc, BFD_RELOC_ARC_GOTPC32, 0),
DEF (plt, BFD_RELOC_ARC_PLT32, 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 (tpoff, BFD_RELOC_ARC_TLS_LE_32, 0),
DEF (dtpoff9, BFD_RELOC_ARC_TLS_DTPOFF_S9, 0), DEF (dtpoff9, BFD_RELOC_ARC_TLS_DTPOFF_S9, 0),
DEF (dtpoff, BFD_RELOC_ARC_TLS_DTPOFF, 0), DEF (dtpoff, BFD_RELOC_ARC_TLS_DTPOFF, 0),
}; };
static const int arc_num_reloc_op static const int arc_num_reloc_op
= sizeof (arc_reloc_op) / sizeof (*arc_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. */ this function is used for regular 4 byte instructions as well. */
static void static void
md_number_to_chars_midend (char *buf, md_number_to_chars_midend (char *buf, valueT val, int n)
valueT val,
int n)
{ {
if (n == 4) if (n == 4)
{ {
@ -623,11 +621,11 @@ tokenize_arguments (char *str,
bfd_boolean saw_arg = FALSE; bfd_boolean saw_arg = FALSE;
int brk_lvl = 0; int brk_lvl = 0;
int num_args = 0; int num_args = 0;
const char *p;
int i; int i;
size_t len; size_t len;
const struct arc_reloc_op_tag *r; const struct arc_reloc_op_tag *r;
expressionS tmpE; expressionS tmpE;
char *reloc_name, c;
memset (tok, 0, sizeof (*tok) * ntok); memset (tok, 0, sizeof (*tok) * ntok);
@ -685,6 +683,8 @@ tokenize_arguments (char *str,
if (*input_line_pointer != '@') if (*input_line_pointer != '@')
goto normalsymbol; /* This is not a relocation. */ goto normalsymbol; /* This is not a relocation. */
relocationsym:
/* A relocation opernad has the following form /* A relocation opernad has the following form
@identifier@relocation_type. The identifier is already @identifier@relocation_type. The identifier is already
in tok! */ in tok! */
@ -695,37 +695,29 @@ tokenize_arguments (char *str,
} }
/* Parse @relocation_type. */ /* Parse @relocation_type. */
memset (&tmpE, 0, sizeof (tmpE)); input_line_pointer++;
tmpE.X_op = O_symbol; c = get_symbol_name (&reloc_name);
expression (&tmpE); len = input_line_pointer - reloc_name;
if (len == 0)
if (tmpE.X_op != O_symbol)
{ {
as_bad (_("No relocation operand")); as_bad (_("No relocation operand"));
goto err; goto err;
} }
p = S_GET_NAME (tmpE.X_add_symbol);
len = strlen (p);
/* Go through known relocation and try to find a match. */ /* Go through known relocation and try to find a match. */
r = &arc_reloc_op[0]; r = &arc_reloc_op[0];
for (i = arc_num_reloc_op - 1; i >= 0; i--, r++) 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; break;
if (i < 0) if (i < 0)
{ {
as_bad (_("Unknown relocation operand: @%s"), p); as_bad (_("Unknown relocation operand: @%s"), reloc_name);
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."));
goto err; goto err;
} }
*input_line_pointer = c;
SKIP_WHITESPACE_AFTER_NAME ();
/* Extra check for TLS: base. */ /* Extra check for TLS: base. */
if (*input_line_pointer == '@') if (*input_line_pointer == '@')
{ {
@ -733,17 +725,44 @@ tokenize_arguments (char *str,
if (tok->X_op_symbol != NULL if (tok->X_op_symbol != NULL
|| tok->X_op != O_symbol) || 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; goto err;
} }
input_line_pointer++; input_line_pointer++;
char *sym_name; char *sym_name;
char c = get_symbol_name (&sym_name); c = get_symbol_name (&sym_name);
base = symbol_find_or_make (sym_name); base = symbol_find_or_make (sym_name);
tok->X_op = O_subtract; tok->X_op = O_subtract;
tok->X_op_symbol = base; tok->X_op_symbol = base;
restore_line_pointer (c); 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); debug_exp (tok);
@ -763,8 +782,15 @@ tokenize_arguments (char *str,
goto err; goto err;
tok->X_op = O_absent; tok->X_op = O_absent;
tok->X_md = O_absent;
expression (tok); 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: normalsymbol:
debug_exp (tok); debug_exp (tok);
@ -1234,6 +1260,7 @@ md_apply_fix (fixS *fixP,
fixP->fx_r_type = BFD_RELOC_ARC_PC32; fixP->fx_r_type = BFD_RELOC_ARC_PC32;
/* Fall through. */ /* Fall through. */
case BFD_RELOC_ARC_PC32: case BFD_RELOC_ARC_PC32:
/* fixP->fx_offset += fixP->fx_where - fixP->fx_dot_value; */
break; break;
default: default:
if ((int) fixP->fx_r_type < 0) 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, bfd_get_reloc_code_name (fixP->fx_r_type), value,
fixP->fx_offset); 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) if (!fixP->fx_done)
{
return; return;
}
/* Addjust the value if we have a constant. */ /* Addjust the value if we have a constant. */
value += fx_offset; value += fx_offset;
@ -1269,6 +1336,7 @@ md_apply_fix (fixS *fixP,
case BFD_RELOC_24: case BFD_RELOC_24:
case BFD_RELOC_32: case BFD_RELOC_32:
case BFD_RELOC_64: case BFD_RELOC_64:
case BFD_RELOC_ARC_32_PCREL:
md_number_to_chars (fixpos, value, fixP->fx_size); md_number_to_chars (fixpos, value, fixP->fx_size);
return; return;
@ -1312,50 +1380,6 @@ md_apply_fix (fixS *fixP,
gas_assert (operand); gas_assert (operand);
break; 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: default:
{ {
if ((int) fixP->fx_r_type >= 0) if ((int) fixP->fx_r_type >= 0)
@ -3046,7 +3070,7 @@ arc_check_reloc (expressionS *exp,
&& exp->X_op == O_subtract && exp->X_op == O_subtract
&& exp->X_op_symbol != NULL && exp->X_op_symbol != NULL
&& exp->X_op_symbol->bsym->section == now_seg) && 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> 2015-10-27 Stephen Fisher <sfisher@panix.com>
* common.h (NT_NETBSD_MARCH): Define. * common.h (NT_NETBSD_MARCH): Define.

View File

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