diff options
author | Alan Modra <amodra@gmail.com> | 2007-02-16 03:40:17 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2007-02-16 03:40:17 +0000 |
commit | e7ff5c732e7b95aafccd0910ea1a5cb8251a1033 (patch) | |
tree | 475ae3dfa37e29602f298ca73b6f1148c5f45231 | |
parent | 010a1144c1ff414a90d5150165ea45a25a8fd65e (diff) | |
download | gdb-e7ff5c732e7b95aafccd0910ea1a5cb8251a1033.zip gdb-e7ff5c732e7b95aafccd0910ea1a5cb8251a1033.tar.gz gdb-e7ff5c732e7b95aafccd0910ea1a5cb8251a1033.tar.bz2 |
* subsegs.c (subseg_change, subseg_get): Use xcalloc rather than
xmalloc, memset. Don't bother assigning NULL to known zero mem.
(subseg_set_rest): Remove unnecessary cast.
* write.c: Include libbfd.h. Replace PTR with void * throughout.
Remove unnecessary forward declarations and casts.
(set_symtab): Delete extern bfd_alloc.
(fixup_segment): Move.
-rw-r--r-- | gas/ChangeLog | 10 | ||||
-rw-r--r-- | gas/subsegs.c | 23 | ||||
-rw-r--r-- | gas/write.c | 524 |
3 files changed, 268 insertions, 289 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 109a7ae..9fe4e79 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2007-02-16 Alan Modra <amodra@bigpond.net.au> + + * subsegs.c (subseg_change, subseg_get): Use xcalloc rather than + xmalloc, memset. Don't bother assigning NULL to known zero mem. + (subseg_set_rest): Remove unnecessary cast. + * write.c: Include libbfd.h. Replace PTR with void * throughout. + Remove unnecessary forward declarations and casts. + (set_symtab): Delete extern bfd_alloc. + (fixup_segment): Move. + 2007-02-15 Nathan Sidwell <nathan@codesourcery.com> * config/m68k-parse.h (m68k_register): Add ROMBAR0, ASID. diff --git a/gas/subsegs.c b/gas/subsegs.c index 8c5f8d8..0094764 100644 --- a/gas/subsegs.c +++ b/gas/subsegs.c @@ -1,6 +1,6 @@ /* subsegs.c - subsegments - Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -65,13 +65,9 @@ subseg_change (register segT seg, register int subseg) if (! seginfo) { - seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo)); - memset ((PTR) seginfo, 0, sizeof (*seginfo)); - seginfo->fix_root = NULL; - seginfo->fix_tail = NULL; + seginfo = xcalloc (1, sizeof (*seginfo)); seginfo->bfd_section = seg; - seginfo->sym = 0; - bfd_set_section_userdata (stdoutput, seg, (PTR) seginfo); + bfd_set_section_userdata (stdoutput, seg, seginfo); } } @@ -107,7 +103,7 @@ subseg_set_rest (segT seg, subsegT subseg) { /* This should be the only code that creates a frchainS. */ - newP = (frchainS *) obstack_alloc (&frchains, sizeof (frchainS)); + newP = obstack_alloc (&frchains, sizeof (frchainS)); newP->frch_subseg = subseg; newP->fix_root = NULL; newP->fix_tail = NULL; @@ -171,16 +167,9 @@ subseg_get (const char *segname, int force_new) if (! seginfo) { secptr->output_section = secptr; - seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo)); - memset ((PTR) seginfo, 0, sizeof (*seginfo)); - seginfo->fix_root = NULL; - seginfo->fix_tail = NULL; + seginfo = xcalloc (1, sizeof (*seginfo)); seginfo->bfd_section = secptr; - bfd_set_section_userdata (stdoutput, secptr, (PTR) seginfo); - seginfo->frchainP = NULL; - seginfo->lineno_list_head = seginfo->lineno_list_tail = NULL; - seginfo->sym = NULL; - seginfo->dot = NULL; + bfd_set_section_userdata (stdoutput, secptr, seginfo); } return secptr; } diff --git a/gas/write.c b/gas/write.c index 62df35c..1c93d43 100644 --- a/gas/write.c +++ b/gas/write.c @@ -27,6 +27,7 @@ #include "obstack.h" #include "output-file.h" #include "dwarf2dbg.h" +#include "libbfd.h" #ifndef TC_ADJUST_RELOC_COUNT #define TC_ADJUST_RELOC_COUNT(FIX, COUNT) @@ -108,8 +109,6 @@ addressT dot_value; void print_fixup (fixS *); -static void renumber_sections (bfd *, asection *, PTR); - /* We generally attach relocs to frag chains. However, after we have chained these all together into a segment, any relocs we add after that must be attached to a segment. This will include relocs added @@ -120,22 +119,6 @@ static int n_fixups; #define RELOC_ENUM enum bfd_reloc_code_real -static fixS *fix_new_internal (fragS *, int where, int size, - symbolS *add, symbolS *sub, - offsetT offset, int pcrel, - RELOC_ENUM r_type); -static long fixup_segment (fixS *, segT); -static relax_addressT relax_align (relax_addressT addr, int align); -static fragS *chain_frchains_together_1 (segT, struct frchain *); -static void chain_frchains_together (bfd *, segT, PTR); -static void cvt_frag_to_fill (segT, fragS *); -static void adjust_reloc_syms (bfd *, asection *, PTR); -static void fix_segment (bfd *, asection *, PTR); -static void write_relocs (bfd *, asection *, PTR); -static void write_contents (bfd *, asection *, PTR); -static void set_symtab (void); -static void merge_data_into_text (void); - /* Create a fixS in obstack 'notes'. */ static fixS * @@ -152,7 +135,7 @@ fix_new_internal (fragS *frag, /* Which frag? */ n_fixups++; - fixP = (fixS *) obstack_alloc (¬es, sizeof (fixS)); + fixP = obstack_alloc (¬es, sizeof (fixS)); fixP->fx_frag = frag; fixP->fx_where = where; @@ -364,7 +347,7 @@ get_recorded_alignment (segT seg) /* Reset the section indices after removing the gas created sections. */ static void -renumber_sections (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, PTR countparg) +renumber_sections (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *countparg) { int *countp = (int *) countparg; @@ -401,7 +384,7 @@ chain_frchains_together_1 (segT section, struct frchain *frchp) static void chain_frchains_together (bfd *abfd ATTRIBUTE_UNUSED, segT section, - PTR xxx ATTRIBUTE_UNUSED) + void *xxx ATTRIBUTE_UNUSED) { segment_info_type *info; @@ -529,10 +512,8 @@ relax_seg (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *xxx) info->changed = 1; } -static void size_seg (bfd *, asection *, PTR); - static void -size_seg (bfd *abfd, asection *sec, PTR xxx ATTRIBUTE_UNUSED) +size_seg (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED) { flagword flags; fragS *fragp; @@ -643,7 +624,7 @@ dump_section_relocs (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, FILE *stream) static void adjust_reloc_syms (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, - PTR xxx ATTRIBUTE_UNUSED) + void *xxx ATTRIBUTE_UNUSED) { segment_info_type *seginfo = seg_info (sec); fixS *fixp; @@ -763,10 +744,250 @@ adjust_reloc_syms (bfd *abfd ATTRIBUTE_UNUSED, dump_section_relocs (abfd, sec, stderr); } +/* fixup_segment() + + Go through all the fixS's in a segment and see which ones can be + handled now. (These consist of fixS where we have since discovered + the value of a symbol, or the address of the frag involved.) + For each one, call md_apply_fix to put the fix into the frag data. + + Result is a count of how many relocation structs will be needed to + handle the remaining fixS's that we couldn't completely handle here. + These will be output later by emit_relocations(). */ + +static long +fixup_segment (fixS *fixP, segT this_segment) +{ + long seg_reloc_count = 0; + valueT add_number; + fragS *fragP; + segT add_symbol_segment = absolute_section; + + if (fixP != NULL && abs_section_sym == NULL) + abs_section_sym = section_symbol (absolute_section); + + /* If the linker is doing the relaxing, we must not do any fixups. + + Well, strictly speaking that's not true -- we could do any that + are PC-relative and don't cross regions that could change size. + And for the i960 we might be able to turn callx/callj into bal + anyways in cases where we know the maximum displacement. */ + if (linkrelax && TC_LINKRELAX_FIXUP (this_segment)) + { + for (; fixP; fixP = fixP->fx_next) + if (!fixP->fx_done) + { + if (fixP->fx_addsy == NULL) + { + /* There was no symbol required by this relocation. + However, BFD doesn't really handle relocations + without symbols well. So fake up a local symbol in + the absolute section. */ + fixP->fx_addsy = abs_section_sym; + } + symbol_mark_used_in_reloc (fixP->fx_addsy); + if (fixP->fx_subsy != NULL) + symbol_mark_used_in_reloc (fixP->fx_subsy); + seg_reloc_count++; + } + TC_ADJUST_RELOC_COUNT (fixP, seg_reloc_count); + return seg_reloc_count; + } + + for (; fixP; fixP = fixP->fx_next) + { +#ifdef DEBUG5 + fprintf (stderr, "\nprocessing fixup:\n"); + print_fixup (fixP); +#endif + + fragP = fixP->fx_frag; + know (fragP); +#ifdef TC_VALIDATE_FIX + TC_VALIDATE_FIX (fixP, this_segment, skip); +#endif + add_number = fixP->fx_offset; + + if (fixP->fx_addsy != NULL + && symbol_mri_common_p (fixP->fx_addsy)) + { + add_number += S_GET_VALUE (fixP->fx_addsy); + fixP->fx_offset = add_number; + fixP->fx_addsy + = symbol_get_value_expression (fixP->fx_addsy)->X_add_symbol; + } + + if (fixP->fx_addsy != NULL) + add_symbol_segment = S_GET_SEGMENT (fixP->fx_addsy); + + if (fixP->fx_subsy != NULL) + { + segT sub_symbol_segment; + resolve_symbol_value (fixP->fx_subsy); + sub_symbol_segment = S_GET_SEGMENT (fixP->fx_subsy); + if (fixP->fx_addsy != NULL + && sub_symbol_segment == add_symbol_segment + && !TC_FORCE_RELOCATION_SUB_SAME (fixP, add_symbol_segment)) + { + add_number += S_GET_VALUE (fixP->fx_addsy); + add_number -= S_GET_VALUE (fixP->fx_subsy); + fixP->fx_offset = add_number; + fixP->fx_addsy = NULL; + fixP->fx_subsy = NULL; +#ifdef TC_M68K + /* See the comment below about 68k weirdness. */ + fixP->fx_pcrel = 0; +#endif + } + else if (sub_symbol_segment == absolute_section + && !TC_FORCE_RELOCATION_SUB_ABS (fixP)) + { + add_number -= S_GET_VALUE (fixP->fx_subsy); + fixP->fx_offset = add_number; + fixP->fx_subsy = NULL; + } + else if (sub_symbol_segment == this_segment + && !TC_FORCE_RELOCATION_SUB_LOCAL (fixP)) + { + add_number -= S_GET_VALUE (fixP->fx_subsy); + fixP->fx_offset = (add_number + fixP->fx_dot_value + + fixP->fx_frag->fr_address); + + /* Make it pc-relative. If the back-end code has not + selected a pc-relative reloc, cancel the adjustment + we do later on all pc-relative relocs. */ + if (0 +#ifdef TC_M68K + /* Do this for m68k even if it's already described + as pc-relative. On the m68k, an operand of + "pc@(foo-.-2)" should address "foo" in a + pc-relative mode. */ + || 1 +#endif + || !fixP->fx_pcrel) + add_number += MD_PCREL_FROM_SECTION (fixP, this_segment); + fixP->fx_subsy = NULL; + fixP->fx_pcrel = 1; + } + else if (!TC_VALIDATE_FIX_SUB (fixP)) + { + as_bad_where (fixP->fx_file, fixP->fx_line, + _("can't resolve `%s' {%s section} - `%s' {%s section}"), + fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0", + segment_name (add_symbol_segment), + S_GET_NAME (fixP->fx_subsy), + segment_name (sub_symbol_segment)); + } + } + + if (fixP->fx_addsy) + { + if (add_symbol_segment == this_segment + && !TC_FORCE_RELOCATION_LOCAL (fixP)) + { + /* This fixup was made when the symbol's segment was + SEG_UNKNOWN, but it is now in the local segment. + So we know how to do the address without relocation. */ + add_number += S_GET_VALUE (fixP->fx_addsy); + fixP->fx_offset = add_number; + if (fixP->fx_pcrel) + add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment); + fixP->fx_addsy = NULL; + fixP->fx_pcrel = 0; + } + else if (add_symbol_segment == absolute_section + && !TC_FORCE_RELOCATION_ABS (fixP)) + { + add_number += S_GET_VALUE (fixP->fx_addsy); + fixP->fx_offset = add_number; + fixP->fx_addsy = NULL; + } + else if (add_symbol_segment != undefined_section + && ! bfd_is_com_section (add_symbol_segment) + && MD_APPLY_SYM_VALUE (fixP)) + add_number += S_GET_VALUE (fixP->fx_addsy); + } + + if (fixP->fx_pcrel) + { + add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment); + if (!fixP->fx_done && fixP->fx_addsy == NULL) + { + /* There was no symbol required by this relocation. + However, BFD doesn't really handle relocations + without symbols well. So fake up a local symbol in + the absolute section. */ + fixP->fx_addsy = abs_section_sym; + } + } + + if (!fixP->fx_done) + md_apply_fix (fixP, &add_number, this_segment); + + if (!fixP->fx_done) + { + ++seg_reloc_count; + if (fixP->fx_addsy == NULL) + fixP->fx_addsy = abs_section_sym; + symbol_mark_used_in_reloc (fixP->fx_addsy); + if (fixP->fx_subsy != NULL) + symbol_mark_used_in_reloc (fixP->fx_subsy); + } + + if (!fixP->fx_bit_fixP && !fixP->fx_no_overflow && fixP->fx_size != 0) + { + if (fixP->fx_size < sizeof (valueT)) + { + valueT mask; + + mask = 0; + mask--; /* Set all bits to one. */ + mask <<= fixP->fx_size * 8 - (fixP->fx_signed ? 1 : 0); + if ((add_number & mask) != 0 && (add_number & mask) != mask) + { + char buf[50], buf2[50]; + sprint_value (buf, fragP->fr_address + fixP->fx_where); + if (add_number > 1000) + sprint_value (buf2, add_number); + else + sprintf (buf2, "%ld", (long) add_number); + as_bad_where (fixP->fx_file, fixP->fx_line, + _("value of %s too large for field of %d bytes at %s"), + buf2, fixP->fx_size, buf); + } /* Generic error checking. */ + } +#ifdef WARN_SIGNED_OVERFLOW_WORD + /* Warn if a .word value is too large when treated as a signed + number. We already know it is not too negative. This is to + catch over-large switches generated by gcc on the 68k. */ + if (!flag_signed_overflow_ok + && fixP->fx_size == 2 + && add_number > 0x7fff) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("signed .word overflow; switch may be too large; %ld at 0x%lx"), + (long) add_number, + (long) (fragP->fr_address + fixP->fx_where)); +#endif + } /* Not a bit fix. */ + +#ifdef TC_VALIDATE_FIX + skip: ATTRIBUTE_UNUSED_LABEL + ; +#endif +#ifdef DEBUG5 + fprintf (stderr, "result:\n"); + print_fixup (fixP); +#endif + } /* For each fixS in this segment. */ + + TC_ADJUST_RELOC_COUNT (fixP, seg_reloc_count); + return seg_reloc_count; +} + static void fix_segment (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, - PTR xxx ATTRIBUTE_UNUSED) + void *xxx ATTRIBUTE_UNUSED) { segment_info_type *seginfo = seg_info (sec); @@ -774,7 +995,7 @@ fix_segment (bfd *abfd ATTRIBUTE_UNUSED, } static void -write_relocs (bfd *abfd, asection *sec, PTR xxx ATTRIBUTE_UNUSED) +write_relocs (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED) { segment_info_type *seginfo = seg_info (sec); unsigned int i; @@ -794,7 +1015,7 @@ write_relocs (bfd *abfd, asection *sec, PTR xxx ATTRIBUTE_UNUSED) #ifndef RELOC_EXPANSION_POSSIBLE /* Set up reloc information as well. */ - relocs = (arelent **) xcalloc (n, sizeof (arelent *)); + relocs = xcalloc (n, sizeof (arelent *)); i = 0; for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next) @@ -866,7 +1087,7 @@ write_relocs (bfd *abfd, asection *sec, PTR xxx ATTRIBUTE_UNUSED) #else n = n * MAX_RELOC_EXPANSION; /* Set up reloc information as well. */ - relocs = (arelent **) xcalloc (n, sizeof (arelent *)); + relocs = xcalloc (n, sizeof (arelent *)); i = 0; for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next) @@ -987,7 +1208,7 @@ write_relocs (bfd *abfd, asection *sec, PTR xxx ATTRIBUTE_UNUSED) static void write_contents (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, - PTR xxx ATTRIBUTE_UNUSED) + void *xxx ATTRIBUTE_UNUSED) { segment_info_type *seginfo = seg_info (sec); addressT offset = 0; @@ -1090,7 +1311,6 @@ set_symtab (void) asymbol **asympp; symbolS *symp; bfd_boolean result; - extern PTR bfd_alloc (bfd *, bfd_size_type); /* Count symbols. We can't rely on a count made by the loop in write_object_file, because *_frob_file may add a new symbol or @@ -1104,7 +1324,7 @@ set_symtab (void) int i; bfd_size_type amt = (bfd_size_type) nsyms * sizeof (asymbol *); - asympp = (asymbol **) bfd_alloc (stdoutput, amt); + asympp = bfd_alloc (stdoutput, amt); symp = symbol_rootP; for (i = 0; i < nsyms; i++, symp = symbol_next (symp)) { @@ -2097,246 +2317,6 @@ relax_segment (struct frag *segment_frag_root, segT segment, int pass) return ret; } -/* fixup_segment() - - Go through all the fixS's in a segment and see which ones can be - handled now. (These consist of fixS where we have since discovered - the value of a symbol, or the address of the frag involved.) - For each one, call md_apply_fix to put the fix into the frag data. - - Result is a count of how many relocation structs will be needed to - handle the remaining fixS's that we couldn't completely handle here. - These will be output later by emit_relocations(). */ - -static long -fixup_segment (fixS *fixP, segT this_segment) -{ - long seg_reloc_count = 0; - valueT add_number; - fragS *fragP; - segT add_symbol_segment = absolute_section; - - if (fixP != NULL && abs_section_sym == NULL) - abs_section_sym = section_symbol (absolute_section); - - /* If the linker is doing the relaxing, we must not do any fixups. - - Well, strictly speaking that's not true -- we could do any that - are PC-relative and don't cross regions that could change size. - And for the i960 we might be able to turn callx/callj into bal - anyways in cases where we know the maximum displacement. */ - if (linkrelax && TC_LINKRELAX_FIXUP (this_segment)) - { - for (; fixP; fixP = fixP->fx_next) - if (!fixP->fx_done) - { - if (fixP->fx_addsy == NULL) - { - /* There was no symbol required by this relocation. - However, BFD doesn't really handle relocations - without symbols well. So fake up a local symbol in - the absolute section. */ - fixP->fx_addsy = abs_section_sym; - } - symbol_mark_used_in_reloc (fixP->fx_addsy); - if (fixP->fx_subsy != NULL) - symbol_mark_used_in_reloc (fixP->fx_subsy); - seg_reloc_count++; - } - TC_ADJUST_RELOC_COUNT (fixP, seg_reloc_count); - return seg_reloc_count; - } - - for (; fixP; fixP = fixP->fx_next) - { -#ifdef DEBUG5 - fprintf (stderr, "\nprocessing fixup:\n"); - print_fixup (fixP); -#endif - - fragP = fixP->fx_frag; - know (fragP); -#ifdef TC_VALIDATE_FIX - TC_VALIDATE_FIX (fixP, this_segment, skip); -#endif - add_number = fixP->fx_offset; - - if (fixP->fx_addsy != NULL - && symbol_mri_common_p (fixP->fx_addsy)) - { - add_number += S_GET_VALUE (fixP->fx_addsy); - fixP->fx_offset = add_number; - fixP->fx_addsy - = symbol_get_value_expression (fixP->fx_addsy)->X_add_symbol; - } - - if (fixP->fx_addsy != NULL) - add_symbol_segment = S_GET_SEGMENT (fixP->fx_addsy); - - if (fixP->fx_subsy != NULL) - { - segT sub_symbol_segment; - resolve_symbol_value (fixP->fx_subsy); - sub_symbol_segment = S_GET_SEGMENT (fixP->fx_subsy); - if (fixP->fx_addsy != NULL - && sub_symbol_segment == add_symbol_segment - && !TC_FORCE_RELOCATION_SUB_SAME (fixP, add_symbol_segment)) - { - add_number += S_GET_VALUE (fixP->fx_addsy); - add_number -= S_GET_VALUE (fixP->fx_subsy); - fixP->fx_offset = add_number; - fixP->fx_addsy = NULL; - fixP->fx_subsy = NULL; -#ifdef TC_M68K - /* See the comment below about 68k weirdness. */ - fixP->fx_pcrel = 0; -#endif - } - else if (sub_symbol_segment == absolute_section - && !TC_FORCE_RELOCATION_SUB_ABS (fixP)) - { - add_number -= S_GET_VALUE (fixP->fx_subsy); - fixP->fx_offset = add_number; - fixP->fx_subsy = NULL; - } - else if (sub_symbol_segment == this_segment - && !TC_FORCE_RELOCATION_SUB_LOCAL (fixP)) - { - add_number -= S_GET_VALUE (fixP->fx_subsy); - fixP->fx_offset = (add_number + fixP->fx_dot_value - + fixP->fx_frag->fr_address); - - /* Make it pc-relative. If the back-end code has not - selected a pc-relative reloc, cancel the adjustment - we do later on all pc-relative relocs. */ - if (0 -#ifdef TC_M68K - /* Do this for m68k even if it's already described - as pc-relative. On the m68k, an operand of - "pc@(foo-.-2)" should address "foo" in a - pc-relative mode. */ - || 1 -#endif - || !fixP->fx_pcrel) - add_number += MD_PCREL_FROM_SECTION (fixP, this_segment); - fixP->fx_subsy = NULL; - fixP->fx_pcrel = 1; - } - else if (!TC_VALIDATE_FIX_SUB (fixP)) - { - as_bad_where (fixP->fx_file, fixP->fx_line, - _("can't resolve `%s' {%s section} - `%s' {%s section}"), - fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0", - segment_name (add_symbol_segment), - S_GET_NAME (fixP->fx_subsy), - segment_name (sub_symbol_segment)); - } - } - - if (fixP->fx_addsy) - { - if (add_symbol_segment == this_segment - && !TC_FORCE_RELOCATION_LOCAL (fixP)) - { - /* This fixup was made when the symbol's segment was - SEG_UNKNOWN, but it is now in the local segment. - So we know how to do the address without relocation. */ - add_number += S_GET_VALUE (fixP->fx_addsy); - fixP->fx_offset = add_number; - if (fixP->fx_pcrel) - add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment); - fixP->fx_addsy = NULL; - fixP->fx_pcrel = 0; - } - else if (add_symbol_segment == absolute_section - && !TC_FORCE_RELOCATION_ABS (fixP)) - { - add_number += S_GET_VALUE (fixP->fx_addsy); - fixP->fx_offset = add_number; - fixP->fx_addsy = NULL; - } - else if (add_symbol_segment != undefined_section - && ! bfd_is_com_section (add_symbol_segment) - && MD_APPLY_SYM_VALUE (fixP)) - add_number += S_GET_VALUE (fixP->fx_addsy); - } - - if (fixP->fx_pcrel) - { - add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment); - if (!fixP->fx_done && fixP->fx_addsy == NULL) - { - /* There was no symbol required by this relocation. - However, BFD doesn't really handle relocations - without symbols well. So fake up a local symbol in - the absolute section. */ - fixP->fx_addsy = abs_section_sym; - } - } - - if (!fixP->fx_done) - md_apply_fix (fixP, &add_number, this_segment); - - if (!fixP->fx_done) - { - ++seg_reloc_count; - if (fixP->fx_addsy == NULL) - fixP->fx_addsy = abs_section_sym; - symbol_mark_used_in_reloc (fixP->fx_addsy); - if (fixP->fx_subsy != NULL) - symbol_mark_used_in_reloc (fixP->fx_subsy); - } - - if (!fixP->fx_bit_fixP && !fixP->fx_no_overflow && fixP->fx_size != 0) - { - if (fixP->fx_size < sizeof (valueT)) - { - valueT mask; - - mask = 0; - mask--; /* Set all bits to one. */ - mask <<= fixP->fx_size * 8 - (fixP->fx_signed ? 1 : 0); - if ((add_number & mask) != 0 && (add_number & mask) != mask) - { - char buf[50], buf2[50]; - sprint_value (buf, fragP->fr_address + fixP->fx_where); - if (add_number > 1000) - sprint_value (buf2, add_number); - else - sprintf (buf2, "%ld", (long) add_number); - as_bad_where (fixP->fx_file, fixP->fx_line, - _("value of %s too large for field of %d bytes at %s"), - buf2, fixP->fx_size, buf); - } /* Generic error checking. */ - } -#ifdef WARN_SIGNED_OVERFLOW_WORD - /* Warn if a .word value is too large when treated as a signed - number. We already know it is not too negative. This is to - catch over-large switches generated by gcc on the 68k. */ - if (!flag_signed_overflow_ok - && fixP->fx_size == 2 - && add_number > 0x7fff) - as_bad_where (fixP->fx_file, fixP->fx_line, - _("signed .word overflow; switch may be too large; %ld at 0x%lx"), - (long) add_number, - (long) (fragP->fr_address + fixP->fx_where)); -#endif - } /* Not a bit fix. */ - -#ifdef TC_VALIDATE_FIX - skip: ATTRIBUTE_UNUSED_LABEL - ; -#endif -#ifdef DEBUG5 - fprintf (stderr, "result:\n"); - print_fixup (fixP); -#endif - } /* For each fixS in this segment. */ - - TC_ADJUST_RELOC_COUNT (fixP, seg_reloc_count); - return seg_reloc_count; -} - void number_to_chars_bigendian (char *buf, valueT val, int n) { |