* config/tc-s390.c (s390_elf_cons): Correct fixups for PLT
relocations.
This commit is contained in:
parent
738472a889
commit
198ce79b6b
@ -1,3 +1,8 @@
|
|||||||
|
2001-08-12 Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||||
|
|
||||||
|
* config/tc-s390.c (s390_elf_cons): Correct fixups for PLT
|
||||||
|
relocations.
|
||||||
|
|
||||||
2001-08-12 TAKAI Kousuke <takai@vlsi.kuee.kyoto-u.ac.jp>
|
2001-08-12 TAKAI Kousuke <takai@vlsi.kuee.kyoto-u.ac.jp>
|
||||||
|
|
||||||
* config/tc-sparc.c (cons_fix_new_sparc): Move
|
* config/tc-sparc.c (cons_fix_new_sparc): Move
|
||||||
|
@ -80,7 +80,7 @@ const pseudo_typeS md_pseudo_table[] =
|
|||||||
{
|
{
|
||||||
{ "align", s_align_bytes, 0 },
|
{ "align", s_align_bytes, 0 },
|
||||||
/* Pseudo-ops which must be defined. */
|
/* Pseudo-ops which must be defined. */
|
||||||
{ "bss", s390_bss, 0 },
|
{ "bss", s390_bss, 0 },
|
||||||
{ "insn", s390_insn, 0 },
|
{ "insn", s390_insn, 0 },
|
||||||
/* Pseudo-ops which must be overridden. */
|
/* Pseudo-ops which must be overridden. */
|
||||||
{ "byte", s390_byte, 0 },
|
{ "byte", s390_byte, 0 },
|
||||||
@ -157,21 +157,21 @@ static const struct pd_reg pre_defined_registers[] =
|
|||||||
{ "c9", 9 },
|
{ "c9", 9 },
|
||||||
|
|
||||||
{ "f0", 0 }, /* Floating point registers */
|
{ "f0", 0 }, /* Floating point registers */
|
||||||
{ "f1", 1 },
|
{ "f1", 1 },
|
||||||
{ "f10", 10 },
|
{ "f10", 10 },
|
||||||
{ "f11", 11 },
|
{ "f11", 11 },
|
||||||
{ "f12", 12 },
|
{ "f12", 12 },
|
||||||
{ "f13", 13 },
|
{ "f13", 13 },
|
||||||
{ "f14", 14 },
|
{ "f14", 14 },
|
||||||
{ "f15", 15 },
|
{ "f15", 15 },
|
||||||
{ "f2", 2 },
|
{ "f2", 2 },
|
||||||
{ "f3", 3 },
|
{ "f3", 3 },
|
||||||
{ "f4", 4 },
|
{ "f4", 4 },
|
||||||
{ "f5", 5 },
|
{ "f5", 5 },
|
||||||
{ "f6", 6 },
|
{ "f6", 6 },
|
||||||
{ "f7", 7 },
|
{ "f7", 7 },
|
||||||
{ "f8", 8 },
|
{ "f8", 8 },
|
||||||
{ "f9", 9 },
|
{ "f9", 9 },
|
||||||
|
|
||||||
{ "lit", 13 }, /* Pointer to literal pool */
|
{ "lit", 13 }, /* Pointer to literal pool */
|
||||||
|
|
||||||
@ -265,11 +265,11 @@ register_name (expressionP)
|
|||||||
*input_line_pointer = c;
|
*input_line_pointer = c;
|
||||||
|
|
||||||
/* Look to see if it's in the register table. */
|
/* Look to see if it's in the register table. */
|
||||||
if (reg_number >= 0)
|
if (reg_number >= 0)
|
||||||
{
|
{
|
||||||
expressionP->X_op = O_register;
|
expressionP->X_op = O_register;
|
||||||
expressionP->X_add_number = reg_number;
|
expressionP->X_add_number = reg_number;
|
||||||
|
|
||||||
/* Make the rest nice. */
|
/* Make the rest nice. */
|
||||||
expressionP->X_add_symbol = NULL;
|
expressionP->X_add_symbol = NULL;
|
||||||
expressionP->X_op_symbol = NULL;
|
expressionP->X_op_symbol = NULL;
|
||||||
@ -353,17 +353,17 @@ md_parse_option (c, arg)
|
|||||||
case 'm':
|
case 'm':
|
||||||
if (arg != NULL && strcmp (arg, "regnames") == 0)
|
if (arg != NULL && strcmp (arg, "regnames") == 0)
|
||||||
reg_names_p = true;
|
reg_names_p = true;
|
||||||
|
|
||||||
else if (arg != NULL && strcmp (arg, "no-regnames") == 0)
|
else if (arg != NULL && strcmp (arg, "no-regnames") == 0)
|
||||||
reg_names_p = false;
|
reg_names_p = false;
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
as_bad (_("invalid switch -m%s"), arg);
|
as_bad (_("invalid switch -m%s"), arg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'A':
|
case 'A':
|
||||||
if (arg != NULL && strcmp (arg, "esa") == 0)
|
if (arg != NULL && strcmp (arg, "esa") == 0)
|
||||||
{
|
{
|
||||||
@ -385,16 +385,16 @@ md_parse_option (c, arg)
|
|||||||
case 'V':
|
case 'V':
|
||||||
print_version_id ();
|
print_version_id ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
|
/* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
|
||||||
should be emitted or not. FIXME: Not implemented. */
|
should be emitted or not. FIXME: Not implemented. */
|
||||||
case 'Q':
|
case 'Q':
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,7 +536,7 @@ s390_insert_operand (insn, operand, val, file, line)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
addressT min, max;
|
addressT min, max;
|
||||||
|
|
||||||
max = (((addressT) 1 << (operand->bits - 1))<<1) - 1;
|
max = (((addressT) 1 << (operand->bits - 1))<<1) - 1;
|
||||||
min = (offsetT) 0;
|
min = (offsetT) 0;
|
||||||
uval = (addressT) val;
|
uval = (addressT) val;
|
||||||
@ -549,7 +549,7 @@ s390_insert_operand (insn, operand, val, file, line)
|
|||||||
const char *err =
|
const char *err =
|
||||||
"operand out of range (%s not between %ld and %ld)";
|
"operand out of range (%s not between %ld and %ld)";
|
||||||
char buf[100];
|
char buf[100];
|
||||||
|
|
||||||
if (operand->flags & S390_OPERAND_LENGTH)
|
if (operand->flags & S390_OPERAND_LENGTH)
|
||||||
{
|
{
|
||||||
uval++;
|
uval++;
|
||||||
@ -709,7 +709,7 @@ s390_exp_compare(exp1, exp2)
|
|||||||
return exp1->X_add_number == exp2->X_add_number;
|
return exp1->X_add_number == exp2->X_add_number;
|
||||||
|
|
||||||
case O_big:
|
case O_big:
|
||||||
as_bad (_("Can't handle O_big in s390_exp_compare"));
|
as_bad (_("Can't handle O_big in s390_exp_compare"));
|
||||||
|
|
||||||
case O_symbol: /* X_add_symbol & X_add_number must be equal. */
|
case O_symbol: /* X_add_symbol & X_add_number must be equal. */
|
||||||
case O_symbol_rva:
|
case O_symbol_rva:
|
||||||
@ -763,7 +763,7 @@ s390_lit_suffix (str_p, exp_p, suffix)
|
|||||||
|
|
||||||
if (*str++ != ':')
|
if (*str++ != ':')
|
||||||
return suffix; /* No modification. */
|
return suffix; /* No modification. */
|
||||||
|
|
||||||
/* We look for a suffix of the form "@lit1", "@lit2", "@lit4" or "@lit8". */
|
/* We look for a suffix of the form "@lit1", "@lit2", "@lit4" or "@lit8". */
|
||||||
ident = str;
|
ident = str;
|
||||||
while (isalnum (*str))
|
while (isalnum (*str))
|
||||||
@ -877,7 +877,7 @@ s390_lit_suffix (str_p, exp_p, suffix)
|
|||||||
else
|
else
|
||||||
lpe_list = lpe_list_tail = lpe;
|
lpe_list = lpe_list_tail = lpe;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now change exp_p to the offset into the literal pool.
|
/* Now change exp_p to the offset into the literal pool.
|
||||||
Thats the expression: .L^Ax^By-.L^Ax */
|
Thats the expression: .L^Ax^By-.L^Ax */
|
||||||
exp_p->X_add_symbol = lpe->sym;
|
exp_p->X_add_symbol = lpe->sym;
|
||||||
@ -942,8 +942,10 @@ s390_elf_cons (nbytes)
|
|||||||
reloc_howto->name, nbytes);
|
reloc_howto->name, nbytes);
|
||||||
where = frag_more (nbytes);
|
where = frag_more (nbytes);
|
||||||
md_number_to_chars (where, 0, size);
|
md_number_to_chars (where, 0, size);
|
||||||
fix_new_exp (frag_now, where - frag_now->fr_literal,
|
/* To make fixup_segment do the pc relative conversion the
|
||||||
size, &exp, reloc_howto->pc_relative, reloc);
|
pcrel parameter on the fix_new_exp call needs to be false. */
|
||||||
|
fix_new_exp (frag_now, where - frag_now->fr_literal,
|
||||||
|
size, &exp, false, reloc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
as_bad (_("relocation not applicable"));
|
as_bad (_("relocation not applicable"));
|
||||||
@ -1001,27 +1003,27 @@ md_gather_operands (str, insn, opcode)
|
|||||||
char *hold;
|
char *hold;
|
||||||
|
|
||||||
operand = s390_operands + *opindex_ptr;
|
operand = s390_operands + *opindex_ptr;
|
||||||
|
|
||||||
if (skip_optional && (operand->flags & S390_OPERAND_INDEX))
|
if (skip_optional && (operand->flags & S390_OPERAND_INDEX))
|
||||||
{
|
{
|
||||||
/* We do an early skip. For D(X,B) constructions the index
|
/* We do an early skip. For D(X,B) constructions the index
|
||||||
register is skipped (X is optional). For D(L,B) the base
|
register is skipped (X is optional). For D(L,B) the base
|
||||||
register will be the skipped operand, because L is NOT
|
register will be the skipped operand, because L is NOT
|
||||||
optional. */
|
optional. */
|
||||||
skip_optional = 0;
|
skip_optional = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Gather the operand. */
|
/* Gather the operand. */
|
||||||
hold = input_line_pointer;
|
hold = input_line_pointer;
|
||||||
input_line_pointer = str;
|
input_line_pointer = str;
|
||||||
|
|
||||||
if (! register_name (&ex)) /* parse the operand */
|
if (! register_name (&ex)) /* parse the operand */
|
||||||
expression (&ex);
|
expression (&ex);
|
||||||
|
|
||||||
str = input_line_pointer;
|
str = input_line_pointer;
|
||||||
input_line_pointer = hold;
|
input_line_pointer = hold;
|
||||||
|
|
||||||
/* Write the operand to the insn. */
|
/* Write the operand to the insn. */
|
||||||
if (ex.X_op == O_illegal)
|
if (ex.X_op == O_illegal)
|
||||||
as_bad (_("illegal operand"));
|
as_bad (_("illegal operand"));
|
||||||
@ -1095,7 +1097,7 @@ md_gather_operands (str, insn, opcode)
|
|||||||
fixups[fc].reloc = reloc;
|
fixups[fc].reloc = reloc;
|
||||||
++fc;
|
++fc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the next character. The call to expression has advanced
|
/* Check the next character. The call to expression has advanced
|
||||||
str past any whitespace. */
|
str past any whitespace. */
|
||||||
if (operand->flags & S390_OPERAND_DISP)
|
if (operand->flags & S390_OPERAND_DISP)
|
||||||
@ -1113,7 +1115,7 @@ md_gather_operands (str, insn, opcode)
|
|||||||
/* Ok, skip all operands until S390_OPERAND_BASE. */
|
/* Ok, skip all operands until S390_OPERAND_BASE. */
|
||||||
while (!(operand->flags & S390_OPERAND_BASE))
|
while (!(operand->flags & S390_OPERAND_BASE))
|
||||||
operand = s390_operands + *(++opindex_ptr);
|
operand = s390_operands + *(++opindex_ptr);
|
||||||
|
|
||||||
/* If there is a next operand it must be seperated by a comma. */
|
/* If there is a next operand it must be seperated by a comma. */
|
||||||
if (opindex_ptr[1] != '\0')
|
if (opindex_ptr[1] != '\0')
|
||||||
{
|
{
|
||||||
@ -1208,18 +1210,18 @@ md_gather_operands (str, insn, opcode)
|
|||||||
reloc_howto_type *reloc_howto;
|
reloc_howto_type *reloc_howto;
|
||||||
fixS *fixP;
|
fixS *fixP;
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
|
reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc);
|
||||||
if (!reloc_howto)
|
if (!reloc_howto)
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
size = bfd_get_reloc_size (reloc_howto);
|
size = bfd_get_reloc_size (reloc_howto);
|
||||||
|
|
||||||
if (size < 1 || size > 4)
|
if (size < 1 || size > 4)
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
fixP = fix_new_exp (frag_now,
|
fixP = fix_new_exp (frag_now,
|
||||||
f - frag_now->fr_literal + (operand->shift/8),
|
f - frag_now->fr_literal + (operand->shift/8),
|
||||||
size, &fixups[i].exp, reloc_howto->pc_relative,
|
size, &fixups[i].exp, reloc_howto->pc_relative,
|
||||||
fixups[i].reloc);
|
fixups[i].reloc);
|
||||||
/* Turn off overflow checking in fixup_segment. This is necessary
|
/* Turn off overflow checking in fixup_segment. This is necessary
|
||||||
@ -1344,7 +1346,7 @@ s390_insn (ignore)
|
|||||||
}
|
}
|
||||||
else if (exp.X_op == O_big)
|
else if (exp.X_op == O_big)
|
||||||
{
|
{
|
||||||
if (exp.X_add_number > 0 &&
|
if (exp.X_add_number > 0 &&
|
||||||
opformat->oplen == 6 &&
|
opformat->oplen == 6 &&
|
||||||
generic_bignum[3] == 0)
|
generic_bignum[3] == 0)
|
||||||
{
|
{
|
||||||
@ -1404,7 +1406,7 @@ s390_byte (ignore)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* The .ltorg pseudo-op.This emits all literals defined since the last
|
/* The .ltorg pseudo-op.This emits all literals defined since the last
|
||||||
.ltorg or the invocation of gas. Literals are defined with the
|
.ltorg or the invocation of gas. Literals are defined with the
|
||||||
@lit suffix. */
|
@lit suffix. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1432,7 +1434,7 @@ s390_literals (ignore)
|
|||||||
/* Emit literal pool entry. */
|
/* Emit literal pool entry. */
|
||||||
if (lpe->reloc != BFD_RELOC_UNUSED)
|
if (lpe->reloc != BFD_RELOC_UNUSED)
|
||||||
{
|
{
|
||||||
reloc_howto_type *reloc_howto =
|
reloc_howto_type *reloc_howto =
|
||||||
bfd_reloc_type_lookup (stdoutput, lpe->reloc);
|
bfd_reloc_type_lookup (stdoutput, lpe->reloc);
|
||||||
int size = bfd_get_reloc_size (reloc_howto);
|
int size = bfd_get_reloc_size (reloc_howto);
|
||||||
char *where;
|
char *where;
|
||||||
@ -1509,7 +1511,7 @@ md_atof (type, litp, sizep)
|
|||||||
md_number_to_chars (litp, (valueT) words[i], 2);
|
md_number_to_chars (litp, (valueT) words[i], 2);
|
||||||
litp += 2;
|
litp += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1647,7 +1649,7 @@ md_apply_fix3 (fixp, valuep, seg)
|
|||||||
&& S_GET_SEGMENT (fixp->fx_addsy) != undefined_section
|
&& S_GET_SEGMENT (fixp->fx_addsy) != undefined_section
|
||||||
&& ! bfd_is_com_section (S_GET_SEGMENT (fixp->fx_addsy)))
|
&& ! bfd_is_com_section (S_GET_SEGMENT (fixp->fx_addsy)))
|
||||||
value -= S_GET_VALUE (fixp->fx_addsy);
|
value -= S_GET_VALUE (fixp->fx_addsy);
|
||||||
|
|
||||||
if (fixp->fx_pcrel)
|
if (fixp->fx_pcrel)
|
||||||
value += fixp->fx_frag->fr_address + fixp->fx_where;
|
value += fixp->fx_frag->fr_address + fixp->fx_where;
|
||||||
}
|
}
|
||||||
@ -1658,10 +1660,10 @@ md_apply_fix3 (fixp, valuep, seg)
|
|||||||
{
|
{
|
||||||
const struct s390_operand *operand;
|
const struct s390_operand *operand;
|
||||||
int opindex;
|
int opindex;
|
||||||
|
|
||||||
opindex = (int) fixp->fx_r_type - (int) BFD_RELOC_UNUSED;
|
opindex = (int) fixp->fx_r_type - (int) BFD_RELOC_UNUSED;
|
||||||
operand = &s390_operands[opindex];
|
operand = &s390_operands[opindex];
|
||||||
|
|
||||||
if (fixp->fx_done)
|
if (fixp->fx_done)
|
||||||
{
|
{
|
||||||
/* Insert the fully resolved operand value. */
|
/* Insert the fully resolved operand value. */
|
||||||
@ -1670,7 +1672,7 @@ md_apply_fix3 (fixp, valuep, seg)
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine a BFD reloc value based on the operand information.
|
/* Determine a BFD reloc value based on the operand information.
|
||||||
We are only prepared to turn a few of the operands into
|
We are only prepared to turn a few of the operands into
|
||||||
relocs. */
|
relocs. */
|
||||||
@ -1717,7 +1719,7 @@ md_apply_fix3 (fixp, valuep, seg)
|
|||||||
{
|
{
|
||||||
char *sfile;
|
char *sfile;
|
||||||
unsigned int sline;
|
unsigned int sline;
|
||||||
|
|
||||||
/* Use expr_symbol_where to see if this is an expression
|
/* Use expr_symbol_where to see if this is an expression
|
||||||
symbol. */
|
symbol. */
|
||||||
if (expr_symbol_where (fixp->fx_addsy, &sfile, &sline))
|
if (expr_symbol_where (fixp->fx_addsy, &sfile, &sline))
|
||||||
@ -1749,9 +1751,9 @@ md_apply_fix3 (fixp, valuep, seg)
|
|||||||
mop = bfd_getb16 ((unsigned char *) where);
|
mop = bfd_getb16 ((unsigned char *) where);
|
||||||
mop |= (unsigned short) (value & 0xfff);
|
mop |= (unsigned short) (value & 0xfff);
|
||||||
bfd_putb16 ((bfd_vma) mop, (unsigned char *) where);
|
bfd_putb16 ((bfd_vma) mop, (unsigned char *) where);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BFD_RELOC_16:
|
case BFD_RELOC_16:
|
||||||
case BFD_RELOC_GPREL16:
|
case BFD_RELOC_GPREL16:
|
||||||
case BFD_RELOC_16_GOT_PCREL:
|
case BFD_RELOC_16_GOT_PCREL:
|
||||||
@ -1840,7 +1842,7 @@ md_apply_fix3 (fixp, valuep, seg)
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
const char *reloc_name = bfd_get_reloc_code_name (fixp->fx_r_type);
|
const char *reloc_name = bfd_get_reloc_code_name (fixp->fx_r_type);
|
||||||
|
|
||||||
if (reloc_name != NULL)
|
if (reloc_name != NULL)
|
||||||
fprintf (stderr, "Gas failure, reloc type %s\n", reloc_name);
|
fprintf (stderr, "Gas failure, reloc type %s\n", reloc_name);
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user