diff options
author | Ken Raeburn <raeburn@cygnus> | 1994-09-13 02:11:25 +0000 |
---|---|---|
committer | Ken Raeburn <raeburn@cygnus> | 1994-09-13 02:11:25 +0000 |
commit | d9d6f09465107e253b57662b3b099ef26bb96a91 (patch) | |
tree | 44d64b25937caf75d163171b4427ec4df2ee6077 /gas | |
parent | d90f530be0671625a8d99f764b7d78d9f6aea55d (diff) | |
download | gdb-d9d6f09465107e253b57662b3b099ef26bb96a91.zip gdb-d9d6f09465107e253b57662b3b099ef26bb96a91.tar.gz gdb-d9d6f09465107e253b57662b3b099ef26bb96a91.tar.bz2 |
* write.c (fixup_segment): Test TC_RELOC_RTSYM_LOC_FIXUP on fixup before
processing same-section pcrel relocations.
(TC_RELOC_RTSYM_LOC_FIXUP): Default to 1.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/write.c | 88 |
1 files changed, 76 insertions, 12 deletions
diff --git a/gas/write.c b/gas/write.c index 7964934..8004ef7 100644 --- a/gas/write.c +++ b/gas/write.c @@ -24,6 +24,10 @@ #include "obstack.h" #include "output-file.h" +/* This looks like a good idea. Let's try turning it on always, for now. */ +#undef BFD_FAST_SECTION_FILL +#define BFD_FAST_SECTION_FILL + /* The NOP_OPCODE is for the alignment fill value. Fill it with a nop instruction so that the disassembler does not choke on it. */ #ifndef NOP_OPCODE @@ -453,7 +457,7 @@ relax_and_size_seg (abfd, sec, xxx) flags = bfd_get_section_flags (abfd, sec); - seginfo = (segment_info_type *) bfd_get_section_userdata (abfd, sec); + seginfo = seg_info (sec); if (seginfo && seginfo->frchainP) { relax_segment (seginfo->frchainP->frch_root, sec); @@ -848,6 +852,11 @@ write_contents (abfd, sec, xxx) count = f->fr_offset; assert (count >= 0); if (fill_size && count) +#ifdef BFD_FAST_SECTION_FILL + { + char buf[256]; + if (fill_size > sizeof(buf)) { + /* Do it the old way. Can this ever happen? */ while (count--) { x = bfd_set_section_contents (stdoutput, sec, @@ -862,6 +871,46 @@ write_contents (abfd, sec, xxx) offset += fill_size; } } + else { + /* Build a buffer full of fill objects and output it as + * often as necessary. This saves on the overhead of potentially + * lots of bfd_set_section_contents calls. + */ + int n_per_buf, bytes, i; + if (fill_size == 1) + { + n_per_buf = sizeof (buf); + memset (buf, *fill_literal, n_per_buf); + } + else + { + char *bufp; + n_per_buf = sizeof(buf)/fill_size; + for (i = n_per_buf, bufp = buf; i; i--, bufp += fill_size) + memcpy(bufp, fill_literal, fill_size); + } + for (; count > 0; count -= n_per_buf) + { + n_per_buf = n_per_buf > count ? count : n_per_buf; + x = bfd_set_section_contents (stdoutput, sec, + buf, (file_ptr) offset, + (bfd_size_type) n_per_buf * fill_size); + assert (x == true); + offset += n_per_buf * fill_size; + } + } + } +#else + while (count--) + { + x = bfd_set_section_contents (stdoutput, sec, + fill_literal, (file_ptr) offset, + (bfd_size_type) fill_size); + assert (x == true); + offset += fill_size; + } +#endif + } } #endif @@ -1213,9 +1262,15 @@ write_object_file () exp.X_op_symbol = lie->sub; exp.X_add_number = lie->addnum; #ifdef BFD_ASSEMBLER +#ifdef TC_CONS_FIX_NEW + TC_CONS_FIX_NEW (lie->frag, + lie->word_goes_here - lie->frag->fr_literal, + 2, &exp); +#else fix_new_exp (lie->frag, lie->word_goes_here - lie->frag->fr_literal, 2, &exp, 0, BFD_RELOC_NONE); +#endif #else #if defined(TC_SPARC) || defined(TC_A29K) || defined(NEED_FX_R_TYPE) fix_new_exp (lie->frag, @@ -1271,6 +1326,9 @@ write_object_file () /* Patch the jump table */ /* This is the offset from ??? to table_ptr+0 */ to_addr = table_addr - S_GET_VALUE (lie->sub); +#ifdef BFD_ASSEMBLER + to_addr -= lie->sub->sy_frag->fr_address; +#endif md_number_to_chars (lie->word_goes_here, to_addr, 2); for (untruth = lie->next_broken_word; untruth && untruth->dispfrag == fragP; untruth = untruth->next_broken_word) { @@ -1282,6 +1340,9 @@ write_object_file () /* this is a long jump from table_ptr+0 to the final target */ from_addr = table_addr; to_addr = S_GET_VALUE (lie->add) + lie->addnum; +#ifdef BFD_ASSEMBLER + to_addr += lie->add->sy_frag->fr_address; +#endif md_create_long_jump (table_ptr, from_addr, to_addr, lie->dispfrag, lie->add); table_ptr += md_long_jump_size; table_addr += md_long_jump_size; @@ -1432,7 +1493,7 @@ write_object_file () Put them in the common section now. */ if (S_IS_DEFINED (symp) == 0 && S_GET_VALUE (symp) != 0) - S_SET_SEGMENT (symp, &bfd_com_section); + S_SET_SEGMENT (symp, bfd_com_section_ptr); #if 0 printf ("symbol `%s'\n\t@%x: value=%d flags=%x seg=%s\n", S_GET_NAME (symp), symp, @@ -1804,16 +1865,14 @@ relax_segment (segment_frag_root, segment) } aim = target - address - fragP->fr_fix; - /* The displacement is affected by the instruction size - for the 32k architecture. I think we ought to be able - to add fragP->fr_pcrel_adjust in all cases (it should be - zero if not used), but just in case it breaks something - else we'll put this inside #ifdef NS32K ... #endif */ -#ifndef TC_NS32K - if (fragP->fr_pcrel_adjust) - abort (); +#ifdef TC_PCREL_ADJUST + /* Currently only the ns32k family needs this */ + aim += TC_PCREL_ADJUST(fragP); +#else + /* This machine doesn't want to use pcrel_adjust. + In that case, pcrel_adjust should be zero. */ + assert (fragP->fr_pcrel_adjust == 0); #endif - aim += fragP->fr_pcrel_adjust; if (aim < 0) { @@ -1880,6 +1939,10 @@ relax_segment (segment_frag_root, segment) #if defined (BFD_ASSEMBLER) || !defined (BFD) +#ifndef TC_RELOC_RTSYM_LOC_FIXUP +#define TC_RELOC_RTSYM_LOC_FIXUP(X) (1) +#endif + /* fixup_segment() Go through all the fixS's in a segment and see which ones can be @@ -2034,7 +2097,8 @@ fixup_segment (fixP, this_segment_type) if (add_symbolP) { - if (add_symbol_segment == this_segment_type && pcrel) + if (add_symbol_segment == this_segment_type && pcrel + && TC_RELOC_RTSYM_LOC_FIXUP (fixP->fx_r_type)) { /* * This fixup was made when the symbol's segment was |