(md_apply_fix): Remove bad assert added 2000-09-26.
This commit is contained in:
parent
dc149a6d17
commit
dc1fc56bde
|
@ -1,5 +1,8 @@
|
||||||
2000-10-07 Alan Modra <alan@linuxcare.com.au>
|
2000-10-07 Alan Modra <alan@linuxcare.com.au>
|
||||||
|
|
||||||
|
* config/tc-hppa.c (md_apply_fix): Remove plainly wrong assert.
|
||||||
|
Re-arrange function a little and improve error message.
|
||||||
|
|
||||||
* write.c (write_relocs): Fix a comment.
|
* write.c (write_relocs): Fix a comment.
|
||||||
|
|
||||||
* config/obj-elf.c (elf_frob_symbol): Make section syms global on
|
* config/obj-elf.c (elf_frob_symbol): Make section syms global on
|
||||||
|
|
|
@ -4341,12 +4341,11 @@ md_apply_fix (fixP, valp)
|
||||||
fixS *fixP;
|
fixS *fixP;
|
||||||
valueT *valp;
|
valueT *valp;
|
||||||
{
|
{
|
||||||
char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
|
unsigned char *buf;
|
||||||
struct hppa_fix_struct *hppa_fixP;
|
struct hppa_fix_struct *hppa_fixP;
|
||||||
offsetT new_val;
|
offsetT new_val;
|
||||||
int insn, val;
|
int insn, val, fmt;
|
||||||
|
|
||||||
hppa_fixP = (struct hppa_fix_struct *) fixP->tc_fix_data;
|
|
||||||
/* SOM uses R_HPPA_ENTRY and R_HPPA_EXIT relocations which can
|
/* SOM uses R_HPPA_ENTRY and R_HPPA_EXIT relocations which can
|
||||||
never be "applied" (they are just markers). Likewise for
|
never be "applied" (they are just markers). Likewise for
|
||||||
R_HPPA_BEGIN_BRTAB and R_HPPA_END_BRTAB. */
|
R_HPPA_BEGIN_BRTAB and R_HPPA_END_BRTAB. */
|
||||||
|
@ -4373,187 +4372,185 @@ md_apply_fix (fixP, valp)
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
insn = bfd_get_32 (stdoutput, (unsigned char *) buf);
|
|
||||||
/* There should have been an HPPA specific fixup associated
|
/* There should have been an HPPA specific fixup associated
|
||||||
with the GAS fixup. */
|
with the GAS fixup. */
|
||||||
if (hppa_fixP)
|
hppa_fixP = (struct hppa_fix_struct *) fixP->tc_fix_data;
|
||||||
|
if (hppa_fixP == NULL)
|
||||||
{
|
{
|
||||||
int fmt = bfd_hppa_insn2fmt (stdoutput, insn);
|
printf (_("no hppa_fixup entry for fixup type 0x%x at %s:%d"),
|
||||||
|
fixP->fx_r_type, fixP->fx_file, fixP->fx_line);
|
||||||
assert (fmt == hppa_fixP->fx_r_format);
|
|
||||||
|
|
||||||
/* If there is a symbol associated with this fixup, then it's something
|
|
||||||
which will need a SOM relocation (except for some PC-relative relocs).
|
|
||||||
In such cases we should treat the "val" or "addend" as zero since it
|
|
||||||
will be added in as needed from fx_offset in tc_gen_reloc. */
|
|
||||||
if ((fixP->fx_addsy != NULL
|
|
||||||
|| fixP->fx_r_type == (int) R_HPPA_NONE)
|
|
||||||
#ifdef OBJ_SOM
|
|
||||||
&& fmt != 32
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0);
|
|
||||||
#ifdef OBJ_SOM
|
|
||||||
/* These field selectors imply that we do not want an addend. */
|
|
||||||
else if (hppa_fixP->fx_r_field == e_psel
|
|
||||||
|| hppa_fixP->fx_r_field == e_rpsel
|
|
||||||
|| hppa_fixP->fx_r_field == e_lpsel
|
|
||||||
|| hppa_fixP->fx_r_field == e_tsel
|
|
||||||
|| hppa_fixP->fx_r_field == e_rtsel
|
|
||||||
|| hppa_fixP->fx_r_field == e_ltsel)
|
|
||||||
new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0);
|
|
||||||
/* This is truely disgusting. The machine independent code blindly
|
|
||||||
adds in the value of the symbol being relocated against. Damn! */
|
|
||||||
else if (fmt == 32
|
|
||||||
&& fixP->fx_addsy != NULL
|
|
||||||
&& S_GET_SEGMENT (fixP->fx_addsy) != bfd_com_section_ptr)
|
|
||||||
new_val = hppa_field_adjust (*valp - S_GET_VALUE (fixP->fx_addsy),
|
|
||||||
0, hppa_fixP->fx_r_field);
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field);
|
|
||||||
|
|
||||||
/* Handle pc-relative exceptions from above. */
|
|
||||||
if ((fmt == 12 || fmt == 17 || fmt == 22)
|
|
||||||
&& fixP->fx_addsy
|
|
||||||
&& fixP->fx_pcrel
|
|
||||||
&& !arg_reloc_stub_needed (symbol_arg_reloc_info (fixP->fx_addsy),
|
|
||||||
hppa_fixP->fx_arg_reloc)
|
|
||||||
#ifdef OBJ_ELF
|
|
||||||
&& (*valp - 8 + 8192 < 16384
|
|
||||||
|| (fmt == 17 && *valp - 8 + 262144 < 524288)
|
|
||||||
|| (fmt == 22 && *valp - 8 + 8388608 < 16777216))
|
|
||||||
#endif
|
|
||||||
#ifdef OBJ_SOM
|
|
||||||
&& (*valp - 8 + 262144 < 524288
|
|
||||||
|| (fmt == 22 && *valp - 8 + 8388608 < 16777216))
|
|
||||||
#endif
|
|
||||||
&& !S_IS_EXTERNAL (fixP->fx_addsy)
|
|
||||||
&& !S_IS_WEAK (fixP->fx_addsy)
|
|
||||||
&& S_GET_SEGMENT (fixP->fx_addsy) == hppa_fixP->segment
|
|
||||||
&& !(fixP->fx_subsy
|
|
||||||
&& S_GET_SEGMENT (fixP->fx_subsy) != hppa_fixP->segment))
|
|
||||||
{
|
|
||||||
new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (fmt)
|
|
||||||
{
|
|
||||||
case 10:
|
|
||||||
CHECK_FIELD (new_val, 8191, -8192, 0);
|
|
||||||
val = new_val;
|
|
||||||
|
|
||||||
insn = (insn & ~ 0x3ff1) | (((val & 0x1ff8) << 1)
|
|
||||||
| ((val & 0x2000) >> 13));
|
|
||||||
break;
|
|
||||||
case -11:
|
|
||||||
CHECK_FIELD (new_val, 8191, -8192, 0);
|
|
||||||
val = new_val;
|
|
||||||
|
|
||||||
insn = (insn & ~ 0x3ff9) | (((val & 0x1ffc) << 1)
|
|
||||||
| ((val & 0x2000) >> 13));
|
|
||||||
break;
|
|
||||||
/* Handle all opcodes with the 'j' operand type. */
|
|
||||||
case 14:
|
|
||||||
CHECK_FIELD (new_val, 8191, -8192, 0);
|
|
||||||
val = new_val;
|
|
||||||
|
|
||||||
insn = ((insn & ~ 0x3fff) | low_sign_unext (val, 14));
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Handle all opcodes with the 'k' operand type. */
|
|
||||||
case 21:
|
|
||||||
CHECK_FIELD (new_val, 1048575, -1048576, 0);
|
|
||||||
val = new_val;
|
|
||||||
|
|
||||||
insn = (insn & ~ 0x1fffff) | re_assemble_21 (val);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Handle all the opcodes with the 'i' operand type. */
|
|
||||||
case 11:
|
|
||||||
CHECK_FIELD (new_val, 1023, -1023, 0);
|
|
||||||
val = new_val;
|
|
||||||
|
|
||||||
insn = (insn & ~ 0x7ff) | low_sign_unext (val, 11);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Handle all the opcodes with the 'w' operand type. */
|
|
||||||
case 12:
|
|
||||||
CHECK_FIELD (new_val - 8, 8191, -8192, 0);
|
|
||||||
val = new_val - 8;
|
|
||||||
|
|
||||||
insn = (insn & ~ 0x1ffd) | re_assemble_12 (val >> 2);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Handle some of the opcodes with the 'W' operand type. */
|
|
||||||
case 17:
|
|
||||||
{
|
|
||||||
offsetT distance = *valp;
|
|
||||||
|
|
||||||
/* If this is an absolute branch (ie no link) with an out of
|
|
||||||
range target, then we want to complain. */
|
|
||||||
if (fixP->fx_r_type == (int) R_HPPA_PCREL_CALL
|
|
||||||
&& (insn & 0xffe00000) == 0xe8000000)
|
|
||||||
CHECK_FIELD (distance - 8, 262143, -262144, 0);
|
|
||||||
|
|
||||||
CHECK_FIELD (new_val - 8, 262143, -262144, 0);
|
|
||||||
val = new_val - 8;
|
|
||||||
|
|
||||||
insn = (insn & ~ 0x1f1ffd) | re_assemble_17 (val >> 2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 22:
|
|
||||||
{
|
|
||||||
offsetT distance = *valp;
|
|
||||||
|
|
||||||
/* If this is an absolute branch (ie no link) with an out of
|
|
||||||
range target, then we want to complain. */
|
|
||||||
if (fixP->fx_r_type == (int) R_HPPA_PCREL_CALL
|
|
||||||
&& (insn & 0xffe00000) == 0xe8000000)
|
|
||||||
CHECK_FIELD (distance - 8, 8388607, -8388608, 0);
|
|
||||||
|
|
||||||
CHECK_FIELD (new_val - 8, 8388607, -8388608, 0);
|
|
||||||
val = new_val - 8;
|
|
||||||
|
|
||||||
insn = (insn & ~ 0x3ff1ffd) | re_assemble_22 (val >> 2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case -10:
|
|
||||||
val = new_val;
|
|
||||||
insn = (insn & ~ 0xfff1) | re_assemble_16 (val & -8);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case -16:
|
|
||||||
val = new_val;
|
|
||||||
insn = (insn & ~ 0xfff9) | re_assemble_16 (val & -4);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 16:
|
|
||||||
val = new_val;
|
|
||||||
insn = (insn & ~ 0xffff) | re_assemble_16 (val);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 32:
|
|
||||||
insn = new_val;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
as_bad (_("Unknown relocation encountered in md_apply_fix."));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Insert the relocation. */
|
|
||||||
bfd_put_32 (stdoutput, insn, (unsigned char *) buf);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf (_("no hppa_fixup entry for this fixup (fixP = 0x%x, type = 0x%x)\n"),
|
|
||||||
(unsigned int) fixP, fixP->fx_r_type);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf = fixP->fx_frag->fr_literal + fixP->fx_where;
|
||||||
|
insn = bfd_get_32 (stdoutput, buf);
|
||||||
|
fmt = bfd_hppa_insn2fmt (stdoutput, insn);
|
||||||
|
|
||||||
|
/* If there is a symbol associated with this fixup, then it's something
|
||||||
|
which will need a SOM relocation (except for some PC-relative relocs).
|
||||||
|
In such cases we should treat the "val" or "addend" as zero since it
|
||||||
|
will be added in as needed from fx_offset in tc_gen_reloc. */
|
||||||
|
if ((fixP->fx_addsy != NULL
|
||||||
|
|| fixP->fx_r_type == (int) R_HPPA_NONE)
|
||||||
|
#ifdef OBJ_SOM
|
||||||
|
&& fmt != 32
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0);
|
||||||
|
#ifdef OBJ_SOM
|
||||||
|
/* These field selectors imply that we do not want an addend. */
|
||||||
|
else if (hppa_fixP->fx_r_field == e_psel
|
||||||
|
|| hppa_fixP->fx_r_field == e_rpsel
|
||||||
|
|| hppa_fixP->fx_r_field == e_lpsel
|
||||||
|
|| hppa_fixP->fx_r_field == e_tsel
|
||||||
|
|| hppa_fixP->fx_r_field == e_rtsel
|
||||||
|
|| hppa_fixP->fx_r_field == e_ltsel)
|
||||||
|
new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0);
|
||||||
|
/* This is truly disgusting. The machine independent code blindly
|
||||||
|
adds in the value of the symbol being relocated against. Damn! */
|
||||||
|
else if (fmt == 32
|
||||||
|
&& fixP->fx_addsy != NULL
|
||||||
|
&& S_GET_SEGMENT (fixP->fx_addsy) != bfd_com_section_ptr)
|
||||||
|
new_val = hppa_field_adjust (*valp - S_GET_VALUE (fixP->fx_addsy),
|
||||||
|
0, hppa_fixP->fx_r_field);
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field);
|
||||||
|
|
||||||
|
/* Handle pc-relative exceptions from above. */
|
||||||
|
if ((fmt == 12 || fmt == 17 || fmt == 22)
|
||||||
|
&& fixP->fx_addsy
|
||||||
|
&& fixP->fx_pcrel
|
||||||
|
&& !arg_reloc_stub_needed (symbol_arg_reloc_info (fixP->fx_addsy),
|
||||||
|
hppa_fixP->fx_arg_reloc)
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
&& (*valp - 8 + 8192 < 16384
|
||||||
|
|| (fmt == 17 && *valp - 8 + 262144 < 524288)
|
||||||
|
|| (fmt == 22 && *valp - 8 + 8388608 < 16777216))
|
||||||
|
#endif
|
||||||
|
#ifdef OBJ_SOM
|
||||||
|
&& (*valp - 8 + 262144 < 524288
|
||||||
|
|| (fmt == 22 && *valp - 8 + 8388608 < 16777216))
|
||||||
|
#endif
|
||||||
|
&& !S_IS_EXTERNAL (fixP->fx_addsy)
|
||||||
|
&& !S_IS_WEAK (fixP->fx_addsy)
|
||||||
|
&& S_GET_SEGMENT (fixP->fx_addsy) == hppa_fixP->segment
|
||||||
|
&& !(fixP->fx_subsy
|
||||||
|
&& S_GET_SEGMENT (fixP->fx_subsy) != hppa_fixP->segment))
|
||||||
|
{
|
||||||
|
new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (fmt)
|
||||||
|
{
|
||||||
|
case 10:
|
||||||
|
CHECK_FIELD (new_val, 8191, -8192, 0);
|
||||||
|
val = new_val;
|
||||||
|
|
||||||
|
insn = (insn & ~ 0x3ff1) | (((val & 0x1ff8) << 1)
|
||||||
|
| ((val & 0x2000) >> 13));
|
||||||
|
break;
|
||||||
|
case -11:
|
||||||
|
CHECK_FIELD (new_val, 8191, -8192, 0);
|
||||||
|
val = new_val;
|
||||||
|
|
||||||
|
insn = (insn & ~ 0x3ff9) | (((val & 0x1ffc) << 1)
|
||||||
|
| ((val & 0x2000) >> 13));
|
||||||
|
break;
|
||||||
|
/* Handle all opcodes with the 'j' operand type. */
|
||||||
|
case 14:
|
||||||
|
CHECK_FIELD (new_val, 8191, -8192, 0);
|
||||||
|
val = new_val;
|
||||||
|
|
||||||
|
insn = ((insn & ~ 0x3fff) | low_sign_unext (val, 14));
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Handle all opcodes with the 'k' operand type. */
|
||||||
|
case 21:
|
||||||
|
CHECK_FIELD (new_val, 1048575, -1048576, 0);
|
||||||
|
val = new_val;
|
||||||
|
|
||||||
|
insn = (insn & ~ 0x1fffff) | re_assemble_21 (val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Handle all the opcodes with the 'i' operand type. */
|
||||||
|
case 11:
|
||||||
|
CHECK_FIELD (new_val, 1023, -1023, 0);
|
||||||
|
val = new_val;
|
||||||
|
|
||||||
|
insn = (insn & ~ 0x7ff) | low_sign_unext (val, 11);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Handle all the opcodes with the 'w' operand type. */
|
||||||
|
case 12:
|
||||||
|
CHECK_FIELD (new_val - 8, 8191, -8192, 0);
|
||||||
|
val = new_val - 8;
|
||||||
|
|
||||||
|
insn = (insn & ~ 0x1ffd) | re_assemble_12 (val >> 2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Handle some of the opcodes with the 'W' operand type. */
|
||||||
|
case 17:
|
||||||
|
{
|
||||||
|
offsetT distance = *valp;
|
||||||
|
|
||||||
|
/* If this is an absolute branch (ie no link) with an out of
|
||||||
|
range target, then we want to complain. */
|
||||||
|
if (fixP->fx_r_type == (int) R_HPPA_PCREL_CALL
|
||||||
|
&& (insn & 0xffe00000) == 0xe8000000)
|
||||||
|
CHECK_FIELD (distance - 8, 262143, -262144, 0);
|
||||||
|
|
||||||
|
CHECK_FIELD (new_val - 8, 262143, -262144, 0);
|
||||||
|
val = new_val - 8;
|
||||||
|
|
||||||
|
insn = (insn & ~ 0x1f1ffd) | re_assemble_17 (val >> 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 22:
|
||||||
|
{
|
||||||
|
offsetT distance = *valp;
|
||||||
|
|
||||||
|
/* If this is an absolute branch (ie no link) with an out of
|
||||||
|
range target, then we want to complain. */
|
||||||
|
if (fixP->fx_r_type == (int) R_HPPA_PCREL_CALL
|
||||||
|
&& (insn & 0xffe00000) == 0xe8000000)
|
||||||
|
CHECK_FIELD (distance - 8, 8388607, -8388608, 0);
|
||||||
|
|
||||||
|
CHECK_FIELD (new_val - 8, 8388607, -8388608, 0);
|
||||||
|
val = new_val - 8;
|
||||||
|
|
||||||
|
insn = (insn & ~ 0x3ff1ffd) | re_assemble_22 (val >> 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case -10:
|
||||||
|
val = new_val;
|
||||||
|
insn = (insn & ~ 0xfff1) | re_assemble_16 (val & -8);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -16:
|
||||||
|
val = new_val;
|
||||||
|
insn = (insn & ~ 0xfff9) | re_assemble_16 (val & -4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 16:
|
||||||
|
val = new_val;
|
||||||
|
insn = (insn & ~ 0xffff) | re_assemble_16 (val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 32:
|
||||||
|
insn = new_val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
as_bad (_("Unknown relocation encountered in md_apply_fix."));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert the relocation. */
|
||||||
|
bfd_put_32 (stdoutput, insn, buf);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exactly what point is a PC-relative offset relative TO?
|
/* Exactly what point is a PC-relative offset relative TO?
|
||||||
|
|
Loading…
Reference in New Issue