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 (&notes, 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