|
|
|
@ -91,122 +91,122 @@ 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 },
|
|
|
|
|
{
|
|
|
|
|
/* Make sure that .word is 32 bits. */
|
|
|
|
|
{ "word", cons, 4 },
|
|
|
|
|
|
|
|
|
|
{ "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */
|
|
|
|
|
{ "lcomm", arc_lcomm, 0 },
|
|
|
|
|
{ "lcommon", arc_lcomm, 0 },
|
|
|
|
|
{ "cpu", arc_option, 0 },
|
|
|
|
|
{ "align", s_align_bytes, 0 }, /* Defaulting is invalid (0). */
|
|
|
|
|
{ "lcomm", arc_lcomm, 0 },
|
|
|
|
|
{ "lcommon", arc_lcomm, 0 },
|
|
|
|
|
{ "cpu", arc_option, 0 },
|
|
|
|
|
|
|
|
|
|
{ "tls_gd_ld", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_LD },
|
|
|
|
|
{ "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL },
|
|
|
|
|
{ "tls_gd_ld", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_LD },
|
|
|
|
|
{ "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL },
|
|
|
|
|
|
|
|
|
|
{ NULL, NULL, 0 }
|
|
|
|
|
};
|
|
|
|
|
{ NULL, NULL, 0 }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const char *md_shortopts = "";
|
|
|
|
|
|
|
|
|
|
enum options
|
|
|
|
|
{
|
|
|
|
|
OPTION_EB = OPTION_MD_BASE,
|
|
|
|
|
OPTION_EL,
|
|
|
|
|
{
|
|
|
|
|
OPTION_EB = OPTION_MD_BASE,
|
|
|
|
|
OPTION_EL,
|
|
|
|
|
|
|
|
|
|
OPTION_ARC600,
|
|
|
|
|
OPTION_ARC601,
|
|
|
|
|
OPTION_ARC700,
|
|
|
|
|
OPTION_ARCEM,
|
|
|
|
|
OPTION_ARCHS,
|
|
|
|
|
OPTION_ARC600,
|
|
|
|
|
OPTION_ARC601,
|
|
|
|
|
OPTION_ARC700,
|
|
|
|
|
OPTION_ARCEM,
|
|
|
|
|
OPTION_ARCHS,
|
|
|
|
|
|
|
|
|
|
OPTION_MCPU,
|
|
|
|
|
OPTION_CD,
|
|
|
|
|
OPTION_MCPU,
|
|
|
|
|
OPTION_CD,
|
|
|
|
|
|
|
|
|
|
/* The following options are deprecated and provided here only for
|
|
|
|
|
compatibility reasons. */
|
|
|
|
|
OPTION_USER_MODE,
|
|
|
|
|
OPTION_LD_EXT_MASK,
|
|
|
|
|
OPTION_SWAP,
|
|
|
|
|
OPTION_NORM,
|
|
|
|
|
OPTION_BARREL_SHIFT,
|
|
|
|
|
OPTION_MIN_MAX,
|
|
|
|
|
OPTION_NO_MPY,
|
|
|
|
|
OPTION_EA,
|
|
|
|
|
OPTION_MUL64,
|
|
|
|
|
OPTION_SIMD,
|
|
|
|
|
OPTION_SPFP,
|
|
|
|
|
OPTION_DPFP,
|
|
|
|
|
OPTION_XMAC_D16,
|
|
|
|
|
OPTION_XMAC_24,
|
|
|
|
|
OPTION_DSP_PACKA,
|
|
|
|
|
OPTION_CRC,
|
|
|
|
|
OPTION_DVBF,
|
|
|
|
|
OPTION_TELEPHONY,
|
|
|
|
|
OPTION_XYMEMORY,
|
|
|
|
|
OPTION_LOCK,
|
|
|
|
|
OPTION_SWAPE,
|
|
|
|
|
OPTION_RTSC,
|
|
|
|
|
OPTION_FPUDA
|
|
|
|
|
};
|
|
|
|
|
/* The following options are deprecated and provided here only for
|
|
|
|
|
compatibility reasons. */
|
|
|
|
|
OPTION_USER_MODE,
|
|
|
|
|
OPTION_LD_EXT_MASK,
|
|
|
|
|
OPTION_SWAP,
|
|
|
|
|
OPTION_NORM,
|
|
|
|
|
OPTION_BARREL_SHIFT,
|
|
|
|
|
OPTION_MIN_MAX,
|
|
|
|
|
OPTION_NO_MPY,
|
|
|
|
|
OPTION_EA,
|
|
|
|
|
OPTION_MUL64,
|
|
|
|
|
OPTION_SIMD,
|
|
|
|
|
OPTION_SPFP,
|
|
|
|
|
OPTION_DPFP,
|
|
|
|
|
OPTION_XMAC_D16,
|
|
|
|
|
OPTION_XMAC_24,
|
|
|
|
|
OPTION_DSP_PACKA,
|
|
|
|
|
OPTION_CRC,
|
|
|
|
|
OPTION_DVBF,
|
|
|
|
|
OPTION_TELEPHONY,
|
|
|
|
|
OPTION_XYMEMORY,
|
|
|
|
|
OPTION_LOCK,
|
|
|
|
|
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 },
|
|
|
|
|
{ "mA6", no_argument, NULL, OPTION_ARC600 },
|
|
|
|
|
{ "mARC600", no_argument, NULL, OPTION_ARC600 },
|
|
|
|
|
{ "mARC601", no_argument, NULL, OPTION_ARC601 },
|
|
|
|
|
{ "mARC700", no_argument, NULL, OPTION_ARC700 },
|
|
|
|
|
{ "mA7", no_argument, NULL, OPTION_ARC700 },
|
|
|
|
|
{ "mEM", no_argument, NULL, OPTION_ARCEM },
|
|
|
|
|
{ "mHS", no_argument, NULL, OPTION_ARCHS },
|
|
|
|
|
{ "mcode-density", no_argument, NULL, OPTION_CD },
|
|
|
|
|
{
|
|
|
|
|
{ "EB", no_argument, NULL, OPTION_EB },
|
|
|
|
|
{ "EL", no_argument, NULL, OPTION_EL },
|
|
|
|
|
{ "mcpu", required_argument, NULL, OPTION_MCPU },
|
|
|
|
|
{ "mA6", no_argument, NULL, OPTION_ARC600 },
|
|
|
|
|
{ "mARC600", no_argument, NULL, OPTION_ARC600 },
|
|
|
|
|
{ "mARC601", no_argument, NULL, OPTION_ARC601 },
|
|
|
|
|
{ "mARC700", no_argument, NULL, OPTION_ARC700 },
|
|
|
|
|
{ "mA7", no_argument, NULL, OPTION_ARC700 },
|
|
|
|
|
{ "mEM", no_argument, NULL, OPTION_ARCEM },
|
|
|
|
|
{ "mHS", no_argument, NULL, OPTION_ARCHS },
|
|
|
|
|
{ "mcode-density", no_argument, NULL, OPTION_CD },
|
|
|
|
|
|
|
|
|
|
/* The following options are deprecated and provided here only for
|
|
|
|
|
compatibility reasons. */
|
|
|
|
|
{ "mav2em", no_argument, NULL, OPTION_ARCEM },
|
|
|
|
|
{ "mav2hs", no_argument, NULL, OPTION_ARCHS },
|
|
|
|
|
{ "muser-mode-only", no_argument, NULL, OPTION_USER_MODE },
|
|
|
|
|
{ "mld-extension-reg-mask", required_argument, NULL, OPTION_LD_EXT_MASK },
|
|
|
|
|
{ "mswap", no_argument, NULL, OPTION_SWAP },
|
|
|
|
|
{ "mnorm", no_argument, NULL, OPTION_NORM },
|
|
|
|
|
{ "mbarrel-shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
|
|
|
|
|
{ "mbarrel_shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
|
|
|
|
|
{ "mmin-max", no_argument, NULL, OPTION_MIN_MAX },
|
|
|
|
|
{ "mmin_max", no_argument, NULL, OPTION_MIN_MAX },
|
|
|
|
|
{ "mno-mpy", no_argument, NULL, OPTION_NO_MPY },
|
|
|
|
|
{ "mea", no_argument, NULL, OPTION_EA },
|
|
|
|
|
{ "mEA", no_argument, NULL, OPTION_EA },
|
|
|
|
|
{ "mmul64", no_argument, NULL, OPTION_MUL64 },
|
|
|
|
|
{ "msimd", no_argument, NULL, OPTION_SIMD},
|
|
|
|
|
{ "mspfp", no_argument, NULL, OPTION_SPFP},
|
|
|
|
|
{ "mspfp-compact", no_argument, NULL, OPTION_SPFP},
|
|
|
|
|
{ "mspfp_compact", no_argument, NULL, OPTION_SPFP},
|
|
|
|
|
{ "mspfp-fast", no_argument, NULL, OPTION_SPFP},
|
|
|
|
|
{ "mspfp_fast", no_argument, NULL, OPTION_SPFP},
|
|
|
|
|
{ "mdpfp", no_argument, NULL, OPTION_DPFP},
|
|
|
|
|
{ "mdpfp-compact", no_argument, NULL, OPTION_DPFP},
|
|
|
|
|
{ "mdpfp_compact", no_argument, NULL, OPTION_DPFP},
|
|
|
|
|
{ "mdpfp-fast", no_argument, NULL, OPTION_DPFP},
|
|
|
|
|
{ "mdpfp_fast", no_argument, NULL, OPTION_DPFP},
|
|
|
|
|
{ "mmac-d16", no_argument, NULL, OPTION_XMAC_D16},
|
|
|
|
|
{ "mmac_d16", no_argument, NULL, OPTION_XMAC_D16},
|
|
|
|
|
{ "mmac-24", no_argument, NULL, OPTION_XMAC_24},
|
|
|
|
|
{ "mmac_24", no_argument, NULL, OPTION_XMAC_24},
|
|
|
|
|
{ "mdsp-packa", no_argument, NULL, OPTION_DSP_PACKA},
|
|
|
|
|
{ "mdsp_packa", no_argument, NULL, OPTION_DSP_PACKA},
|
|
|
|
|
{ "mcrc", no_argument, NULL, OPTION_CRC},
|
|
|
|
|
{ "mdvbf", no_argument, NULL, OPTION_DVBF},
|
|
|
|
|
{ "mtelephony", no_argument, NULL, OPTION_TELEPHONY},
|
|
|
|
|
{ "mxy", no_argument, NULL, OPTION_XYMEMORY},
|
|
|
|
|
{ "mlock", no_argument, NULL, OPTION_LOCK},
|
|
|
|
|
{ "mswape", no_argument, NULL, OPTION_SWAPE},
|
|
|
|
|
{ "mrtsc", no_argument, NULL, OPTION_RTSC},
|
|
|
|
|
{ "mfpuda", no_argument, NULL, OPTION_FPUDA},
|
|
|
|
|
/* The following options are deprecated and provided here only for
|
|
|
|
|
compatibility reasons. */
|
|
|
|
|
{ "mav2em", no_argument, NULL, OPTION_ARCEM },
|
|
|
|
|
{ "mav2hs", no_argument, NULL, OPTION_ARCHS },
|
|
|
|
|
{ "muser-mode-only", no_argument, NULL, OPTION_USER_MODE },
|
|
|
|
|
{ "mld-extension-reg-mask", required_argument, NULL, OPTION_LD_EXT_MASK },
|
|
|
|
|
{ "mswap", no_argument, NULL, OPTION_SWAP },
|
|
|
|
|
{ "mnorm", no_argument, NULL, OPTION_NORM },
|
|
|
|
|
{ "mbarrel-shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
|
|
|
|
|
{ "mbarrel_shifter", no_argument, NULL, OPTION_BARREL_SHIFT },
|
|
|
|
|
{ "mmin-max", no_argument, NULL, OPTION_MIN_MAX },
|
|
|
|
|
{ "mmin_max", no_argument, NULL, OPTION_MIN_MAX },
|
|
|
|
|
{ "mno-mpy", no_argument, NULL, OPTION_NO_MPY },
|
|
|
|
|
{ "mea", no_argument, NULL, OPTION_EA },
|
|
|
|
|
{ "mEA", no_argument, NULL, OPTION_EA },
|
|
|
|
|
{ "mmul64", no_argument, NULL, OPTION_MUL64 },
|
|
|
|
|
{ "msimd", no_argument, NULL, OPTION_SIMD},
|
|
|
|
|
{ "mspfp", no_argument, NULL, OPTION_SPFP},
|
|
|
|
|
{ "mspfp-compact", no_argument, NULL, OPTION_SPFP},
|
|
|
|
|
{ "mspfp_compact", no_argument, NULL, OPTION_SPFP},
|
|
|
|
|
{ "mspfp-fast", no_argument, NULL, OPTION_SPFP},
|
|
|
|
|
{ "mspfp_fast", no_argument, NULL, OPTION_SPFP},
|
|
|
|
|
{ "mdpfp", no_argument, NULL, OPTION_DPFP},
|
|
|
|
|
{ "mdpfp-compact", no_argument, NULL, OPTION_DPFP},
|
|
|
|
|
{ "mdpfp_compact", no_argument, NULL, OPTION_DPFP},
|
|
|
|
|
{ "mdpfp-fast", no_argument, NULL, OPTION_DPFP},
|
|
|
|
|
{ "mdpfp_fast", no_argument, NULL, OPTION_DPFP},
|
|
|
|
|
{ "mmac-d16", no_argument, NULL, OPTION_XMAC_D16},
|
|
|
|
|
{ "mmac_d16", no_argument, NULL, OPTION_XMAC_D16},
|
|
|
|
|
{ "mmac-24", no_argument, NULL, OPTION_XMAC_24},
|
|
|
|
|
{ "mmac_24", no_argument, NULL, OPTION_XMAC_24},
|
|
|
|
|
{ "mdsp-packa", no_argument, NULL, OPTION_DSP_PACKA},
|
|
|
|
|
{ "mdsp_packa", no_argument, NULL, OPTION_DSP_PACKA},
|
|
|
|
|
{ "mcrc", no_argument, NULL, OPTION_CRC},
|
|
|
|
|
{ "mdvbf", no_argument, NULL, OPTION_DVBF},
|
|
|
|
|
{ "mtelephony", no_argument, NULL, OPTION_TELEPHONY},
|
|
|
|
|
{ "mxy", no_argument, NULL, OPTION_XYMEMORY},
|
|
|
|
|
{ "mlock", no_argument, NULL, OPTION_LOCK},
|
|
|
|
|
{ "mswape", no_argument, NULL, OPTION_SWAPE},
|
|
|
|
|
{ "mrtsc", no_argument, NULL, OPTION_RTSC},
|
|
|
|
|
{ "mfpuda", no_argument, NULL, OPTION_FPUDA},
|
|
|
|
|
|
|
|
|
|
{ NULL, no_argument, NULL, 0 }
|
|
|
|
|
};
|
|
|
|
|
{ NULL, no_argument, NULL, 0 }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
size_t md_longopts_size = sizeof (md_longopts);
|
|
|
|
|
|
|
|
|
@ -354,19 +354,19 @@ 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),
|
|
|
|
|
DEF (sda, DUMMY_RELOC_ARC_ENTRY, 1),
|
|
|
|
|
DEF (pcl, BFD_RELOC_ARC_PC32, 1),
|
|
|
|
|
DEF (tlsgd, BFD_RELOC_ARC_TLS_GD_GOT, 0),
|
|
|
|
|
DEF (tlsie, BFD_RELOC_ARC_TLS_IE_GOT, 0),
|
|
|
|
|
DEF (tpoff9, BFD_RELOC_ARC_TLS_LE_S9, 0),
|
|
|
|
|
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),
|
|
|
|
|
};
|
|
|
|
|
{
|
|
|
|
|
DEF (gotoff, BFD_RELOC_ARC_GOTOFF, 1),
|
|
|
|
|
DEF (gotpc, BFD_RELOC_ARC_GOTPC32, 0),
|
|
|
|
|
DEF (plt, BFD_RELOC_ARC_PLT32, 0),
|
|
|
|
|
DEF (sda, DUMMY_RELOC_ARC_ENTRY, 1),
|
|
|
|
|
DEF (pcl, BFD_RELOC_ARC_PC32, 1),
|
|
|
|
|
DEF (tlsgd, BFD_RELOC_ARC_TLS_GD_GOT, 0),
|
|
|
|
|
DEF (tlsie, BFD_RELOC_ARC_TLS_IE_GOT, 0),
|
|
|
|
|
DEF (tpoff9, BFD_RELOC_ARC_TLS_LE_S9, 0),
|
|
|
|
|
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;
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|