* config/tc-cris.c: Update all comments regarding explicit relocations

to, besides PIC, also imply TLS or to say "relocation specifier" or
	similar.
	(RELOC_SUFFIX_CHAR): Rename from PIC_SUFFIX_CHAR.  Change all callers.
	(cris_get_reloc_suffix): Rename from cris_get_pic_suffix.  Change all
	callers.  Also handle TLS relocs.
	(cris_get_specified_reloc_size): Rename from cris_get_pic_reloc_size.
	Change all callers.  Also handle TLS relocs.
	(tls): New constant.
	(cris_process_instruction): Check for non-PIC TLS relocations and
	adjust message when emitting error message about relocation not
	fitting.
	(get_autoinc_prefix_or_indir_op): Also check for relocation suffix
	when tls is true.
	(get_3op_or_dip_prefix_op): Ditto.
	(cris_number_to_imm, tc_gen_reloc): Handle TLS relocs like PIC relocs.
This commit is contained in:
Hans-Peter Nilsson 2008-10-04 17:20:38 +00:00
parent 3926fc5473
commit cc99daad35
2 changed files with 108 additions and 39 deletions

View File

@ -1,3 +1,22 @@
2008-10-04 Hans-Peter Nilsson <hp@axis.com>
* config/tc-cris.c: Update all comments regarding explicit relocations
to, besides PIC, also imply TLS or to say "relocation specifier" or
similar.
(RELOC_SUFFIX_CHAR): Rename from PIC_SUFFIX_CHAR. Change all callers.
(cris_get_reloc_suffix): Rename from cris_get_pic_suffix. Change all
callers. Also handle TLS relocs.
(cris_get_specified_reloc_size): Rename from cris_get_pic_reloc_size.
Change all callers. Also handle TLS relocs.
(tls): New constant.
(cris_process_instruction): Check for non-PIC TLS relocations and
adjust message when emitting error message about relocation not
fitting.
(get_autoinc_prefix_or_indir_op): Also check for relocation suffix
when tls is true.
(get_3op_or_dip_prefix_op): Ditto.
(cris_number_to_imm, tc_gen_reloc): Handle TLS relocs like PIC relocs.
2008-10-03 Kazu Hirata <kazu@codesourcery.com>
* listing.c (buffer_line): Open the source file with FOPEN_RB.

View File

@ -52,7 +52,7 @@
/* Like in ":GOT", ":GOTOFF" etc. Other ports use '@', but that's in
line_separator_chars for CRIS, so we avoid it. */
#define PIC_SUFFIX_CHAR ':'
#define RELOC_SUFFIX_CHAR ':'
/* This might be CRIS_INSN_NONE if we're assembling a prefix-insn only.
Note that some prefix-insns might be assembled as CRIS_INSN_NORMAL. */
@ -150,9 +150,9 @@ static void s_cris_loc (int);
static void s_cris_arch (int);
/* Get ":GOT", ":GOTOFF", ":PLT" etc. suffixes. */
static void cris_get_pic_suffix (char **, bfd_reloc_code_real_type *,
expressionS *);
static unsigned int cris_get_pic_reloc_size (bfd_reloc_code_real_type);
static void cris_get_reloc_suffix (char **, bfd_reloc_code_real_type *,
expressionS *);
static unsigned int cris_get_specified_reloc_size (bfd_reloc_code_real_type);
/* All the .syntax functions. */
static void cris_force_reg_prefix (void);
@ -183,6 +183,9 @@ static bfd_boolean symbols_have_leading_underscore
/* Whether or not we allow PIC, and expand to PIC-friendly constructs. */
static bfd_boolean pic = FALSE;
/* Whether or not we allow TLS suffixes. For the moment, we always do. */
static const bfd_boolean tls = TRUE;
/* If we're configured for "cris", default to allow all v0..v10
instructions and register names. */
#ifndef DEFAULT_CRIS_ARCH
@ -1252,7 +1255,7 @@ md_assemble (char *str)
/* When the expression is unknown for a BDAP, it can need 0, 2 or 4
extra bytes, so we handle it separately. */
case PREFIX_BDAP_IMM:
/* We only do it if the relocation is unspecified, i.e. not a PIC
/* We only do it if the relocation is unspecified, i.e. not a PIC or TLS
relocation. */
if (prefix.reloc == BFD_RELOC_NONE)
{
@ -1269,13 +1272,13 @@ md_assemble (char *str)
md_number_to_chars (opcodep, (long) prefix.opcode, 2);
/* Having a specified reloc only happens for DIP and for BDAP with
PIC operands, but it is ok to drop through here for the other
PIC or TLS operands, but it is ok to drop through here for the other
prefixes as they can have no relocs specified. */
if (prefix.reloc != BFD_RELOC_NONE)
{
unsigned int relocsize
= (prefix.kind == PREFIX_DIP
? 4 : cris_get_pic_reloc_size (prefix.reloc));
? 4 : cris_get_specified_reloc_size (prefix.reloc));
p = frag_more (relocsize);
fix_new_exp (frag_now, (p - frag_now->fr_literal), relocsize,
@ -1889,7 +1892,7 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
whether or not this is autoincrement mode. */
out_insnp->opcode |= (mode << 10);
/* If there was a PIC reloc specifier, then it was
/* If there was a reloc specifier, then it was
attached to the prefix. Note that we can't check
that the reloc size matches, since we don't have
all the operands yet in all cases. */
@ -1903,8 +1906,8 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
case 'N':
case 'Y':
/* Like 's', but immediate operand only. Also does not
modify insn. There are no insns where a PIC reloc
/* Like 's', but immediate operand only. Also do not
modify insn. There are no insns where an explicit reloc
specifier makes sense. */
if (cris_get_expression (&s, &out_insnp->expr))
{
@ -1927,9 +1930,10 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
relocation. */
out_insnp->expr.X_add_number += 6;
if (pic && *s == PIC_SUFFIX_CHAR)
cris_get_pic_suffix (&s, &out_insnp->reloc,
&out_insnp->expr);
/* TLS specifiers do not make sense here. */
if (pic && *s == RELOC_SUFFIX_CHAR)
cris_get_reloc_suffix (&s, &out_insnp->reloc,
&out_insnp->expr);
continue;
}
@ -2194,13 +2198,17 @@ cris_process_instruction (char *insn_text, struct cris_instruction *out_insnp,
}
/* If there was a relocation specified for the immediate
expression (i.e. it had a PIC modifier) check that the
size of the PIC relocation matches the size specified by
expression (i.e. it had a PIC or TLS modifier) check that the
size of the relocation matches the size specified by
the opcode. */
if (out_insnp->reloc != BFD_RELOC_NONE
&& (cris_get_pic_reloc_size (out_insnp->reloc)
&& (cris_get_specified_reloc_size (out_insnp->reloc)
!= (unsigned int) out_insnp->imm_oprnd_size))
as_bad (_("PIC relocation size does not match operand size"));
as_bad (out_insnp->reloc == BFD_RELOC_CRIS_32_GD
|| out_insnp->reloc == BFD_RELOC_CRIS_32_TPREL
|| out_insnp->reloc == BFD_RELOC_CRIS_16_TPREL
? _("TLS relocation size does not match operand size")
: _("PIC relocation size does not match operand size"));
}
else if (instruction->op == cris_muls_op
|| instruction->op == cris_mulu_op)
@ -2715,8 +2723,8 @@ get_autoinc_prefix_or_indir_op (char **cPP, struct cris_prefix *prefixp,
/* We tentatively put an opcode corresponding to
a 32-bit operand here, although it may be
relaxed when there's no PIC specifier for the
operand. */
relaxed when there's no relocation
specifier for the operand. */
prefixp->opcode
= (BDAP_INDIR_OPCODE
| (prefixp->base_reg_number << 12)
@ -2726,18 +2734,18 @@ get_autoinc_prefix_or_indir_op (char **cPP, struct cris_prefix *prefixp,
/* This can have a PIC suffix, specifying reloc
type to use. */
if (pic && **cPP == PIC_SUFFIX_CHAR)
if ((pic || tls) && **cPP == RELOC_SUFFIX_CHAR)
{
unsigned int relocsize;
cris_get_pic_suffix (cPP, &prefixp->reloc,
&prefixp->expr);
cris_get_reloc_suffix (cPP, &prefixp->reloc,
&prefixp->expr);
/* Tweak the size of the immediate operand
in the prefix opcode if it isn't what we
set. */
relocsize
= cris_get_pic_reloc_size (prefixp->reloc);
= cris_get_specified_reloc_size (prefixp->reloc);
if (relocsize != 4)
prefixp->opcode
= ((prefixp->opcode & ~(3 << 4))
@ -2763,8 +2771,9 @@ get_autoinc_prefix_or_indir_op (char **cPP, struct cris_prefix *prefixp,
in the blanks and break out to match the
final ']'.
Note that we don't allow a PIC suffix for an
operand with a minus sign. */
Note that we don't allow a relocation
suffix for an operand with a minus
sign. */
prefixp->kind = PREFIX_BDAP_IMM;
break;
}
@ -2802,8 +2811,8 @@ get_autoinc_prefix_or_indir_op (char **cPP, struct cris_prefix *prefixp,
/* This can have a PIC suffix, specifying reloc type to use. The
caller must check that the reloc size matches the operand size. */
if (pic && **cPP == PIC_SUFFIX_CHAR)
cris_get_pic_suffix (cPP, &prefixp->reloc, imm_exprP);
if ((pic || tls) && **cPP == RELOC_SUFFIX_CHAR)
cris_get_reloc_suffix (cPP, &prefixp->reloc, imm_exprP);
return 1;
}
@ -2971,15 +2980,15 @@ get_3op_or_dip_prefix_op (char **cPP, struct cris_prefix *prefixp)
| REG_PC /* << 0 */);
/* This can have a PIC suffix, specifying reloc type to use. */
if (pic && **cPP == PIC_SUFFIX_CHAR)
if ((pic || tls) && **cPP == RELOC_SUFFIX_CHAR)
{
unsigned int relocsize;
cris_get_pic_suffix (cPP, &prefixp->reloc, &prefixp->expr);
cris_get_reloc_suffix (cPP, &prefixp->reloc, &prefixp->expr);
/* Tweak the size of the immediate operand in the prefix
opcode if it isn't what we set. */
relocsize = cris_get_pic_reloc_size (prefixp->reloc);
relocsize = cris_get_specified_reloc_size (prefixp->reloc);
if (relocsize != 4)
prefixp->opcode
= ((prefixp->opcode & ~(3 << 4))
@ -3426,13 +3435,19 @@ gen_cond_branch_32 (char *opcodep, char *writep, fragS *fragP,
md_number_to_chars (writep + 8, MOVE_PC_INCR_OPCODE_SUFFIX, 2);
}
/* Get the size of an immediate-reloc in bytes. Only valid for PIC
relocs. */
/* Get the size of an immediate-reloc in bytes. Only valid for
specified relocs (TLS, PIC). */
static unsigned int
cris_get_pic_reloc_size (bfd_reloc_code_real_type reloc)
cris_get_specified_reloc_size (bfd_reloc_code_real_type reloc)
{
return reloc == BFD_RELOC_CRIS_16_GOTPLT || reloc == BFD_RELOC_CRIS_16_GOT
return
reloc == BFD_RELOC_CRIS_16_GOTPLT
|| reloc == BFD_RELOC_CRIS_16_GOT
|| reloc == BFD_RELOC_CRIS_16_GOT_GD
|| reloc == BFD_RELOC_CRIS_16_DTPREL
|| reloc == BFD_RELOC_CRIS_16_GOT_TPREL
|| reloc == BFD_RELOC_CRIS_16_TPREL
? 2 : 4;
}
@ -3440,8 +3455,8 @@ cris_get_pic_reloc_size (bfd_reloc_code_real_type reloc)
Adjust *EXPRP with any addend found after the PIC suffix. */
static void
cris_get_pic_suffix (char **cPP, bfd_reloc_code_real_type *relocp,
expressionS *exprP)
cris_get_reloc_suffix (char **cPP, bfd_reloc_code_real_type *relocp,
expressionS *exprP)
{
char *s = *cPP;
unsigned int i;
@ -3452,10 +3467,14 @@ cris_get_pic_suffix (char **cPP, bfd_reloc_code_real_type *relocp,
const char *const suffix;
unsigned int len;
bfd_reloc_code_real_type reloc;
bfd_boolean pic_p;
bfd_boolean tls_p;
} pic_suffixes[] =
{
#undef PICMAP
#define PICMAP(s, r) {s, sizeof (s) - 1, r}
#define PICMAP(s, r) {s, sizeof (s) - 1, r, TRUE, FALSE}
#define PICTLSMAP(s, r) {s, sizeof (s) - 1, r, TRUE, TRUE}
#define TLSMAP(s, r) {s, sizeof (s) - 1, r, FALSE, TRUE}
/* Keep this in order with longest unambiguous prefix first. */
PICMAP ("GOTPLT16", BFD_RELOC_CRIS_16_GOTPLT),
PICMAP ("GOTPLT", BFD_RELOC_CRIS_32_GOTPLT),
@ -3463,7 +3482,16 @@ cris_get_pic_suffix (char **cPP, bfd_reloc_code_real_type *relocp,
PICMAP ("PLT", BFD_RELOC_CRIS_32_PLT_PCREL),
PICMAP ("GOTOFF", BFD_RELOC_CRIS_32_GOTREL),
PICMAP ("GOT16", BFD_RELOC_CRIS_16_GOT),
PICMAP ("GOT", BFD_RELOC_CRIS_32_GOT)
PICMAP ("GOT", BFD_RELOC_CRIS_32_GOT),
PICTLSMAP ("GDGOTREL16", BFD_RELOC_CRIS_16_GOT_GD),
PICTLSMAP ("GDGOTREL", BFD_RELOC_CRIS_32_GOT_GD),
TLSMAP ("GD", BFD_RELOC_CRIS_32_GD),
PICTLSMAP ("DTPREL16", BFD_RELOC_CRIS_16_DTPREL),
PICTLSMAP ("DTPREL", BFD_RELOC_CRIS_32_DTPREL),
PICTLSMAP ("TPOFFGOT16", BFD_RELOC_CRIS_16_GOT_TPREL),
PICTLSMAP ("TPOFFGOT", BFD_RELOC_CRIS_32_GOT_TPREL),
TLSMAP ("TPOFF16", BFD_RELOC_CRIS_16_TPREL),
TLSMAP ("TPOFF", BFD_RELOC_CRIS_32_TPREL)
};
/* We've already seen the ':', so consume it. */
@ -3472,7 +3500,11 @@ cris_get_pic_suffix (char **cPP, bfd_reloc_code_real_type *relocp,
for (i = 0; i < sizeof (pic_suffixes)/sizeof (pic_suffixes[0]); i++)
{
if (strncmp (s, pic_suffixes[i].suffix, pic_suffixes[i].len) == 0
&& ! is_part_of_name (s[pic_suffixes[i].len]))
&& ! is_part_of_name (s[pic_suffixes[i].len])
/* PIC and non-PIC relocations are exclusive. */
&& (pic != 0) == (pic_suffixes[i].pic_p != 0)
/* But TLS can be active for non-TLS relocations too. */
&& (pic_suffixes[i].tls_p == 0 || tls))
{
/* We have a match. Consume the suffix and set the relocation
type. */
@ -3599,6 +3631,15 @@ cris_number_to_imm (char *bufp, long val, int n, fixS *fixP, segT seg)
case BFD_RELOC_CRIS_32_GOTPLT:
case BFD_RELOC_CRIS_32_PLT_GOTREL:
case BFD_RELOC_CRIS_32_PLT_PCREL:
case BFD_RELOC_CRIS_32_GOT_GD:
case BFD_RELOC_CRIS_16_GOT_GD:
case BFD_RELOC_CRIS_32_GD:
case BFD_RELOC_CRIS_32_DTPREL:
case BFD_RELOC_CRIS_16_DTPREL:
case BFD_RELOC_CRIS_32_GOT_TPREL:
case BFD_RELOC_CRIS_16_GOT_TPREL:
case BFD_RELOC_CRIS_32_TPREL:
case BFD_RELOC_CRIS_16_TPREL:
/* We don't want to put in any kind of non-zero bits in the data
being relocated for these. */
break;
@ -3870,6 +3911,15 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
case BFD_RELOC_CRIS_UNSIGNED_8:
case BFD_RELOC_CRIS_UNSIGNED_16:
case BFD_RELOC_CRIS_LAPCQ_OFFSET:
case BFD_RELOC_CRIS_32_GOT_GD:
case BFD_RELOC_CRIS_16_GOT_GD:
case BFD_RELOC_CRIS_32_GD:
case BFD_RELOC_CRIS_32_DTPREL:
case BFD_RELOC_CRIS_16_DTPREL:
case BFD_RELOC_CRIS_32_GOT_TPREL:
case BFD_RELOC_CRIS_16_GOT_TPREL:
case BFD_RELOC_CRIS_32_TPREL:
case BFD_RELOC_CRIS_16_TPREL:
code = fixP->fx_r_type;
break;
default: