133965Sjdp/* write.c - emit .o file 278828Sobrien Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 3218822Sdim 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 433965Sjdp Free Software Foundation, Inc. 533965Sjdp 633965Sjdp This file is part of GAS, the GNU Assembler. 733965Sjdp 833965Sjdp GAS is free software; you can redistribute it and/or modify 933965Sjdp it under the terms of the GNU General Public License as published by 1033965Sjdp the Free Software Foundation; either version 2, or (at your option) 1133965Sjdp any later version. 1233965Sjdp 1333965Sjdp GAS is distributed in the hope that it will be useful, 1433965Sjdp but WITHOUT ANY WARRANTY; without even the implied warranty of 1533965Sjdp MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1633965Sjdp GNU General Public License for more details. 1733965Sjdp 1833965Sjdp You should have received a copy of the GNU General Public License 1933965Sjdp along with GAS; see the file COPYING. If not, write to the Free 20218822Sdim Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 21218822Sdim 02110-1301, USA. */ 2233965Sjdp 2377298Sobrien/* This thing should be set up to do byteordering correctly. But... */ 2433965Sjdp 2533965Sjdp#include "as.h" 2633965Sjdp#include "subsegs.h" 2733965Sjdp#include "obstack.h" 2833965Sjdp#include "output-file.h" 2977298Sobrien#include "dwarf2dbg.h" 30218822Sdim#include "libbfd.h" 3133965Sjdp 3233965Sjdp#ifndef TC_ADJUST_RELOC_COUNT 33130561Sobrien#define TC_ADJUST_RELOC_COUNT(FIX, COUNT) 3433965Sjdp#endif 3533965Sjdp 3633965Sjdp#ifndef TC_FORCE_RELOCATION 37130561Sobrien#define TC_FORCE_RELOCATION(FIX) \ 38130561Sobrien (generic_force_reloc (FIX)) 3933965Sjdp#endif 4033965Sjdp 41130561Sobrien#ifndef TC_FORCE_RELOCATION_ABS 42130561Sobrien#define TC_FORCE_RELOCATION_ABS(FIX) \ 43130561Sobrien (TC_FORCE_RELOCATION (FIX)) 4433965Sjdp#endif 4533965Sjdp 46130561Sobrien#ifndef TC_FORCE_RELOCATION_LOCAL 47130561Sobrien#define TC_FORCE_RELOCATION_LOCAL(FIX) \ 48130561Sobrien (!(FIX)->fx_pcrel \ 49130561Sobrien || TC_FORCE_RELOCATION (FIX)) 50130561Sobrien#endif 51130561Sobrien 52130561Sobrien#ifndef TC_FORCE_RELOCATION_SUB_SAME 53130561Sobrien#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEG) \ 54130561Sobrien (! SEG_NORMAL (SEG)) 55130561Sobrien#endif 56130561Sobrien 57130561Sobrien#ifndef TC_FORCE_RELOCATION_SUB_ABS 58130561Sobrien#define TC_FORCE_RELOCATION_SUB_ABS(FIX) 0 59130561Sobrien#endif 60130561Sobrien 61130561Sobrien#ifndef TC_FORCE_RELOCATION_SUB_LOCAL 62130561Sobrien#ifdef DIFF_EXPR_OK 63130561Sobrien#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX) 0 64130561Sobrien#else 65130561Sobrien#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX) 1 66130561Sobrien#endif 67130561Sobrien#endif 68130561Sobrien 69130561Sobrien#ifndef TC_VALIDATE_FIX_SUB 70130561Sobrien#ifdef UNDEFINED_DIFFERENCE_OK 71130561Sobrien/* The PA needs this for PIC code generation. */ 72130561Sobrien#define TC_VALIDATE_FIX_SUB(FIX) 1 73130561Sobrien#else 74130561Sobrien#define TC_VALIDATE_FIX_SUB(FIX) \ 75130561Sobrien ((FIX)->fx_r_type == BFD_RELOC_GPREL32 \ 76130561Sobrien || (FIX)->fx_r_type == BFD_RELOC_GPREL16) 77130561Sobrien#endif 78130561Sobrien#endif 79130561Sobrien 8077298Sobrien#ifndef TC_LINKRELAX_FIXUP 8177298Sobrien#define TC_LINKRELAX_FIXUP(SEG) 1 8277298Sobrien#endif 8377298Sobrien 84130561Sobrien#ifndef MD_APPLY_SYM_VALUE 85130561Sobrien#define MD_APPLY_SYM_VALUE(FIX) 1 8677298Sobrien#endif 8777298Sobrien 8889857Sobrien#ifndef TC_FINALIZE_SYMS_BEFORE_SIZE_SEG 8989857Sobrien#define TC_FINALIZE_SYMS_BEFORE_SIZE_SEG 1 9089857Sobrien#endif 9189857Sobrien 9233965Sjdp#ifndef MD_PCREL_FROM_SECTION 93130561Sobrien#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from (FIX) 9433965Sjdp#endif 9533965Sjdp 96218822Sdim#ifndef TC_FAKE_LABEL 97218822Sdim#define TC_FAKE_LABEL(NAME) (strcmp ((NAME), FAKE_LABEL_NAME) == 0) 9833965Sjdp#endif 9933965Sjdp 100218822Sdim/* Positive values of TC_FX_SIZE_SLACK allow a target to define 101218822Sdim fixups that far past the end of a frag. Having such fixups 102218822Sdim is of course most most likely a bug in setting fx_size correctly. 103218822Sdim A negative value disables the fixup check entirely, which is 104218822Sdim appropriate for something like the Renesas / SuperH SH_COUNT 105218822Sdim reloc. */ 106218822Sdim#ifndef TC_FX_SIZE_SLACK 107218822Sdim#define TC_FX_SIZE_SLACK(FIX) 0 108218822Sdim#endif 109218822Sdim 11089857Sobrien/* Used to control final evaluation of expressions. */ 11189857Sobrienint finalize_syms = 0; 11289857Sobrien 11333965Sjdpint symbol_table_frozen; 11433965Sjdp 115130561SobriensymbolS *abs_section_sym; 116130561Sobrien 117130561Sobrien/* Remember the value of dot when parsing expressions. */ 118130561SobrienaddressT dot_value; 119130561Sobrien 120218822Sdim/* Relocs generated by ".reloc" pseudo. */ 121218822Sdimstruct reloc_list* reloc_list; 122218822Sdim 123130561Sobrienvoid print_fixup (fixS *); 124130561Sobrien 12533965Sjdp/* We generally attach relocs to frag chains. However, after we have 12633965Sjdp chained these all together into a segment, any relocs we add after 12733965Sjdp that must be attached to a segment. This will include relocs added 12833965Sjdp in md_estimate_size_for_relax, for example. */ 12933965Sjdpstatic int frags_chained = 0; 13033965Sjdp 13133965Sjdpstatic int n_fixups; 13233965Sjdp 133130561Sobrien#define RELOC_ENUM enum bfd_reloc_code_real 134130561Sobrien 13577298Sobrien/* Create a fixS in obstack 'notes'. */ 13677298Sobrien 13733965Sjdpstatic fixS * 138130561Sobrienfix_new_internal (fragS *frag, /* Which frag? */ 139130561Sobrien int where, /* Where in that frag? */ 140130561Sobrien int size, /* 1, 2, or 4 usually. */ 141130561Sobrien symbolS *add_symbol, /* X_add_symbol. */ 142130561Sobrien symbolS *sub_symbol, /* X_op_symbol. */ 143130561Sobrien offsetT offset, /* X_add_number. */ 144130561Sobrien int pcrel, /* TRUE if PC-relative relocation. */ 145130561Sobrien RELOC_ENUM r_type ATTRIBUTE_UNUSED /* Relocation type. */) 14633965Sjdp{ 14733965Sjdp fixS *fixP; 14833965Sjdp 14933965Sjdp n_fixups++; 15033965Sjdp 151218822Sdim fixP = obstack_alloc (¬es, sizeof (fixS)); 15233965Sjdp 15333965Sjdp fixP->fx_frag = frag; 15433965Sjdp fixP->fx_where = where; 15533965Sjdp fixP->fx_size = size; 15633965Sjdp /* We've made fx_size a narrow field; check that it's wide enough. */ 15733965Sjdp if (fixP->fx_size != size) 15833965Sjdp { 15960484Sobrien as_bad (_("field fx_size too small to hold %d"), size); 16033965Sjdp abort (); 16133965Sjdp } 16233965Sjdp fixP->fx_addsy = add_symbol; 16333965Sjdp fixP->fx_subsy = sub_symbol; 16433965Sjdp fixP->fx_offset = offset; 165130561Sobrien fixP->fx_dot_value = dot_value; 16633965Sjdp fixP->fx_pcrel = pcrel; 16733965Sjdp fixP->fx_r_type = r_type; 16833965Sjdp fixP->fx_im_disp = 0; 16933965Sjdp fixP->fx_pcrel_adjust = 0; 17033965Sjdp fixP->fx_bit_fixP = 0; 17133965Sjdp fixP->fx_addnumber = 0; 17233965Sjdp fixP->fx_tcbit = 0; 173218822Sdim fixP->fx_tcbit2 = 0; 17433965Sjdp fixP->fx_done = 0; 17533965Sjdp fixP->fx_no_overflow = 0; 17633965Sjdp fixP->fx_signed = 0; 17733965Sjdp 17860484Sobrien#ifdef USING_CGEN 17960484Sobrien fixP->fx_cgen.insn = NULL; 18060484Sobrien fixP->fx_cgen.opinfo = 0; 18160484Sobrien#endif 18260484Sobrien 18333965Sjdp#ifdef TC_FIX_TYPE 18477298Sobrien TC_INIT_FIX_DATA (fixP); 18533965Sjdp#endif 18633965Sjdp 18733965Sjdp as_where (&fixP->fx_file, &fixP->fx_line); 18833965Sjdp 18933965Sjdp /* Usually, we want relocs sorted numerically, but while 19033965Sjdp comparing to older versions of gas that have relocs 19133965Sjdp reverse sorted, it is convenient to have this compile 19277298Sobrien time option. xoxorich. */ 19333965Sjdp { 19433965Sjdp 19533965Sjdp fixS **seg_fix_rootP = (frags_chained 19633965Sjdp ? &seg_info (now_seg)->fix_root 19733965Sjdp : &frchain_now->fix_root); 19833965Sjdp fixS **seg_fix_tailP = (frags_chained 19933965Sjdp ? &seg_info (now_seg)->fix_tail 20033965Sjdp : &frchain_now->fix_tail); 20133965Sjdp 20233965Sjdp#ifdef REVERSE_SORT_RELOCS 20333965Sjdp 20433965Sjdp fixP->fx_next = *seg_fix_rootP; 20533965Sjdp *seg_fix_rootP = fixP; 20633965Sjdp 20777298Sobrien#else /* REVERSE_SORT_RELOCS */ 20833965Sjdp 20933965Sjdp fixP->fx_next = NULL; 21033965Sjdp 21133965Sjdp if (*seg_fix_tailP) 21233965Sjdp (*seg_fix_tailP)->fx_next = fixP; 21333965Sjdp else 21433965Sjdp *seg_fix_rootP = fixP; 21533965Sjdp *seg_fix_tailP = fixP; 21633965Sjdp 21777298Sobrien#endif /* REVERSE_SORT_RELOCS */ 21833965Sjdp } 21933965Sjdp 22033965Sjdp return fixP; 22133965Sjdp} 22233965Sjdp 22333965Sjdp/* Create a fixup relative to a symbol (plus a constant). */ 22433965Sjdp 22533965SjdpfixS * 226130561Sobrienfix_new (fragS *frag, /* Which frag? */ 227130561Sobrien int where, /* Where in that frag? */ 228130561Sobrien int size, /* 1, 2, or 4 usually. */ 229130561Sobrien symbolS *add_symbol, /* X_add_symbol. */ 230130561Sobrien offsetT offset, /* X_add_number. */ 231130561Sobrien int pcrel, /* TRUE if PC-relative relocation. */ 232130561Sobrien RELOC_ENUM r_type /* Relocation type. */) 23333965Sjdp{ 23433965Sjdp return fix_new_internal (frag, where, size, add_symbol, 23533965Sjdp (symbolS *) NULL, offset, pcrel, r_type); 23633965Sjdp} 23733965Sjdp 23833965Sjdp/* Create a fixup for an expression. Currently we only support fixups 23933965Sjdp for difference expressions. That is itself more than most object 24033965Sjdp file formats support anyhow. */ 24133965Sjdp 24233965SjdpfixS * 243130561Sobrienfix_new_exp (fragS *frag, /* Which frag? */ 244130561Sobrien int where, /* Where in that frag? */ 245130561Sobrien int size, /* 1, 2, or 4 usually. */ 246130561Sobrien expressionS *exp, /* Expression. */ 247130561Sobrien int pcrel, /* TRUE if PC-relative relocation. */ 248130561Sobrien RELOC_ENUM r_type /* Relocation type. */) 24933965Sjdp{ 25033965Sjdp symbolS *add = NULL; 25133965Sjdp symbolS *sub = NULL; 25233965Sjdp offsetT off = 0; 25333965Sjdp 25433965Sjdp switch (exp->X_op) 25533965Sjdp { 25633965Sjdp case O_absent: 25733965Sjdp break; 25833965Sjdp 25978828Sobrien case O_register: 26078828Sobrien as_bad (_("register value used as expression")); 26178828Sobrien break; 26278828Sobrien 26333965Sjdp case O_add: 26433965Sjdp /* This comes up when _GLOBAL_OFFSET_TABLE_+(.-L0) is read, if 26533965Sjdp the difference expression cannot immediately be reduced. */ 26633965Sjdp { 26733965Sjdp symbolS *stmp = make_expr_symbol (exp); 26877298Sobrien 26933965Sjdp exp->X_op = O_symbol; 27033965Sjdp exp->X_op_symbol = 0; 27133965Sjdp exp->X_add_symbol = stmp; 27233965Sjdp exp->X_add_number = 0; 27377298Sobrien 27433965Sjdp return fix_new_exp (frag, where, size, exp, pcrel, r_type); 27533965Sjdp } 27633965Sjdp 27733965Sjdp case O_symbol_rva: 27833965Sjdp add = exp->X_add_symbol; 27933965Sjdp off = exp->X_add_number; 28033965Sjdp r_type = BFD_RELOC_RVA; 28133965Sjdp break; 28233965Sjdp 28333965Sjdp case O_uminus: 28433965Sjdp sub = exp->X_add_symbol; 28533965Sjdp off = exp->X_add_number; 28633965Sjdp break; 28733965Sjdp 28833965Sjdp case O_subtract: 28933965Sjdp sub = exp->X_op_symbol; 29033965Sjdp /* Fall through. */ 29133965Sjdp case O_symbol: 29233965Sjdp add = exp->X_add_symbol; 29377298Sobrien /* Fall through. */ 29433965Sjdp case O_constant: 29533965Sjdp off = exp->X_add_number; 29633965Sjdp break; 29733965Sjdp 29833965Sjdp default: 29933965Sjdp add = make_expr_symbol (exp); 30033965Sjdp break; 30133965Sjdp } 30233965Sjdp 30377298Sobrien return fix_new_internal (frag, where, size, add, sub, off, pcrel, r_type); 30433965Sjdp} 30533965Sjdp 306130561Sobrien/* Generic function to determine whether a fixup requires a relocation. */ 307130561Sobrienint 308130561Sobriengeneric_force_reloc (fixS *fix) 309130561Sobrien{ 310130561Sobrien if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT 311130561Sobrien || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY) 312130561Sobrien return 1; 313218822Sdim 314218822Sdim if (fix->fx_addsy == NULL) 315218822Sdim return 0; 316218822Sdim 317130561Sobrien return S_FORCE_RELOC (fix->fx_addsy, fix->fx_subsy == NULL); 318130561Sobrien} 319130561Sobrien 32033965Sjdp/* Append a string onto another string, bumping the pointer along. */ 32133965Sjdpvoid 322130561Sobrienappend (char **charPP, char *fromP, unsigned long length) 32333965Sjdp{ 32477298Sobrien /* Don't trust memcpy() of 0 chars. */ 32533965Sjdp if (length == 0) 32633965Sjdp return; 32733965Sjdp 32833965Sjdp memcpy (*charPP, fromP, length); 32933965Sjdp *charPP += length; 33033965Sjdp} 33133965Sjdp 33277298Sobrien/* This routine records the largest alignment seen for each segment. 33377298Sobrien If the beginning of the segment is aligned on the worst-case 33477298Sobrien boundary, all of the other alignments within it will work. At 33577298Sobrien least one object format really uses this info. */ 33677298Sobrien 33733965Sjdpvoid 338130561Sobrienrecord_alignment (/* Segment to which alignment pertains. */ 339130561Sobrien segT seg, 340130561Sobrien /* Alignment, as a power of 2 (e.g., 1 => 2-byte 341130561Sobrien boundary, 2 => 4-byte boundary, etc.) */ 342130561Sobrien int align) 34333965Sjdp{ 34433965Sjdp if (seg == absolute_section) 34533965Sjdp return; 346218822Sdim 34738889Sjdp if ((unsigned int) align > bfd_get_section_alignment (stdoutput, seg)) 348222205Sbenl (void) bfd_set_section_alignment (stdoutput, seg, align); 34933965Sjdp} 35033965Sjdp 35177298Sobrienint 352130561Sobrienget_recorded_alignment (segT seg) 35377298Sobrien{ 35477298Sobrien if (seg == absolute_section) 35577298Sobrien return 0; 356218822Sdim 35777298Sobrien return bfd_get_section_alignment (stdoutput, seg); 35877298Sobrien} 35933965Sjdp 36033965Sjdp/* Reset the section indices after removing the gas created sections. */ 36133965Sjdp 36233965Sjdpstatic void 363218822Sdimrenumber_sections (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *countparg) 36433965Sjdp{ 36533965Sjdp int *countp = (int *) countparg; 36633965Sjdp 36733965Sjdp sec->index = *countp; 36833965Sjdp ++*countp; 36933965Sjdp} 37033965Sjdp 37133965Sjdpstatic fragS * 372130561Sobrienchain_frchains_together_1 (segT section, struct frchain *frchp) 37333965Sjdp{ 37433965Sjdp fragS dummy, *prev_frag = &dummy; 37533965Sjdp fixS fix_dummy, *prev_fix = &fix_dummy; 37633965Sjdp 377218822Sdim for (; frchp; frchp = frchp->frch_next) 37833965Sjdp { 37933965Sjdp prev_frag->fr_next = frchp->frch_root; 38033965Sjdp prev_frag = frchp->frch_last; 38133965Sjdp assert (prev_frag->fr_type != 0); 38233965Sjdp if (frchp->fix_root != (fixS *) NULL) 38333965Sjdp { 38433965Sjdp if (seg_info (section)->fix_root == (fixS *) NULL) 38533965Sjdp seg_info (section)->fix_root = frchp->fix_root; 38633965Sjdp prev_fix->fx_next = frchp->fix_root; 38733965Sjdp seg_info (section)->fix_tail = frchp->fix_tail; 38833965Sjdp prev_fix = frchp->fix_tail; 38933965Sjdp } 39033965Sjdp } 39133965Sjdp assert (prev_frag->fr_type != 0); 392218822Sdim assert (prev_frag != &dummy); 39333965Sjdp prev_frag->fr_next = 0; 39433965Sjdp return prev_frag; 39533965Sjdp} 39633965Sjdp 39733965Sjdpstatic void 398130561Sobrienchain_frchains_together (bfd *abfd ATTRIBUTE_UNUSED, 399130561Sobrien segT section, 400218822Sdim void *xxx ATTRIBUTE_UNUSED) 40133965Sjdp{ 40233965Sjdp segment_info_type *info; 40333965Sjdp 40433965Sjdp /* BFD may have introduced its own sections without using 40533965Sjdp subseg_new, so it is possible that seg_info is NULL. */ 40633965Sjdp info = seg_info (section); 40733965Sjdp if (info != (segment_info_type *) NULL) 40877298Sobrien info->frchainP->frch_last 40977298Sobrien = chain_frchains_together_1 (section, info->frchainP); 41033965Sjdp 41133965Sjdp /* Now that we've chained the frags together, we must add new fixups 41233965Sjdp to the segment, not to the frag chain. */ 41333965Sjdp frags_chained = 1; 41433965Sjdp} 41533965Sjdp 41633965Sjdpstatic void 417130561Sobriencvt_frag_to_fill (segT sec ATTRIBUTE_UNUSED, fragS *fragP) 41833965Sjdp{ 41933965Sjdp switch (fragP->fr_type) 42033965Sjdp { 42133965Sjdp case rs_align: 42233965Sjdp case rs_align_code: 42377298Sobrien case rs_align_test: 42433965Sjdp case rs_org: 42533965Sjdp case rs_space: 42633965Sjdp#ifdef HANDLE_ALIGN 42733965Sjdp HANDLE_ALIGN (fragP); 42833965Sjdp#endif 42933965Sjdp know (fragP->fr_next != NULL); 43033965Sjdp fragP->fr_offset = (fragP->fr_next->fr_address 43133965Sjdp - fragP->fr_address 43233965Sjdp - fragP->fr_fix) / fragP->fr_var; 43333965Sjdp if (fragP->fr_offset < 0) 43433965Sjdp { 43560484Sobrien as_bad_where (fragP->fr_file, fragP->fr_line, 43660484Sobrien _("attempt to .org/.space backwards? (%ld)"), 43760484Sobrien (long) fragP->fr_offset); 438104834Sobrien fragP->fr_offset = 0; 43933965Sjdp } 44033965Sjdp fragP->fr_type = rs_fill; 44133965Sjdp break; 44233965Sjdp 44333965Sjdp case rs_fill: 44433965Sjdp break; 44533965Sjdp 44638889Sjdp case rs_leb128: 44738889Sjdp { 44838889Sjdp valueT value = S_GET_VALUE (fragP->fr_symbol); 44938889Sjdp int size; 45038889Sjdp 45138889Sjdp size = output_leb128 (fragP->fr_literal + fragP->fr_fix, value, 45238889Sjdp fragP->fr_subtype); 45338889Sjdp 45438889Sjdp fragP->fr_fix += size; 45538889Sjdp fragP->fr_type = rs_fill; 45638889Sjdp fragP->fr_var = 0; 45738889Sjdp fragP->fr_offset = 0; 45838889Sjdp fragP->fr_symbol = NULL; 45938889Sjdp } 46038889Sjdp break; 46138889Sjdp 46238889Sjdp case rs_cfa: 46338889Sjdp eh_frame_convert_frag (fragP); 46438889Sjdp break; 46538889Sjdp 46677298Sobrien case rs_dwarf2dbg: 46777298Sobrien dwarf2dbg_convert_frag (fragP); 46877298Sobrien break; 46977298Sobrien 47033965Sjdp case rs_machine_dependent: 47133965Sjdp md_convert_frag (stdoutput, sec, fragP); 47233965Sjdp 47338889Sjdp assert (fragP->fr_next == NULL 47438889Sjdp || ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address) 47538889Sjdp == fragP->fr_fix)); 47633965Sjdp 47777298Sobrien /* After md_convert_frag, we make the frag into a ".space 0". 47877298Sobrien md_convert_frag() should set up any fixSs and constants 47977298Sobrien required. */ 48033965Sjdp frag_wane (fragP); 48133965Sjdp break; 48233965Sjdp 48333965Sjdp#ifndef WORKING_DOT_WORD 48433965Sjdp case rs_broken_word: 48533965Sjdp { 48633965Sjdp struct broken_word *lie; 48733965Sjdp 48833965Sjdp if (fragP->fr_subtype) 48933965Sjdp { 49033965Sjdp fragP->fr_fix += md_short_jump_size; 49133965Sjdp for (lie = (struct broken_word *) (fragP->fr_symbol); 49233965Sjdp lie && lie->dispfrag == fragP; 49333965Sjdp lie = lie->next_broken_word) 49433965Sjdp if (lie->added == 1) 49533965Sjdp fragP->fr_fix += md_long_jump_size; 49633965Sjdp } 49733965Sjdp frag_wane (fragP); 49833965Sjdp } 49933965Sjdp break; 50033965Sjdp#endif 50133965Sjdp 50233965Sjdp default: 50333965Sjdp BAD_CASE (fragP->fr_type); 50433965Sjdp break; 50533965Sjdp } 506218822Sdim#ifdef md_frag_check 507218822Sdim md_frag_check (fragP); 508218822Sdim#endif 50933965Sjdp} 51033965Sjdp 511218822Sdimstruct relax_seg_info 512218822Sdim{ 513218822Sdim int pass; 514218822Sdim int changed; 515218822Sdim}; 51633965Sjdp 51733965Sjdpstatic void 518218822Sdimrelax_seg (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *xxx) 51977298Sobrien{ 52077298Sobrien segment_info_type *seginfo = seg_info (sec); 521218822Sdim struct relax_seg_info *info = (struct relax_seg_info *) xxx; 52277298Sobrien 52389857Sobrien if (seginfo && seginfo->frchainP 524218822Sdim && relax_segment (seginfo->frchainP->frch_root, sec, info->pass)) 525218822Sdim info->changed = 1; 52677298Sobrien} 52777298Sobrien 52877298Sobrienstatic void 529218822Sdimsize_seg (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED) 53033965Sjdp{ 53133965Sjdp flagword flags; 53233965Sjdp fragS *fragp; 53333965Sjdp segment_info_type *seginfo; 53433965Sjdp int x; 53533965Sjdp valueT size, newsize; 53633965Sjdp 53733965Sjdp subseg_change (sec, 0); 53833965Sjdp 53933965Sjdp seginfo = seg_info (sec); 54033965Sjdp if (seginfo && seginfo->frchainP) 54133965Sjdp { 54233965Sjdp for (fragp = seginfo->frchainP->frch_root; fragp; fragp = fragp->fr_next) 54333965Sjdp cvt_frag_to_fill (sec, fragp); 54433965Sjdp for (fragp = seginfo->frchainP->frch_root; 54533965Sjdp fragp->fr_next; 54633965Sjdp fragp = fragp->fr_next) 54777298Sobrien /* Walk to last elt. */ 54877298Sobrien ; 54933965Sjdp size = fragp->fr_address + fragp->fr_fix; 55033965Sjdp } 55133965Sjdp else 55233965Sjdp size = 0; 55333965Sjdp 55477298Sobrien flags = bfd_get_section_flags (abfd, sec); 55577298Sobrien 55633965Sjdp if (size > 0 && ! seginfo->bss) 55733965Sjdp flags |= SEC_HAS_CONTENTS; 55833965Sjdp 559218822Sdim flags &= ~SEC_RELOC; 56033965Sjdp x = bfd_set_section_flags (abfd, sec, flags); 561130561Sobrien assert (x); 56233965Sjdp 56333965Sjdp newsize = md_section_align (sec, size); 56433965Sjdp x = bfd_set_section_size (abfd, sec, newsize); 565130561Sobrien assert (x); 56633965Sjdp 56733965Sjdp /* If the size had to be rounded up, add some padding in the last 56833965Sjdp non-empty frag. */ 56933965Sjdp assert (newsize >= size); 57033965Sjdp if (size != newsize) 57133965Sjdp { 57233965Sjdp fragS *last = seginfo->frchainP->frch_last; 57333965Sjdp fragp = seginfo->frchainP->frch_root; 57433965Sjdp while (fragp->fr_next != last) 57533965Sjdp fragp = fragp->fr_next; 57633965Sjdp last->fr_address = size; 577104834Sobrien if ((newsize - size) % fragp->fr_var == 0) 578104834Sobrien fragp->fr_offset += (newsize - size) / fragp->fr_var; 579104834Sobrien else 580104834Sobrien /* If we hit this abort, it's likely due to subsegs_finish not 581104834Sobrien providing sufficient alignment on the last frag, and the 582104834Sobrien machine dependent code using alignment frags with fr_var 583104834Sobrien greater than 1. */ 584104834Sobrien abort (); 58533965Sjdp } 58633965Sjdp 58733965Sjdp#ifdef tc_frob_section 58833965Sjdp tc_frob_section (sec); 58933965Sjdp#endif 59033965Sjdp#ifdef obj_frob_section 59133965Sjdp obj_frob_section (sec); 59233965Sjdp#endif 59333965Sjdp} 59433965Sjdp 59533965Sjdp#ifdef DEBUG2 59633965Sjdpstatic void 597218822Sdimdump_section_relocs (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, FILE *stream) 59833965Sjdp{ 59933965Sjdp segment_info_type *seginfo = seg_info (sec); 60033965Sjdp fixS *fixp = seginfo->fix_root; 60133965Sjdp 60233965Sjdp if (!fixp) 60333965Sjdp return; 60433965Sjdp 60533965Sjdp fprintf (stream, "sec %s relocs:\n", sec->name); 60633965Sjdp while (fixp) 60733965Sjdp { 60833965Sjdp symbolS *s = fixp->fx_addsy; 60960484Sobrien 61060484Sobrien fprintf (stream, " %08lx: type %d ", (unsigned long) fixp, 61160484Sobrien (int) fixp->fx_r_type); 61260484Sobrien if (s == NULL) 61360484Sobrien fprintf (stream, "no sym\n"); 61460484Sobrien else 61533965Sjdp { 61660484Sobrien print_symbol_value_1 (stream, s); 61760484Sobrien fprintf (stream, "\n"); 61833965Sjdp } 61933965Sjdp fixp = fixp->fx_next; 62033965Sjdp } 62133965Sjdp} 62233965Sjdp#else 62333965Sjdp#define dump_section_relocs(ABFD,SEC,STREAM) ((void) 0) 62433965Sjdp#endif 62533965Sjdp 62633965Sjdp#ifndef EMIT_SECTION_SYMBOLS 62733965Sjdp#define EMIT_SECTION_SYMBOLS 1 62833965Sjdp#endif 62933965Sjdp 630218822Sdim/* Resolve U.A.OFFSET_SYM and U.A.SYM fields of RELOC_LIST entries, 631218822Sdim and check for validity. Convert RELOC_LIST from using U.A fields 632218822Sdim to U.B fields. */ 633218822Sdimstatic void 634218822Sdimresolve_reloc_expr_symbols (void) 635218822Sdim{ 636218822Sdim struct reloc_list *r; 637218822Sdim 638218822Sdim for (r = reloc_list; r; r = r->next) 639218822Sdim { 640218822Sdim expressionS *symval; 641218822Sdim symbolS *sym; 642218822Sdim bfd_vma offset, addend; 643218822Sdim asection *sec; 644218822Sdim reloc_howto_type *howto; 645218822Sdim 646218822Sdim resolve_symbol_value (r->u.a.offset_sym); 647218822Sdim symval = symbol_get_value_expression (r->u.a.offset_sym); 648218822Sdim 649218822Sdim offset = 0; 650218822Sdim sym = NULL; 651218822Sdim if (symval->X_op == O_constant) 652218822Sdim sym = r->u.a.offset_sym; 653218822Sdim else if (symval->X_op == O_symbol) 654218822Sdim { 655218822Sdim sym = symval->X_add_symbol; 656218822Sdim offset = symval->X_add_number; 657218822Sdim symval = symbol_get_value_expression (symval->X_add_symbol); 658218822Sdim } 659218822Sdim if (sym == NULL 660218822Sdim || symval->X_op != O_constant 661218822Sdim || (sec = S_GET_SEGMENT (sym)) == NULL 662218822Sdim || !SEG_NORMAL (sec)) 663218822Sdim { 664218822Sdim as_bad_where (r->file, r->line, _("invalid offset expression")); 665218822Sdim sec = NULL; 666218822Sdim } 667218822Sdim else 668218822Sdim offset += S_GET_VALUE (sym); 669218822Sdim 670218822Sdim sym = NULL; 671218822Sdim addend = r->u.a.addend; 672218822Sdim if (r->u.a.sym != NULL) 673218822Sdim { 674218822Sdim resolve_symbol_value (r->u.a.sym); 675218822Sdim symval = symbol_get_value_expression (r->u.a.sym); 676218822Sdim if (symval->X_op == O_constant) 677218822Sdim sym = r->u.a.sym; 678218822Sdim else if (symval->X_op == O_symbol) 679218822Sdim { 680218822Sdim sym = symval->X_add_symbol; 681218822Sdim addend += symval->X_add_number; 682218822Sdim symval = symbol_get_value_expression (symval->X_add_symbol); 683218822Sdim } 684218822Sdim if (symval->X_op != O_constant) 685218822Sdim { 686218822Sdim as_bad_where (r->file, r->line, _("invalid reloc expression")); 687218822Sdim sec = NULL; 688218822Sdim } 689218822Sdim else if (sym != NULL) 690218822Sdim symbol_mark_used_in_reloc (sym); 691218822Sdim } 692218822Sdim if (sym == NULL) 693218822Sdim { 694218822Sdim if (abs_section_sym == NULL) 695218822Sdim abs_section_sym = section_symbol (absolute_section); 696218822Sdim sym = abs_section_sym; 697218822Sdim } 698218822Sdim 699218822Sdim howto = r->u.a.howto; 700218822Sdim 701218822Sdim r->u.b.sec = sec; 702218822Sdim r->u.b.s = symbol_get_bfdsym (sym); 703218822Sdim r->u.b.r.sym_ptr_ptr = &r->u.b.s; 704218822Sdim r->u.b.r.address = offset; 705218822Sdim r->u.b.r.addend = addend; 706218822Sdim r->u.b.r.howto = howto; 707218822Sdim } 708218822Sdim} 709218822Sdim 710130561Sobrien/* This pass over fixups decides whether symbols can be replaced with 711130561Sobrien section symbols. */ 712130561Sobrien 71333965Sjdpstatic void 714130561Sobrienadjust_reloc_syms (bfd *abfd ATTRIBUTE_UNUSED, 715130561Sobrien asection *sec, 716218822Sdim void *xxx ATTRIBUTE_UNUSED) 71733965Sjdp{ 71833965Sjdp segment_info_type *seginfo = seg_info (sec); 71933965Sjdp fixS *fixp; 72033965Sjdp 72133965Sjdp if (seginfo == NULL) 72233965Sjdp return; 72333965Sjdp 72433965Sjdp dump_section_relocs (abfd, sec, stderr); 72533965Sjdp 72633965Sjdp for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next) 72733965Sjdp if (fixp->fx_done) 72877298Sobrien /* Ignore it. */ 72977298Sobrien ; 73033965Sjdp else if (fixp->fx_addsy) 73133965Sjdp { 73233965Sjdp symbolS *sym; 73333965Sjdp asection *symsec; 73433965Sjdp 73533965Sjdp#ifdef DEBUG5 73633965Sjdp fprintf (stderr, "\n\nadjusting fixup:\n"); 73733965Sjdp print_fixup (fixp); 73833965Sjdp#endif 73933965Sjdp 74033965Sjdp sym = fixp->fx_addsy; 74133965Sjdp 74233965Sjdp /* All symbols should have already been resolved at this 74333965Sjdp point. It is possible to see unresolved expression 74433965Sjdp symbols, though, since they are not in the regular symbol 74533965Sjdp table. */ 746130561Sobrien resolve_symbol_value (sym); 74777298Sobrien 74860484Sobrien if (fixp->fx_subsy != NULL) 74989857Sobrien resolve_symbol_value (fixp->fx_subsy); 75033965Sjdp 751218822Sdim /* If this symbol is equated to an undefined or common symbol, 752218822Sdim convert the fixup to being against that symbol. */ 753218822Sdim while (symbol_equated_reloc_p (sym) 754218822Sdim || S_IS_WEAKREFR (sym)) 75533965Sjdp { 756218822Sdim symbolS *newsym = symbol_get_value_expression (sym)->X_add_symbol; 757218822Sdim if (sym == newsym) 758218822Sdim break; 75960484Sobrien fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number; 760218822Sdim fixp->fx_addsy = newsym; 761218822Sdim sym = newsym; 76233965Sjdp } 76333965Sjdp 764130561Sobrien if (symbol_mri_common_p (sym)) 76533965Sjdp { 766218822Sdim fixp->fx_offset += S_GET_VALUE (sym); 767218822Sdim fixp->fx_addsy = symbol_get_value_expression (sym)->X_add_symbol; 768130561Sobrien continue; 76933965Sjdp } 77033965Sjdp 771130561Sobrien /* If the symbol is undefined, common, weak, or global (ELF 772130561Sobrien shared libs), we can't replace it with the section symbol. */ 773130561Sobrien if (S_FORCE_RELOC (fixp->fx_addsy, 1)) 774130561Sobrien continue; 775130561Sobrien 776130561Sobrien /* Is there some other (target cpu dependent) reason we can't adjust 777130561Sobrien this one? (E.g. relocations involving function addresses on 778130561Sobrien the PA. */ 779130561Sobrien#ifdef tc_fix_adjustable 780130561Sobrien if (! tc_fix_adjustable (fixp)) 781130561Sobrien continue; 782130561Sobrien#endif 783130561Sobrien 784130561Sobrien /* Since we're reducing to section symbols, don't attempt to reduce 785130561Sobrien anything that's already using one. */ 786130561Sobrien if (symbol_section_p (sym)) 787130561Sobrien continue; 788130561Sobrien 78960484Sobrien symsec = S_GET_SEGMENT (sym); 79060484Sobrien if (symsec == NULL) 79160484Sobrien abort (); 79277298Sobrien 79333965Sjdp if (bfd_is_abs_section (symsec)) 79433965Sjdp { 795130561Sobrien /* The fixup_segment routine normally will not use this 796218822Sdim symbol in a relocation. */ 797130561Sobrien continue; 79833965Sjdp } 79933965Sjdp 80060484Sobrien /* Don't try to reduce relocs which refer to non-local symbols 801218822Sdim in .linkonce sections. It can lead to confusion when a 802218822Sdim debugging section refers to a .linkonce section. I hope 803218822Sdim this will always be correct. */ 80460484Sobrien if (symsec != sec && ! S_IS_LOCAL (sym)) 80533965Sjdp { 806130561Sobrien if ((symsec->flags & SEC_LINK_ONCE) != 0 807130561Sobrien || (IS_ELF 808130561Sobrien /* The GNU toolchain uses an extension for ELF: a 809130561Sobrien section beginning with the magic string 810130561Sobrien .gnu.linkonce is a linkonce section. */ 811130561Sobrien && strncmp (segment_name (symsec), ".gnu.linkonce", 812130561Sobrien sizeof ".gnu.linkonce" - 1) == 0)) 813130561Sobrien continue; 81433965Sjdp } 81533965Sjdp 81689857Sobrien /* Never adjust a reloc against local symbol in a merge section 81789857Sobrien with non-zero addend. */ 818107492Sobrien if ((symsec->flags & SEC_MERGE) != 0 819107492Sobrien && (fixp->fx_offset != 0 || fixp->fx_subsy != NULL)) 820130561Sobrien continue; 821104834Sobrien 822104834Sobrien /* Never adjust a reloc against TLS local symbol. */ 823130561Sobrien if ((symsec->flags & SEC_THREAD_LOCAL) != 0) 824130561Sobrien continue; 82560484Sobrien 826130561Sobrien /* We refetch the segment when calling section_symbol, rather 82733965Sjdp than using symsec, because S_GET_VALUE may wind up changing 82877298Sobrien the section when it calls resolve_symbol_value. */ 82933965Sjdp fixp->fx_offset += S_GET_VALUE (sym); 83033965Sjdp fixp->fx_addsy = section_symbol (S_GET_SEGMENT (sym)); 83160484Sobrien#ifdef DEBUG5 83260484Sobrien fprintf (stderr, "\nadjusted fixup:\n"); 83360484Sobrien print_fixup (fixp); 83460484Sobrien#endif 83533965Sjdp } 83633965Sjdp 83733965Sjdp dump_section_relocs (abfd, sec, stderr); 83833965Sjdp} 83933965Sjdp 840218822Sdim/* fixup_segment() 841218822Sdim 842218822Sdim Go through all the fixS's in a segment and see which ones can be 843218822Sdim handled now. (These consist of fixS where we have since discovered 844218822Sdim the value of a symbol, or the address of the frag involved.) 845218822Sdim For each one, call md_apply_fix to put the fix into the frag data. 846218822Sdim 847218822Sdim Result is a count of how many relocation structs will be needed to 848218822Sdim handle the remaining fixS's that we couldn't completely handle here. 849218822Sdim These will be output later by emit_relocations(). */ 850218822Sdim 851218822Sdimstatic long 852218822Sdimfixup_segment (fixS *fixP, segT this_segment) 853218822Sdim{ 854218822Sdim long seg_reloc_count = 0; 855218822Sdim valueT add_number; 856218822Sdim fragS *fragP; 857218822Sdim segT add_symbol_segment = absolute_section; 858218822Sdim 859218822Sdim if (fixP != NULL && abs_section_sym == NULL) 860218822Sdim abs_section_sym = section_symbol (absolute_section); 861218822Sdim 862218822Sdim /* If the linker is doing the relaxing, we must not do any fixups. 863218822Sdim 864218822Sdim Well, strictly speaking that's not true -- we could do any that 865218822Sdim are PC-relative and don't cross regions that could change size. 866218822Sdim And for the i960 we might be able to turn callx/callj into bal 867218822Sdim anyways in cases where we know the maximum displacement. */ 868218822Sdim if (linkrelax && TC_LINKRELAX_FIXUP (this_segment)) 869218822Sdim { 870218822Sdim for (; fixP; fixP = fixP->fx_next) 871218822Sdim if (!fixP->fx_done) 872218822Sdim { 873218822Sdim if (fixP->fx_addsy == NULL) 874218822Sdim { 875218822Sdim /* There was no symbol required by this relocation. 876218822Sdim However, BFD doesn't really handle relocations 877218822Sdim without symbols well. So fake up a local symbol in 878218822Sdim the absolute section. */ 879218822Sdim fixP->fx_addsy = abs_section_sym; 880218822Sdim } 881218822Sdim symbol_mark_used_in_reloc (fixP->fx_addsy); 882218822Sdim if (fixP->fx_subsy != NULL) 883218822Sdim symbol_mark_used_in_reloc (fixP->fx_subsy); 884218822Sdim seg_reloc_count++; 885218822Sdim } 886218822Sdim TC_ADJUST_RELOC_COUNT (fixP, seg_reloc_count); 887218822Sdim return seg_reloc_count; 888218822Sdim } 889218822Sdim 890218822Sdim for (; fixP; fixP = fixP->fx_next) 891218822Sdim { 892218822Sdim#ifdef DEBUG5 893218822Sdim fprintf (stderr, "\nprocessing fixup:\n"); 894218822Sdim print_fixup (fixP); 895218822Sdim#endif 896218822Sdim 897218822Sdim fragP = fixP->fx_frag; 898218822Sdim know (fragP); 899218822Sdim#ifdef TC_VALIDATE_FIX 900218822Sdim TC_VALIDATE_FIX (fixP, this_segment, skip); 901218822Sdim#endif 902218822Sdim add_number = fixP->fx_offset; 903218822Sdim 904218822Sdim if (fixP->fx_addsy != NULL) 905218822Sdim add_symbol_segment = S_GET_SEGMENT (fixP->fx_addsy); 906218822Sdim 907218822Sdim if (fixP->fx_subsy != NULL) 908218822Sdim { 909218822Sdim segT sub_symbol_segment; 910218822Sdim resolve_symbol_value (fixP->fx_subsy); 911218822Sdim sub_symbol_segment = S_GET_SEGMENT (fixP->fx_subsy); 912218822Sdim if (fixP->fx_addsy != NULL 913218822Sdim && sub_symbol_segment == add_symbol_segment 914218822Sdim && !TC_FORCE_RELOCATION_SUB_SAME (fixP, add_symbol_segment)) 915218822Sdim { 916218822Sdim add_number += S_GET_VALUE (fixP->fx_addsy); 917218822Sdim add_number -= S_GET_VALUE (fixP->fx_subsy); 918218822Sdim fixP->fx_offset = add_number; 919218822Sdim fixP->fx_addsy = NULL; 920218822Sdim fixP->fx_subsy = NULL; 921218822Sdim#ifdef TC_M68K 922218822Sdim /* See the comment below about 68k weirdness. */ 923218822Sdim fixP->fx_pcrel = 0; 924218822Sdim#endif 925218822Sdim } 926218822Sdim else if (sub_symbol_segment == absolute_section 927218822Sdim && !TC_FORCE_RELOCATION_SUB_ABS (fixP)) 928218822Sdim { 929218822Sdim add_number -= S_GET_VALUE (fixP->fx_subsy); 930218822Sdim fixP->fx_offset = add_number; 931218822Sdim fixP->fx_subsy = NULL; 932218822Sdim } 933218822Sdim else if (sub_symbol_segment == this_segment 934218822Sdim && !TC_FORCE_RELOCATION_SUB_LOCAL (fixP)) 935218822Sdim { 936218822Sdim add_number -= S_GET_VALUE (fixP->fx_subsy); 937218822Sdim fixP->fx_offset = (add_number + fixP->fx_dot_value 938218822Sdim + fixP->fx_frag->fr_address); 939218822Sdim 940218822Sdim /* Make it pc-relative. If the back-end code has not 941218822Sdim selected a pc-relative reloc, cancel the adjustment 942218822Sdim we do later on all pc-relative relocs. */ 943218822Sdim if (0 944218822Sdim#ifdef TC_M68K 945218822Sdim /* Do this for m68k even if it's already described 946218822Sdim as pc-relative. On the m68k, an operand of 947218822Sdim "pc@(foo-.-2)" should address "foo" in a 948218822Sdim pc-relative mode. */ 949218822Sdim || 1 950218822Sdim#endif 951218822Sdim || !fixP->fx_pcrel) 952218822Sdim add_number += MD_PCREL_FROM_SECTION (fixP, this_segment); 953218822Sdim fixP->fx_subsy = NULL; 954218822Sdim fixP->fx_pcrel = 1; 955218822Sdim } 956218822Sdim else if (!TC_VALIDATE_FIX_SUB (fixP)) 957218822Sdim { 958218822Sdim as_bad_where (fixP->fx_file, fixP->fx_line, 959218822Sdim _("can't resolve `%s' {%s section} - `%s' {%s section}"), 960218822Sdim fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0", 961218822Sdim segment_name (add_symbol_segment), 962218822Sdim S_GET_NAME (fixP->fx_subsy), 963218822Sdim segment_name (sub_symbol_segment)); 964218822Sdim } 965218822Sdim } 966218822Sdim 967218822Sdim if (fixP->fx_addsy) 968218822Sdim { 969218822Sdim if (add_symbol_segment == this_segment 970218822Sdim && !TC_FORCE_RELOCATION_LOCAL (fixP)) 971218822Sdim { 972218822Sdim /* This fixup was made when the symbol's segment was 973218822Sdim SEG_UNKNOWN, but it is now in the local segment. 974218822Sdim So we know how to do the address without relocation. */ 975218822Sdim add_number += S_GET_VALUE (fixP->fx_addsy); 976218822Sdim fixP->fx_offset = add_number; 977218822Sdim if (fixP->fx_pcrel) 978218822Sdim add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment); 979218822Sdim fixP->fx_addsy = NULL; 980218822Sdim fixP->fx_pcrel = 0; 981218822Sdim } 982218822Sdim else if (add_symbol_segment == absolute_section 983218822Sdim && !TC_FORCE_RELOCATION_ABS (fixP)) 984218822Sdim { 985218822Sdim add_number += S_GET_VALUE (fixP->fx_addsy); 986218822Sdim fixP->fx_offset = add_number; 987218822Sdim fixP->fx_addsy = NULL; 988218822Sdim } 989218822Sdim else if (add_symbol_segment != undefined_section 990218822Sdim && ! bfd_is_com_section (add_symbol_segment) 991218822Sdim && MD_APPLY_SYM_VALUE (fixP)) 992218822Sdim add_number += S_GET_VALUE (fixP->fx_addsy); 993218822Sdim } 994218822Sdim 995218822Sdim if (fixP->fx_pcrel) 996218822Sdim { 997218822Sdim add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment); 998218822Sdim if (!fixP->fx_done && fixP->fx_addsy == NULL) 999218822Sdim { 1000218822Sdim /* There was no symbol required by this relocation. 1001218822Sdim However, BFD doesn't really handle relocations 1002218822Sdim without symbols well. So fake up a local symbol in 1003218822Sdim the absolute section. */ 1004218822Sdim fixP->fx_addsy = abs_section_sym; 1005218822Sdim } 1006218822Sdim } 1007218822Sdim 1008218822Sdim if (!fixP->fx_done) 1009218822Sdim md_apply_fix (fixP, &add_number, this_segment); 1010218822Sdim 1011218822Sdim if (!fixP->fx_done) 1012218822Sdim { 1013218822Sdim ++seg_reloc_count; 1014218822Sdim if (fixP->fx_addsy == NULL) 1015218822Sdim fixP->fx_addsy = abs_section_sym; 1016218822Sdim symbol_mark_used_in_reloc (fixP->fx_addsy); 1017218822Sdim if (fixP->fx_subsy != NULL) 1018218822Sdim symbol_mark_used_in_reloc (fixP->fx_subsy); 1019218822Sdim } 1020218822Sdim 1021218822Sdim if (!fixP->fx_bit_fixP && !fixP->fx_no_overflow && fixP->fx_size != 0) 1022218822Sdim { 1023218822Sdim if (fixP->fx_size < sizeof (valueT)) 1024218822Sdim { 1025218822Sdim valueT mask; 1026218822Sdim 1027218822Sdim mask = 0; 1028218822Sdim mask--; /* Set all bits to one. */ 1029218822Sdim mask <<= fixP->fx_size * 8 - (fixP->fx_signed ? 1 : 0); 1030218822Sdim if ((add_number & mask) != 0 && (add_number & mask) != mask) 1031218822Sdim { 1032218822Sdim char buf[50], buf2[50]; 1033218822Sdim sprint_value (buf, fragP->fr_address + fixP->fx_where); 1034218822Sdim if (add_number > 1000) 1035218822Sdim sprint_value (buf2, add_number); 1036218822Sdim else 1037218822Sdim sprintf (buf2, "%ld", (long) add_number); 1038218822Sdim as_bad_where (fixP->fx_file, fixP->fx_line, 1039218822Sdim _("value of %s too large for field of %d bytes at %s"), 1040218822Sdim buf2, fixP->fx_size, buf); 1041218822Sdim } /* Generic error checking. */ 1042218822Sdim } 1043218822Sdim#ifdef WARN_SIGNED_OVERFLOW_WORD 1044218822Sdim /* Warn if a .word value is too large when treated as a signed 1045218822Sdim number. We already know it is not too negative. This is to 1046218822Sdim catch over-large switches generated by gcc on the 68k. */ 1047218822Sdim if (!flag_signed_overflow_ok 1048218822Sdim && fixP->fx_size == 2 1049218822Sdim && add_number > 0x7fff) 1050218822Sdim as_bad_where (fixP->fx_file, fixP->fx_line, 1051218822Sdim _("signed .word overflow; switch may be too large; %ld at 0x%lx"), 1052218822Sdim (long) add_number, 1053218822Sdim (long) (fragP->fr_address + fixP->fx_where)); 1054218822Sdim#endif 1055218822Sdim } /* Not a bit fix. */ 1056218822Sdim 1057218822Sdim#ifdef TC_VALIDATE_FIX 1058218822Sdim skip: ATTRIBUTE_UNUSED_LABEL 1059218822Sdim ; 1060218822Sdim#endif 1061218822Sdim#ifdef DEBUG5 1062218822Sdim fprintf (stderr, "result:\n"); 1063218822Sdim print_fixup (fixP); 1064218822Sdim#endif 1065218822Sdim } /* For each fixS in this segment. */ 1066218822Sdim 1067218822Sdim TC_ADJUST_RELOC_COUNT (fixP, seg_reloc_count); 1068218822Sdim return seg_reloc_count; 1069218822Sdim} 1070218822Sdim 107133965Sjdpstatic void 1072130561Sobrienfix_segment (bfd *abfd ATTRIBUTE_UNUSED, 1073130561Sobrien asection *sec, 1074218822Sdim void *xxx ATTRIBUTE_UNUSED) 107533965Sjdp{ 107633965Sjdp segment_info_type *seginfo = seg_info (sec); 1077130561Sobrien 1078130561Sobrien fixup_segment (seginfo->fix_root, sec); 1079130561Sobrien} 1080130561Sobrien 1081130561Sobrienstatic void 1082218822Sdiminstall_reloc (asection *sec, arelent *reloc, fragS *fragp, 1083218822Sdim char *file, unsigned int line) 1084130561Sobrien{ 1085218822Sdim char *err; 1086218822Sdim bfd_reloc_status_type s; 1087218822Sdim 1088218822Sdim s = bfd_install_relocation (stdoutput, reloc, 1089218822Sdim fragp->fr_literal, fragp->fr_address, 1090218822Sdim sec, &err); 1091218822Sdim switch (s) 1092218822Sdim { 1093218822Sdim case bfd_reloc_ok: 1094218822Sdim break; 1095218822Sdim case bfd_reloc_overflow: 1096218822Sdim as_bad_where (file, line, _("relocation overflow")); 1097218822Sdim break; 1098218822Sdim case bfd_reloc_outofrange: 1099218822Sdim as_bad_where (file, line, _("relocation out of range")); 1100218822Sdim break; 1101218822Sdim default: 1102218822Sdim as_fatal (_("%s:%u: bad return from bfd_install_relocation: %x"), 1103218822Sdim file, line, s); 1104218822Sdim } 1105218822Sdim} 1106218822Sdim 1107218822Sdimstatic void 1108218822Sdimwrite_relocs (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED) 1109218822Sdim{ 1110130561Sobrien segment_info_type *seginfo = seg_info (sec); 111177298Sobrien unsigned int i; 111233965Sjdp unsigned int n; 1113218822Sdim struct reloc_list *my_reloc_list, **rp, *r; 111433965Sjdp arelent **relocs; 111533965Sjdp fixS *fixp; 111633965Sjdp 111733965Sjdp /* If seginfo is NULL, we did not create this section; don't do 111833965Sjdp anything with it. */ 111933965Sjdp if (seginfo == NULL) 112033965Sjdp return; 112133965Sjdp 112233965Sjdp n = 0; 112333965Sjdp for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next) 1124218822Sdim if (!fixp->fx_done) 1125218822Sdim n++; 112633965Sjdp 1127218822Sdim#ifdef RELOC_EXPANSION_POSSIBLE 1128218822Sdim n *= MAX_RELOC_EXPANSION; 1129218822Sdim#endif 113033965Sjdp 1131218822Sdim /* Extract relocs for this section from reloc_list. */ 1132218822Sdim rp = &reloc_list; 1133218822Sdim my_reloc_list = NULL; 1134218822Sdim while ((r = *rp) != NULL) 113533965Sjdp { 1136218822Sdim if (r->u.b.sec == sec) 113733965Sjdp { 1138218822Sdim *rp = r->next; 1139218822Sdim r->next = my_reloc_list; 1140218822Sdim my_reloc_list = r; 1141218822Sdim n++; 114233965Sjdp } 1143218822Sdim else 1144218822Sdim rp = &r->next; 1145218822Sdim } 114633965Sjdp 1147218822Sdim relocs = xcalloc (n, sizeof (arelent *)); 114833965Sjdp 114933965Sjdp i = 0; 115033965Sjdp for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next) 115133965Sjdp { 115233965Sjdp int j; 1153218822Sdim int fx_size, slack; 1154218822Sdim offsetT loc; 115533965Sjdp 115633965Sjdp if (fixp->fx_done) 1157218822Sdim continue; 115833965Sjdp 1159218822Sdim fx_size = fixp->fx_size; 1160218822Sdim slack = TC_FX_SIZE_SLACK (fixp); 1161218822Sdim if (slack > 0) 1162218822Sdim fx_size = fx_size > slack ? fx_size - slack : 0; 1163218822Sdim loc = fixp->fx_where + fx_size; 1164218822Sdim if (slack >= 0 && loc > fixp->fx_frag->fr_fix) 1165218822Sdim as_bad_where (fixp->fx_file, fixp->fx_line, 1166218822Sdim _("internal error: fixup not contained within frag")); 1167130561Sobrien 1168218822Sdim#ifndef RELOC_EXPANSION_POSSIBLE 1169218822Sdim { 1170218822Sdim arelent *reloc = tc_gen_reloc (sec, fixp); 117133965Sjdp 1172218822Sdim if (!reloc) 1173218822Sdim continue; 1174218822Sdim relocs[i++] = reloc; 1175218822Sdim j = 1; 1176218822Sdim } 1177218822Sdim#else 1178218822Sdim { 1179218822Sdim arelent **reloc = tc_gen_reloc (sec, fixp); 118033965Sjdp 1181218822Sdim for (j = 0; reloc[j]; j++) 118277298Sobrien relocs[i++] = reloc[j]; 1183218822Sdim } 1184218822Sdim#endif 1185218822Sdim 1186218822Sdim for ( ; j != 0; --j) 1187218822Sdim install_reloc (sec, relocs[i - j], fixp->fx_frag, 1188218822Sdim fixp->fx_file, fixp->fx_line); 118933965Sjdp } 119033965Sjdp n = i; 119133965Sjdp 119233965Sjdp#ifdef DEBUG4 119333965Sjdp { 1194218822Sdim unsigned int i, j, nsyms; 119533965Sjdp asymbol **sympp; 119633965Sjdp sympp = bfd_get_outsymbols (stdoutput); 119733965Sjdp nsyms = bfd_get_symcount (stdoutput); 119833965Sjdp for (i = 0; i < n; i++) 119933965Sjdp if (((*relocs[i]->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0) 120033965Sjdp { 120133965Sjdp for (j = 0; j < nsyms; j++) 120233965Sjdp if (sympp[j] == *relocs[i]->sym_ptr_ptr) 120333965Sjdp break; 120433965Sjdp if (j == nsyms) 120533965Sjdp abort (); 120633965Sjdp } 120733965Sjdp } 120833965Sjdp#endif 120933965Sjdp 1210218822Sdim for (r = my_reloc_list; r != NULL; r = r->next) 1211218822Sdim { 1212218822Sdim fragS *f; 1213218822Sdim for (f = seginfo->frchainP->frch_root; f; f = f->fr_next) 1214218822Sdim if (f->fr_address <= r->u.b.r.address 1215218822Sdim && r->u.b.r.address < f->fr_address + f->fr_fix) 1216218822Sdim break; 1217218822Sdim if (f == NULL) 1218218822Sdim as_bad_where (r->file, r->line, 1219218822Sdim _("reloc not within (fixed part of) section")); 1220218822Sdim else 1221218822Sdim { 1222218822Sdim relocs[n++] = &r->u.b.r; 1223218822Sdim install_reloc (sec, &r->u.b.r, f, r->file, r->line); 1224218822Sdim } 1225218822Sdim } 1226218822Sdim 122733965Sjdp if (n) 1228218822Sdim { 1229218822Sdim flagword flags = bfd_get_section_flags (abfd, sec); 1230218822Sdim flags |= SEC_RELOC; 1231218822Sdim bfd_set_section_flags (abfd, sec, flags); 1232218822Sdim bfd_set_reloc (stdoutput, sec, relocs, n); 1233218822Sdim } 123433965Sjdp 123560484Sobrien#ifdef SET_SECTION_RELOCS 123660484Sobrien SET_SECTION_RELOCS (sec, relocs, n); 123760484Sobrien#endif 123860484Sobrien 123933965Sjdp#ifdef DEBUG3 124033965Sjdp { 1241218822Sdim unsigned int i; 124233965Sjdp arelent *r; 124333965Sjdp asymbol *s; 124433965Sjdp fprintf (stderr, "relocs for sec %s\n", sec->name); 124533965Sjdp for (i = 0; i < n; i++) 124633965Sjdp { 124733965Sjdp r = relocs[i]; 124833965Sjdp s = *r->sym_ptr_ptr; 1249218822Sdim fprintf (stderr, " reloc %2d @%p off %4lx : sym %-10s addend %lx\n", 1250218822Sdim i, r, (unsigned long)r->address, s->name, (unsigned long)r->addend); 125133965Sjdp } 125233965Sjdp } 125333965Sjdp#endif 125433965Sjdp} 125533965Sjdp 125633965Sjdpstatic void 1257130561Sobrienwrite_contents (bfd *abfd ATTRIBUTE_UNUSED, 1258130561Sobrien asection *sec, 1259218822Sdim void *xxx ATTRIBUTE_UNUSED) 126033965Sjdp{ 126133965Sjdp segment_info_type *seginfo = seg_info (sec); 1262130561Sobrien addressT offset = 0; 126333965Sjdp fragS *f; 126433965Sjdp 126533965Sjdp /* Write out the frags. */ 126633965Sjdp if (seginfo == NULL 126777298Sobrien || !(bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS)) 126833965Sjdp return; 126933965Sjdp 127033965Sjdp for (f = seginfo->frchainP->frch_root; 127133965Sjdp f; 127233965Sjdp f = f->fr_next) 127333965Sjdp { 127433965Sjdp int x; 1275130561Sobrien addressT fill_size; 127633965Sjdp char *fill_literal; 1277130561Sobrien offsetT count; 127833965Sjdp 127933965Sjdp assert (f->fr_type == rs_fill); 128033965Sjdp if (f->fr_fix) 128133965Sjdp { 128233965Sjdp x = bfd_set_section_contents (stdoutput, sec, 128333965Sjdp f->fr_literal, (file_ptr) offset, 128433965Sjdp (bfd_size_type) f->fr_fix); 1285130561Sobrien if (!x) 1286218822Sdim as_fatal (_("can't write %s: %s"), stdoutput->filename, 1287218822Sdim bfd_errmsg (bfd_get_error ())); 128833965Sjdp offset += f->fr_fix; 128933965Sjdp } 129033965Sjdp fill_literal = f->fr_literal + f->fr_fix; 129133965Sjdp fill_size = f->fr_var; 129233965Sjdp count = f->fr_offset; 129333965Sjdp assert (count >= 0); 129433965Sjdp if (fill_size && count) 129533965Sjdp { 129633965Sjdp char buf[256]; 129777298Sobrien if (fill_size > sizeof (buf)) 129833965Sjdp { 129977298Sobrien /* Do it the old way. Can this ever happen? */ 130033965Sjdp while (count--) 130133965Sjdp { 130233965Sjdp x = bfd_set_section_contents (stdoutput, sec, 130333965Sjdp fill_literal, 130433965Sjdp (file_ptr) offset, 130533965Sjdp (bfd_size_type) fill_size); 1306130561Sobrien if (!x) 1307218822Sdim as_fatal (_("can't write %s: %s"), stdoutput->filename, 1308218822Sdim bfd_errmsg (bfd_get_error ())); 130933965Sjdp offset += fill_size; 131033965Sjdp } 131133965Sjdp } 131233965Sjdp else 131333965Sjdp { 131433965Sjdp /* Build a buffer full of fill objects and output it as 131533965Sjdp often as necessary. This saves on the overhead of 131633965Sjdp potentially lots of bfd_set_section_contents calls. */ 131733965Sjdp int n_per_buf, i; 131833965Sjdp if (fill_size == 1) 131933965Sjdp { 132033965Sjdp n_per_buf = sizeof (buf); 132133965Sjdp memset (buf, *fill_literal, n_per_buf); 132233965Sjdp } 132333965Sjdp else 132433965Sjdp { 132533965Sjdp char *bufp; 132677298Sobrien n_per_buf = sizeof (buf) / fill_size; 132733965Sjdp for (i = n_per_buf, bufp = buf; i; i--, bufp += fill_size) 132877298Sobrien memcpy (bufp, fill_literal, fill_size); 132933965Sjdp } 133033965Sjdp for (; count > 0; count -= n_per_buf) 133133965Sjdp { 133233965Sjdp n_per_buf = n_per_buf > count ? count : n_per_buf; 133377298Sobrien x = bfd_set_section_contents 133477298Sobrien (stdoutput, sec, buf, (file_ptr) offset, 133577298Sobrien (bfd_size_type) n_per_buf * fill_size); 1336130561Sobrien if (!x) 133789857Sobrien as_fatal (_("cannot write to output file")); 133833965Sjdp offset += n_per_buf * fill_size; 133933965Sjdp } 134033965Sjdp } 134133965Sjdp } 134233965Sjdp } 134333965Sjdp} 134433965Sjdp 134533965Sjdpstatic void 1346130561Sobrienmerge_data_into_text (void) 134733965Sjdp{ 134833965Sjdp seg_info (text_section)->frchainP->frch_last->fr_next = 134933965Sjdp seg_info (data_section)->frchainP->frch_root; 135033965Sjdp seg_info (text_section)->frchainP->frch_last = 135133965Sjdp seg_info (data_section)->frchainP->frch_last; 135233965Sjdp seg_info (data_section)->frchainP = 0; 135333965Sjdp} 135433965Sjdp 135533965Sjdpstatic void 1356130561Sobrienset_symtab (void) 135733965Sjdp{ 135833965Sjdp int nsyms; 135933965Sjdp asymbol **asympp; 136033965Sjdp symbolS *symp; 1361130561Sobrien bfd_boolean result; 136233965Sjdp 136333965Sjdp /* Count symbols. We can't rely on a count made by the loop in 136433965Sjdp write_object_file, because *_frob_file may add a new symbol or 136533965Sjdp two. */ 136633965Sjdp nsyms = 0; 136733965Sjdp for (symp = symbol_rootP; symp; symp = symbol_next (symp)) 136833965Sjdp nsyms++; 136933965Sjdp 137033965Sjdp if (nsyms) 137133965Sjdp { 137233965Sjdp int i; 137389857Sobrien bfd_size_type amt = (bfd_size_type) nsyms * sizeof (asymbol *); 137433965Sjdp 1375218822Sdim asympp = bfd_alloc (stdoutput, amt); 137633965Sjdp symp = symbol_rootP; 137733965Sjdp for (i = 0; i < nsyms; i++, symp = symbol_next (symp)) 137833965Sjdp { 137960484Sobrien asympp[i] = symbol_get_bfdsym (symp); 138060484Sobrien symbol_mark_written (symp); 138133965Sjdp } 138233965Sjdp } 138333965Sjdp else 138433965Sjdp asympp = 0; 138533965Sjdp result = bfd_set_symtab (stdoutput, asympp, nsyms); 1386130561Sobrien assert (result); 138733965Sjdp symbol_table_frozen = 1; 138833965Sjdp} 138933965Sjdp 139038889Sjdp/* Finish the subsegments. After every sub-segment, we fake an 139138889Sjdp ".align ...". This conforms to BSD4.2 brane-damage. We then fake 139238889Sjdp ".fill 0" because that is the kind of frag that requires least 139338889Sjdp thought. ".align" frags like to have a following frag since that 139438889Sjdp makes calculating their intended length trivial. */ 139538889Sjdp 139638889Sjdp#ifndef SUB_SEGMENT_ALIGN 1397104834Sobrien#ifdef HANDLE_ALIGN 1398130561Sobrien/* The last subsegment gets an alignment corresponding to the alignment 1399104834Sobrien of the section. This allows proper nop-filling at the end of 1400104834Sobrien code-bearing sections. */ 1401104834Sobrien#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \ 1402218822Sdim (!(FRCHAIN)->frch_next ? get_recorded_alignment (SEG) : 0) 1403104834Sobrien#else 1404104834Sobrien#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0 140538889Sjdp#endif 140638889Sjdp#endif 140738889Sjdp 140833965Sjdpvoid 1409130561Sobriensubsegs_finish (void) 141038889Sjdp{ 141138889Sjdp struct frchain *frchainP; 1412218822Sdim asection *s; 141338889Sjdp 1414218822Sdim for (s = stdoutput->sections; s; s = s->next) 141538889Sjdp { 1416218822Sdim segment_info_type *seginfo = seg_info (s); 1417218822Sdim if (!seginfo) 1418218822Sdim continue; 141977298Sobrien 1420218822Sdim for (frchainP = seginfo->frchainP; 1421218822Sdim frchainP != NULL; 1422218822Sdim frchainP = frchainP->frch_next) 1423218822Sdim { 1424218822Sdim int alignment = 0; 142538889Sjdp 1426218822Sdim subseg_set (s, frchainP->frch_subseg); 1427218822Sdim 1428218822Sdim /* This now gets called even if we had errors. In that case, 1429218822Sdim any alignment is meaningless, and, moreover, will look weird 1430218822Sdim if we are generating a listing. */ 1431218822Sdim if (!had_errors ()) 1432130561Sobrien { 1433218822Sdim alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP); 1434218822Sdim if ((bfd_get_section_flags (now_seg->owner, now_seg) & SEC_MERGE) 1435218822Sdim && now_seg->entsize) 1436218822Sdim { 1437218822Sdim unsigned int entsize = now_seg->entsize; 1438218822Sdim int entalign = 0; 143960484Sobrien 1440218822Sdim while ((entsize & 1) == 0) 1441218822Sdim { 1442218822Sdim ++entalign; 1443218822Sdim entsize >>= 1; 1444218822Sdim } 1445218822Sdim if (entalign > alignment) 1446218822Sdim alignment = entalign; 1447130561Sobrien } 1448130561Sobrien } 1449130561Sobrien 1450218822Sdim if (subseg_text_p (now_seg)) 1451218822Sdim frag_align_code (alignment, 0); 1452218822Sdim else 1453218822Sdim frag_align (alignment, 0, 0); 145477298Sobrien 1455218822Sdim /* frag_align will have left a new frag. 1456218822Sdim Use this last frag for an empty ".fill". 145738889Sjdp 1458218822Sdim For this segment ... 1459218822Sdim Create a last frag. Do not leave a "being filled in frag". */ 1460218822Sdim frag_wane (frag_now); 1461218822Sdim frag_now->fr_fix = 0; 1462218822Sdim know (frag_now->fr_next == NULL); 1463218822Sdim } 146438889Sjdp } 146538889Sjdp} 146638889Sjdp 146738889Sjdp/* Write the object file. */ 146838889Sjdp 146938889Sjdpvoid 1470130561Sobrienwrite_object_file (void) 147133965Sjdp{ 1472218822Sdim struct relax_seg_info rsi; 1473218822Sdim#ifndef WORKING_DOT_WORD 147477298Sobrien fragS *fragP; /* Track along all frags. */ 147533965Sjdp#endif 147633965Sjdp 147733965Sjdp /* Do we really want to write it? */ 147833965Sjdp { 147933965Sjdp int n_warns, n_errs; 148033965Sjdp n_warns = had_warnings (); 148133965Sjdp n_errs = had_errors (); 148233965Sjdp /* The -Z flag indicates that an object file should be generated, 148333965Sjdp regardless of warnings and errors. */ 148433965Sjdp if (flag_always_generate_output) 148533965Sjdp { 148633965Sjdp if (n_warns || n_errs) 148789857Sobrien as_warn (_("%d error%s, %d warning%s, generating bad object file"), 148833965Sjdp n_errs, n_errs == 1 ? "" : "s", 148933965Sjdp n_warns, n_warns == 1 ? "" : "s"); 149033965Sjdp } 149133965Sjdp else 149233965Sjdp { 149333965Sjdp if (n_errs) 149489857Sobrien as_fatal (_("%d error%s, %d warning%s, no object file generated"), 149533965Sjdp n_errs, n_errs == 1 ? "" : "s", 149633965Sjdp n_warns, n_warns == 1 ? "" : "s"); 149733965Sjdp } 149833965Sjdp } 149933965Sjdp 150033965Sjdp#ifdef OBJ_VMS 150133965Sjdp /* Under VMS we try to be compatible with VAX-11 "C". Thus, we call 150233965Sjdp a routine to check for the definition of the procedure "_main", 150377298Sobrien and if so -- fix it up so that it can be program entry point. */ 150433965Sjdp vms_check_for_main (); 150577298Sobrien#endif /* OBJ_VMS */ 150633965Sjdp 150733965Sjdp /* From now on, we don't care about sub-segments. Build one frag chain 150833965Sjdp for each segment. Linked thru fr_next. */ 150933965Sjdp 151033965Sjdp /* Remove the sections created by gas for its own purposes. */ 151133965Sjdp { 151233965Sjdp int i; 151333965Sjdp 1514218822Sdim bfd_section_list_remove (stdoutput, reg_section); 1515218822Sdim bfd_section_list_remove (stdoutput, expr_section); 1516218822Sdim stdoutput->section_count -= 2; 151733965Sjdp i = 0; 151833965Sjdp bfd_map_over_sections (stdoutput, renumber_sections, &i); 151933965Sjdp } 152033965Sjdp 152133965Sjdp bfd_map_over_sections (stdoutput, chain_frchains_together, (char *) 0); 152233965Sjdp 152333965Sjdp /* We have two segments. If user gave -R flag, then we must put the 152433965Sjdp data frags into the text segment. Do this before relaxing so 152533965Sjdp we know to take advantage of -R and make shorter addresses. */ 152633965Sjdp if (flag_readonly_data_in_text) 152733965Sjdp { 152833965Sjdp merge_data_into_text (); 152933965Sjdp } 153033965Sjdp 1531218822Sdim rsi.pass = 0; 153289857Sobrien while (1) 153389857Sobrien { 153489857Sobrien#ifndef WORKING_DOT_WORD 153589857Sobrien /* We need to reset the markers in the broken word list and 153689857Sobrien associated frags between calls to relax_segment (via 153789857Sobrien relax_seg). Since the broken word list is global, we do it 153889857Sobrien once per round, rather than locally in relax_segment for each 153989857Sobrien segment. */ 154089857Sobrien struct broken_word *brokp; 154189857Sobrien 154289857Sobrien for (brokp = broken_words; 154389857Sobrien brokp != (struct broken_word *) NULL; 154489857Sobrien brokp = brokp->next_broken_word) 154589857Sobrien { 154689857Sobrien brokp->added = 0; 154789857Sobrien 154889857Sobrien if (brokp->dispfrag != (fragS *) NULL 154989857Sobrien && brokp->dispfrag->fr_type == rs_broken_word) 155089857Sobrien brokp->dispfrag->fr_subtype = 0; 155189857Sobrien } 155289857Sobrien#endif 155389857Sobrien 1554218822Sdim rsi.changed = 0; 1555218822Sdim bfd_map_over_sections (stdoutput, relax_seg, &rsi); 1556218822Sdim rsi.pass++; 1557218822Sdim if (!rsi.changed) 155889857Sobrien break; 155989857Sobrien } 156089857Sobrien 156189857Sobrien /* Note - Most ports will use the default value of 156289857Sobrien TC_FINALIZE_SYMS_BEFORE_SIZE_SEG, which 1. This will force 156389857Sobrien local symbols to be resolved, removing their frag information. 156489857Sobrien Some ports however, will not have finished relaxing all of 156589857Sobrien their frags and will still need the local symbol frag 156689857Sobrien information. These ports can set 156789857Sobrien TC_FINALIZE_SYMS_BEFORE_SIZE_SEG to 0. */ 156889857Sobrien finalize_syms = TC_FINALIZE_SYMS_BEFORE_SIZE_SEG; 156989857Sobrien 157077298Sobrien bfd_map_over_sections (stdoutput, size_seg, (char *) 0); 157133965Sjdp 157289857Sobrien /* Relaxation has completed. Freeze all syms. */ 157389857Sobrien finalize_syms = 1; 157489857Sobrien 1575130561Sobrien#ifdef md_post_relax_hook 1576130561Sobrien md_post_relax_hook; 1577130561Sobrien#endif 1578130561Sobrien 157933965Sjdp#ifndef WORKING_DOT_WORD 158033965Sjdp { 158133965Sjdp struct broken_word *lie; 158233965Sjdp struct broken_word **prevP; 158333965Sjdp 158433965Sjdp prevP = &broken_words; 158533965Sjdp for (lie = broken_words; lie; lie = lie->next_broken_word) 158633965Sjdp if (!lie->added) 158733965Sjdp { 158833965Sjdp expressionS exp; 158933965Sjdp 159060484Sobrien subseg_change (lie->seg, lie->subseg); 159133965Sjdp exp.X_op = O_subtract; 159233965Sjdp exp.X_add_symbol = lie->add; 159333965Sjdp exp.X_op_symbol = lie->sub; 159433965Sjdp exp.X_add_number = lie->addnum; 159533965Sjdp#ifdef TC_CONS_FIX_NEW 159633965Sjdp TC_CONS_FIX_NEW (lie->frag, 159777298Sobrien lie->word_goes_here - lie->frag->fr_literal, 159877298Sobrien 2, &exp); 159933965Sjdp#else 160033965Sjdp fix_new_exp (lie->frag, 160133965Sjdp lie->word_goes_here - lie->frag->fr_literal, 160233965Sjdp 2, &exp, 0, BFD_RELOC_16); 160333965Sjdp#endif 160433965Sjdp *prevP = lie->next_broken_word; 160533965Sjdp } 160633965Sjdp else 160733965Sjdp prevP = &(lie->next_broken_word); 160833965Sjdp 160933965Sjdp for (lie = broken_words; lie;) 161033965Sjdp { 161133965Sjdp struct broken_word *untruth; 161233965Sjdp char *table_ptr; 161333965Sjdp addressT table_addr; 161433965Sjdp addressT from_addr, to_addr; 161533965Sjdp int n, m; 161633965Sjdp 161760484Sobrien subseg_change (lie->seg, lie->subseg); 161833965Sjdp fragP = lie->dispfrag; 161933965Sjdp 162033965Sjdp /* Find out how many broken_words go here. */ 162133965Sjdp n = 0; 162277298Sobrien for (untruth = lie; 162377298Sobrien untruth && untruth->dispfrag == fragP; 162477298Sobrien untruth = untruth->next_broken_word) 162533965Sjdp if (untruth->added == 1) 162633965Sjdp n++; 162733965Sjdp 162833965Sjdp table_ptr = lie->dispfrag->fr_opcode; 162977298Sobrien table_addr = (lie->dispfrag->fr_address 163077298Sobrien + (table_ptr - lie->dispfrag->fr_literal)); 163133965Sjdp /* Create the jump around the long jumps. This is a short 163233965Sjdp jump from table_ptr+0 to table_ptr+n*long_jump_size. */ 163333965Sjdp from_addr = table_addr; 163433965Sjdp to_addr = table_addr + md_short_jump_size + n * md_long_jump_size; 163577298Sobrien md_create_short_jump (table_ptr, from_addr, to_addr, lie->dispfrag, 163677298Sobrien lie->add); 163733965Sjdp table_ptr += md_short_jump_size; 163833965Sjdp table_addr += md_short_jump_size; 163933965Sjdp 164077298Sobrien for (m = 0; 164177298Sobrien lie && lie->dispfrag == fragP; 164277298Sobrien m++, lie = lie->next_broken_word) 164333965Sjdp { 164433965Sjdp if (lie->added == 2) 164533965Sjdp continue; 164677298Sobrien /* Patch the jump table. */ 164777298Sobrien /* This is the offset from ??? to table_ptr+0. */ 164833965Sjdp to_addr = table_addr - S_GET_VALUE (lie->sub); 164977298Sobrien#ifdef TC_CHECK_ADJUSTED_BROKEN_DOT_WORD 165077298Sobrien TC_CHECK_ADJUSTED_BROKEN_DOT_WORD (to_addr, lie); 165177298Sobrien#endif 165233965Sjdp md_number_to_chars (lie->word_goes_here, to_addr, 2); 165377298Sobrien for (untruth = lie->next_broken_word; 165477298Sobrien untruth && untruth->dispfrag == fragP; 165577298Sobrien untruth = untruth->next_broken_word) 165633965Sjdp { 165733965Sjdp if (untruth->use_jump == lie) 165833965Sjdp md_number_to_chars (untruth->word_goes_here, to_addr, 2); 165933965Sjdp } 166033965Sjdp 166177298Sobrien /* Install the long jump. */ 166277298Sobrien /* This is a long jump from table_ptr+0 to the final target. */ 166333965Sjdp from_addr = table_addr; 166433965Sjdp to_addr = S_GET_VALUE (lie->add) + lie->addnum; 166577298Sobrien md_create_long_jump (table_ptr, from_addr, to_addr, lie->dispfrag, 166677298Sobrien lie->add); 166733965Sjdp table_ptr += md_long_jump_size; 166833965Sjdp table_addr += md_long_jump_size; 166933965Sjdp } 167033965Sjdp } 167133965Sjdp } 167277298Sobrien#endif /* not WORKING_DOT_WORD */ 167333965Sjdp 167433965Sjdp /* Resolve symbol values. This needs to be done before processing 167533965Sjdp the relocations. */ 167633965Sjdp if (symbol_rootP) 167733965Sjdp { 167833965Sjdp symbolS *symp; 167933965Sjdp 168033965Sjdp for (symp = symbol_rootP; symp; symp = symbol_next (symp)) 168189857Sobrien resolve_symbol_value (symp); 168233965Sjdp } 168360484Sobrien resolve_local_symbol_values (); 1684218822Sdim resolve_reloc_expr_symbols (); 168533965Sjdp 168633965Sjdp PROGRESS (1); 168733965Sjdp 168833965Sjdp#ifdef tc_frob_file_before_adjust 168933965Sjdp tc_frob_file_before_adjust (); 169033965Sjdp#endif 169133965Sjdp#ifdef obj_frob_file_before_adjust 169233965Sjdp obj_frob_file_before_adjust (); 169333965Sjdp#endif 169433965Sjdp 169577298Sobrien bfd_map_over_sections (stdoutput, adjust_reloc_syms, (char *) 0); 169633965Sjdp 1697130561Sobrien#ifdef tc_frob_file_before_fix 1698130561Sobrien tc_frob_file_before_fix (); 1699130561Sobrien#endif 1700130561Sobrien#ifdef obj_frob_file_before_fix 1701130561Sobrien obj_frob_file_before_fix (); 1702130561Sobrien#endif 1703130561Sobrien 1704130561Sobrien bfd_map_over_sections (stdoutput, fix_segment, (char *) 0); 1705130561Sobrien 170633965Sjdp /* Set up symbol table, and write it out. */ 170733965Sjdp if (symbol_rootP) 170833965Sjdp { 170933965Sjdp symbolS *symp; 1710218822Sdim bfd_boolean skip_next_symbol = FALSE; 171133965Sjdp 171233965Sjdp for (symp = symbol_rootP; symp; symp = symbol_next (symp)) 171333965Sjdp { 171433965Sjdp int punt = 0; 171533965Sjdp const char *name; 171633965Sjdp 1717218822Sdim if (skip_next_symbol) 1718218822Sdim { 1719218822Sdim /* Don't do anything besides moving the value of the 1720218822Sdim symbol from the GAS value-field to the BFD value-field. */ 1721218822Sdim symbol_get_bfdsym (symp)->value = S_GET_VALUE (symp); 1722218822Sdim skip_next_symbol = FALSE; 1723218822Sdim continue; 1724218822Sdim } 1725218822Sdim 172660484Sobrien if (symbol_mri_common_p (symp)) 172733965Sjdp { 172833965Sjdp if (S_IS_EXTERNAL (symp)) 172960484Sobrien as_bad (_("%s: global symbols not supported in common sections"), 173033965Sjdp S_GET_NAME (symp)); 173133965Sjdp symbol_remove (symp, &symbol_rootP, &symbol_lastP); 173233965Sjdp continue; 173333965Sjdp } 173433965Sjdp 173533965Sjdp name = S_GET_NAME (symp); 173633965Sjdp if (name) 173733965Sjdp { 173877298Sobrien const char *name2 = 173977298Sobrien decode_local_label_name ((char *) S_GET_NAME (symp)); 174033965Sjdp /* They only differ if `name' is a fb or dollar local 174133965Sjdp label name. */ 174233965Sjdp if (name2 != name && ! S_IS_DEFINED (symp)) 174389857Sobrien as_bad (_("local label `%s' is not defined"), name2); 174433965Sjdp } 174533965Sjdp 174633965Sjdp /* Do it again, because adjust_reloc_syms might introduce 174733965Sjdp more symbols. They'll probably only be section symbols, 174833965Sjdp but they'll still need to have the values computed. */ 174989857Sobrien resolve_symbol_value (symp); 175033965Sjdp 175133965Sjdp /* Skip symbols which were equated to undefined or common 1752218822Sdim symbols. */ 1753218822Sdim if (symbol_equated_reloc_p (symp) 1754218822Sdim || S_IS_WEAKREFR (symp)) 175533965Sjdp { 1756218822Sdim const char *name = S_GET_NAME (symp); 1757218822Sdim if (S_IS_COMMON (symp) 1758218822Sdim && !TC_FAKE_LABEL (name) 1759218822Sdim && !S_IS_WEAKREFR (symp) 1760218822Sdim && (!S_IS_EXTERNAL (symp) || S_IS_LOCAL (symp))) 1761218822Sdim { 1762218822Sdim expressionS *e = symbol_get_value_expression (symp); 1763218822Sdim as_bad (_("Local symbol `%s' can't be equated to common symbol `%s'"), 1764218822Sdim name, S_GET_NAME (e->X_add_symbol)); 1765218822Sdim } 176633965Sjdp symbol_remove (symp, &symbol_rootP, &symbol_lastP); 176733965Sjdp continue; 176833965Sjdp } 176933965Sjdp 177033965Sjdp#ifdef obj_frob_symbol 177133965Sjdp obj_frob_symbol (symp, punt); 177233965Sjdp#endif 177333965Sjdp#ifdef tc_frob_symbol 177460484Sobrien if (! punt || symbol_used_in_reloc_p (symp)) 177533965Sjdp tc_frob_symbol (symp, punt); 177633965Sjdp#endif 177733965Sjdp 177833965Sjdp /* If we don't want to keep this symbol, splice it out of 177933965Sjdp the chain now. If EMIT_SECTION_SYMBOLS is 0, we never 178033965Sjdp want section symbols. Otherwise, we skip local symbols 178133965Sjdp and symbols that the frob_symbol macros told us to punt, 178233965Sjdp but we keep such symbols if they are used in relocs. */ 1783130561Sobrien if (symp == abs_section_sym 1784130561Sobrien || (! EMIT_SECTION_SYMBOLS 1785130561Sobrien && symbol_section_p (symp)) 1786218822Sdim /* Note that S_IS_EXTERNAL and S_IS_LOCAL are not always 178733965Sjdp opposites. Sometimes the former checks flags and the 178833965Sjdp latter examines the name... */ 1789218822Sdim || (!S_IS_EXTERNAL (symp) 1790218822Sdim && (punt || S_IS_LOCAL (symp) || 1791218822Sdim (S_IS_WEAKREFD (symp) && ! symbol_used_p (symp))) 179260484Sobrien && ! symbol_used_in_reloc_p (symp))) 179333965Sjdp { 179433965Sjdp symbol_remove (symp, &symbol_rootP, &symbol_lastP); 179577298Sobrien 179633965Sjdp /* After symbol_remove, symbol_next(symp) still returns 179733965Sjdp the one that came after it in the chain. So we don't 179833965Sjdp need to do any extra cleanup work here. */ 179933965Sjdp continue; 180033965Sjdp } 180133965Sjdp 180233965Sjdp /* Make sure we really got a value for the symbol. */ 180360484Sobrien if (! symbol_resolved_p (symp)) 180433965Sjdp { 180589857Sobrien as_bad (_("can't resolve value for symbol `%s'"), 180633965Sjdp S_GET_NAME (symp)); 180760484Sobrien symbol_mark_resolved (symp); 180833965Sjdp } 180933965Sjdp 181033965Sjdp /* Set the value into the BFD symbol. Up til now the value 181133965Sjdp has only been kept in the gas symbolS struct. */ 181260484Sobrien symbol_get_bfdsym (symp)->value = S_GET_VALUE (symp); 1813218822Sdim 1814218822Sdim /* A warning construct is a warning symbol followed by the 1815218822Sdim symbol warned about. Don't let anything object-format or 1816218822Sdim target-specific muck with it; it's ready for output. */ 1817218822Sdim if (symbol_get_bfdsym (symp)->flags & BSF_WARNING) 1818218822Sdim skip_next_symbol = TRUE; 181933965Sjdp } 182033965Sjdp } 182133965Sjdp 182233965Sjdp PROGRESS (1); 182333965Sjdp 182433965Sjdp /* Now do any format-specific adjustments to the symbol table, such 182533965Sjdp as adding file symbols. */ 182633965Sjdp#ifdef tc_adjust_symtab 182733965Sjdp tc_adjust_symtab (); 182833965Sjdp#endif 182933965Sjdp#ifdef obj_adjust_symtab 183033965Sjdp obj_adjust_symtab (); 183133965Sjdp#endif 183233965Sjdp 183333965Sjdp /* Now that all the sizes are known, and contents correct, we can 183433965Sjdp start writing to the file. */ 183533965Sjdp set_symtab (); 183633965Sjdp 183733965Sjdp /* If *_frob_file changes the symbol value at this point, it is 183833965Sjdp responsible for moving the changed value into symp->bsym->value 183933965Sjdp as well. Hopefully all symbol value changing can be done in 184033965Sjdp *_frob_symbol. */ 184133965Sjdp#ifdef tc_frob_file 184233965Sjdp tc_frob_file (); 184333965Sjdp#endif 184433965Sjdp#ifdef obj_frob_file 184533965Sjdp obj_frob_file (); 184633965Sjdp#endif 184733965Sjdp 184833965Sjdp bfd_map_over_sections (stdoutput, write_relocs, (char *) 0); 184933965Sjdp 185033965Sjdp#ifdef tc_frob_file_after_relocs 185133965Sjdp tc_frob_file_after_relocs (); 185233965Sjdp#endif 185333965Sjdp#ifdef obj_frob_file_after_relocs 185433965Sjdp obj_frob_file_after_relocs (); 185533965Sjdp#endif 185633965Sjdp 185733965Sjdp bfd_map_over_sections (stdoutput, write_contents, (char *) 0); 185833965Sjdp} 185933965Sjdp 186033965Sjdp#ifdef TC_GENERIC_RELAX_TABLE 186133965Sjdp/* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */ 186233965Sjdp 186333965Sjdplong 1864130561Sobrienrelax_frag (segT segment, fragS *fragP, long stretch) 186533965Sjdp{ 186633965Sjdp const relax_typeS *this_type; 186733965Sjdp const relax_typeS *start_type; 186833965Sjdp relax_substateT next_state; 186933965Sjdp relax_substateT this_state; 1870130561Sobrien offsetT growth; 187178828Sobrien offsetT aim; 187278828Sobrien addressT target; 187378828Sobrien addressT address; 187478828Sobrien symbolS *symbolP; 187578828Sobrien const relax_typeS *table; 187633965Sjdp 187778828Sobrien target = fragP->fr_offset; 187878828Sobrien address = fragP->fr_address; 187978828Sobrien table = TC_GENERIC_RELAX_TABLE; 188033965Sjdp this_state = fragP->fr_subtype; 188133965Sjdp start_type = this_type = table + this_state; 188278828Sobrien symbolP = fragP->fr_symbol; 188333965Sjdp 188433965Sjdp if (symbolP) 188533965Sjdp { 188678828Sobrien fragS *sym_frag; 188778828Sobrien 188878828Sobrien sym_frag = symbol_get_frag (symbolP); 188978828Sobrien 189033965Sjdp#ifndef DIFF_EXPR_OK 189178828Sobrien know (sym_frag != NULL); 189233965Sjdp#endif 1893130561Sobrien know (S_GET_SEGMENT (symbolP) != absolute_section 189478828Sobrien || sym_frag == &zero_address_frag); 189589857Sobrien target += S_GET_VALUE (symbolP); 189633965Sjdp 189733965Sjdp /* If frag has yet to be reached on this pass, 189833965Sjdp assume it will move by STRETCH just as we did. 189933965Sjdp If this is not so, it will be because some frag 190078828Sobrien between grows, and that will force another pass. */ 190133965Sjdp 190278828Sobrien if (stretch != 0 190378828Sobrien && sym_frag->relax_marker != fragP->relax_marker 190478828Sobrien && S_GET_SEGMENT (symbolP) == segment) 190533965Sjdp { 190633965Sjdp target += stretch; 190733965Sjdp } 190833965Sjdp } 190933965Sjdp 191033965Sjdp aim = target - address - fragP->fr_fix; 191133965Sjdp#ifdef TC_PCREL_ADJUST 191277298Sobrien /* Currently only the ns32k family needs this. */ 191377298Sobrien aim += TC_PCREL_ADJUST (fragP); 191433965Sjdp#endif 1915218822Sdim 1916218822Sdim#ifdef md_prepare_relax_scan 1917218822Sdim /* Formerly called M68K_AIM_KLUDGE. */ 191833965Sjdp md_prepare_relax_scan (fragP, address, aim, this_state, this_type); 191933965Sjdp#endif 192033965Sjdp 192133965Sjdp if (aim < 0) 192233965Sjdp { 192377298Sobrien /* Look backwards. */ 192433965Sjdp for (next_state = this_type->rlx_more; next_state;) 192533965Sjdp if (aim >= this_type->rlx_backward) 192633965Sjdp next_state = 0; 192733965Sjdp else 192833965Sjdp { 192977298Sobrien /* Grow to next state. */ 193033965Sjdp this_state = next_state; 193133965Sjdp this_type = table + this_state; 193233965Sjdp next_state = this_type->rlx_more; 193333965Sjdp } 193433965Sjdp } 193533965Sjdp else 193633965Sjdp { 193777298Sobrien /* Look forwards. */ 193833965Sjdp for (next_state = this_type->rlx_more; next_state;) 193933965Sjdp if (aim <= this_type->rlx_forward) 194033965Sjdp next_state = 0; 194133965Sjdp else 194233965Sjdp { 194377298Sobrien /* Grow to next state. */ 194433965Sjdp this_state = next_state; 194533965Sjdp this_type = table + this_state; 194633965Sjdp next_state = this_type->rlx_more; 194733965Sjdp } 194833965Sjdp } 194933965Sjdp 195033965Sjdp growth = this_type->rlx_length - start_type->rlx_length; 195133965Sjdp if (growth != 0) 195233965Sjdp fragP->fr_subtype = this_state; 195333965Sjdp return growth; 195433965Sjdp} 195533965Sjdp 195677298Sobrien#endif /* defined (TC_GENERIC_RELAX_TABLE) */ 195733965Sjdp 195833965Sjdp/* Relax_align. Advance location counter to next address that has 'alignment' 195933965Sjdp lowest order bits all 0s, return size of adjustment made. */ 196033965Sjdpstatic relax_addressT 1961130561Sobrienrelax_align (register relax_addressT address, /* Address now. */ 1962130561Sobrien register int alignment /* Alignment (binary). */) 196333965Sjdp{ 196433965Sjdp relax_addressT mask; 196533965Sjdp relax_addressT new_address; 196633965Sjdp 196733965Sjdp mask = ~((~0) << alignment); 196833965Sjdp new_address = (address + mask) & (~mask); 196933965Sjdp#ifdef LINKER_RELAXING_SHRINKS_ONLY 197033965Sjdp if (linkrelax) 197133965Sjdp /* We must provide lots of padding, so the linker can discard it 197233965Sjdp when needed. The linker will not add extra space, ever. */ 197333965Sjdp new_address += (1 << alignment); 197433965Sjdp#endif 197533965Sjdp return (new_address - address); 197633965Sjdp} 197733965Sjdp 197877298Sobrien/* Now we have a segment, not a crowd of sub-segments, we can make 197977298Sobrien fr_address values. 198077298Sobrien 198177298Sobrien Relax the frags. 198277298Sobrien 198377298Sobrien After this, all frags in this segment have addresses that are correct 198477298Sobrien within the segment. Since segments live in different file addresses, 198577298Sobrien these frag addresses may not be the same as final object-file 198677298Sobrien addresses. */ 198777298Sobrien 198889857Sobrienint 1989218822Sdimrelax_segment (struct frag *segment_frag_root, segT segment, int pass) 199033965Sjdp{ 1991218822Sdim unsigned long frag_count; 1992218822Sdim struct frag *fragP; 1993218822Sdim relax_addressT address; 199489857Sobrien int ret; 199589857Sobrien 199677298Sobrien /* In case md_estimate_size_before_relax() wants to make fixSs. */ 199733965Sjdp subseg_change (segment, 0); 199833965Sjdp 199933965Sjdp /* For each frag in segment: count and store (a 1st guess of) 200033965Sjdp fr_address. */ 200133965Sjdp address = 0; 2002218822Sdim for (frag_count = 0, fragP = segment_frag_root; 2003218822Sdim fragP; 2004218822Sdim fragP = fragP->fr_next, frag_count ++) 200533965Sjdp { 200678828Sobrien fragP->relax_marker = 0; 200733965Sjdp fragP->fr_address = address; 200833965Sjdp address += fragP->fr_fix; 200933965Sjdp 201033965Sjdp switch (fragP->fr_type) 201133965Sjdp { 201233965Sjdp case rs_fill: 201333965Sjdp address += fragP->fr_offset * fragP->fr_var; 201433965Sjdp break; 201533965Sjdp 201633965Sjdp case rs_align: 201733965Sjdp case rs_align_code: 201877298Sobrien case rs_align_test: 201933965Sjdp { 202033965Sjdp addressT offset = relax_align (address, (int) fragP->fr_offset); 202133965Sjdp 202233965Sjdp if (fragP->fr_subtype != 0 && offset > fragP->fr_subtype) 202333965Sjdp offset = 0; 202433965Sjdp 202533965Sjdp if (offset % fragP->fr_var != 0) 202633965Sjdp { 202789857Sobrien as_bad_where (fragP->fr_file, fragP->fr_line, 202889857Sobrien _("alignment padding (%lu bytes) not a multiple of %ld"), 202989857Sobrien (unsigned long) offset, (long) fragP->fr_var); 203033965Sjdp offset -= (offset % fragP->fr_var); 203133965Sjdp } 203233965Sjdp 203333965Sjdp address += offset; 203433965Sjdp } 203533965Sjdp break; 203633965Sjdp 203733965Sjdp case rs_org: 203833965Sjdp case rs_space: 203933965Sjdp /* Assume .org is nugatory. It will grow with 1st relax. */ 204033965Sjdp break; 204133965Sjdp 204233965Sjdp case rs_machine_dependent: 204389857Sobrien /* If fr_symbol is an expression, this call to 204489857Sobrien resolve_symbol_value sets up the correct segment, which will 204589857Sobrien likely be needed in md_estimate_size_before_relax. */ 204689857Sobrien if (fragP->fr_symbol) 204789857Sobrien resolve_symbol_value (fragP->fr_symbol); 204889857Sobrien 204933965Sjdp address += md_estimate_size_before_relax (fragP, segment); 205033965Sjdp break; 205133965Sjdp 205233965Sjdp#ifndef WORKING_DOT_WORD 205377298Sobrien /* Broken words don't concern us yet. */ 205433965Sjdp case rs_broken_word: 205533965Sjdp break; 205633965Sjdp#endif 205733965Sjdp 205838889Sjdp case rs_leb128: 205977298Sobrien /* Initial guess is always 1; doing otherwise can result in 206038889Sjdp stable solutions that are larger than the minimum. */ 206138889Sjdp address += fragP->fr_offset = 1; 206238889Sjdp break; 206338889Sjdp 206438889Sjdp case rs_cfa: 206538889Sjdp address += eh_frame_estimate_size_before_relax (fragP); 206638889Sjdp break; 206738889Sjdp 206877298Sobrien case rs_dwarf2dbg: 206977298Sobrien address += dwarf2dbg_estimate_size_before_relax (fragP); 207077298Sobrien break; 207177298Sobrien 207233965Sjdp default: 207333965Sjdp BAD_CASE (fragP->fr_type); 207433965Sjdp break; 207577298Sobrien } 207677298Sobrien } 207733965Sjdp 207833965Sjdp /* Do relax(). */ 207933965Sjdp { 2080218822Sdim unsigned long max_iterations; 208133965Sjdp 2082218822Sdim /* Cumulative address adjustment. */ 2083218822Sdim offsetT stretch; 2084218822Sdim 2085218822Sdim /* Have we made any adjustment this pass? We can't just test 2086218822Sdim stretch because one piece of code may have grown and another 2087218822Sdim shrank. */ 2088218822Sdim int stretched; 2089218822Sdim 2090218822Sdim /* Most horrible, but gcc may give us some exception data that 2091218822Sdim is impossible to assemble, of the form 2092218822Sdim 2093218822Sdim .align 4 2094218822Sdim .byte 0, 0 2095218822Sdim .uleb128 end - start 2096218822Sdim start: 2097218822Sdim .space 128*128 - 1 2098218822Sdim .align 4 2099218822Sdim end: 2100218822Sdim 2101218822Sdim If the leb128 is two bytes in size, then end-start is 128*128, 2102218822Sdim which requires a three byte leb128. If the leb128 is three 2103218822Sdim bytes in size, then end-start is 128*128-1, which requires a 2104218822Sdim two byte leb128. We work around this dilemma by inserting 2105218822Sdim an extra 4 bytes of alignment just after the .align. This 2106218822Sdim works because the data after the align is accessed relative to 2107218822Sdim the end label. 2108218822Sdim 2109218822Sdim This counter is used in a tiny state machine to detect 2110218822Sdim whether a leb128 followed by an align is impossible to 2111218822Sdim relax. */ 2112218822Sdim int rs_leb128_fudge = 0; 2113218822Sdim 2114218822Sdim /* We want to prevent going into an infinite loop where one frag grows 2115218822Sdim depending upon the location of a symbol which is in turn moved by 2116218822Sdim the growing frag. eg: 2117218822Sdim 2118218822Sdim foo = . 2119218822Sdim .org foo+16 2120218822Sdim foo = . 2121218822Sdim 2122218822Sdim So we dictate that this algorithm can be at most O2. */ 2123218822Sdim max_iterations = frag_count * frag_count; 2124218822Sdim /* Check for overflow. */ 2125218822Sdim if (max_iterations < frag_count) 2126218822Sdim max_iterations = frag_count; 2127218822Sdim 2128218822Sdim ret = 0; 212933965Sjdp do 213033965Sjdp { 213178828Sobrien stretch = 0; 213278828Sobrien stretched = 0; 213377298Sobrien 213433965Sjdp for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next) 213533965Sjdp { 2136130561Sobrien offsetT growth = 0; 213733965Sjdp addressT was_address; 213833965Sjdp offsetT offset; 213933965Sjdp symbolS *symbolP; 214033965Sjdp 214178828Sobrien fragP->relax_marker ^= 1; 214233965Sjdp was_address = fragP->fr_address; 214333965Sjdp address = fragP->fr_address += stretch; 214433965Sjdp symbolP = fragP->fr_symbol; 214533965Sjdp offset = fragP->fr_offset; 214633965Sjdp 214733965Sjdp switch (fragP->fr_type) 214833965Sjdp { 214977298Sobrien case rs_fill: /* .fill never relaxes. */ 215033965Sjdp growth = 0; 215133965Sjdp break; 215233965Sjdp 215333965Sjdp#ifndef WORKING_DOT_WORD 215433965Sjdp /* JF: This is RMS's idea. I do *NOT* want to be blamed 215533965Sjdp for it I do not want to write it. I do not want to have 215633965Sjdp anything to do with it. This is not the proper way to 215733965Sjdp implement this misfeature. */ 215833965Sjdp case rs_broken_word: 215933965Sjdp { 216033965Sjdp struct broken_word *lie; 216133965Sjdp struct broken_word *untruth; 216233965Sjdp 216333965Sjdp /* Yes this is ugly (storing the broken_word pointer 216433965Sjdp in the symbol slot). Still, this whole chunk of 216533965Sjdp code is ugly, and I don't feel like doing anything 216633965Sjdp about it. Think of it as stubbornness in action. */ 216733965Sjdp growth = 0; 216833965Sjdp for (lie = (struct broken_word *) (fragP->fr_symbol); 216933965Sjdp lie && lie->dispfrag == fragP; 217033965Sjdp lie = lie->next_broken_word) 217133965Sjdp { 217233965Sjdp 217333965Sjdp if (lie->added) 217433965Sjdp continue; 217533965Sjdp 217689857Sobrien offset = (S_GET_VALUE (lie->add) 217733965Sjdp + lie->addnum 217889857Sobrien - S_GET_VALUE (lie->sub)); 217933965Sjdp if (offset <= -32768 || offset >= 32767) 218033965Sjdp { 218133965Sjdp if (flag_warn_displacement) 218233965Sjdp { 218333965Sjdp char buf[50]; 218433965Sjdp sprint_value (buf, (addressT) lie->addnum); 218589857Sobrien as_warn_where (fragP->fr_file, fragP->fr_line, 218689857Sobrien _(".word %s-%s+%s didn't fit"), 218789857Sobrien S_GET_NAME (lie->add), 218889857Sobrien S_GET_NAME (lie->sub), 218989857Sobrien buf); 219033965Sjdp } 219133965Sjdp lie->added = 1; 219233965Sjdp if (fragP->fr_subtype == 0) 219333965Sjdp { 219433965Sjdp fragP->fr_subtype++; 219533965Sjdp growth += md_short_jump_size; 219633965Sjdp } 219733965Sjdp for (untruth = lie->next_broken_word; 219833965Sjdp untruth && untruth->dispfrag == lie->dispfrag; 219933965Sjdp untruth = untruth->next_broken_word) 220060484Sobrien if ((symbol_get_frag (untruth->add) 220160484Sobrien == symbol_get_frag (lie->add)) 220260484Sobrien && (S_GET_VALUE (untruth->add) 220360484Sobrien == S_GET_VALUE (lie->add))) 220433965Sjdp { 220533965Sjdp untruth->added = 2; 220633965Sjdp untruth->use_jump = lie; 220733965Sjdp } 220833965Sjdp growth += md_long_jump_size; 220933965Sjdp } 221033965Sjdp } 221133965Sjdp 221233965Sjdp break; 221377298Sobrien } /* case rs_broken_word */ 221433965Sjdp#endif 221533965Sjdp case rs_align: 221633965Sjdp case rs_align_code: 221777298Sobrien case rs_align_test: 221833965Sjdp { 221933965Sjdp addressT oldoff, newoff; 222033965Sjdp 222133965Sjdp oldoff = relax_align (was_address + fragP->fr_fix, 222233965Sjdp (int) offset); 222333965Sjdp newoff = relax_align (address + fragP->fr_fix, 222433965Sjdp (int) offset); 222533965Sjdp 222633965Sjdp if (fragP->fr_subtype != 0) 222733965Sjdp { 222833965Sjdp if (oldoff > fragP->fr_subtype) 222933965Sjdp oldoff = 0; 223033965Sjdp if (newoff > fragP->fr_subtype) 223133965Sjdp newoff = 0; 223233965Sjdp } 223333965Sjdp 223433965Sjdp growth = newoff - oldoff; 2235218822Sdim 2236218822Sdim /* If this align happens to follow a leb128 and 2237218822Sdim we have determined that the leb128 is bouncing 2238218822Sdim in size, then break the cycle by inserting an 2239218822Sdim extra alignment. */ 2240218822Sdim if (growth < 0 2241218822Sdim && (rs_leb128_fudge & 16) != 0 2242218822Sdim && (rs_leb128_fudge & 15) >= 2) 2243218822Sdim { 2244218822Sdim segment_info_type *seginfo = seg_info (segment); 2245218822Sdim struct obstack *ob = &seginfo->frchainP->frch_obstack; 2246218822Sdim struct frag *newf; 2247218822Sdim 2248218822Sdim newf = frag_alloc (ob); 2249218822Sdim obstack_blank_fast (ob, fragP->fr_var); 2250222205Sbenl (void) obstack_finish (ob); 2251218822Sdim memcpy (newf, fragP, SIZEOF_STRUCT_FRAG); 2252218822Sdim memcpy (newf->fr_literal, 2253218822Sdim fragP->fr_literal + fragP->fr_fix, 2254218822Sdim fragP->fr_var); 2255218822Sdim newf->fr_type = rs_fill; 2256218822Sdim newf->fr_fix = 0; 2257218822Sdim newf->fr_offset = (((offsetT) 1 << fragP->fr_offset) 2258218822Sdim / fragP->fr_var); 2259218822Sdim if (newf->fr_offset * newf->fr_var 2260218822Sdim != (offsetT) 1 << fragP->fr_offset) 2261218822Sdim { 2262218822Sdim newf->fr_offset = (offsetT) 1 << fragP->fr_offset; 2263218822Sdim newf->fr_var = 1; 2264218822Sdim } 2265218822Sdim /* Include growth of new frag, because rs_fill 2266218822Sdim frags don't normally grow. */ 2267218822Sdim growth += newf->fr_offset * newf->fr_var; 2268218822Sdim /* The new frag address is newoff. Adjust this 2269218822Sdim for the amount we'll add when we process the 2270218822Sdim new frag. */ 2271218822Sdim newf->fr_address = newoff - stretch - growth; 2272218822Sdim newf->relax_marker ^= 1; 2273218822Sdim fragP->fr_next = newf; 2274218822Sdim#ifdef DEBUG 2275218822Sdim as_warn (_("padding added")); 2276218822Sdim#endif 2277218822Sdim } 227833965Sjdp } 227933965Sjdp break; 228033965Sjdp 228133965Sjdp case rs_org: 228233965Sjdp { 228378828Sobrien addressT target = offset; 228478828Sobrien addressT after; 228533965Sjdp 228633965Sjdp if (symbolP) 228733965Sjdp { 2288218822Sdim /* Convert from an actual address to an octet offset 2289218822Sdim into the section. Here it is assumed that the 2290218822Sdim section's VMA is zero, and can omit subtracting it 2291218822Sdim from the symbol's value to get the address offset. */ 2292218822Sdim know (S_GET_SEGMENT (symbolP)->vma == 0); 229389857Sobrien target += S_GET_VALUE (symbolP) * OCTETS_PER_BYTE; 229489857Sobrien } 229533965Sjdp 229633965Sjdp know (fragP->fr_next); 229733965Sjdp after = fragP->fr_next->fr_address; 229833965Sjdp growth = target - after; 229933965Sjdp if (growth < 0) 230033965Sjdp { 2301218822Sdim growth = 0; 2302218822Sdim 2303218822Sdim /* Don't error on first few frag relax passes. 2304218822Sdim The symbol might be an expression involving 2305218822Sdim symbol values from other sections. If those 2306218822Sdim sections have not yet been processed their 2307218822Sdim frags will all have zero addresses, so we 2308218822Sdim will calculate incorrect values for them. The 2309218822Sdim number of passes we allow before giving an 2310218822Sdim error is somewhat arbitrary. It should be at 2311218822Sdim least one, with larger values requiring 2312218822Sdim increasingly contrived dependencies between 2313218822Sdim frags to trigger a false error. */ 2314218822Sdim if (pass < 2) 2315218822Sdim { 2316218822Sdim /* Force another pass. */ 2317218822Sdim ret = 1; 2318218822Sdim break; 2319218822Sdim } 2320218822Sdim 232133965Sjdp /* Growth may be negative, but variable part of frag 232233965Sjdp cannot have fewer than 0 chars. That is, we can't 232377298Sobrien .org backwards. */ 232460484Sobrien as_bad_where (fragP->fr_file, fragP->fr_line, 2325130561Sobrien _("attempt to move .org backwards")); 232660484Sobrien 232760484Sobrien /* We've issued an error message. Change the 2328218822Sdim frag to avoid cascading errors. */ 232960484Sobrien fragP->fr_type = rs_align; 233060484Sobrien fragP->fr_subtype = 0; 233160484Sobrien fragP->fr_offset = 0; 2332218822Sdim fragP->fr_fix = after - was_address; 2333218822Sdim break; 233433965Sjdp } 233533965Sjdp 233677298Sobrien /* This is an absolute growth factor */ 233777298Sobrien growth -= stretch; 233833965Sjdp break; 233933965Sjdp } 234033965Sjdp 234133965Sjdp case rs_space: 234289857Sobrien growth = 0; 234333965Sjdp if (symbolP) 234433965Sjdp { 234589857Sobrien offsetT amount; 234689857Sobrien 234789857Sobrien amount = S_GET_VALUE (symbolP); 234889857Sobrien if (S_GET_SEGMENT (symbolP) != absolute_section 234933965Sjdp || S_IS_COMMON (symbolP) 235033965Sjdp || ! S_IS_DEFINED (symbolP)) 235133965Sjdp { 235289857Sobrien as_bad_where (fragP->fr_file, fragP->fr_line, 235389857Sobrien _(".space specifies non-absolute value")); 235489857Sobrien /* Prevent repeat of this error message. */ 235589857Sobrien fragP->fr_symbol = 0; 235633965Sjdp } 235789857Sobrien else if (amount < 0) 235889857Sobrien { 2359218822Sdim /* Don't error on first few frag relax passes. 2360218822Sdim See rs_org comment for a longer explanation. */ 2361218822Sdim if (pass < 2) 2362218822Sdim { 2363218822Sdim ret = 1; 2364218822Sdim break; 2365218822Sdim } 2366218822Sdim 236789857Sobrien as_warn_where (fragP->fr_file, fragP->fr_line, 236889857Sobrien _(".space or .fill with negative value, ignored")); 236989857Sobrien fragP->fr_symbol = 0; 237089857Sobrien } 237189857Sobrien else 237289857Sobrien growth = (was_address + fragP->fr_fix + amount 237389857Sobrien - fragP->fr_next->fr_address); 237433965Sjdp } 237533965Sjdp break; 237633965Sjdp 237733965Sjdp case rs_machine_dependent: 237833965Sjdp#ifdef md_relax_frag 237978828Sobrien growth = md_relax_frag (segment, fragP, stretch); 238033965Sjdp#else 238133965Sjdp#ifdef TC_GENERIC_RELAX_TABLE 238233965Sjdp /* The default way to relax a frag is to look through 238333965Sjdp TC_GENERIC_RELAX_TABLE. */ 238478828Sobrien growth = relax_frag (segment, fragP, stretch); 238577298Sobrien#endif /* TC_GENERIC_RELAX_TABLE */ 238633965Sjdp#endif 238733965Sjdp break; 238833965Sjdp 238938889Sjdp case rs_leb128: 239038889Sjdp { 239138889Sjdp valueT value; 2392130561Sobrien offsetT size; 239338889Sjdp 239489857Sobrien value = resolve_symbol_value (fragP->fr_symbol); 239538889Sjdp size = sizeof_leb128 (value, fragP->fr_subtype); 239638889Sjdp growth = size - fragP->fr_offset; 239738889Sjdp fragP->fr_offset = size; 239838889Sjdp } 239938889Sjdp break; 240038889Sjdp 240138889Sjdp case rs_cfa: 240238889Sjdp growth = eh_frame_relax_frag (fragP); 240338889Sjdp break; 240438889Sjdp 240577298Sobrien case rs_dwarf2dbg: 240677298Sobrien growth = dwarf2dbg_relax_frag (fragP); 240777298Sobrien break; 240877298Sobrien 240933965Sjdp default: 241033965Sjdp BAD_CASE (fragP->fr_type); 241133965Sjdp break; 241233965Sjdp } 241333965Sjdp if (growth) 241433965Sjdp { 241533965Sjdp stretch += growth; 241678828Sobrien stretched = 1; 2417218822Sdim if (fragP->fr_type == rs_leb128) 2418218822Sdim rs_leb128_fudge += 16; 2419218822Sdim else if (fragP->fr_type == rs_align 2420218822Sdim && (rs_leb128_fudge & 16) != 0 2421218822Sdim && stretch == 0) 2422218822Sdim rs_leb128_fudge += 16; 2423218822Sdim else 2424218822Sdim rs_leb128_fudge = 0; 242533965Sjdp } 2426218822Sdim } 2427218822Sdim 2428218822Sdim if (stretch == 0 2429218822Sdim && (rs_leb128_fudge & 16) == 0 2430218822Sdim && (rs_leb128_fudge & -16) != 0) 2431218822Sdim rs_leb128_fudge += 1; 2432218822Sdim else 2433218822Sdim rs_leb128_fudge = 0; 243433965Sjdp } 2435218822Sdim /* Until nothing further to relax. */ 2436218822Sdim while (stretched && -- max_iterations); 243733965Sjdp 2438218822Sdim if (stretched) 2439218822Sdim as_fatal (_("Infinite loop encountered whilst attempting to compute the addresses of symbols in section %s"), 2440218822Sdim segment_name (segment)); 2441218822Sdim } 2442218822Sdim 244389857Sobrien for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next) 244489857Sobrien if (fragP->last_fr_address != fragP->fr_address) 244589857Sobrien { 244689857Sobrien fragP->last_fr_address = fragP->fr_address; 244789857Sobrien ret = 1; 244889857Sobrien } 244989857Sobrien return ret; 245077298Sobrien} 245133965Sjdp 245233965Sjdpvoid 2453130561Sobriennumber_to_chars_bigendian (char *buf, valueT val, int n) 245433965Sjdp{ 245594536Sobrien if (n <= 0) 245633965Sjdp abort (); 245733965Sjdp while (n--) 245833965Sjdp { 245933965Sjdp buf[n] = val & 0xff; 246033965Sjdp val >>= 8; 246133965Sjdp } 246233965Sjdp} 246333965Sjdp 246433965Sjdpvoid 2465130561Sobriennumber_to_chars_littleendian (char *buf, valueT val, int n) 246633965Sjdp{ 246794536Sobrien if (n <= 0) 246833965Sjdp abort (); 246933965Sjdp while (n--) 247033965Sjdp { 247133965Sjdp *buf++ = val & 0xff; 247233965Sjdp val >>= 8; 247333965Sjdp } 247433965Sjdp} 247533965Sjdp 247633965Sjdpvoid 2477130561Sobrienwrite_print_statistics (FILE *file) 247833965Sjdp{ 247960484Sobrien fprintf (file, "fixups: %d\n", n_fixups); 248033965Sjdp} 248133965Sjdp 248277298Sobrien/* For debugging. */ 248333965Sjdpextern int indent_level; 248433965Sjdp 248533965Sjdpvoid 2486130561Sobrienprint_fixup (fixS *fixp) 248733965Sjdp{ 248833965Sjdp indent_level = 1; 248933965Sjdp fprintf (stderr, "fix %lx %s:%d", (long) fixp, fixp->fx_file, fixp->fx_line); 249033965Sjdp if (fixp->fx_pcrel) 249133965Sjdp fprintf (stderr, " pcrel"); 249233965Sjdp if (fixp->fx_pcrel_adjust) 249333965Sjdp fprintf (stderr, " pcrel_adjust=%d", fixp->fx_pcrel_adjust); 249433965Sjdp if (fixp->fx_im_disp) 249533965Sjdp { 249633965Sjdp#ifdef TC_NS32K 249733965Sjdp fprintf (stderr, " im_disp=%d", fixp->fx_im_disp); 249833965Sjdp#else 249933965Sjdp fprintf (stderr, " im_disp"); 250033965Sjdp#endif 250133965Sjdp } 250233965Sjdp if (fixp->fx_tcbit) 250333965Sjdp fprintf (stderr, " tcbit"); 250433965Sjdp if (fixp->fx_done) 250533965Sjdp fprintf (stderr, " done"); 250633965Sjdp fprintf (stderr, "\n size=%d frag=%lx where=%ld offset=%lx addnumber=%lx", 250733965Sjdp fixp->fx_size, (long) fixp->fx_frag, (long) fixp->fx_where, 250833965Sjdp (long) fixp->fx_offset, (long) fixp->fx_addnumber); 250933965Sjdp fprintf (stderr, "\n %s (%d)", bfd_get_reloc_code_name (fixp->fx_r_type), 251033965Sjdp fixp->fx_r_type); 251133965Sjdp if (fixp->fx_addsy) 251233965Sjdp { 251333965Sjdp fprintf (stderr, "\n +<"); 251433965Sjdp print_symbol_value_1 (stderr, fixp->fx_addsy); 251533965Sjdp fprintf (stderr, ">"); 251633965Sjdp } 251733965Sjdp if (fixp->fx_subsy) 251833965Sjdp { 251933965Sjdp fprintf (stderr, "\n -<"); 252033965Sjdp print_symbol_value_1 (stderr, fixp->fx_subsy); 252133965Sjdp fprintf (stderr, ">"); 252233965Sjdp } 252333965Sjdp fprintf (stderr, "\n"); 252438889Sjdp#ifdef TC_FIX_DATA_PRINT 252538889Sjdp TC_FIX_DATA_PRINT (stderr, fixp); 252638889Sjdp#endif 252733965Sjdp} 2528