diff options
Diffstat (limited to 'contrib/binutils/gas/config/obj-coff.c')
-rw-r--r-- | contrib/binutils/gas/config/obj-coff.c | 74 |
1 files changed, 48 insertions, 26 deletions
diff --git a/contrib/binutils/gas/config/obj-coff.c b/contrib/binutils/gas/config/obj-coff.c index 2fe0cb8..a6421bf 100644 --- a/contrib/binutils/gas/config/obj-coff.c +++ b/contrib/binutils/gas/config/obj-coff.c @@ -1,5 +1,5 @@ /* coff object file format - Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 1997 + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. This file is part of GAS. @@ -30,6 +30,7 @@ #define KEEP_RELOC_INFO #endif +static void obj_coff_bss PARAMS ((int)); const char *s_get_name PARAMS ((symbolS * s)); static symbolS *def_symbol_in_progress; @@ -165,7 +166,18 @@ tag_find_or_make (name) return symbolP; } +/* We accept the .bss directive to set the section for backward + compatibility with earlier versions of gas. */ +static void +obj_coff_bss (ignore) + int ignore; +{ + if (*input_line_pointer == '\n') + subseg_new (".bss", get_absolute_expression ()); + else + s_lcomm (0); +} #ifdef BFD_ASSEMBLER @@ -1088,8 +1100,9 @@ coff_adjust_section_syms (abfd, sec, x) fixS *fixp = seginfo->fix_root; while (fixp) { + if (! fixp->fx_done) + nrelocs++; fixp = fixp->fx_next; - nrelocs++; } } if (bfd_get_section_size_before_reloc (sec) == 0 @@ -1105,7 +1118,7 @@ coff_adjust_section_syms (abfd, sec, x) } void -coff_frob_file () +coff_frob_file_after_relocs () { bfd_map_over_sections (stdoutput, coff_adjust_section_syms, (char*) 0); } @@ -1433,7 +1446,6 @@ static void adjust_stab_section PARAMS ((bfd *abfd, segT seg)); static void obj_coff_lcomm PARAMS ((int)); static void obj_coff_text PARAMS ((int)); static void obj_coff_data PARAMS ((int)); -static void obj_coff_bss PARAMS ((int)); static void obj_coff_ident PARAMS ((int)); void obj_coff_section PARAMS ((int)); @@ -1684,7 +1696,7 @@ do_relocs_for (abfd, h, file_cursor) /* Turn the segment of the symbol into an offset. */ if (symbol_ptr) { - resolve_symbol_value (symbol_ptr); + resolve_symbol_value (symbol_ptr, 1); if (! symbol_ptr->sy_resolved) { char *file; @@ -1978,8 +1990,12 @@ symbol_to_chars (abfd, where, symbolP) } /* At the same time, relocate all symbols to their output value */ +#ifndef TE_PE val = (segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr + S_GET_VALUE (symbolP)); +#else + val = S_GET_VALUE (symbolP); +#endif S_SET_VALUE (symbolP, val); @@ -2656,7 +2672,7 @@ yank_symbols () S_SET_SEGMENT (symbolP, SEG_E0); } /* push data into text */ - resolve_symbol_value (symbolP); + resolve_symbol_value (symbolP, 1); if (S_GET_STORAGE_CLASS (symbolP) == C_NULL) { @@ -3200,7 +3216,11 @@ write_object_file () /* I think the section alignment is only used on the i960; the i960 needs it, and it should do no harm on other targets. */ +#ifdef ALIGNMENT_IN_S_FLAGS + segment_info[i].scnhdr.s_flags |= (section_alignment[i] & 0xF) << 8; +#else segment_info[i].scnhdr.s_align = 1 << section_alignment[i]; +#endif if (i == SEG_E0) H_SET_TEXT_SIZE (&headers, size); @@ -3456,16 +3476,6 @@ obj_coff_data (ignore) } static void -obj_coff_bss (ignore) - int ignore; -{ - if (*input_line_pointer == '\n') /* .bss */ - subseg_new(".bss", get_absolute_expression()); - else /* .bss id,expr */ - obj_coff_lcomm(0); -} - -static void obj_coff_ident (ignore) int ignore; { @@ -3885,7 +3895,7 @@ fixup_segment (segP, this_segment_type) /* Make sure the symbols have been resolved; this may not have happened if these are expression symbols. */ if (add_symbolP != NULL && ! add_symbolP->sy_resolved) - resolve_symbol_value (add_symbolP); + resolve_symbol_value (add_symbolP, 1); if (add_symbolP != NULL) { @@ -3915,7 +3925,7 @@ fixup_segment (segP, this_segment_type) } if (sub_symbolP != NULL && ! sub_symbolP->sy_resolved) - resolve_symbol_value (sub_symbolP); + resolve_symbol_value (sub_symbolP, 1); if (add_symbolP != NULL && add_symbolP->sy_mri_common) @@ -4048,11 +4058,21 @@ fixup_segment (segP, this_segment_type) add_number += S_GET_VALUE (add_symbolP); add_number -= md_pcrel_from (fixP); -#if defined (TC_I386) || defined (TE_LYNX) - /* On the 386 we must adjust by the segment vaddr as - well. Ian Taylor. */ - add_number -= segP->scnhdr.s_vaddr; -#endif + + /* We used to do + add_number -= segP->scnhdr.s_vaddr; + if defined (TC_I386) || defined (TE_LYNX). I now + think that was an error propagated from the case when + we are going to emit the relocation. If we are not + going to emit the relocation, then we just want to + set add_number to the difference between the symbols. + This is a case that would only arise when there is a + PC relative reference from a section other than .text + to a symbol defined in the same section, and the + reference is not relaxed. Since jump instructions on + the i386 are relaxed, this could only arise with a + call instruction. */ + pcrel = 0; /* Lie. Don't want further pcrel processing. */ if (!TC_FORCE_RELOCATION (fixP)) { @@ -4196,7 +4216,7 @@ fixup_segment (segP, this_segment_type) /* Once this fix has been applied, we don't have to output anything nothing more need be done. */ #ifdef MD_APPLY_FIX3 - md_apply_fix3 (fixP, &add_number, this_segment_type); + md_apply_fix3 (fixP, (valueT *) &add_number, this_segment_type); #else md_apply_fix (fixP, add_number); #endif @@ -4300,11 +4320,13 @@ const pseudo_typeS obj_pseudo_table[] = /* FIXME: We ignore the MRI short attribute. */ {"section.s", obj_coff_section, 0}, {"sect.s", obj_coff_section, 0}, + /* We accept the .bss directive for backward compatibility with + earlier versions of gas. */ + {"bss", obj_coff_bss, 0}, #ifndef BFD_ASSEMBLER {"use", obj_coff_section, 0}, {"text", obj_coff_text, 0}, {"data", obj_coff_data, 0}, - {"bss", obj_coff_bss, 0}, {"lcomm", obj_coff_lcomm, 0}, {"ident", obj_coff_ident, 0}, #else @@ -4349,8 +4371,8 @@ const struct format_ops coff_format_ops = 0, 1, coff_frob_symbol, - coff_frob_file, no_func, + coff_frob_file_after_relocs, 0, 0, 0, 0, 0, |