diff options
author | Ian Lance Taylor <ian@airs.com> | 1996-05-16 19:57:12 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1996-05-16 19:57:12 +0000 |
commit | bccbc0aa84e92cb7d48e8221552bd4edcb876811 (patch) | |
tree | 6cfc6f316cb9dd6bb15c863bf49f4c99f7b39d4e | |
parent | f4e769dc02fd968cb5a9e845cd544fd158ca4269 (diff) | |
download | gdb-bccbc0aa84e92cb7d48e8221552bd4edcb876811.zip gdb-bccbc0aa84e92cb7d48e8221552bd4edcb876811.tar.gz gdb-bccbc0aa84e92cb7d48e8221552bd4edcb876811.tar.bz2 |
* 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.
-rw-r--r-- | gas/config/tc-sh.c | 60 |
1 files changed, 56 insertions, 4 deletions
diff --git a/gas/config/tc-sh.c b/gas/config/tc-sh.c index 7a849a0..9a406a6 100644 --- a/gas/config/tc-sh.c +++ b/gas/config/tc-sh.c @@ -900,6 +900,15 @@ md_assemble (str) 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 || 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 DEFUN (tc_crawl_symbol_chain, (headers), object_headers * headers) @@ -1166,7 +1200,11 @@ sh_coff_frob_file () for (fscan = segment_info[iseg].fix_root; fscan != NULL; 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; if (fscan == NULL) { @@ -1344,7 +1382,7 @@ md_convert_frag (headers, seg, fragP) case C (COND_JUMP, COND32): case C (COND_JUMP, UNDEF_WORD_DISP): 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); else 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 || SWITCH_TABLE (fix) || 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. */ @@ -1593,6 +1634,9 @@ md_apply_fix (fixP, val) case R_SH_COUNT: case R_SH_ALIGN: + case R_SH_CODE: + case R_SH_DATA: + case R_SH_LABEL: /* Nothing to do here. */ break; @@ -1705,7 +1749,8 @@ sh_do_align (n, fill, len) #ifdef BFD_ASSEMBLER || (now_seg->flags & SEC_CODE) != 0 #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 little_nop_pattern[] = { 0x09, 0x00 }; @@ -1804,6 +1849,13 @@ sh_coff_reloc_mangle (seg, fix, intr, paddr) /* This reloc is always absolute. */ 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. */ if (symbol_ptr != NULL) |