diff options
author | Hans-Peter Nilsson <hp@axis.com> | 2009-03-10 14:38:03 +0000 |
---|---|---|
committer | Hans-Peter Nilsson <hp@axis.com> | 2009-03-10 14:38:03 +0000 |
commit | 187af7df3bda10fc5b13e81d71460b9c9935b131 (patch) | |
tree | 699c8be7c8850d432cefa00c4164fcf763e36444 /gas/write.c | |
parent | 34dd024a28c6d4a73183aebdd52967672ed458f4 (diff) | |
download | gdb-187af7df3bda10fc5b13e81d71460b9c9935b131.zip gdb-187af7df3bda10fc5b13e81d71460b9c9935b131.tar.gz gdb-187af7df3bda10fc5b13e81d71460b9c9935b131.tar.bz2 |
* write.c (write_object_file) [!WORKING_DOT_WORD]: When patching
the jump table for multiple overflowing entries with the same
target, handle base symbols being different.
(relax_segment) <case rs_broken_word, second loop>: Whenever a
single entry overflows, arrange to redirect all entries with the
same target.
Diffstat (limited to 'gas/write.c')
-rw-r--r-- | gas/write.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/gas/write.c b/gas/write.c index 1af81a7..9d681f2 100644 --- a/gas/write.c +++ b/gas/write.c @@ -1671,18 +1671,22 @@ write_object_file (void) if (lie->added == 2) continue; /* Patch the jump table. */ - /* This is the offset from ??? to table_ptr+0. */ - to_addr = table_addr - S_GET_VALUE (lie->sub); -#ifdef TC_CHECK_ADJUSTED_BROKEN_DOT_WORD - TC_CHECK_ADJUSTED_BROKEN_DOT_WORD (to_addr, lie); -#endif - md_number_to_chars (lie->word_goes_here, to_addr, 2); - for (untruth = lie->next_broken_word; + for (untruth = (struct broken_word *) (fragP->fr_symbol); untruth && untruth->dispfrag == fragP; untruth = untruth->next_broken_word) { if (untruth->use_jump == lie) - md_number_to_chars (untruth->word_goes_here, to_addr, 2); + { + /* This is the offset from ??? to table_ptr+0. + The target is the same for all users of this + md_long_jump, but the "sub" bases (and hence the + offsets) may be different. */ + addressT to_word = table_addr - S_GET_VALUE (untruth->sub); +#ifdef TC_CHECK_ADJUSTED_BROKEN_DOT_WORD + TC_CHECK_ADJUSTED_BROKEN_DOT_WORD (to_word, untruth); +#endif + md_number_to_chars (untruth->word_goes_here, to_word, 2); + } } /* Install the long jump. */ @@ -2226,13 +2230,17 @@ relax_segment (struct frag *segment_frag_root, segT segment, int pass) S_GET_NAME (lie->sub), buf); } - lie->added = 1; if (fragP->fr_subtype == 0) { fragP->fr_subtype++; growth += md_short_jump_size; } - for (untruth = lie->next_broken_word; + + /* Redirect *all* words of this table with the same + target, lest we have to handle the case where the + same target but with a offset that fits on this + round overflows at the next relaxation round. */ + for (untruth = (struct broken_word *) (fragP->fr_symbol); untruth && untruth->dispfrag == lie->dispfrag; untruth = untruth->next_broken_word) if ((symbol_get_frag (untruth->add) @@ -2243,6 +2251,8 @@ relax_segment (struct frag *segment_frag_root, segT segment, int pass) untruth->added = 2; untruth->use_jump = lie; } + + lie->added = 1; growth += md_long_jump_size; } } |