* config/tc-sh.h (struct sh_segment_info_type): Define.
(TC_SEGMENT_INFO_TYPE): Define. (sh_frob_label): Declare. (tc_frob_label): Define. (sh_flush_pending_output): Declare. (md_flush_pending_output): Define. * config/tc-sh.c (md_assemble): If relaxing, emit a R_SH_CODE reloc before the instruction if necessary. (sh_frob_label): New function. (sh_flush_pending_output): New function. (sh_coff_frob_file): Ignore ALIGN, CODE, DATA, and LABEL relocs when looking for the reloc for the target of .uses. (md_convert_frag): Fix printf format (%0xlx to 0x%lx). (sh_force_relocation): Force CODE, DATA, and LABEL relocs to be emitted. (md_apply_fix): Ignore CODE, DATA, and LABEL relocs. (sh_coff_reloc_mangle): Force CODE, DATA, and LABEL relocs to use the absolute symbol.
This commit is contained in:
parent
f4e769dc02
commit
bccbc0aa84
1 changed files with 56 additions and 4 deletions
|
@ -900,6 +900,15 @@ md_assemble (str)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sh_relax
|
||||||
|
&& ! seg_info (now_seg)->tc_segment_info_data.in_code)
|
||||||
|
{
|
||||||
|
/* Output a CODE reloc to tell the linker that the following
|
||||||
|
bytes are instructions, not data. */
|
||||||
|
fix_new (frag_now, frag_now_fix (), 2, &abs_symbol, 0, 0, R_SH_CODE);
|
||||||
|
seg_info (now_seg)->tc_segment_info_data.in_code = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (opcode->arg[0] == A_BDISP12
|
if (opcode->arg[0] == A_BDISP12
|
||||||
|| opcode->arg[0] == A_BDISP8)
|
|| opcode->arg[0] == A_BDISP8)
|
||||||
{
|
{
|
||||||
|
@ -930,6 +939,31 @@ md_assemble (str)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This routine is called each time a label definition is seen. It
|
||||||
|
emits a R_SH_LABEL reloc if necessary. */
|
||||||
|
|
||||||
|
void
|
||||||
|
sh_frob_label ()
|
||||||
|
{
|
||||||
|
if (sh_relax
|
||||||
|
&& seg_info (now_seg)->tc_segment_info_data.in_code)
|
||||||
|
fix_new (frag_now, frag_now_fix (), 2, &abs_symbol, 0, 0, R_SH_LABEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This routine is called when the assembler is about to output some
|
||||||
|
data. It emits a R_SH_DATA reloc if necessary. */
|
||||||
|
|
||||||
|
void
|
||||||
|
sh_flush_pending_output ()
|
||||||
|
{
|
||||||
|
if (sh_relax
|
||||||
|
&& seg_info (now_seg)->tc_segment_info_data.in_code)
|
||||||
|
{
|
||||||
|
fix_new (frag_now, frag_now_fix (), 2, &abs_symbol, 0, 0, R_SH_DATA);
|
||||||
|
seg_info (now_seg)->tc_segment_info_data.in_code = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DEFUN (tc_crawl_symbol_chain, (headers),
|
DEFUN (tc_crawl_symbol_chain, (headers),
|
||||||
object_headers * headers)
|
object_headers * headers)
|
||||||
|
@ -1166,7 +1200,11 @@ sh_coff_frob_file ()
|
||||||
for (fscan = segment_info[iseg].fix_root;
|
for (fscan = segment_info[iseg].fix_root;
|
||||||
fscan != NULL;
|
fscan != NULL;
|
||||||
fscan = fscan->fx_next)
|
fscan = fscan->fx_next)
|
||||||
if (val == fscan->fx_frag->fr_address + fscan->fx_where)
|
if (val == fscan->fx_frag->fr_address + fscan->fx_where
|
||||||
|
&& fscan->fx_r_type != R_SH_ALIGN
|
||||||
|
&& fscan->fx_r_type != R_SH_CODE
|
||||||
|
&& fscan->fx_r_type != R_SH_DATA
|
||||||
|
&& fscan->fx_r_type != R_SH_LABEL)
|
||||||
break;
|
break;
|
||||||
if (fscan == NULL)
|
if (fscan == NULL)
|
||||||
{
|
{
|
||||||
|
@ -1344,7 +1382,7 @@ md_convert_frag (headers, seg, fragP)
|
||||||
case C (COND_JUMP, COND32):
|
case C (COND_JUMP, COND32):
|
||||||
case C (COND_JUMP, UNDEF_WORD_DISP):
|
case C (COND_JUMP, UNDEF_WORD_DISP):
|
||||||
if (fragP->fr_symbol == NULL)
|
if (fragP->fr_symbol == NULL)
|
||||||
as_bad ("at %0xlx, displacement overflows 8-bit field",
|
as_bad ("at 0x%lx, displacement overflows 8-bit field",
|
||||||
(unsigned long) fragP->fr_address);
|
(unsigned long) fragP->fr_address);
|
||||||
else
|
else
|
||||||
as_bad ("at 0x%lx, displacement to %sdefined symbol %s overflows 8-bit field ",
|
as_bad ("at 0x%lx, displacement to %sdefined symbol %s overflows 8-bit field ",
|
||||||
|
@ -1462,7 +1500,10 @@ sh_force_relocation (fix)
|
||||||
return (fix->fx_pcrel
|
return (fix->fx_pcrel
|
||||||
|| SWITCH_TABLE (fix)
|
|| SWITCH_TABLE (fix)
|
||||||
|| fix->fx_r_type == R_SH_COUNT
|
|| fix->fx_r_type == R_SH_COUNT
|
||||||
|| fix->fx_r_type == R_SH_ALIGN);
|
|| fix->fx_r_type == R_SH_ALIGN
|
||||||
|
|| fix->fx_r_type == R_SH_CODE
|
||||||
|
|| fix->fx_r_type == R_SH_DATA
|
||||||
|
|| fix->fx_r_type == R_SH_LABEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply a fixup to the object file. */
|
/* Apply a fixup to the object file. */
|
||||||
|
@ -1593,6 +1634,9 @@ md_apply_fix (fixP, val)
|
||||||
|
|
||||||
case R_SH_COUNT:
|
case R_SH_COUNT:
|
||||||
case R_SH_ALIGN:
|
case R_SH_ALIGN:
|
||||||
|
case R_SH_CODE:
|
||||||
|
case R_SH_DATA:
|
||||||
|
case R_SH_LABEL:
|
||||||
/* Nothing to do here. */
|
/* Nothing to do here. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1705,7 +1749,8 @@ sh_do_align (n, fill, len)
|
||||||
#ifdef BFD_ASSEMBLER
|
#ifdef BFD_ASSEMBLER
|
||||||
|| (now_seg->flags & SEC_CODE) != 0
|
|| (now_seg->flags & SEC_CODE) != 0
|
||||||
#endif
|
#endif
|
||||||
|| strcmp (obj_segment_name (now_seg), ".init") == 0))
|
|| strcmp (obj_segment_name (now_seg), ".init") == 0)
|
||||||
|
&& n > 1)
|
||||||
{
|
{
|
||||||
static const unsigned char big_nop_pattern[] = { 0x00, 0x09 };
|
static const unsigned char big_nop_pattern[] = { 0x00, 0x09 };
|
||||||
static const unsigned char little_nop_pattern[] = { 0x09, 0x00 };
|
static const unsigned char little_nop_pattern[] = { 0x09, 0x00 };
|
||||||
|
@ -1804,6 +1849,13 @@ sh_coff_reloc_mangle (seg, fix, intr, paddr)
|
||||||
/* This reloc is always absolute. */
|
/* This reloc is always absolute. */
|
||||||
symbol_ptr = NULL;
|
symbol_ptr = NULL;
|
||||||
}
|
}
|
||||||
|
else if (fix->fx_r_type == R_SH_CODE
|
||||||
|
|| fix->fx_r_type == R_SH_DATA
|
||||||
|
|| fix->fx_r_type == R_SH_LABEL)
|
||||||
|
{
|
||||||
|
/* These relocs are always absolute. */
|
||||||
|
symbol_ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Turn the segment of the symbol into an offset. */
|
/* Turn the segment of the symbol into an offset. */
|
||||||
if (symbol_ptr != NULL)
|
if (symbol_ptr != NULL)
|
||||||
|
|
Loading…
Add table
Reference in a new issue