write.c revision 130561
133965Sjdp/* write.c - emit .o file
278828Sobrien   Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
3130561Sobrien   1998, 1999, 2000, 2001, 2002, 2003
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
2033965Sjdp   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2133965Sjdp   02111-1307, 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"
3033965Sjdp
3133965Sjdp#ifndef TC_ADJUST_RELOC_COUNT
32130561Sobrien#define TC_ADJUST_RELOC_COUNT(FIX, COUNT)
3333965Sjdp#endif
3433965Sjdp
3533965Sjdp#ifndef TC_FORCE_RELOCATION
36130561Sobrien#define TC_FORCE_RELOCATION(FIX)		\
37130561Sobrien  (generic_force_reloc (FIX))
3833965Sjdp#endif
3933965Sjdp
40130561Sobrien#ifndef TC_FORCE_RELOCATION_ABS
41130561Sobrien#define TC_FORCE_RELOCATION_ABS(FIX)		\
42130561Sobrien  (TC_FORCE_RELOCATION (FIX))
4333965Sjdp#endif
4433965Sjdp
45130561Sobrien#ifndef TC_FORCE_RELOCATION_LOCAL
46130561Sobrien#define TC_FORCE_RELOCATION_LOCAL(FIX)		\
47130561Sobrien  (!(FIX)->fx_pcrel				\
48130561Sobrien   || (FIX)->fx_plt				\
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#ifdef BFD_ASSEMBLER
75130561Sobrien#define TC_VALIDATE_FIX_SUB(FIX)		\
76130561Sobrien  ((FIX)->fx_r_type == BFD_RELOC_GPREL32	\
77130561Sobrien   || (FIX)->fx_r_type == BFD_RELOC_GPREL16)
78130561Sobrien#else
79130561Sobrien#define TC_VALIDATE_FIX_SUB(FIX) 0
80130561Sobrien#endif
81130561Sobrien#endif
82130561Sobrien#endif
83130561Sobrien
8477298Sobrien#ifndef TC_LINKRELAX_FIXUP
8577298Sobrien#define TC_LINKRELAX_FIXUP(SEG) 1
8677298Sobrien#endif
8777298Sobrien
88130561Sobrien#ifndef MD_APPLY_SYM_VALUE
89130561Sobrien#define MD_APPLY_SYM_VALUE(FIX) 1
9077298Sobrien#endif
9177298Sobrien
9289857Sobrien#ifndef TC_FINALIZE_SYMS_BEFORE_SIZE_SEG
9389857Sobrien#define TC_FINALIZE_SYMS_BEFORE_SIZE_SEG 1
9489857Sobrien#endif
9589857Sobrien
9633965Sjdp#ifndef	MD_PCREL_FROM_SECTION
97130561Sobrien#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from (FIX)
9833965Sjdp#endif
9933965Sjdp
10033965Sjdp#ifndef WORKING_DOT_WORD
101104834Sobrienextern const int md_short_jump_size;
102104834Sobrienextern const int md_long_jump_size;
10333965Sjdp#endif
10433965Sjdp
10589857Sobrien/* Used to control final evaluation of expressions.  */
10689857Sobrienint finalize_syms = 0;
10789857Sobrien
10833965Sjdpint symbol_table_frozen;
10933965Sjdp
110130561SobriensymbolS *abs_section_sym;
111130561Sobrien
112130561Sobrien/* Remember the value of dot when parsing expressions.  */
113130561SobrienaddressT dot_value;
114130561Sobrien
115130561Sobrienvoid print_fixup (fixS *);
116130561Sobrien
11733965Sjdp#ifdef BFD_ASSEMBLER
118130561Sobrienstatic void renumber_sections (bfd *, asection *, PTR);
11933965Sjdp
12033965Sjdp/* We generally attach relocs to frag chains.  However, after we have
12133965Sjdp   chained these all together into a segment, any relocs we add after
12233965Sjdp   that must be attached to a segment.  This will include relocs added
12333965Sjdp   in md_estimate_size_for_relax, for example.  */
12433965Sjdpstatic int frags_chained = 0;
12533965Sjdp#endif
12633965Sjdp
12733965Sjdp#ifndef BFD_ASSEMBLER
12833965Sjdp
12933965Sjdp#ifndef MANY_SEGMENTS
13033965Sjdpstruct frag *text_frag_root;
13133965Sjdpstruct frag *data_frag_root;
13233965Sjdpstruct frag *bss_frag_root;
13333965Sjdp
13477298Sobrienstruct frag *text_last_frag;	/* Last frag in segment.  */
13577298Sobrienstruct frag *data_last_frag;	/* Last frag in segment.  */
13677298Sobrienstatic struct frag *bss_last_frag;	/* Last frag in segment.  */
13733965Sjdp#endif
13833965Sjdp
13933965Sjdp#ifndef BFD
14033965Sjdpstatic object_headers headers;
14133965Sjdp#endif
14233965Sjdp
14333965Sjdplong string_byte_count;
14477298Sobrienchar *next_object_file_charP;	/* Tracks object file bytes.  */
14533965Sjdp
14633965Sjdp#ifndef OBJ_VMS
14733965Sjdpint magic_number_for_object_file = DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE;
14833965Sjdp#endif
14933965Sjdp
15077298Sobrien#endif /* BFD_ASSEMBLER  */
15133965Sjdp
15233965Sjdpstatic int n_fixups;
15333965Sjdp
15433965Sjdp#ifdef BFD_ASSEMBLER
155130561Sobrien#define RELOC_ENUM enum bfd_reloc_code_real
15633965Sjdp#else
157130561Sobrien#define RELOC_ENUM int
15833965Sjdp#endif
159130561Sobrien
160130561Sobrienstatic fixS *fix_new_internal (fragS *, int where, int size,
161130561Sobrien			       symbolS *add, symbolS *sub,
162130561Sobrien			       offsetT offset, int pcrel,
163130561Sobrien			       RELOC_ENUM r_type);
16433965Sjdp#if defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS))
165130561Sobrienstatic long fixup_segment (fixS *, segT);
16633965Sjdp#endif
167130561Sobrienstatic relax_addressT relax_align (relax_addressT addr, int align);
16833965Sjdp#if defined (BFD_ASSEMBLER) || ! defined (BFD)
169130561Sobrienstatic fragS *chain_frchains_together_1 (segT, struct frchain *);
17033965Sjdp#endif
17133965Sjdp#ifdef BFD_ASSEMBLER
172130561Sobrienstatic void chain_frchains_together (bfd *, segT, PTR);
173130561Sobrienstatic void cvt_frag_to_fill (segT, fragS *);
174130561Sobrienstatic void adjust_reloc_syms (bfd *, asection *, PTR);
175130561Sobrienstatic void fix_segment (bfd *, asection *, PTR);
176130561Sobrienstatic void write_relocs (bfd *, asection *, PTR);
177130561Sobrienstatic void write_contents (bfd *, asection *, PTR);
178130561Sobrienstatic void set_symtab (void);
17933965Sjdp#endif
18033965Sjdp#if defined (BFD_ASSEMBLER) || (! defined (BFD) && ! defined (OBJ_AOUT))
181130561Sobrienstatic void merge_data_into_text (void);
18233965Sjdp#endif
18333965Sjdp#if ! defined (BFD_ASSEMBLER) && ! defined (BFD)
184130561Sobrienstatic void cvt_frag_to_fill (object_headers *, segT, fragS *);
185130561Sobrienstatic void remove_subsegs (frchainS *, int, fragS **, fragS **);
186130561Sobrienstatic void relax_and_size_all_segments (void);
18733965Sjdp#endif
18833965Sjdp
18977298Sobrien/* Create a fixS in obstack 'notes'.  */
19077298Sobrien
19133965Sjdpstatic fixS *
192130561Sobrienfix_new_internal (fragS *frag,		/* Which frag?  */
193130561Sobrien		  int where,		/* Where in that frag?  */
194130561Sobrien		  int size,		/* 1, 2, or 4 usually.  */
195130561Sobrien		  symbolS *add_symbol,	/* X_add_symbol.  */
196130561Sobrien		  symbolS *sub_symbol,	/* X_op_symbol.  */
197130561Sobrien		  offsetT offset,	/* X_add_number.  */
198130561Sobrien		  int pcrel,		/* TRUE if PC-relative relocation.  */
199130561Sobrien		  RELOC_ENUM r_type ATTRIBUTE_UNUSED /* Relocation type.  */)
20033965Sjdp{
20133965Sjdp  fixS *fixP;
20233965Sjdp
20333965Sjdp  n_fixups++;
20433965Sjdp
20533965Sjdp  fixP = (fixS *) obstack_alloc (&notes, sizeof (fixS));
20633965Sjdp
20733965Sjdp  fixP->fx_frag = frag;
20833965Sjdp  fixP->fx_where = where;
20933965Sjdp  fixP->fx_size = size;
21033965Sjdp  /* We've made fx_size a narrow field; check that it's wide enough.  */
21133965Sjdp  if (fixP->fx_size != size)
21233965Sjdp    {
21360484Sobrien      as_bad (_("field fx_size too small to hold %d"), size);
21433965Sjdp      abort ();
21533965Sjdp    }
21633965Sjdp  fixP->fx_addsy = add_symbol;
21733965Sjdp  fixP->fx_subsy = sub_symbol;
21833965Sjdp  fixP->fx_offset = offset;
219130561Sobrien  fixP->fx_dot_value = dot_value;
22033965Sjdp  fixP->fx_pcrel = pcrel;
22133965Sjdp  fixP->fx_plt = 0;
22233965Sjdp#if defined(NEED_FX_R_TYPE) || defined (BFD_ASSEMBLER)
22333965Sjdp  fixP->fx_r_type = r_type;
22433965Sjdp#endif
22533965Sjdp  fixP->fx_im_disp = 0;
22633965Sjdp  fixP->fx_pcrel_adjust = 0;
22733965Sjdp  fixP->fx_bit_fixP = 0;
22833965Sjdp  fixP->fx_addnumber = 0;
22933965Sjdp  fixP->fx_tcbit = 0;
23033965Sjdp  fixP->fx_done = 0;
23133965Sjdp  fixP->fx_no_overflow = 0;
23233965Sjdp  fixP->fx_signed = 0;
23333965Sjdp
23460484Sobrien#ifdef USING_CGEN
23560484Sobrien  fixP->fx_cgen.insn = NULL;
23660484Sobrien  fixP->fx_cgen.opinfo = 0;
23760484Sobrien#endif
23860484Sobrien
23933965Sjdp#ifdef TC_FIX_TYPE
24077298Sobrien  TC_INIT_FIX_DATA (fixP);
24133965Sjdp#endif
24233965Sjdp
24333965Sjdp  as_where (&fixP->fx_file, &fixP->fx_line);
24433965Sjdp
24533965Sjdp  /* Usually, we want relocs sorted numerically, but while
24633965Sjdp     comparing to older versions of gas that have relocs
24733965Sjdp     reverse sorted, it is convenient to have this compile
24877298Sobrien     time option.  xoxorich.  */
24933965Sjdp  {
25033965Sjdp
25133965Sjdp#ifdef BFD_ASSEMBLER
25233965Sjdp    fixS **seg_fix_rootP = (frags_chained
25333965Sjdp			    ? &seg_info (now_seg)->fix_root
25433965Sjdp			    : &frchain_now->fix_root);
25533965Sjdp    fixS **seg_fix_tailP = (frags_chained
25633965Sjdp			    ? &seg_info (now_seg)->fix_tail
25733965Sjdp			    : &frchain_now->fix_tail);
25833965Sjdp#endif
25933965Sjdp
26033965Sjdp#ifdef REVERSE_SORT_RELOCS
26133965Sjdp
26233965Sjdp    fixP->fx_next = *seg_fix_rootP;
26333965Sjdp    *seg_fix_rootP = fixP;
26433965Sjdp
26577298Sobrien#else /* REVERSE_SORT_RELOCS  */
26633965Sjdp
26733965Sjdp    fixP->fx_next = NULL;
26833965Sjdp
26933965Sjdp    if (*seg_fix_tailP)
27033965Sjdp      (*seg_fix_tailP)->fx_next = fixP;
27133965Sjdp    else
27233965Sjdp      *seg_fix_rootP = fixP;
27333965Sjdp    *seg_fix_tailP = fixP;
27433965Sjdp
27577298Sobrien#endif /* REVERSE_SORT_RELOCS  */
27633965Sjdp  }
27733965Sjdp
27833965Sjdp  return fixP;
27933965Sjdp}
28033965Sjdp
28133965Sjdp/* Create a fixup relative to a symbol (plus a constant).  */
28233965Sjdp
28333965SjdpfixS *
284130561Sobrienfix_new (fragS *frag,		/* Which frag?  */
285130561Sobrien	 int where,			/* Where in that frag?  */
286130561Sobrien	 int size,			/* 1, 2, or 4 usually.  */
287130561Sobrien	 symbolS *add_symbol,	/* X_add_symbol.  */
288130561Sobrien	 offsetT offset,		/* X_add_number.  */
289130561Sobrien	 int pcrel,			/* TRUE if PC-relative relocation.  */
290130561Sobrien	 RELOC_ENUM r_type		/* Relocation type.  */)
29133965Sjdp{
29233965Sjdp  return fix_new_internal (frag, where, size, add_symbol,
29333965Sjdp			   (symbolS *) NULL, offset, pcrel, r_type);
29433965Sjdp}
29533965Sjdp
29633965Sjdp/* Create a fixup for an expression.  Currently we only support fixups
29733965Sjdp   for difference expressions.  That is itself more than most object
29833965Sjdp   file formats support anyhow.  */
29933965Sjdp
30033965SjdpfixS *
301130561Sobrienfix_new_exp (fragS *frag,		/* Which frag?  */
302130561Sobrien	     int where,			/* Where in that frag?  */
303130561Sobrien	     int size,			/* 1, 2, or 4 usually.  */
304130561Sobrien	     expressionS *exp,		/* Expression.  */
305130561Sobrien	     int pcrel,			/* TRUE if PC-relative relocation.  */
306130561Sobrien	     RELOC_ENUM r_type		/* Relocation type.  */)
30733965Sjdp{
30833965Sjdp  symbolS *add = NULL;
30933965Sjdp  symbolS *sub = NULL;
31033965Sjdp  offsetT off = 0;
31133965Sjdp
31233965Sjdp  switch (exp->X_op)
31333965Sjdp    {
31433965Sjdp    case O_absent:
31533965Sjdp      break;
31633965Sjdp
31778828Sobrien    case O_register:
31878828Sobrien      as_bad (_("register value used as expression"));
31978828Sobrien      break;
32078828Sobrien
32133965Sjdp    case O_add:
32233965Sjdp      /* This comes up when _GLOBAL_OFFSET_TABLE_+(.-L0) is read, if
32333965Sjdp	 the difference expression cannot immediately be reduced.  */
32433965Sjdp      {
32533965Sjdp	symbolS *stmp = make_expr_symbol (exp);
32677298Sobrien
32733965Sjdp	exp->X_op = O_symbol;
32833965Sjdp	exp->X_op_symbol = 0;
32933965Sjdp	exp->X_add_symbol = stmp;
33033965Sjdp	exp->X_add_number = 0;
33177298Sobrien
33233965Sjdp	return fix_new_exp (frag, where, size, exp, pcrel, r_type);
33333965Sjdp      }
33433965Sjdp
33533965Sjdp    case O_symbol_rva:
33633965Sjdp      add = exp->X_add_symbol;
33733965Sjdp      off = exp->X_add_number;
33833965Sjdp
33933965Sjdp#if defined(BFD_ASSEMBLER)
34033965Sjdp      r_type = BFD_RELOC_RVA;
34133965Sjdp#else
34233965Sjdp#if defined(TC_RVA_RELOC)
34333965Sjdp      r_type = TC_RVA_RELOC;
34433965Sjdp#else
34577298Sobrien      as_fatal (_("rva not supported"));
34633965Sjdp#endif
34733965Sjdp#endif
34833965Sjdp      break;
34933965Sjdp
35033965Sjdp    case O_uminus:
35133965Sjdp      sub = exp->X_add_symbol;
35233965Sjdp      off = exp->X_add_number;
35333965Sjdp      break;
35433965Sjdp
35533965Sjdp    case O_subtract:
35633965Sjdp      sub = exp->X_op_symbol;
35733965Sjdp      /* Fall through.  */
35833965Sjdp    case O_symbol:
35933965Sjdp      add = exp->X_add_symbol;
36077298Sobrien      /* Fall through.  */
36133965Sjdp    case O_constant:
36233965Sjdp      off = exp->X_add_number;
36333965Sjdp      break;
36433965Sjdp
36533965Sjdp    default:
36633965Sjdp      add = make_expr_symbol (exp);
36733965Sjdp      break;
36833965Sjdp    }
36933965Sjdp
37077298Sobrien  return fix_new_internal (frag, where, size, add, sub, off, pcrel, r_type);
37133965Sjdp}
37233965Sjdp
373130561Sobrien/* Generic function to determine whether a fixup requires a relocation.  */
374130561Sobrienint
375130561Sobriengeneric_force_reloc (fixS *fix)
376130561Sobrien{
377130561Sobrien#ifdef BFD_ASSEMBLER
378130561Sobrien  if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
379130561Sobrien      || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
380130561Sobrien    return 1;
381130561Sobrien#endif
382130561Sobrien  return S_FORCE_RELOC (fix->fx_addsy, fix->fx_subsy == NULL);
383130561Sobrien}
384130561Sobrien
38533965Sjdp/* Append a string onto another string, bumping the pointer along.  */
38633965Sjdpvoid
387130561Sobrienappend (char **charPP, char *fromP, unsigned long length)
38833965Sjdp{
38977298Sobrien  /* Don't trust memcpy() of 0 chars.  */
39033965Sjdp  if (length == 0)
39133965Sjdp    return;
39233965Sjdp
39333965Sjdp  memcpy (*charPP, fromP, length);
39433965Sjdp  *charPP += length;
39533965Sjdp}
39633965Sjdp
39733965Sjdp#ifndef BFD_ASSEMBLER
39833965Sjdpint section_alignment[SEG_MAXIMUM_ORDINAL];
39933965Sjdp#endif
40033965Sjdp
40177298Sobrien/* This routine records the largest alignment seen for each segment.
40277298Sobrien   If the beginning of the segment is aligned on the worst-case
40377298Sobrien   boundary, all of the other alignments within it will work.  At
40477298Sobrien   least one object format really uses this info.  */
40577298Sobrien
40633965Sjdpvoid
407130561Sobrienrecord_alignment (/* Segment to which alignment pertains.  */
408130561Sobrien		  segT seg,
409130561Sobrien		  /* Alignment, as a power of 2 (e.g., 1 => 2-byte
410130561Sobrien		     boundary, 2 => 4-byte boundary, etc.)  */
411130561Sobrien		  int align)
41233965Sjdp{
41333965Sjdp  if (seg == absolute_section)
41433965Sjdp    return;
41533965Sjdp#ifdef BFD_ASSEMBLER
41638889Sjdp  if ((unsigned int) align > bfd_get_section_alignment (stdoutput, seg))
41733965Sjdp    bfd_set_section_alignment (stdoutput, seg, align);
41833965Sjdp#else
41933965Sjdp  if (align > section_alignment[(int) seg])
42033965Sjdp    section_alignment[(int) seg] = align;
42133965Sjdp#endif
42233965Sjdp}
42333965Sjdp
42477298Sobrienint
425130561Sobrienget_recorded_alignment (segT seg)
42677298Sobrien{
42777298Sobrien  if (seg == absolute_section)
42877298Sobrien    return 0;
42933965Sjdp#ifdef BFD_ASSEMBLER
43077298Sobrien  return bfd_get_section_alignment (stdoutput, seg);
43177298Sobrien#else
43277298Sobrien  return section_alignment[(int) seg];
43377298Sobrien#endif
43477298Sobrien}
43533965Sjdp
43677298Sobrien#ifdef BFD_ASSEMBLER
43777298Sobrien
43833965Sjdp/* Reset the section indices after removing the gas created sections.  */
43933965Sjdp
44033965Sjdpstatic void
441130561Sobrienrenumber_sections (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, PTR countparg)
44233965Sjdp{
44333965Sjdp  int *countp = (int *) countparg;
44433965Sjdp
44533965Sjdp  sec->index = *countp;
44633965Sjdp  ++*countp;
44733965Sjdp}
44833965Sjdp
44977298Sobrien#endif /* defined (BFD_ASSEMBLER)  */
45033965Sjdp
45133965Sjdp#if defined (BFD_ASSEMBLER) || ! defined (BFD)
45233965Sjdp
45333965Sjdpstatic fragS *
454130561Sobrienchain_frchains_together_1 (segT section, struct frchain *frchp)
45533965Sjdp{
45633965Sjdp  fragS dummy, *prev_frag = &dummy;
45733965Sjdp#ifdef BFD_ASSEMBLER
45833965Sjdp  fixS fix_dummy, *prev_fix = &fix_dummy;
45933965Sjdp#endif
46033965Sjdp
46133965Sjdp  for (; frchp && frchp->frch_seg == section; frchp = frchp->frch_next)
46233965Sjdp    {
46333965Sjdp      prev_frag->fr_next = frchp->frch_root;
46433965Sjdp      prev_frag = frchp->frch_last;
46533965Sjdp      assert (prev_frag->fr_type != 0);
46633965Sjdp#ifdef BFD_ASSEMBLER
46733965Sjdp      if (frchp->fix_root != (fixS *) NULL)
46833965Sjdp	{
46933965Sjdp	  if (seg_info (section)->fix_root == (fixS *) NULL)
47033965Sjdp	    seg_info (section)->fix_root = frchp->fix_root;
47133965Sjdp	  prev_fix->fx_next = frchp->fix_root;
47233965Sjdp	  seg_info (section)->fix_tail = frchp->fix_tail;
47333965Sjdp	  prev_fix = frchp->fix_tail;
47433965Sjdp	}
47533965Sjdp#endif
47633965Sjdp    }
47733965Sjdp  assert (prev_frag->fr_type != 0);
47833965Sjdp  prev_frag->fr_next = 0;
47933965Sjdp  return prev_frag;
48033965Sjdp}
48133965Sjdp
48233965Sjdp#endif
48333965Sjdp
48433965Sjdp#ifdef BFD_ASSEMBLER
48533965Sjdp
48633965Sjdpstatic void
487130561Sobrienchain_frchains_together (bfd *abfd ATTRIBUTE_UNUSED,
488130561Sobrien			 segT section,
489130561Sobrien			 PTR xxx ATTRIBUTE_UNUSED)
49033965Sjdp{
49133965Sjdp  segment_info_type *info;
49233965Sjdp
49333965Sjdp  /* BFD may have introduced its own sections without using
49433965Sjdp     subseg_new, so it is possible that seg_info is NULL.  */
49533965Sjdp  info = seg_info (section);
49633965Sjdp  if (info != (segment_info_type *) NULL)
49777298Sobrien    info->frchainP->frch_last
49877298Sobrien      = chain_frchains_together_1 (section, info->frchainP);
49933965Sjdp
50033965Sjdp  /* Now that we've chained the frags together, we must add new fixups
50133965Sjdp     to the segment, not to the frag chain.  */
50233965Sjdp  frags_chained = 1;
50333965Sjdp}
50433965Sjdp
50533965Sjdp#endif
50633965Sjdp
50733965Sjdp#if !defined (BFD) && !defined (BFD_ASSEMBLER)
50833965Sjdp
50933965Sjdpstatic void
510130561Sobrienremove_subsegs (frchainS *head, int seg, fragS **root, fragS **last)
51133965Sjdp{
51233965Sjdp  *root = head->frch_root;
51333965Sjdp  *last = chain_frchains_together_1 (seg, head);
51433965Sjdp}
51533965Sjdp
51677298Sobrien#endif /* BFD  */
51733965Sjdp
51833965Sjdp#if defined (BFD_ASSEMBLER) || !defined (BFD)
51933965Sjdp
52033965Sjdp#ifdef BFD_ASSEMBLER
52133965Sjdpstatic void
522130561Sobriencvt_frag_to_fill (segT sec ATTRIBUTE_UNUSED, fragS *fragP)
52333965Sjdp#else
52433965Sjdpstatic void
525130561Sobriencvt_frag_to_fill (object_headers *headersP, segT sec, fragS *fragP)
52633965Sjdp#endif
52733965Sjdp{
52833965Sjdp  switch (fragP->fr_type)
52933965Sjdp    {
53033965Sjdp    case rs_align:
53133965Sjdp    case rs_align_code:
53277298Sobrien    case rs_align_test:
53333965Sjdp    case rs_org:
53433965Sjdp    case rs_space:
53533965Sjdp#ifdef HANDLE_ALIGN
53633965Sjdp      HANDLE_ALIGN (fragP);
53733965Sjdp#endif
53833965Sjdp      know (fragP->fr_next != NULL);
53933965Sjdp      fragP->fr_offset = (fragP->fr_next->fr_address
54033965Sjdp			  - fragP->fr_address
54133965Sjdp			  - fragP->fr_fix) / fragP->fr_var;
54233965Sjdp      if (fragP->fr_offset < 0)
54333965Sjdp	{
54460484Sobrien	  as_bad_where (fragP->fr_file, fragP->fr_line,
54560484Sobrien			_("attempt to .org/.space backwards? (%ld)"),
54660484Sobrien			(long) fragP->fr_offset);
547104834Sobrien	  fragP->fr_offset = 0;
54833965Sjdp	}
54933965Sjdp      fragP->fr_type = rs_fill;
55033965Sjdp      break;
55133965Sjdp
55233965Sjdp    case rs_fill:
55333965Sjdp      break;
55433965Sjdp
55538889Sjdp    case rs_leb128:
55638889Sjdp      {
55738889Sjdp	valueT value = S_GET_VALUE (fragP->fr_symbol);
55838889Sjdp	int size;
55938889Sjdp
56038889Sjdp	size = output_leb128 (fragP->fr_literal + fragP->fr_fix, value,
56138889Sjdp			      fragP->fr_subtype);
56238889Sjdp
56338889Sjdp	fragP->fr_fix += size;
56438889Sjdp	fragP->fr_type = rs_fill;
56538889Sjdp	fragP->fr_var = 0;
56638889Sjdp	fragP->fr_offset = 0;
56738889Sjdp	fragP->fr_symbol = NULL;
56838889Sjdp      }
56938889Sjdp      break;
57038889Sjdp
57138889Sjdp    case rs_cfa:
57238889Sjdp      eh_frame_convert_frag (fragP);
57338889Sjdp      break;
57438889Sjdp
57577298Sobrien    case rs_dwarf2dbg:
57677298Sobrien      dwarf2dbg_convert_frag (fragP);
57777298Sobrien      break;
57877298Sobrien
57933965Sjdp    case rs_machine_dependent:
58033965Sjdp#ifdef BFD_ASSEMBLER
58133965Sjdp      md_convert_frag (stdoutput, sec, fragP);
58233965Sjdp#else
58333965Sjdp      md_convert_frag (headersP, sec, fragP);
58433965Sjdp#endif
58533965Sjdp
58638889Sjdp      assert (fragP->fr_next == NULL
58738889Sjdp	      || ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
58838889Sjdp		  == fragP->fr_fix));
58933965Sjdp
59077298Sobrien      /* After md_convert_frag, we make the frag into a ".space 0".
59177298Sobrien	 md_convert_frag() should set up any fixSs and constants
59277298Sobrien	 required.  */
59333965Sjdp      frag_wane (fragP);
59433965Sjdp      break;
59533965Sjdp
59633965Sjdp#ifndef WORKING_DOT_WORD
59733965Sjdp    case rs_broken_word:
59833965Sjdp      {
59933965Sjdp	struct broken_word *lie;
60033965Sjdp
60133965Sjdp	if (fragP->fr_subtype)
60233965Sjdp	  {
60333965Sjdp	    fragP->fr_fix += md_short_jump_size;
60433965Sjdp	    for (lie = (struct broken_word *) (fragP->fr_symbol);
60533965Sjdp		 lie && lie->dispfrag == fragP;
60633965Sjdp		 lie = lie->next_broken_word)
60733965Sjdp	      if (lie->added == 1)
60833965Sjdp		fragP->fr_fix += md_long_jump_size;
60933965Sjdp	  }
61033965Sjdp	frag_wane (fragP);
61133965Sjdp      }
61233965Sjdp      break;
61333965Sjdp#endif
61433965Sjdp
61533965Sjdp    default:
61633965Sjdp      BAD_CASE (fragP->fr_type);
61733965Sjdp      break;
61833965Sjdp    }
61933965Sjdp}
62033965Sjdp
62177298Sobrien#endif /* defined (BFD_ASSEMBLER) || !defined (BFD)  */
62233965Sjdp
62333965Sjdp#ifdef BFD_ASSEMBLER
624130561Sobrienstatic void relax_seg (bfd *, asection *, PTR);
625130561Sobrien
62633965Sjdpstatic void
627130561Sobrienrelax_seg (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, PTR xxx)
62877298Sobrien{
62977298Sobrien  segment_info_type *seginfo = seg_info (sec);
63077298Sobrien
63189857Sobrien  if (seginfo && seginfo->frchainP
63289857Sobrien      && relax_segment (seginfo->frchainP->frch_root, sec))
63389857Sobrien    {
63489857Sobrien      int *result = (int *) xxx;
63589857Sobrien      *result = 1;
63689857Sobrien    }
63777298Sobrien}
63877298Sobrien
639130561Sobrienstatic void size_seg (bfd *, asection *, PTR);
640130561Sobrien
64177298Sobrienstatic void
642130561Sobriensize_seg (bfd *abfd, asection *sec, PTR xxx ATTRIBUTE_UNUSED)
64333965Sjdp{
64433965Sjdp  flagword flags;
64533965Sjdp  fragS *fragp;
64633965Sjdp  segment_info_type *seginfo;
64733965Sjdp  int x;
64833965Sjdp  valueT size, newsize;
64933965Sjdp
65033965Sjdp  subseg_change (sec, 0);
65133965Sjdp
65233965Sjdp  seginfo = seg_info (sec);
65333965Sjdp  if (seginfo && seginfo->frchainP)
65433965Sjdp    {
65533965Sjdp      for (fragp = seginfo->frchainP->frch_root; fragp; fragp = fragp->fr_next)
65633965Sjdp	cvt_frag_to_fill (sec, fragp);
65733965Sjdp      for (fragp = seginfo->frchainP->frch_root;
65833965Sjdp	   fragp->fr_next;
65933965Sjdp	   fragp = fragp->fr_next)
66077298Sobrien	/* Walk to last elt.  */
66177298Sobrien	;
66233965Sjdp      size = fragp->fr_address + fragp->fr_fix;
66333965Sjdp    }
66433965Sjdp  else
66533965Sjdp    size = 0;
66633965Sjdp
66777298Sobrien  flags = bfd_get_section_flags (abfd, sec);
66877298Sobrien
66933965Sjdp  if (size > 0 && ! seginfo->bss)
67033965Sjdp    flags |= SEC_HAS_CONTENTS;
67133965Sjdp
67233965Sjdp  /* @@ This is just an approximation.  */
67333965Sjdp  if (seginfo && seginfo->fix_root)
67433965Sjdp    flags |= SEC_RELOC;
67533965Sjdp  else
67633965Sjdp    flags &= ~SEC_RELOC;
67733965Sjdp  x = bfd_set_section_flags (abfd, sec, flags);
678130561Sobrien  assert (x);
67933965Sjdp
68033965Sjdp  newsize = md_section_align (sec, size);
68133965Sjdp  x = bfd_set_section_size (abfd, sec, newsize);
682130561Sobrien  assert (x);
68333965Sjdp
68433965Sjdp  /* If the size had to be rounded up, add some padding in the last
68533965Sjdp     non-empty frag.  */
68633965Sjdp  assert (newsize >= size);
68733965Sjdp  if (size != newsize)
68833965Sjdp    {
68933965Sjdp      fragS *last = seginfo->frchainP->frch_last;
69033965Sjdp      fragp = seginfo->frchainP->frch_root;
69133965Sjdp      while (fragp->fr_next != last)
69233965Sjdp	fragp = fragp->fr_next;
69333965Sjdp      last->fr_address = size;
694104834Sobrien      if ((newsize - size) % fragp->fr_var == 0)
695104834Sobrien	fragp->fr_offset += (newsize - size) / fragp->fr_var;
696104834Sobrien      else
697104834Sobrien	/* If we hit this abort, it's likely due to subsegs_finish not
698104834Sobrien	   providing sufficient alignment on the last frag, and the
699104834Sobrien	   machine dependent code using alignment frags with fr_var
700104834Sobrien	   greater than 1.  */
701104834Sobrien	abort ();
70233965Sjdp    }
70333965Sjdp
70433965Sjdp#ifdef tc_frob_section
70533965Sjdp  tc_frob_section (sec);
70633965Sjdp#endif
70733965Sjdp#ifdef obj_frob_section
70833965Sjdp  obj_frob_section (sec);
70933965Sjdp#endif
71033965Sjdp}
71133965Sjdp
71233965Sjdp#ifdef DEBUG2
71333965Sjdpstatic void
71433965Sjdpdump_section_relocs (abfd, sec, stream_)
71560484Sobrien     bfd *abfd ATTRIBUTE_UNUSED;
71633965Sjdp     asection *sec;
71733965Sjdp     char *stream_;
71833965Sjdp{
71933965Sjdp  FILE *stream = (FILE *) stream_;
72033965Sjdp  segment_info_type *seginfo = seg_info (sec);
72133965Sjdp  fixS *fixp = seginfo->fix_root;
72233965Sjdp
72333965Sjdp  if (!fixp)
72433965Sjdp    return;
72533965Sjdp
72633965Sjdp  fprintf (stream, "sec %s relocs:\n", sec->name);
72733965Sjdp  while (fixp)
72833965Sjdp    {
72933965Sjdp      symbolS *s = fixp->fx_addsy;
73060484Sobrien
73160484Sobrien      fprintf (stream, "  %08lx: type %d ", (unsigned long) fixp,
73260484Sobrien	       (int) fixp->fx_r_type);
73360484Sobrien      if (s == NULL)
73460484Sobrien	fprintf (stream, "no sym\n");
73560484Sobrien      else
73633965Sjdp	{
73760484Sobrien	  print_symbol_value_1 (stream, s);
73860484Sobrien	  fprintf (stream, "\n");
73933965Sjdp	}
74033965Sjdp      fixp = fixp->fx_next;
74133965Sjdp    }
74233965Sjdp}
74333965Sjdp#else
74433965Sjdp#define dump_section_relocs(ABFD,SEC,STREAM)	((void) 0)
74533965Sjdp#endif
74633965Sjdp
74733965Sjdp#ifndef EMIT_SECTION_SYMBOLS
74833965Sjdp#define EMIT_SECTION_SYMBOLS 1
74933965Sjdp#endif
75033965Sjdp
751130561Sobrien/* This pass over fixups decides whether symbols can be replaced with
752130561Sobrien   section symbols.  */
753130561Sobrien
75433965Sjdpstatic void
755130561Sobrienadjust_reloc_syms (bfd *abfd ATTRIBUTE_UNUSED,
756130561Sobrien		   asection *sec,
757130561Sobrien		   PTR xxx ATTRIBUTE_UNUSED)
75833965Sjdp{
75933965Sjdp  segment_info_type *seginfo = seg_info (sec);
76033965Sjdp  fixS *fixp;
76133965Sjdp
76233965Sjdp  if (seginfo == NULL)
76333965Sjdp    return;
76433965Sjdp
76533965Sjdp  dump_section_relocs (abfd, sec, stderr);
76633965Sjdp
76733965Sjdp  for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
76833965Sjdp    if (fixp->fx_done)
76977298Sobrien      /* Ignore it.  */
77077298Sobrien      ;
77133965Sjdp    else if (fixp->fx_addsy)
77233965Sjdp      {
77333965Sjdp	symbolS *sym;
77433965Sjdp	asection *symsec;
77533965Sjdp
77633965Sjdp#ifdef DEBUG5
77733965Sjdp	fprintf (stderr, "\n\nadjusting fixup:\n");
77833965Sjdp	print_fixup (fixp);
77933965Sjdp#endif
78033965Sjdp
78133965Sjdp	sym = fixp->fx_addsy;
78233965Sjdp
78333965Sjdp	/* All symbols should have already been resolved at this
78433965Sjdp	   point.  It is possible to see unresolved expression
78533965Sjdp	   symbols, though, since they are not in the regular symbol
78633965Sjdp	   table.  */
787130561Sobrien	resolve_symbol_value (sym);
78877298Sobrien
78960484Sobrien	if (fixp->fx_subsy != NULL)
79089857Sobrien	  resolve_symbol_value (fixp->fx_subsy);
79133965Sjdp
79233965Sjdp	/* If this symbol is equated to an undefined symbol, convert
79333965Sjdp           the fixup to being against that symbol.  */
794130561Sobrien	if (symbol_equated_reloc_p (sym))
79533965Sjdp	  {
79660484Sobrien	    fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number;
79760484Sobrien	    sym = symbol_get_value_expression (sym)->X_add_symbol;
79833965Sjdp	    fixp->fx_addsy = sym;
79933965Sjdp	  }
80033965Sjdp
801130561Sobrien	if (symbol_mri_common_p (sym))
80233965Sjdp	  {
80333965Sjdp	    /* These symbols are handled specially in fixup_segment.  */
804130561Sobrien	    continue;
80533965Sjdp	  }
80633965Sjdp
807130561Sobrien	/* If the symbol is undefined, common, weak, or global (ELF
808130561Sobrien	   shared libs), we can't replace it with the section symbol.  */
809130561Sobrien	if (S_FORCE_RELOC (fixp->fx_addsy, 1))
810130561Sobrien	  continue;
811130561Sobrien
812130561Sobrien	/* Is there some other (target cpu dependent) reason we can't adjust
813130561Sobrien	   this one?  (E.g. relocations involving function addresses on
814130561Sobrien	   the PA.  */
815130561Sobrien#ifdef tc_fix_adjustable
816130561Sobrien	if (! tc_fix_adjustable (fixp))
817130561Sobrien	  continue;
818130561Sobrien#endif
819130561Sobrien
820130561Sobrien	/* Since we're reducing to section symbols, don't attempt to reduce
821130561Sobrien	   anything that's already using one.  */
822130561Sobrien	if (symbol_section_p (sym))
823130561Sobrien	  continue;
824130561Sobrien
82560484Sobrien	symsec = S_GET_SEGMENT (sym);
82660484Sobrien	if (symsec == NULL)
82760484Sobrien	  abort ();
82877298Sobrien
82933965Sjdp	if (bfd_is_abs_section (symsec))
83033965Sjdp	  {
831130561Sobrien	    /* The fixup_segment routine normally will not use this
832130561Sobrien               symbol in a relocation.  */
833130561Sobrien	    continue;
83433965Sjdp	  }
83533965Sjdp
83660484Sobrien	/* Don't try to reduce relocs which refer to non-local symbols
83760484Sobrien           in .linkonce sections.  It can lead to confusion when a
83860484Sobrien           debugging section refers to a .linkonce section.  I hope
83960484Sobrien           this will always be correct.  */
84060484Sobrien	if (symsec != sec && ! S_IS_LOCAL (sym))
84133965Sjdp	  {
842130561Sobrien	    if ((symsec->flags & SEC_LINK_ONCE) != 0
843130561Sobrien		|| (IS_ELF
844130561Sobrien		    /* The GNU toolchain uses an extension for ELF: a
845130561Sobrien		       section beginning with the magic string
846130561Sobrien		       .gnu.linkonce is a linkonce section.  */
847130561Sobrien		    && strncmp (segment_name (symsec), ".gnu.linkonce",
848130561Sobrien				sizeof ".gnu.linkonce" - 1) == 0))
849130561Sobrien	      continue;
85033965Sjdp	  }
85133965Sjdp
85289857Sobrien	/* Never adjust a reloc against local symbol in a merge section
85389857Sobrien	   with non-zero addend.  */
854107492Sobrien	if ((symsec->flags & SEC_MERGE) != 0
855107492Sobrien	    && (fixp->fx_offset != 0 || fixp->fx_subsy != NULL))
856130561Sobrien	  continue;
857104834Sobrien
858104834Sobrien	/* Never adjust a reloc against TLS local symbol.  */
859130561Sobrien	if ((symsec->flags & SEC_THREAD_LOCAL) != 0)
860130561Sobrien	  continue;
86160484Sobrien
862130561Sobrien	/* We refetch the segment when calling section_symbol, rather
86333965Sjdp	   than using symsec, because S_GET_VALUE may wind up changing
86477298Sobrien	   the section when it calls resolve_symbol_value.  */
86533965Sjdp	fixp->fx_offset += S_GET_VALUE (sym);
86633965Sjdp	fixp->fx_addsy = section_symbol (S_GET_SEGMENT (sym));
86760484Sobrien#ifdef DEBUG5
86860484Sobrien	fprintf (stderr, "\nadjusted fixup:\n");
86960484Sobrien	print_fixup (fixp);
87060484Sobrien#endif
87133965Sjdp      }
87233965Sjdp
87333965Sjdp  dump_section_relocs (abfd, sec, stderr);
87433965Sjdp}
87533965Sjdp
87633965Sjdpstatic void
877130561Sobrienfix_segment (bfd *abfd ATTRIBUTE_UNUSED,
878130561Sobrien	     asection *sec,
879130561Sobrien	     PTR xxx ATTRIBUTE_UNUSED)
88033965Sjdp{
88133965Sjdp  segment_info_type *seginfo = seg_info (sec);
882130561Sobrien
883130561Sobrien  fixup_segment (seginfo->fix_root, sec);
884130561Sobrien}
885130561Sobrien
886130561Sobrienstatic void
887130561Sobrienwrite_relocs (bfd *abfd, asection *sec, PTR xxx ATTRIBUTE_UNUSED)
888130561Sobrien{
889130561Sobrien  segment_info_type *seginfo = seg_info (sec);
89077298Sobrien  unsigned int i;
89133965Sjdp  unsigned int n;
89233965Sjdp  arelent **relocs;
89333965Sjdp  fixS *fixp;
89433965Sjdp  char *err;
89533965Sjdp
89633965Sjdp  /* If seginfo is NULL, we did not create this section; don't do
89733965Sjdp     anything with it.  */
89833965Sjdp  if (seginfo == NULL)
89933965Sjdp    return;
90033965Sjdp
90133965Sjdp  n = 0;
90233965Sjdp  for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
90333965Sjdp    n++;
90433965Sjdp
90533965Sjdp#ifndef RELOC_EXPANSION_POSSIBLE
90633965Sjdp  /* Set up reloc information as well.  */
907130561Sobrien  relocs = (arelent **) xcalloc (n, sizeof (arelent *));
90833965Sjdp
90933965Sjdp  i = 0;
91033965Sjdp  for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
91133965Sjdp    {
91233965Sjdp      arelent *reloc;
91333965Sjdp      bfd_reloc_status_type s;
91433965Sjdp      symbolS *sym;
91533965Sjdp
91633965Sjdp      if (fixp->fx_done)
91733965Sjdp	{
91833965Sjdp	  n--;
91933965Sjdp	  continue;
92033965Sjdp	}
92133965Sjdp
92233965Sjdp      /* If this is an undefined symbol which was equated to another
92389857Sobrien         symbol, then generate the reloc against the latter symbol
92433965Sjdp         rather than the former.  */
92533965Sjdp      sym = fixp->fx_addsy;
92689857Sobrien      while (symbol_equated_reloc_p (sym))
92733965Sjdp	{
92833965Sjdp	  symbolS *n;
92933965Sjdp
93033965Sjdp	  /* We must avoid looping, as that can occur with a badly
93133965Sjdp	     written program.  */
93260484Sobrien	  n = symbol_get_value_expression (sym)->X_add_symbol;
93333965Sjdp	  if (n == sym)
93433965Sjdp	    break;
93560484Sobrien	  fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number;
93633965Sjdp	  sym = n;
93733965Sjdp	}
93833965Sjdp      fixp->fx_addsy = sym;
93933965Sjdp
94033965Sjdp      reloc = tc_gen_reloc (sec, fixp);
94133965Sjdp      if (!reloc)
94233965Sjdp	{
94333965Sjdp	  n--;
94433965Sjdp	  continue;
94533965Sjdp	}
94633965Sjdp
94733965Sjdp#if 0
94833965Sjdp      /* This test is triggered inappropriately for the SH.  */
94933965Sjdp      if (fixp->fx_where + fixp->fx_size
95033965Sjdp	  > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
95133965Sjdp	abort ();
95233965Sjdp#endif
95333965Sjdp
95433965Sjdp      s = bfd_install_relocation (stdoutput, reloc,
95533965Sjdp				  fixp->fx_frag->fr_literal,
95633965Sjdp				  fixp->fx_frag->fr_address,
95733965Sjdp				  sec, &err);
95833965Sjdp      switch (s)
95933965Sjdp	{
96033965Sjdp	case bfd_reloc_ok:
96133965Sjdp	  break;
96233965Sjdp	case bfd_reloc_overflow:
963130561Sobrien	  as_bad_where (fixp->fx_file, fixp->fx_line,
964130561Sobrien			_("relocation overflow"));
96533965Sjdp	  break;
96660484Sobrien	case bfd_reloc_outofrange:
967130561Sobrien	  as_bad_where (fixp->fx_file, fixp->fx_line,
968130561Sobrien			_("relocation out of range"));
96960484Sobrien	  break;
97033965Sjdp	default:
97160484Sobrien	  as_fatal (_("%s:%u: bad return from bfd_install_relocation: %x"),
97260484Sobrien		    fixp->fx_file, fixp->fx_line, s);
97333965Sjdp	}
97433965Sjdp      relocs[i++] = reloc;
97533965Sjdp    }
97633965Sjdp#else
97733965Sjdp  n = n * MAX_RELOC_EXPANSION;
97833965Sjdp  /* Set up reloc information as well.  */
979130561Sobrien  relocs = (arelent **) xcalloc (n, sizeof (arelent *));
98033965Sjdp
98133965Sjdp  i = 0;
98233965Sjdp  for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
98333965Sjdp    {
98433965Sjdp      arelent **reloc;
98533965Sjdp      bfd_reloc_status_type s;
98633965Sjdp      symbolS *sym;
98733965Sjdp      int j;
98833965Sjdp
98933965Sjdp      if (fixp->fx_done)
99033965Sjdp	{
99133965Sjdp	  n--;
99233965Sjdp	  continue;
99333965Sjdp	}
99433965Sjdp
99533965Sjdp      /* If this is an undefined symbol which was equated to another
99677298Sobrien         symbol, then generate the reloc against the latter symbol
99733965Sjdp         rather than the former.  */
99833965Sjdp      sym = fixp->fx_addsy;
99989857Sobrien      while (symbol_equated_reloc_p (sym))
1000130561Sobrien	{
1001130561Sobrien	  symbolS *n;
1002130561Sobrien
1003130561Sobrien	  /* We must avoid looping, as that can occur with a badly
1004130561Sobrien	     written program.  */
1005130561Sobrien	  n = symbol_get_value_expression (sym)->X_add_symbol;
1006130561Sobrien	  if (n == sym)
1007130561Sobrien	    break;
1008130561Sobrien	  fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number;
1009130561Sobrien	  sym = n;
1010130561Sobrien	}
101133965Sjdp      fixp->fx_addsy = sym;
101233965Sjdp
101333965Sjdp      reloc = tc_gen_reloc (sec, fixp);
101433965Sjdp
101533965Sjdp      for (j = 0; reloc[j]; j++)
101633965Sjdp	{
101777298Sobrien	  relocs[i++] = reloc[j];
101877298Sobrien	  assert (i <= n);
101933965Sjdp	}
102033965Sjdp      if (fixp->fx_where + fixp->fx_size
102133965Sjdp	  > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
102233965Sjdp	as_bad_where (fixp->fx_file, fixp->fx_line,
102360484Sobrien		      _("internal error: fixup not contained within frag"));
102433965Sjdp      for (j = 0; reloc[j]; j++)
102577298Sobrien	{
102633965Sjdp	  s = bfd_install_relocation (stdoutput, reloc[j],
102733965Sjdp				      fixp->fx_frag->fr_literal,
102833965Sjdp				      fixp->fx_frag->fr_address,
102933965Sjdp				      sec, &err);
103077298Sobrien	  switch (s)
103133965Sjdp	    {
103233965Sjdp	    case bfd_reloc_ok:
103333965Sjdp	      break;
103433965Sjdp	    case bfd_reloc_overflow:
103533965Sjdp	      as_bad_where (fixp->fx_file, fixp->fx_line,
103660484Sobrien			    _("relocation overflow"));
103733965Sjdp	      break;
1038130561Sobrien	    case bfd_reloc_outofrange:
1039130561Sobrien	      as_bad_where (fixp->fx_file, fixp->fx_line,
1040130561Sobrien			    _("relocation out of range"));
1041130561Sobrien	      break;
104233965Sjdp	    default:
1043130561Sobrien	      as_fatal (_("%s:%u: bad return from bfd_install_relocation: %x"),
1044130561Sobrien			fixp->fx_file, fixp->fx_line, s);
104533965Sjdp	    }
104677298Sobrien	}
104733965Sjdp    }
104833965Sjdp  n = i;
104933965Sjdp#endif
105033965Sjdp
105133965Sjdp#ifdef DEBUG4
105233965Sjdp  {
105333965Sjdp    int i, j, nsyms;
105433965Sjdp    asymbol **sympp;
105533965Sjdp    sympp = bfd_get_outsymbols (stdoutput);
105633965Sjdp    nsyms = bfd_get_symcount (stdoutput);
105733965Sjdp    for (i = 0; i < n; i++)
105833965Sjdp      if (((*relocs[i]->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0)
105933965Sjdp	{
106033965Sjdp	  for (j = 0; j < nsyms; j++)
106133965Sjdp	    if (sympp[j] == *relocs[i]->sym_ptr_ptr)
106233965Sjdp	      break;
106333965Sjdp	  if (j == nsyms)
106433965Sjdp	    abort ();
106533965Sjdp	}
106633965Sjdp  }
106733965Sjdp#endif
106833965Sjdp
106933965Sjdp  if (n)
107033965Sjdp    bfd_set_reloc (stdoutput, sec, relocs, n);
107133965Sjdp  else
107233965Sjdp    bfd_set_section_flags (abfd, sec,
107333965Sjdp			   (bfd_get_section_flags (abfd, sec)
107433965Sjdp			    & (flagword) ~SEC_RELOC));
107533965Sjdp
107660484Sobrien#ifdef SET_SECTION_RELOCS
107760484Sobrien  SET_SECTION_RELOCS (sec, relocs, n);
107860484Sobrien#endif
107960484Sobrien
108033965Sjdp#ifdef DEBUG3
108133965Sjdp  {
108233965Sjdp    int i;
108333965Sjdp    arelent *r;
108433965Sjdp    asymbol *s;
108533965Sjdp    fprintf (stderr, "relocs for sec %s\n", sec->name);
108633965Sjdp    for (i = 0; i < n; i++)
108733965Sjdp      {
108833965Sjdp	r = relocs[i];
108933965Sjdp	s = *r->sym_ptr_ptr;
109033965Sjdp	fprintf (stderr, "  reloc %2d @%08x off %4x : sym %-10s addend %x\n",
109133965Sjdp		 i, r, r->address, s->name, r->addend);
109233965Sjdp      }
109333965Sjdp  }
109433965Sjdp#endif
109533965Sjdp}
109633965Sjdp
109733965Sjdpstatic void
1098130561Sobrienwrite_contents (bfd *abfd ATTRIBUTE_UNUSED,
1099130561Sobrien		asection *sec,
1100130561Sobrien		PTR xxx ATTRIBUTE_UNUSED)
110133965Sjdp{
110233965Sjdp  segment_info_type *seginfo = seg_info (sec);
1103130561Sobrien  addressT offset = 0;
110433965Sjdp  fragS *f;
110533965Sjdp
110633965Sjdp  /* Write out the frags.  */
110733965Sjdp  if (seginfo == NULL
110877298Sobrien      || !(bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS))
110933965Sjdp    return;
111033965Sjdp
111133965Sjdp  for (f = seginfo->frchainP->frch_root;
111233965Sjdp       f;
111333965Sjdp       f = f->fr_next)
111433965Sjdp    {
111533965Sjdp      int x;
1116130561Sobrien      addressT fill_size;
111733965Sjdp      char *fill_literal;
1118130561Sobrien      offsetT count;
111933965Sjdp
112033965Sjdp      assert (f->fr_type == rs_fill);
112133965Sjdp      if (f->fr_fix)
112233965Sjdp	{
112333965Sjdp	  x = bfd_set_section_contents (stdoutput, sec,
112433965Sjdp					f->fr_literal, (file_ptr) offset,
112533965Sjdp					(bfd_size_type) f->fr_fix);
1126130561Sobrien	  if (!x)
112733965Sjdp	    {
112833965Sjdp	      bfd_perror (stdoutput->filename);
112960484Sobrien	      as_perror (_("FATAL: Can't write %s"), stdoutput->filename);
113033965Sjdp	      exit (EXIT_FAILURE);
113133965Sjdp	    }
113233965Sjdp	  offset += f->fr_fix;
113333965Sjdp	}
113433965Sjdp      fill_literal = f->fr_literal + f->fr_fix;
113533965Sjdp      fill_size = f->fr_var;
113633965Sjdp      count = f->fr_offset;
113733965Sjdp      assert (count >= 0);
113833965Sjdp      if (fill_size && count)
113933965Sjdp	{
114033965Sjdp	  char buf[256];
114177298Sobrien	  if (fill_size > sizeof (buf))
114233965Sjdp	    {
114377298Sobrien	      /* Do it the old way. Can this ever happen?  */
114433965Sjdp	      while (count--)
114533965Sjdp		{
114633965Sjdp		  x = bfd_set_section_contents (stdoutput, sec,
114733965Sjdp						fill_literal,
114833965Sjdp						(file_ptr) offset,
114933965Sjdp						(bfd_size_type) fill_size);
1150130561Sobrien		  if (!x)
115133965Sjdp		    {
115233965Sjdp		      bfd_perror (stdoutput->filename);
115377298Sobrien		      as_perror (_("FATAL: Can't write %s"),
115477298Sobrien				 stdoutput->filename);
115533965Sjdp		      exit (EXIT_FAILURE);
115633965Sjdp		    }
115733965Sjdp		  offset += fill_size;
115833965Sjdp		}
115933965Sjdp	    }
116033965Sjdp	  else
116133965Sjdp	    {
116233965Sjdp	      /* Build a buffer full of fill objects and output it as
116333965Sjdp		 often as necessary. This saves on the overhead of
116433965Sjdp		 potentially lots of bfd_set_section_contents calls.  */
116533965Sjdp	      int n_per_buf, i;
116633965Sjdp	      if (fill_size == 1)
116733965Sjdp		{
116833965Sjdp		  n_per_buf = sizeof (buf);
116933965Sjdp		  memset (buf, *fill_literal, n_per_buf);
117033965Sjdp		}
117133965Sjdp	      else
117233965Sjdp		{
117333965Sjdp		  char *bufp;
117477298Sobrien		  n_per_buf = sizeof (buf) / fill_size;
117533965Sjdp		  for (i = n_per_buf, bufp = buf; i; i--, bufp += fill_size)
117677298Sobrien		    memcpy (bufp, fill_literal, fill_size);
117733965Sjdp		}
117833965Sjdp	      for (; count > 0; count -= n_per_buf)
117933965Sjdp		{
118033965Sjdp		  n_per_buf = n_per_buf > count ? count : n_per_buf;
118177298Sobrien		  x = bfd_set_section_contents
118277298Sobrien		    (stdoutput, sec, buf, (file_ptr) offset,
118377298Sobrien		     (bfd_size_type) n_per_buf * fill_size);
1184130561Sobrien		  if (!x)
118589857Sobrien		    as_fatal (_("cannot write to output file"));
118633965Sjdp		  offset += n_per_buf * fill_size;
118733965Sjdp		}
118833965Sjdp	    }
118933965Sjdp	}
119033965Sjdp    }
119133965Sjdp}
119233965Sjdp#endif
119333965Sjdp
119433965Sjdp#if defined(BFD_ASSEMBLER) || (!defined (BFD) && !defined(OBJ_AOUT))
119533965Sjdpstatic void
1196130561Sobrienmerge_data_into_text (void)
119733965Sjdp{
119833965Sjdp#if defined(BFD_ASSEMBLER) || defined(MANY_SEGMENTS)
119933965Sjdp  seg_info (text_section)->frchainP->frch_last->fr_next =
120033965Sjdp    seg_info (data_section)->frchainP->frch_root;
120133965Sjdp  seg_info (text_section)->frchainP->frch_last =
120233965Sjdp    seg_info (data_section)->frchainP->frch_last;
120333965Sjdp  seg_info (data_section)->frchainP = 0;
120433965Sjdp#else
120533965Sjdp  fixS *tmp;
120633965Sjdp
120733965Sjdp  text_last_frag->fr_next = data_frag_root;
120833965Sjdp  text_last_frag = data_last_frag;
120933965Sjdp  data_last_frag = NULL;
121033965Sjdp  data_frag_root = NULL;
121133965Sjdp  if (text_fix_root)
121233965Sjdp    {
121333965Sjdp      for (tmp = text_fix_root; tmp->fx_next; tmp = tmp->fx_next);;
121433965Sjdp      tmp->fx_next = data_fix_root;
121533965Sjdp      text_fix_tail = data_fix_tail;
121633965Sjdp    }
121733965Sjdp  else
121833965Sjdp    text_fix_root = data_fix_root;
121933965Sjdp  data_fix_root = NULL;
122033965Sjdp#endif
122133965Sjdp}
122277298Sobrien#endif /* BFD_ASSEMBLER || (! BFD && ! OBJ_AOUT)  */
122333965Sjdp
122433965Sjdp#if !defined (BFD_ASSEMBLER) && !defined (BFD)
122533965Sjdpstatic void
122633965Sjdprelax_and_size_all_segments ()
122733965Sjdp{
122833965Sjdp  fragS *fragP;
122933965Sjdp
123033965Sjdp  relax_segment (text_frag_root, SEG_TEXT);
123133965Sjdp  relax_segment (data_frag_root, SEG_DATA);
123233965Sjdp  relax_segment (bss_frag_root, SEG_BSS);
123333965Sjdp
123477298Sobrien  /* Now the addresses of frags are correct within the segment.  */
123533965Sjdp  know (text_last_frag->fr_type == rs_fill && text_last_frag->fr_offset == 0);
123633965Sjdp  H_SET_TEXT_SIZE (&headers, text_last_frag->fr_address);
123733965Sjdp  text_last_frag->fr_address = H_GET_TEXT_SIZE (&headers);
123833965Sjdp
123977298Sobrien  /* Join the 2 segments into 1 huge segment.
124077298Sobrien     To do this, re-compute every rn_address in the SEG_DATA frags.
124177298Sobrien     Then join the data frags after the text frags.
124277298Sobrien
124377298Sobrien     Determine a_data [length of data segment].  */
124433965Sjdp  if (data_frag_root)
124533965Sjdp    {
124633965Sjdp      register relax_addressT slide;
124733965Sjdp
124877298Sobrien      know ((text_last_frag->fr_type == rs_fill)
124977298Sobrien	    && (text_last_frag->fr_offset == 0));
125033965Sjdp
125133965Sjdp      H_SET_DATA_SIZE (&headers, data_last_frag->fr_address);
125233965Sjdp      data_last_frag->fr_address = H_GET_DATA_SIZE (&headers);
125377298Sobrien      slide = H_GET_TEXT_SIZE (&headers);	/* & in file of the data segment.  */
125433965Sjdp#ifdef OBJ_BOUT
125533965Sjdp#define RoundUp(N,S) (((N)+(S)-1)&-(S))
125633965Sjdp      /* For b.out: If the data section has a strict alignment
125733965Sjdp	 requirement, its load address in the .o file will be
125833965Sjdp	 rounded up from the size of the text section.  These
125933965Sjdp	 two values are *not* the same!  Similarly for the bss
126033965Sjdp	 section....  */
126133965Sjdp      slide = RoundUp (slide, 1 << section_alignment[SEG_DATA]);
126233965Sjdp#endif
126333965Sjdp
126433965Sjdp      for (fragP = data_frag_root; fragP; fragP = fragP->fr_next)
126577298Sobrien	fragP->fr_address += slide;
126633965Sjdp
126733965Sjdp      know (text_last_frag != 0);
126833965Sjdp      text_last_frag->fr_next = data_frag_root;
126933965Sjdp    }
127033965Sjdp  else
127133965Sjdp    {
127233965Sjdp      H_SET_DATA_SIZE (&headers, 0);
127333965Sjdp    }
127433965Sjdp
127533965Sjdp#ifdef OBJ_BOUT
127633965Sjdp  /* See above comments on b.out data section address.  */
127733965Sjdp  {
1278130561Sobrien    addressT bss_vma;
127933965Sjdp    if (data_last_frag == 0)
128033965Sjdp      bss_vma = H_GET_TEXT_SIZE (&headers);
128133965Sjdp    else
128233965Sjdp      bss_vma = data_last_frag->fr_address;
128333965Sjdp    bss_vma = RoundUp (bss_vma, 1 << section_alignment[SEG_BSS]);
128433965Sjdp    bss_address_frag.fr_address = bss_vma;
128533965Sjdp  }
128677298Sobrien#else /* ! OBJ_BOUT  */
128733965Sjdp  bss_address_frag.fr_address = (H_GET_TEXT_SIZE (&headers) +
128833965Sjdp				 H_GET_DATA_SIZE (&headers));
128933965Sjdp
129077298Sobrien#endif /* ! OBJ_BOUT  */
129133965Sjdp
129277298Sobrien  /* Slide all the frags.  */
129333965Sjdp  if (bss_frag_root)
129433965Sjdp    {
129533965Sjdp      relax_addressT slide = bss_address_frag.fr_address;
129633965Sjdp
129733965Sjdp      for (fragP = bss_frag_root; fragP; fragP = fragP->fr_next)
129877298Sobrien	fragP->fr_address += slide;
129933965Sjdp    }
130033965Sjdp
130133965Sjdp  if (bss_last_frag)
130233965Sjdp    H_SET_BSS_SIZE (&headers,
130333965Sjdp		    bss_last_frag->fr_address - bss_frag_root->fr_address);
130433965Sjdp  else
130533965Sjdp    H_SET_BSS_SIZE (&headers, 0);
130633965Sjdp}
130777298Sobrien#endif /* ! BFD_ASSEMBLER && ! BFD  */
130833965Sjdp
130933965Sjdp#if defined (BFD_ASSEMBLER) || !defined (BFD)
131033965Sjdp
131133965Sjdp#ifdef BFD_ASSEMBLER
131233965Sjdpstatic void
1313130561Sobrienset_symtab (void)
131433965Sjdp{
131533965Sjdp  int nsyms;
131633965Sjdp  asymbol **asympp;
131733965Sjdp  symbolS *symp;
1318130561Sobrien  bfd_boolean result;
1319130561Sobrien  extern PTR bfd_alloc (bfd *, bfd_size_type);
132033965Sjdp
132133965Sjdp  /* Count symbols.  We can't rely on a count made by the loop in
132233965Sjdp     write_object_file, because *_frob_file may add a new symbol or
132333965Sjdp     two.  */
132433965Sjdp  nsyms = 0;
132533965Sjdp  for (symp = symbol_rootP; symp; symp = symbol_next (symp))
132633965Sjdp    nsyms++;
132733965Sjdp
132833965Sjdp  if (nsyms)
132933965Sjdp    {
133033965Sjdp      int i;
133189857Sobrien      bfd_size_type amt = (bfd_size_type) nsyms * sizeof (asymbol *);
133233965Sjdp
133389857Sobrien      asympp = (asymbol **) bfd_alloc (stdoutput, amt);
133433965Sjdp      symp = symbol_rootP;
133533965Sjdp      for (i = 0; i < nsyms; i++, symp = symbol_next (symp))
133633965Sjdp	{
133760484Sobrien	  asympp[i] = symbol_get_bfdsym (symp);
133860484Sobrien	  symbol_mark_written (symp);
133933965Sjdp	}
134033965Sjdp    }
134133965Sjdp  else
134233965Sjdp    asympp = 0;
134333965Sjdp  result = bfd_set_symtab (stdoutput, asympp, nsyms);
1344130561Sobrien  assert (result);
134533965Sjdp  symbol_table_frozen = 1;
134633965Sjdp}
134733965Sjdp#endif
134833965Sjdp
134938889Sjdp/* Finish the subsegments.  After every sub-segment, we fake an
135038889Sjdp   ".align ...".  This conforms to BSD4.2 brane-damage.  We then fake
135138889Sjdp   ".fill 0" because that is the kind of frag that requires least
135238889Sjdp   thought.  ".align" frags like to have a following frag since that
135338889Sjdp   makes calculating their intended length trivial.  */
135438889Sjdp
135538889Sjdp#ifndef SUB_SEGMENT_ALIGN
1356104834Sobrien#ifdef HANDLE_ALIGN
1357130561Sobrien/* The last subsegment gets an alignment corresponding to the alignment
1358104834Sobrien   of the section.  This allows proper nop-filling at the end of
1359104834Sobrien   code-bearing sections.  */
1360104834Sobrien#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN)					\
1361104834Sobrien  (!(FRCHAIN)->frch_next || (FRCHAIN)->frch_next->frch_seg != (SEG)	\
1362104834Sobrien   ? get_recorded_alignment (SEG) : 0)
1363104834Sobrien#else
136438889Sjdp#ifdef BFD_ASSEMBLER
1365104834Sobrien#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
136638889Sjdp#else
1367104834Sobrien#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 2
136838889Sjdp#endif
136938889Sjdp#endif
1370104834Sobrien#endif
137138889Sjdp
137233965Sjdpvoid
1373130561Sobriensubsegs_finish (void)
137438889Sjdp{
137538889Sjdp  struct frchain *frchainP;
137638889Sjdp
137738889Sjdp  for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next)
137838889Sjdp    {
1379104834Sobrien      int alignment = 0;
138077298Sobrien
138138889Sjdp      subseg_set (frchainP->frch_seg, frchainP->frch_subseg);
138238889Sjdp
138360484Sobrien      /* This now gets called even if we had errors.  In that case,
138460484Sobrien         any alignment is meaningless, and, moreover, will look weird
138560484Sobrien         if we are generating a listing.  */
1386104834Sobrien      if (!had_errors ())
1387130561Sobrien	{
1388130561Sobrien	  alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP);
1389130561Sobrien#ifdef BFD_ASSEMBLER
1390130561Sobrien	  if ((bfd_get_section_flags (now_seg->owner, now_seg) & SEC_MERGE)
1391130561Sobrien	      && now_seg->entsize)
1392130561Sobrien	    {
1393130561Sobrien	      unsigned int entsize = now_seg->entsize;
1394130561Sobrien	      int entalign = 0;
139560484Sobrien
1396130561Sobrien	      while ((entsize & 1) == 0)
1397130561Sobrien		{
1398130561Sobrien		  ++entalign;
1399130561Sobrien		  entsize >>= 1;
1400130561Sobrien		}
1401130561Sobrien	      if (entalign > alignment)
1402130561Sobrien		alignment = entalign;
1403130561Sobrien	    }
1404130561Sobrien#endif
1405130561Sobrien	}
1406130561Sobrien
140777298Sobrien      if (subseg_text_p (now_seg))
140877298Sobrien	frag_align_code (alignment, 0);
140977298Sobrien      else
141077298Sobrien	frag_align (alignment, 0, 0);
141177298Sobrien
141238889Sjdp      /* frag_align will have left a new frag.
141338889Sjdp	 Use this last frag for an empty ".fill".
141438889Sjdp
141538889Sjdp	 For this segment ...
141638889Sjdp	 Create a last frag. Do not leave a "being filled in frag".  */
141738889Sjdp      frag_wane (frag_now);
141838889Sjdp      frag_now->fr_fix = 0;
141938889Sjdp      know (frag_now->fr_next == NULL);
142038889Sjdp    }
142138889Sjdp}
142238889Sjdp
142338889Sjdp/* Write the object file.  */
142438889Sjdp
142538889Sjdpvoid
1426130561Sobrienwrite_object_file (void)
142733965Sjdp{
142833965Sjdp#if ! defined (BFD_ASSEMBLER) || ! defined (WORKING_DOT_WORD)
142977298Sobrien  fragS *fragP;			/* Track along all frags.  */
143033965Sjdp#endif
143133965Sjdp
143233965Sjdp  /* Do we really want to write it?  */
143333965Sjdp  {
143433965Sjdp    int n_warns, n_errs;
143533965Sjdp    n_warns = had_warnings ();
143633965Sjdp    n_errs = had_errors ();
143733965Sjdp    /* The -Z flag indicates that an object file should be generated,
143833965Sjdp       regardless of warnings and errors.  */
143933965Sjdp    if (flag_always_generate_output)
144033965Sjdp      {
144133965Sjdp	if (n_warns || n_errs)
144289857Sobrien	  as_warn (_("%d error%s, %d warning%s, generating bad object file"),
144333965Sjdp		   n_errs, n_errs == 1 ? "" : "s",
144433965Sjdp		   n_warns, n_warns == 1 ? "" : "s");
144533965Sjdp      }
144633965Sjdp    else
144733965Sjdp      {
144833965Sjdp	if (n_errs)
144989857Sobrien	  as_fatal (_("%d error%s, %d warning%s, no object file generated"),
145033965Sjdp		    n_errs, n_errs == 1 ? "" : "s",
145133965Sjdp		    n_warns, n_warns == 1 ? "" : "s");
145233965Sjdp      }
145333965Sjdp  }
145433965Sjdp
145533965Sjdp#ifdef	OBJ_VMS
145633965Sjdp  /* Under VMS we try to be compatible with VAX-11 "C".  Thus, we call
145733965Sjdp     a routine to check for the definition of the procedure "_main",
145877298Sobrien     and if so -- fix it up so that it can be program entry point.  */
145933965Sjdp  vms_check_for_main ();
146077298Sobrien#endif /* OBJ_VMS  */
146133965Sjdp
146233965Sjdp  /* From now on, we don't care about sub-segments.  Build one frag chain
146333965Sjdp     for each segment. Linked thru fr_next.  */
146433965Sjdp
146533965Sjdp#ifdef BFD_ASSEMBLER
146633965Sjdp  /* Remove the sections created by gas for its own purposes.  */
146733965Sjdp  {
146889857Sobrien    asection **seclist;
146933965Sjdp    int i;
147033965Sjdp
147133965Sjdp    seclist = &stdoutput->sections;
147289857Sobrien    while (*seclist)
147333965Sjdp      {
147489857Sobrien	if (*seclist == reg_section || *seclist == expr_section)
147533965Sjdp	  {
147689857Sobrien	    bfd_section_list_remove (stdoutput, seclist);
147733965Sjdp	    stdoutput->section_count--;
147833965Sjdp	  }
147989857Sobrien	else
148033965Sjdp	  seclist = &(*seclist)->next;
148133965Sjdp      }
148233965Sjdp    i = 0;
148333965Sjdp    bfd_map_over_sections (stdoutput, renumber_sections, &i);
148433965Sjdp  }
148533965Sjdp
148633965Sjdp  bfd_map_over_sections (stdoutput, chain_frchains_together, (char *) 0);
148733965Sjdp#else
148833965Sjdp  remove_subsegs (frchain_root, SEG_TEXT, &text_frag_root, &text_last_frag);
148933965Sjdp  remove_subsegs (data0_frchainP, SEG_DATA, &data_frag_root, &data_last_frag);
149033965Sjdp  remove_subsegs (bss0_frchainP, SEG_BSS, &bss_frag_root, &bss_last_frag);
149133965Sjdp#endif
149233965Sjdp
149333965Sjdp  /* We have two segments. If user gave -R flag, then we must put the
149433965Sjdp     data frags into the text segment. Do this before relaxing so
149533965Sjdp     we know to take advantage of -R and make shorter addresses.  */
149633965Sjdp#if !defined (OBJ_AOUT) || defined (BFD_ASSEMBLER)
149733965Sjdp  if (flag_readonly_data_in_text)
149833965Sjdp    {
149933965Sjdp      merge_data_into_text ();
150033965Sjdp    }
150133965Sjdp#endif
150233965Sjdp
150333965Sjdp#ifdef BFD_ASSEMBLER
150489857Sobrien  while (1)
150589857Sobrien    {
150689857Sobrien      int changed;
150789857Sobrien
150889857Sobrien#ifndef WORKING_DOT_WORD
150989857Sobrien      /* We need to reset the markers in the broken word list and
151089857Sobrien	 associated frags between calls to relax_segment (via
151189857Sobrien	 relax_seg).  Since the broken word list is global, we do it
151289857Sobrien	 once per round, rather than locally in relax_segment for each
151389857Sobrien	 segment.  */
151489857Sobrien      struct broken_word *brokp;
151589857Sobrien
151689857Sobrien      for (brokp = broken_words;
151789857Sobrien	   brokp != (struct broken_word *) NULL;
151889857Sobrien	   brokp = brokp->next_broken_word)
151989857Sobrien	{
152089857Sobrien	  brokp->added = 0;
152189857Sobrien
152289857Sobrien	  if (brokp->dispfrag != (fragS *) NULL
152389857Sobrien	      && brokp->dispfrag->fr_type == rs_broken_word)
152489857Sobrien	    brokp->dispfrag->fr_subtype = 0;
152589857Sobrien	}
152689857Sobrien#endif
152789857Sobrien
152889857Sobrien      changed = 0;
152989857Sobrien      bfd_map_over_sections (stdoutput, relax_seg, &changed);
153089857Sobrien      if (!changed)
153189857Sobrien	break;
153289857Sobrien    }
153389857Sobrien
153489857Sobrien  /* Note - Most ports will use the default value of
153589857Sobrien     TC_FINALIZE_SYMS_BEFORE_SIZE_SEG, which 1.  This will force
153689857Sobrien     local symbols to be resolved, removing their frag information.
153789857Sobrien     Some ports however, will not have finished relaxing all of
153889857Sobrien     their frags and will still need the local symbol frag
153989857Sobrien     information.  These ports can set
154089857Sobrien     TC_FINALIZE_SYMS_BEFORE_SIZE_SEG to 0.  */
154189857Sobrien  finalize_syms = TC_FINALIZE_SYMS_BEFORE_SIZE_SEG;
154289857Sobrien
154377298Sobrien  bfd_map_over_sections (stdoutput, size_seg, (char *) 0);
154433965Sjdp#else
154533965Sjdp  relax_and_size_all_segments ();
154677298Sobrien#endif /* BFD_ASSEMBLER  */
154733965Sjdp
154889857Sobrien  /* Relaxation has completed.  Freeze all syms.  */
154989857Sobrien  finalize_syms = 1;
155089857Sobrien
1551130561Sobrien#ifdef md_post_relax_hook
1552130561Sobrien  md_post_relax_hook;
1553130561Sobrien#endif
1554130561Sobrien
155533965Sjdp#ifndef BFD_ASSEMBLER
155677298Sobrien  /* Crawl the symbol chain.
155777298Sobrien
155877298Sobrien     For each symbol whose value depends on a frag, take the address of
155977298Sobrien     that frag and subsume it into the value of the symbol.
156077298Sobrien     After this, there is just one way to lookup a symbol value.
156177298Sobrien     Values are left in their final state for object file emission.
156277298Sobrien     We adjust the values of 'L' local symbols, even if we do
156377298Sobrien     not intend to emit them to the object file, because their values
156477298Sobrien     are needed for fix-ups.
156577298Sobrien
156677298Sobrien     Unless we saw a -L flag, remove all symbols that begin with 'L'
156777298Sobrien     from the symbol chain.  (They are still pointed to by the fixes.)
156877298Sobrien
156977298Sobrien     Count the remaining symbols.
157077298Sobrien     Assign a symbol number to each symbol.
157177298Sobrien     Count the number of string-table chars we will emit.
157277298Sobrien     Put this info into the headers as appropriate.  */
157333965Sjdp  know (zero_address_frag.fr_address == 0);
157433965Sjdp  string_byte_count = sizeof (string_byte_count);
157533965Sjdp
157633965Sjdp  obj_crawl_symbol_chain (&headers);
157733965Sjdp
157833965Sjdp  if (string_byte_count == sizeof (string_byte_count))
157933965Sjdp    string_byte_count = 0;
158033965Sjdp
158133965Sjdp  H_SET_STRING_SIZE (&headers, string_byte_count);
158233965Sjdp
158377298Sobrien  /* Addresses of frags now reflect addresses we use in the object file.
158477298Sobrien     Symbol values are correct.
158577298Sobrien     Scan the frags, converting any ".org"s and ".align"s to ".fill"s.
158677298Sobrien     Also converting any machine-dependent frags using md_convert_frag();  */
158733965Sjdp  subseg_change (SEG_TEXT, 0);
158833965Sjdp
158933965Sjdp  for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
159033965Sjdp    {
159138889Sjdp      /* At this point we have linked all the frags into a single
159238889Sjdp         chain.  However, cvt_frag_to_fill may call md_convert_frag
159338889Sjdp         which may call fix_new.  We need to ensure that fix_new adds
159438889Sjdp         the fixup to the right section.  */
159538889Sjdp      if (fragP == data_frag_root)
159638889Sjdp	subseg_change (SEG_DATA, 0);
159738889Sjdp
159833965Sjdp      cvt_frag_to_fill (&headers, SEG_TEXT, fragP);
159933965Sjdp
160033965Sjdp      /* Some assert macros don't work with # directives mixed in.  */
160133965Sjdp#ifndef NDEBUG
160233965Sjdp      if (!(fragP->fr_next == NULL
160333965Sjdp#ifdef OBJ_BOUT
160433965Sjdp	    || fragP->fr_next == data_frag_root
160533965Sjdp#endif
1606130561Sobrien	    || ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
160733965Sjdp		== (fragP->fr_fix + fragP->fr_offset * fragP->fr_var))))
160833965Sjdp	abort ();
160933965Sjdp#endif
161033965Sjdp    }
161177298Sobrien#endif /* ! BFD_ASSEMBLER  */
161233965Sjdp
161333965Sjdp#ifndef WORKING_DOT_WORD
161433965Sjdp  {
161533965Sjdp    struct broken_word *lie;
161633965Sjdp    struct broken_word **prevP;
161733965Sjdp
161833965Sjdp    prevP = &broken_words;
161933965Sjdp    for (lie = broken_words; lie; lie = lie->next_broken_word)
162033965Sjdp      if (!lie->added)
162133965Sjdp	{
162233965Sjdp	  expressionS exp;
162333965Sjdp
162460484Sobrien	  subseg_change (lie->seg, lie->subseg);
162533965Sjdp	  exp.X_op = O_subtract;
162633965Sjdp	  exp.X_add_symbol = lie->add;
162733965Sjdp	  exp.X_op_symbol = lie->sub;
162833965Sjdp	  exp.X_add_number = lie->addnum;
162933965Sjdp#ifdef BFD_ASSEMBLER
163033965Sjdp#ifdef TC_CONS_FIX_NEW
163133965Sjdp	  TC_CONS_FIX_NEW (lie->frag,
163277298Sobrien			   lie->word_goes_here - lie->frag->fr_literal,
163377298Sobrien			   2, &exp);
163433965Sjdp#else
163533965Sjdp	  fix_new_exp (lie->frag,
163633965Sjdp		       lie->word_goes_here - lie->frag->fr_literal,
163733965Sjdp		       2, &exp, 0, BFD_RELOC_16);
163833965Sjdp#endif
163933965Sjdp#else
164033965Sjdp#if defined(TC_SPARC) || defined(TC_A29K) || defined(NEED_FX_R_TYPE)
164133965Sjdp	  fix_new_exp (lie->frag,
164233965Sjdp		       lie->word_goes_here - lie->frag->fr_literal,
164333965Sjdp		       2, &exp, 0, NO_RELOC);
164433965Sjdp#else
164533965Sjdp#ifdef TC_NS32K
164633965Sjdp	  fix_new_ns32k_exp (lie->frag,
164733965Sjdp			     lie->word_goes_here - lie->frag->fr_literal,
164833965Sjdp			     2, &exp, 0, 0, 2, 0, 0);
164933965Sjdp#else
165033965Sjdp	  fix_new_exp (lie->frag,
165133965Sjdp		       lie->word_goes_here - lie->frag->fr_literal,
165233965Sjdp		       2, &exp, 0, 0);
165377298Sobrien#endif /* TC_NS32K  */
165477298Sobrien#endif /* TC_SPARC|TC_A29K|NEED_FX_R_TYPE  */
165577298Sobrien#endif /* BFD_ASSEMBLER  */
165633965Sjdp	  *prevP = lie->next_broken_word;
165733965Sjdp	}
165833965Sjdp      else
165933965Sjdp	prevP = &(lie->next_broken_word);
166033965Sjdp
166133965Sjdp    for (lie = broken_words; lie;)
166233965Sjdp      {
166333965Sjdp	struct broken_word *untruth;
166433965Sjdp	char *table_ptr;
166533965Sjdp	addressT table_addr;
166633965Sjdp	addressT from_addr, to_addr;
166733965Sjdp	int n, m;
166833965Sjdp
166960484Sobrien	subseg_change (lie->seg, lie->subseg);
167033965Sjdp	fragP = lie->dispfrag;
167133965Sjdp
167233965Sjdp	/* Find out how many broken_words go here.  */
167333965Sjdp	n = 0;
167477298Sobrien	for (untruth = lie;
167577298Sobrien	     untruth && untruth->dispfrag == fragP;
167677298Sobrien	     untruth = untruth->next_broken_word)
167733965Sjdp	  if (untruth->added == 1)
167833965Sjdp	    n++;
167933965Sjdp
168033965Sjdp	table_ptr = lie->dispfrag->fr_opcode;
168177298Sobrien	table_addr = (lie->dispfrag->fr_address
168277298Sobrien		      + (table_ptr - lie->dispfrag->fr_literal));
168333965Sjdp	/* Create the jump around the long jumps.  This is a short
168433965Sjdp	   jump from table_ptr+0 to table_ptr+n*long_jump_size.  */
168533965Sjdp	from_addr = table_addr;
168633965Sjdp	to_addr = table_addr + md_short_jump_size + n * md_long_jump_size;
168777298Sobrien	md_create_short_jump (table_ptr, from_addr, to_addr, lie->dispfrag,
168877298Sobrien			      lie->add);
168933965Sjdp	table_ptr += md_short_jump_size;
169033965Sjdp	table_addr += md_short_jump_size;
169133965Sjdp
169277298Sobrien	for (m = 0;
169377298Sobrien	     lie && lie->dispfrag == fragP;
169477298Sobrien	     m++, lie = lie->next_broken_word)
169533965Sjdp	  {
169633965Sjdp	    if (lie->added == 2)
169733965Sjdp	      continue;
169877298Sobrien	    /* Patch the jump table.  */
169977298Sobrien	    /* This is the offset from ??? to table_ptr+0.  */
170033965Sjdp	    to_addr = table_addr - S_GET_VALUE (lie->sub);
170177298Sobrien#ifdef TC_CHECK_ADJUSTED_BROKEN_DOT_WORD
170277298Sobrien	    TC_CHECK_ADJUSTED_BROKEN_DOT_WORD (to_addr, lie);
170377298Sobrien#endif
170433965Sjdp	    md_number_to_chars (lie->word_goes_here, to_addr, 2);
170577298Sobrien	    for (untruth = lie->next_broken_word;
170677298Sobrien		 untruth && untruth->dispfrag == fragP;
170777298Sobrien		 untruth = untruth->next_broken_word)
170833965Sjdp	      {
170933965Sjdp		if (untruth->use_jump == lie)
171033965Sjdp		  md_number_to_chars (untruth->word_goes_here, to_addr, 2);
171133965Sjdp	      }
171233965Sjdp
171377298Sobrien	    /* Install the long jump.  */
171477298Sobrien	    /* This is a long jump from table_ptr+0 to the final target.  */
171533965Sjdp	    from_addr = table_addr;
171633965Sjdp	    to_addr = S_GET_VALUE (lie->add) + lie->addnum;
171777298Sobrien	    md_create_long_jump (table_ptr, from_addr, to_addr, lie->dispfrag,
171877298Sobrien				 lie->add);
171933965Sjdp	    table_ptr += md_long_jump_size;
172033965Sjdp	    table_addr += md_long_jump_size;
172133965Sjdp	  }
172233965Sjdp      }
172333965Sjdp  }
172477298Sobrien#endif /* not WORKING_DOT_WORD  */
172533965Sjdp
172633965Sjdp#ifndef BFD_ASSEMBLER
172733965Sjdp#ifndef	OBJ_VMS
172877298Sobrien  {				/* not vms  */
172933965Sjdp    char *the_object_file;
173033965Sjdp    long object_file_size;
173177298Sobrien    /* Scan every FixS performing fixups. We had to wait until now to
173277298Sobrien       do this because md_convert_frag() may have made some fixSs.  */
173333965Sjdp    int trsize, drsize;
173433965Sjdp
173533965Sjdp    subseg_change (SEG_TEXT, 0);
173633965Sjdp    trsize = md_reloc_size * fixup_segment (text_fix_root, SEG_TEXT);
173733965Sjdp    subseg_change (SEG_DATA, 0);
173833965Sjdp    drsize = md_reloc_size * fixup_segment (data_fix_root, SEG_DATA);
173933965Sjdp    H_SET_RELOCATION_SIZE (&headers, trsize, drsize);
174033965Sjdp
174177298Sobrien    /* FIXME: Move this stuff into the pre-write-hook.  */
174233965Sjdp    H_SET_MAGIC_NUMBER (&headers, magic_number_for_object_file);
174333965Sjdp    H_SET_ENTRY_POINT (&headers, 0);
174433965Sjdp
174577298Sobrien    obj_pre_write_hook (&headers);	/* Extra coff stuff.  */
174633965Sjdp
174733965Sjdp    object_file_size = H_GET_FILE_SIZE (&headers);
174833965Sjdp    next_object_file_charP = the_object_file = xmalloc (object_file_size);
174933965Sjdp
175033965Sjdp    output_file_create (out_file_name);
175133965Sjdp
175233965Sjdp    obj_header_append (&next_object_file_charP, &headers);
175333965Sjdp
175477298Sobrien    know ((next_object_file_charP - the_object_file)
175577298Sobrien	  == H_GET_HEADER_SIZE (&headers));
175633965Sjdp
175777298Sobrien    /* Emit code.  */
175833965Sjdp    for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
175933965Sjdp      {
176033965Sjdp	register long count;
176133965Sjdp	register char *fill_literal;
176233965Sjdp	register long fill_size;
176333965Sjdp
176433965Sjdp	PROGRESS (1);
176533965Sjdp	know (fragP->fr_type == rs_fill);
176677298Sobrien	append (&next_object_file_charP, fragP->fr_literal,
176777298Sobrien		(unsigned long) fragP->fr_fix);
176833965Sjdp	fill_literal = fragP->fr_literal + fragP->fr_fix;
176933965Sjdp	fill_size = fragP->fr_var;
177033965Sjdp	know (fragP->fr_offset >= 0);
177133965Sjdp
177233965Sjdp	for (count = fragP->fr_offset; count; count--)
177377298Sobrien	  append (&next_object_file_charP, fill_literal,
177477298Sobrien		  (unsigned long) fill_size);
177577298Sobrien      }
177633965Sjdp
177777298Sobrien    know ((next_object_file_charP - the_object_file)
177877298Sobrien	  == (H_GET_HEADER_SIZE (&headers)
177977298Sobrien	      + H_GET_TEXT_SIZE (&headers)
178077298Sobrien	      + H_GET_DATA_SIZE (&headers)));
178133965Sjdp
178277298Sobrien    /* Emit relocations.  */
178377298Sobrien    obj_emit_relocations (&next_object_file_charP, text_fix_root,
178477298Sobrien			  (relax_addressT) 0);
178577298Sobrien    know ((next_object_file_charP - the_object_file)
178677298Sobrien	  == (H_GET_HEADER_SIZE (&headers)
178777298Sobrien	      + H_GET_TEXT_SIZE (&headers)
178877298Sobrien	      + H_GET_DATA_SIZE (&headers)
178977298Sobrien	      + H_GET_TEXT_RELOCATION_SIZE (&headers)));
179033965Sjdp#ifdef TC_I960
179133965Sjdp    /* Make addresses in data relocation directives relative to beginning of
179277298Sobrien       first data fragment, not end of last text fragment:  alignment of the
179377298Sobrien       start of the data segment may place a gap between the segments.  */
179477298Sobrien    obj_emit_relocations (&next_object_file_charP, data_fix_root,
179577298Sobrien			  data0_frchainP->frch_root->fr_address);
179677298Sobrien#else /* TC_I960  */
179777298Sobrien    obj_emit_relocations (&next_object_file_charP, data_fix_root,
179877298Sobrien			  text_last_frag->fr_address);
179977298Sobrien#endif /* TC_I960  */
180033965Sjdp
180177298Sobrien    know ((next_object_file_charP - the_object_file)
180277298Sobrien	  == (H_GET_HEADER_SIZE (&headers)
180377298Sobrien	      + H_GET_TEXT_SIZE (&headers)
180477298Sobrien	      + H_GET_DATA_SIZE (&headers)
180577298Sobrien	      + H_GET_TEXT_RELOCATION_SIZE (&headers)
180677298Sobrien	      + H_GET_DATA_RELOCATION_SIZE (&headers)));
180733965Sjdp
180877298Sobrien    /* Emit line number entries.  */
180933965Sjdp    OBJ_EMIT_LINENO (&next_object_file_charP, lineno_rootP, the_object_file);
181077298Sobrien    know ((next_object_file_charP - the_object_file)
181177298Sobrien	  == (H_GET_HEADER_SIZE (&headers)
181277298Sobrien	      + H_GET_TEXT_SIZE (&headers)
181377298Sobrien	      + H_GET_DATA_SIZE (&headers)
181477298Sobrien	      + H_GET_TEXT_RELOCATION_SIZE (&headers)
181577298Sobrien	      + H_GET_DATA_RELOCATION_SIZE (&headers)
181677298Sobrien	      + H_GET_LINENO_SIZE (&headers)));
181733965Sjdp
181877298Sobrien    /* Emit symbols.  */
181933965Sjdp    obj_emit_symbols (&next_object_file_charP, symbol_rootP);
182077298Sobrien    know ((next_object_file_charP - the_object_file)
182177298Sobrien	  == (H_GET_HEADER_SIZE (&headers)
182277298Sobrien	      + H_GET_TEXT_SIZE (&headers)
182377298Sobrien	      + H_GET_DATA_SIZE (&headers)
182477298Sobrien	      + H_GET_TEXT_RELOCATION_SIZE (&headers)
182577298Sobrien	      + H_GET_DATA_RELOCATION_SIZE (&headers)
182677298Sobrien	      + H_GET_LINENO_SIZE (&headers)
182777298Sobrien	      + H_GET_SYMBOL_TABLE_SIZE (&headers)));
182833965Sjdp
182977298Sobrien    /* Emit strings.  */
183033965Sjdp    if (string_byte_count > 0)
183177298Sobrien      obj_emit_strings (&next_object_file_charP);
183233965Sjdp
183333965Sjdp#ifdef BFD_HEADERS
183489857Sobrien    bfd_seek (stdoutput, (file_ptr) 0, 0);
183589857Sobrien    bfd_bwrite (the_object_file, (bfd_size_type) object_file_size, stdoutput);
183633965Sjdp#else
183733965Sjdp
183877298Sobrien    /* Write the data to the file.  */
183933965Sjdp    output_file_append (the_object_file, object_file_size, out_file_name);
184033965Sjdp    free (the_object_file);
184133965Sjdp#endif
184277298Sobrien  }
184377298Sobrien#else /* OBJ_VMS  */
184477298Sobrien  /* Now do the VMS-dependent part of writing the object file.  */
184533965Sjdp  vms_write_object_file (H_GET_TEXT_SIZE (&headers),
184633965Sjdp			 H_GET_DATA_SIZE (&headers),
184733965Sjdp			 H_GET_BSS_SIZE (&headers),
184833965Sjdp			 text_frag_root, data_frag_root);
184977298Sobrien#endif /* OBJ_VMS  */
185077298Sobrien#else /* BFD_ASSEMBLER  */
185133965Sjdp
185233965Sjdp  /* Resolve symbol values.  This needs to be done before processing
185333965Sjdp     the relocations.  */
185433965Sjdp  if (symbol_rootP)
185533965Sjdp    {
185633965Sjdp      symbolS *symp;
185733965Sjdp
185833965Sjdp      for (symp = symbol_rootP; symp; symp = symbol_next (symp))
185989857Sobrien	resolve_symbol_value (symp);
186033965Sjdp    }
186160484Sobrien  resolve_local_symbol_values ();
186233965Sjdp
186333965Sjdp  PROGRESS (1);
186433965Sjdp
186533965Sjdp#ifdef tc_frob_file_before_adjust
186633965Sjdp  tc_frob_file_before_adjust ();
186733965Sjdp#endif
186833965Sjdp#ifdef obj_frob_file_before_adjust
186933965Sjdp  obj_frob_file_before_adjust ();
187033965Sjdp#endif
187133965Sjdp
187277298Sobrien  bfd_map_over_sections (stdoutput, adjust_reloc_syms, (char *) 0);
187333965Sjdp
1874130561Sobrien#ifdef tc_frob_file_before_fix
1875130561Sobrien  tc_frob_file_before_fix ();
1876130561Sobrien#endif
1877130561Sobrien#ifdef obj_frob_file_before_fix
1878130561Sobrien  obj_frob_file_before_fix ();
1879130561Sobrien#endif
1880130561Sobrien
1881130561Sobrien  bfd_map_over_sections (stdoutput, fix_segment, (char *) 0);
1882130561Sobrien
188333965Sjdp  /* Set up symbol table, and write it out.  */
188433965Sjdp  if (symbol_rootP)
188533965Sjdp    {
188633965Sjdp      symbolS *symp;
188733965Sjdp
188833965Sjdp      for (symp = symbol_rootP; symp; symp = symbol_next (symp))
188933965Sjdp	{
189033965Sjdp	  int punt = 0;
189133965Sjdp	  const char *name;
189233965Sjdp
189360484Sobrien	  if (symbol_mri_common_p (symp))
189433965Sjdp	    {
189533965Sjdp	      if (S_IS_EXTERNAL (symp))
189660484Sobrien		as_bad (_("%s: global symbols not supported in common sections"),
189733965Sjdp			S_GET_NAME (symp));
189833965Sjdp	      symbol_remove (symp, &symbol_rootP, &symbol_lastP);
189933965Sjdp	      continue;
190033965Sjdp	    }
190133965Sjdp
190233965Sjdp	  name = S_GET_NAME (symp);
190333965Sjdp	  if (name)
190433965Sjdp	    {
190577298Sobrien	      const char *name2 =
190677298Sobrien		decode_local_label_name ((char *) S_GET_NAME (symp));
190733965Sjdp	      /* They only differ if `name' is a fb or dollar local
190833965Sjdp		 label name.  */
190933965Sjdp	      if (name2 != name && ! S_IS_DEFINED (symp))
191089857Sobrien		as_bad (_("local label `%s' is not defined"), name2);
191133965Sjdp	    }
191233965Sjdp
191333965Sjdp	  /* Do it again, because adjust_reloc_syms might introduce
191433965Sjdp	     more symbols.  They'll probably only be section symbols,
191533965Sjdp	     but they'll still need to have the values computed.  */
191689857Sobrien	  resolve_symbol_value (symp);
191733965Sjdp
191833965Sjdp	  /* Skip symbols which were equated to undefined or common
191933965Sjdp             symbols.  */
192089857Sobrien	  if (symbol_equated_reloc_p (symp))
192133965Sjdp	    {
192233965Sjdp	      symbol_remove (symp, &symbol_rootP, &symbol_lastP);
192333965Sjdp	      continue;
192433965Sjdp	    }
192533965Sjdp
192633965Sjdp	  /* So far, common symbols have been treated like undefined symbols.
192733965Sjdp	     Put them in the common section now.  */
192833965Sjdp	  if (S_IS_DEFINED (symp) == 0
192933965Sjdp	      && S_GET_VALUE (symp) != 0)
193033965Sjdp	    S_SET_SEGMENT (symp, bfd_com_section_ptr);
193133965Sjdp#if 0
193233965Sjdp	  printf ("symbol `%s'\n\t@%x: value=%d flags=%x seg=%s\n",
193333965Sjdp		  S_GET_NAME (symp), symp,
193433965Sjdp		  S_GET_VALUE (symp),
193560484Sobrien		  symbol_get_bfdsym (symp)->flags,
193660484Sobrien		  segment_name (S_GET_SEGMENT (symp)));
193733965Sjdp#endif
193833965Sjdp
193933965Sjdp#ifdef obj_frob_symbol
194033965Sjdp	  obj_frob_symbol (symp, punt);
194133965Sjdp#endif
194233965Sjdp#ifdef tc_frob_symbol
194360484Sobrien	  if (! punt || symbol_used_in_reloc_p (symp))
194433965Sjdp	    tc_frob_symbol (symp, punt);
194533965Sjdp#endif
194633965Sjdp
194733965Sjdp	  /* If we don't want to keep this symbol, splice it out of
194833965Sjdp	     the chain now.  If EMIT_SECTION_SYMBOLS is 0, we never
194933965Sjdp	     want section symbols.  Otherwise, we skip local symbols
195033965Sjdp	     and symbols that the frob_symbol macros told us to punt,
195133965Sjdp	     but we keep such symbols if they are used in relocs.  */
1952130561Sobrien	  if (symp == abs_section_sym
1953130561Sobrien	      || (! EMIT_SECTION_SYMBOLS
1954130561Sobrien		  && symbol_section_p (symp))
195533965Sjdp	      /* Note that S_IS_EXTERN and S_IS_LOCAL are not always
195633965Sjdp		 opposites.  Sometimes the former checks flags and the
195733965Sjdp		 latter examines the name...  */
195833965Sjdp	      || (!S_IS_EXTERN (symp)
1959130561Sobrien		  && (punt || S_IS_LOCAL (symp))
196060484Sobrien		  && ! symbol_used_in_reloc_p (symp)))
196133965Sjdp	    {
196233965Sjdp	      symbol_remove (symp, &symbol_rootP, &symbol_lastP);
196377298Sobrien
196433965Sjdp	      /* After symbol_remove, symbol_next(symp) still returns
196533965Sjdp		 the one that came after it in the chain.  So we don't
196633965Sjdp		 need to do any extra cleanup work here.  */
196733965Sjdp	      continue;
196833965Sjdp	    }
196933965Sjdp
197033965Sjdp	  /* Make sure we really got a value for the symbol.  */
197160484Sobrien	  if (! symbol_resolved_p (symp))
197233965Sjdp	    {
197389857Sobrien	      as_bad (_("can't resolve value for symbol `%s'"),
197433965Sjdp		      S_GET_NAME (symp));
197560484Sobrien	      symbol_mark_resolved (symp);
197633965Sjdp	    }
197733965Sjdp
197833965Sjdp	  /* Set the value into the BFD symbol.  Up til now the value
197933965Sjdp	     has only been kept in the gas symbolS struct.  */
198060484Sobrien	  symbol_get_bfdsym (symp)->value = S_GET_VALUE (symp);
198133965Sjdp	}
198233965Sjdp    }
198333965Sjdp
198433965Sjdp  PROGRESS (1);
198533965Sjdp
198633965Sjdp  /* Now do any format-specific adjustments to the symbol table, such
198733965Sjdp     as adding file symbols.  */
198833965Sjdp#ifdef tc_adjust_symtab
198933965Sjdp  tc_adjust_symtab ();
199033965Sjdp#endif
199133965Sjdp#ifdef obj_adjust_symtab
199233965Sjdp  obj_adjust_symtab ();
199333965Sjdp#endif
199433965Sjdp
199533965Sjdp  /* Now that all the sizes are known, and contents correct, we can
199633965Sjdp     start writing to the file.  */
199733965Sjdp  set_symtab ();
199833965Sjdp
199933965Sjdp  /* If *_frob_file changes the symbol value at this point, it is
200033965Sjdp     responsible for moving the changed value into symp->bsym->value
200133965Sjdp     as well.  Hopefully all symbol value changing can be done in
200233965Sjdp     *_frob_symbol.  */
200333965Sjdp#ifdef tc_frob_file
200433965Sjdp  tc_frob_file ();
200533965Sjdp#endif
200633965Sjdp#ifdef obj_frob_file
200733965Sjdp  obj_frob_file ();
200833965Sjdp#endif
200933965Sjdp
201033965Sjdp  bfd_map_over_sections (stdoutput, write_relocs, (char *) 0);
201133965Sjdp
201233965Sjdp#ifdef tc_frob_file_after_relocs
201333965Sjdp  tc_frob_file_after_relocs ();
201433965Sjdp#endif
201533965Sjdp#ifdef obj_frob_file_after_relocs
201633965Sjdp  obj_frob_file_after_relocs ();
201733965Sjdp#endif
201833965Sjdp
201933965Sjdp  bfd_map_over_sections (stdoutput, write_contents, (char *) 0);
202077298Sobrien#endif /* BFD_ASSEMBLER  */
202133965Sjdp}
202277298Sobrien#endif /* ! BFD  */
202333965Sjdp
202433965Sjdp#ifdef TC_GENERIC_RELAX_TABLE
202533965Sjdp
202633965Sjdp/* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE.  */
202733965Sjdp
202833965Sjdplong
2029130561Sobrienrelax_frag (segT segment, fragS *fragP, long stretch)
203033965Sjdp{
203133965Sjdp  const relax_typeS *this_type;
203233965Sjdp  const relax_typeS *start_type;
203333965Sjdp  relax_substateT next_state;
203433965Sjdp  relax_substateT this_state;
2035130561Sobrien  offsetT growth;
203678828Sobrien  offsetT aim;
203778828Sobrien  addressT target;
203878828Sobrien  addressT address;
203978828Sobrien  symbolS *symbolP;
204078828Sobrien  const relax_typeS *table;
204133965Sjdp
204278828Sobrien  target = fragP->fr_offset;
204378828Sobrien  address = fragP->fr_address;
204478828Sobrien  table = TC_GENERIC_RELAX_TABLE;
204533965Sjdp  this_state = fragP->fr_subtype;
204633965Sjdp  start_type = this_type = table + this_state;
204778828Sobrien  symbolP = fragP->fr_symbol;
204833965Sjdp
204933965Sjdp  if (symbolP)
205033965Sjdp    {
205178828Sobrien      fragS *sym_frag;
205278828Sobrien
205378828Sobrien      sym_frag = symbol_get_frag (symbolP);
205478828Sobrien
205533965Sjdp#ifndef DIFF_EXPR_OK
205633965Sjdp#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
205733965Sjdp      know ((S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
205833965Sjdp	    || (S_GET_SEGMENT (symbolP) == SEG_DATA)
205933965Sjdp	    || (S_GET_SEGMENT (symbolP) == SEG_BSS)
206033965Sjdp	    || (S_GET_SEGMENT (symbolP) == SEG_TEXT));
206133965Sjdp#endif
206278828Sobrien      know (sym_frag != NULL);
206333965Sjdp#endif
2064130561Sobrien      know (S_GET_SEGMENT (symbolP) != absolute_section
206578828Sobrien	    || sym_frag == &zero_address_frag);
206689857Sobrien      target += S_GET_VALUE (symbolP);
206733965Sjdp
206833965Sjdp      /* If frag has yet to be reached on this pass,
206933965Sjdp	 assume it will move by STRETCH just as we did.
207033965Sjdp	 If this is not so, it will be because some frag
207178828Sobrien	 between grows, and that will force another pass.  */
207233965Sjdp
207378828Sobrien      if (stretch != 0
207478828Sobrien	  && sym_frag->relax_marker != fragP->relax_marker
207578828Sobrien	  && S_GET_SEGMENT (symbolP) == segment)
207633965Sjdp	{
207733965Sjdp	  target += stretch;
207833965Sjdp	}
207933965Sjdp    }
208033965Sjdp
208133965Sjdp  aim = target - address - fragP->fr_fix;
208233965Sjdp#ifdef TC_PCREL_ADJUST
208377298Sobrien  /* Currently only the ns32k family needs this.  */
208477298Sobrien  aim += TC_PCREL_ADJUST (fragP);
208577298Sobrien/* #else */
208633965Sjdp  /* This machine doesn't want to use pcrel_adjust.
208733965Sjdp     In that case, pcrel_adjust should be zero.  */
208877298Sobrien#if 0
208977298Sobrien  assert (fragP->fr_targ.ns32k.pcrel_adjust == 0);
209033965Sjdp#endif
209177298Sobrien#endif
209277298Sobrien#ifdef md_prepare_relax_scan /* formerly called M68K_AIM_KLUDGE  */
209333965Sjdp  md_prepare_relax_scan (fragP, address, aim, this_state, this_type);
209433965Sjdp#endif
209533965Sjdp
209633965Sjdp  if (aim < 0)
209733965Sjdp    {
209877298Sobrien      /* Look backwards.  */
209933965Sjdp      for (next_state = this_type->rlx_more; next_state;)
210033965Sjdp	if (aim >= this_type->rlx_backward)
210133965Sjdp	  next_state = 0;
210233965Sjdp	else
210333965Sjdp	  {
210477298Sobrien	    /* Grow to next state.  */
210533965Sjdp	    this_state = next_state;
210633965Sjdp	    this_type = table + this_state;
210733965Sjdp	    next_state = this_type->rlx_more;
210833965Sjdp	  }
210933965Sjdp    }
211033965Sjdp  else
211133965Sjdp    {
211277298Sobrien      /* Look forwards.  */
211333965Sjdp      for (next_state = this_type->rlx_more; next_state;)
211433965Sjdp	if (aim <= this_type->rlx_forward)
211533965Sjdp	  next_state = 0;
211633965Sjdp	else
211733965Sjdp	  {
211877298Sobrien	    /* Grow to next state.  */
211933965Sjdp	    this_state = next_state;
212033965Sjdp	    this_type = table + this_state;
212133965Sjdp	    next_state = this_type->rlx_more;
212233965Sjdp	  }
212333965Sjdp    }
212433965Sjdp
212533965Sjdp  growth = this_type->rlx_length - start_type->rlx_length;
212633965Sjdp  if (growth != 0)
212733965Sjdp    fragP->fr_subtype = this_state;
212833965Sjdp  return growth;
212933965Sjdp}
213033965Sjdp
213177298Sobrien#endif /* defined (TC_GENERIC_RELAX_TABLE)  */
213233965Sjdp
213333965Sjdp/* Relax_align. Advance location counter to next address that has 'alignment'
213433965Sjdp   lowest order bits all 0s, return size of adjustment made.  */
213533965Sjdpstatic relax_addressT
2136130561Sobrienrelax_align (register relax_addressT address,	/* Address now.  */
2137130561Sobrien	     register int alignment	/* Alignment (binary).  */)
213833965Sjdp{
213933965Sjdp  relax_addressT mask;
214033965Sjdp  relax_addressT new_address;
214133965Sjdp
214233965Sjdp  mask = ~((~0) << alignment);
214333965Sjdp  new_address = (address + mask) & (~mask);
214433965Sjdp#ifdef LINKER_RELAXING_SHRINKS_ONLY
214533965Sjdp  if (linkrelax)
214633965Sjdp    /* We must provide lots of padding, so the linker can discard it
214733965Sjdp       when needed.  The linker will not add extra space, ever.  */
214833965Sjdp    new_address += (1 << alignment);
214933965Sjdp#endif
215033965Sjdp  return (new_address - address);
215133965Sjdp}
215233965Sjdp
215377298Sobrien/* Now we have a segment, not a crowd of sub-segments, we can make
215477298Sobrien   fr_address values.
215577298Sobrien
215677298Sobrien   Relax the frags.
215777298Sobrien
215877298Sobrien   After this, all frags in this segment have addresses that are correct
215977298Sobrien   within the segment. Since segments live in different file addresses,
216077298Sobrien   these frag addresses may not be the same as final object-file
216177298Sobrien   addresses.  */
216277298Sobrien
216389857Sobrienint
2164130561Sobrienrelax_segment (struct frag *segment_frag_root, segT segment)
216533965Sjdp{
216633965Sjdp  register struct frag *fragP;
216733965Sjdp  register relax_addressT address;
216889857Sobrien  int ret;
216989857Sobrien
217033965Sjdp#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
217133965Sjdp  know (segment == SEG_DATA || segment == SEG_TEXT || segment == SEG_BSS);
217233965Sjdp#endif
217377298Sobrien  /* In case md_estimate_size_before_relax() wants to make fixSs.  */
217433965Sjdp  subseg_change (segment, 0);
217533965Sjdp
217633965Sjdp  /* For each frag in segment: count and store  (a 1st guess of)
217733965Sjdp     fr_address.  */
217833965Sjdp  address = 0;
217933965Sjdp  for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
218033965Sjdp    {
218178828Sobrien      fragP->relax_marker = 0;
218233965Sjdp      fragP->fr_address = address;
218333965Sjdp      address += fragP->fr_fix;
218433965Sjdp
218533965Sjdp      switch (fragP->fr_type)
218633965Sjdp	{
218733965Sjdp	case rs_fill:
218833965Sjdp	  address += fragP->fr_offset * fragP->fr_var;
218933965Sjdp	  break;
219033965Sjdp
219133965Sjdp	case rs_align:
219233965Sjdp	case rs_align_code:
219377298Sobrien	case rs_align_test:
219433965Sjdp	  {
219533965Sjdp	    addressT offset = relax_align (address, (int) fragP->fr_offset);
219633965Sjdp
219733965Sjdp	    if (fragP->fr_subtype != 0 && offset > fragP->fr_subtype)
219833965Sjdp	      offset = 0;
219933965Sjdp
220033965Sjdp	    if (offset % fragP->fr_var != 0)
220133965Sjdp	      {
220289857Sobrien		as_bad_where (fragP->fr_file, fragP->fr_line,
220389857Sobrien			      _("alignment padding (%lu bytes) not a multiple of %ld"),
220489857Sobrien			      (unsigned long) offset, (long) fragP->fr_var);
220533965Sjdp		offset -= (offset % fragP->fr_var);
220633965Sjdp	      }
220733965Sjdp
220833965Sjdp	    address += offset;
220933965Sjdp	  }
221033965Sjdp	  break;
221133965Sjdp
221233965Sjdp	case rs_org:
221333965Sjdp	case rs_space:
221433965Sjdp	  /* Assume .org is nugatory. It will grow with 1st relax.  */
221533965Sjdp	  break;
221633965Sjdp
221733965Sjdp	case rs_machine_dependent:
221889857Sobrien	  /* If fr_symbol is an expression, this call to
221989857Sobrien	     resolve_symbol_value sets up the correct segment, which will
222089857Sobrien	     likely be needed in md_estimate_size_before_relax.  */
222189857Sobrien	  if (fragP->fr_symbol)
222289857Sobrien	    resolve_symbol_value (fragP->fr_symbol);
222389857Sobrien
222433965Sjdp	  address += md_estimate_size_before_relax (fragP, segment);
222533965Sjdp	  break;
222633965Sjdp
222733965Sjdp#ifndef WORKING_DOT_WORD
222877298Sobrien	  /* Broken words don't concern us yet.  */
222933965Sjdp	case rs_broken_word:
223033965Sjdp	  break;
223133965Sjdp#endif
223233965Sjdp
223338889Sjdp	case rs_leb128:
223477298Sobrien	  /* Initial guess is always 1; doing otherwise can result in
223538889Sjdp	     stable solutions that are larger than the minimum.  */
223638889Sjdp	  address += fragP->fr_offset = 1;
223738889Sjdp	  break;
223838889Sjdp
223938889Sjdp	case rs_cfa:
224038889Sjdp	  address += eh_frame_estimate_size_before_relax (fragP);
224138889Sjdp	  break;
224238889Sjdp
224377298Sobrien	case rs_dwarf2dbg:
224477298Sobrien	  address += dwarf2dbg_estimate_size_before_relax (fragP);
224577298Sobrien	  break;
224677298Sobrien
224733965Sjdp	default:
224833965Sjdp	  BAD_CASE (fragP->fr_type);
224933965Sjdp	  break;
225077298Sobrien	}
225177298Sobrien    }
225233965Sjdp
225333965Sjdp  /* Do relax().  */
225433965Sjdp  {
2255130561Sobrien    offsetT stretch;	/* May be any size, 0 or negative.  */
225677298Sobrien    /* Cumulative number of addresses we have relaxed this pass.
225777298Sobrien       We may have relaxed more than one address.  */
225878828Sobrien    int stretched;	/* Have we stretched on this pass?  */
225933965Sjdp    /* This is 'cuz stretch may be zero, when, in fact some piece of code
226033965Sjdp       grew, and another shrank.  If a branch instruction doesn't fit anymore,
226133965Sjdp       we could be scrod.  */
226233965Sjdp
226333965Sjdp    do
226433965Sjdp      {
226578828Sobrien	stretch = 0;
226678828Sobrien	stretched = 0;
226777298Sobrien
226833965Sjdp	for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
226933965Sjdp	  {
2270130561Sobrien	    offsetT growth = 0;
227133965Sjdp	    addressT was_address;
227233965Sjdp	    offsetT offset;
227333965Sjdp	    symbolS *symbolP;
227433965Sjdp
227578828Sobrien	    fragP->relax_marker ^= 1;
227633965Sjdp	    was_address = fragP->fr_address;
227733965Sjdp	    address = fragP->fr_address += stretch;
227833965Sjdp	    symbolP = fragP->fr_symbol;
227933965Sjdp	    offset = fragP->fr_offset;
228033965Sjdp
228133965Sjdp	    switch (fragP->fr_type)
228233965Sjdp	      {
228377298Sobrien	      case rs_fill:	/* .fill never relaxes.  */
228433965Sjdp		growth = 0;
228533965Sjdp		break;
228633965Sjdp
228733965Sjdp#ifndef WORKING_DOT_WORD
228833965Sjdp		/* JF:  This is RMS's idea.  I do *NOT* want to be blamed
228933965Sjdp		   for it I do not want to write it.  I do not want to have
229033965Sjdp		   anything to do with it.  This is not the proper way to
229133965Sjdp		   implement this misfeature.  */
229233965Sjdp	      case rs_broken_word:
229333965Sjdp		{
229433965Sjdp		  struct broken_word *lie;
229533965Sjdp		  struct broken_word *untruth;
229633965Sjdp
229733965Sjdp		  /* Yes this is ugly (storing the broken_word pointer
229833965Sjdp		     in the symbol slot).  Still, this whole chunk of
229933965Sjdp		     code is ugly, and I don't feel like doing anything
230033965Sjdp		     about it.  Think of it as stubbornness in action.  */
230133965Sjdp		  growth = 0;
230233965Sjdp		  for (lie = (struct broken_word *) (fragP->fr_symbol);
230333965Sjdp		       lie && lie->dispfrag == fragP;
230433965Sjdp		       lie = lie->next_broken_word)
230533965Sjdp		    {
230633965Sjdp
230733965Sjdp		      if (lie->added)
230833965Sjdp			continue;
230933965Sjdp
231089857Sobrien		      offset = (S_GET_VALUE (lie->add)
231133965Sjdp				+ lie->addnum
231289857Sobrien				- S_GET_VALUE (lie->sub));
231333965Sjdp		      if (offset <= -32768 || offset >= 32767)
231433965Sjdp			{
231533965Sjdp			  if (flag_warn_displacement)
231633965Sjdp			    {
231733965Sjdp			      char buf[50];
231833965Sjdp			      sprint_value (buf, (addressT) lie->addnum);
231989857Sobrien			      as_warn_where (fragP->fr_file, fragP->fr_line,
232089857Sobrien					     _(".word %s-%s+%s didn't fit"),
232189857Sobrien					     S_GET_NAME (lie->add),
232289857Sobrien					     S_GET_NAME (lie->sub),
232389857Sobrien					     buf);
232433965Sjdp			    }
232533965Sjdp			  lie->added = 1;
232633965Sjdp			  if (fragP->fr_subtype == 0)
232733965Sjdp			    {
232833965Sjdp			      fragP->fr_subtype++;
232933965Sjdp			      growth += md_short_jump_size;
233033965Sjdp			    }
233133965Sjdp			  for (untruth = lie->next_broken_word;
233233965Sjdp			       untruth && untruth->dispfrag == lie->dispfrag;
233333965Sjdp			       untruth = untruth->next_broken_word)
233460484Sobrien			    if ((symbol_get_frag (untruth->add)
233560484Sobrien				 == symbol_get_frag (lie->add))
233660484Sobrien				&& (S_GET_VALUE (untruth->add)
233760484Sobrien				    == S_GET_VALUE (lie->add)))
233833965Sjdp			      {
233933965Sjdp				untruth->added = 2;
234033965Sjdp				untruth->use_jump = lie;
234133965Sjdp			      }
234233965Sjdp			  growth += md_long_jump_size;
234333965Sjdp			}
234433965Sjdp		    }
234533965Sjdp
234633965Sjdp		  break;
234777298Sobrien		}		/* case rs_broken_word  */
234833965Sjdp#endif
234933965Sjdp	      case rs_align:
235033965Sjdp	      case rs_align_code:
235177298Sobrien	      case rs_align_test:
235233965Sjdp		{
235333965Sjdp		  addressT oldoff, newoff;
235433965Sjdp
235533965Sjdp		  oldoff = relax_align (was_address + fragP->fr_fix,
235633965Sjdp					(int) offset);
235733965Sjdp		  newoff = relax_align (address + fragP->fr_fix,
235833965Sjdp					(int) offset);
235933965Sjdp
236033965Sjdp		  if (fragP->fr_subtype != 0)
236133965Sjdp		    {
236233965Sjdp		      if (oldoff > fragP->fr_subtype)
236333965Sjdp			oldoff = 0;
236433965Sjdp		      if (newoff > fragP->fr_subtype)
236533965Sjdp			newoff = 0;
236633965Sjdp		    }
236733965Sjdp
236833965Sjdp		  growth = newoff - oldoff;
236933965Sjdp		}
237033965Sjdp		break;
237133965Sjdp
237233965Sjdp	      case rs_org:
237333965Sjdp		{
237478828Sobrien		  addressT target = offset;
237578828Sobrien		  addressT after;
237633965Sjdp
237733965Sjdp		  if (symbolP)
237833965Sjdp		    {
237933965Sjdp#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
238033965Sjdp		      know ((S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
238133965Sjdp			    || (S_GET_SEGMENT (symbolP) == SEG_DATA)
238233965Sjdp			    || (S_GET_SEGMENT (symbolP) == SEG_TEXT)
238333965Sjdp			    || S_GET_SEGMENT (symbolP) == SEG_BSS);
238433965Sjdp		      know (symbolP->sy_frag);
238533965Sjdp		      know (!(S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
238633965Sjdp			    || (symbolP->sy_frag == &zero_address_frag));
238733965Sjdp#endif
238889857Sobrien                      /* Convert from an actual address to an octet offset
238989857Sobrien                         into the section.  Here it is assumed that the
239089857Sobrien                         section's VMA is zero, and can omit subtracting it
239189857Sobrien                         from the symbol's value to get the address offset.  */
239289857Sobrien                      know (S_GET_SECTION (symbolP)->vma == 0);
239389857Sobrien		      target += S_GET_VALUE (symbolP) * OCTETS_PER_BYTE;
239489857Sobrien		    }
239533965Sjdp
239633965Sjdp		  know (fragP->fr_next);
239733965Sjdp		  after = fragP->fr_next->fr_address;
239833965Sjdp		  growth = target - after;
239933965Sjdp		  if (growth < 0)
240033965Sjdp		    {
240133965Sjdp		      /* Growth may be negative, but variable part of frag
240233965Sjdp			 cannot have fewer than 0 chars.  That is, we can't
240377298Sobrien			 .org backwards.  */
240460484Sobrien		      as_bad_where (fragP->fr_file, fragP->fr_line,
2405130561Sobrien				    _("attempt to move .org backwards"));
240660484Sobrien
240760484Sobrien		      /* We've issued an error message.  Change the
240860484Sobrien                         frag to avoid cascading errors.  */
240960484Sobrien		      fragP->fr_type = rs_align;
241060484Sobrien		      fragP->fr_subtype = 0;
241160484Sobrien		      fragP->fr_offset = 0;
241260484Sobrien		      fragP->fr_fix = after - address;
241360484Sobrien		      growth = stretch;
241433965Sjdp		    }
241533965Sjdp
241677298Sobrien		  /* This is an absolute growth factor  */
241777298Sobrien		  growth -= stretch;
241833965Sjdp		  break;
241933965Sjdp		}
242033965Sjdp
242133965Sjdp	      case rs_space:
242289857Sobrien		growth = 0;
242333965Sjdp		if (symbolP)
242433965Sjdp		  {
242589857Sobrien		    offsetT amount;
242689857Sobrien
242789857Sobrien		    amount = S_GET_VALUE (symbolP);
242889857Sobrien		    if (S_GET_SEGMENT (symbolP) != absolute_section
242933965Sjdp			|| S_IS_COMMON (symbolP)
243033965Sjdp			|| ! S_IS_DEFINED (symbolP))
243133965Sjdp		      {
243289857Sobrien			as_bad_where (fragP->fr_file, fragP->fr_line,
243389857Sobrien				      _(".space specifies non-absolute value"));
243489857Sobrien			/* Prevent repeat of this error message.  */
243589857Sobrien			fragP->fr_symbol = 0;
243633965Sjdp		      }
243789857Sobrien		    else if (amount < 0)
243889857Sobrien		      {
243989857Sobrien			as_warn_where (fragP->fr_file, fragP->fr_line,
244089857Sobrien				       _(".space or .fill with negative value, ignored"));
244189857Sobrien			fragP->fr_symbol = 0;
244289857Sobrien		      }
244389857Sobrien		    else
244489857Sobrien		      growth = (was_address + fragP->fr_fix + amount
244589857Sobrien				- fragP->fr_next->fr_address);
244633965Sjdp		  }
244733965Sjdp		break;
244833965Sjdp
244933965Sjdp	      case rs_machine_dependent:
245033965Sjdp#ifdef md_relax_frag
245178828Sobrien		growth = md_relax_frag (segment, fragP, stretch);
245233965Sjdp#else
245333965Sjdp#ifdef TC_GENERIC_RELAX_TABLE
245433965Sjdp		/* The default way to relax a frag is to look through
245533965Sjdp		   TC_GENERIC_RELAX_TABLE.  */
245678828Sobrien		growth = relax_frag (segment, fragP, stretch);
245777298Sobrien#endif /* TC_GENERIC_RELAX_TABLE  */
245833965Sjdp#endif
245933965Sjdp		break;
246033965Sjdp
246138889Sjdp	      case rs_leb128:
246238889Sjdp		{
246338889Sjdp		  valueT value;
2464130561Sobrien		  offsetT size;
246538889Sjdp
246689857Sobrien		  value = resolve_symbol_value (fragP->fr_symbol);
246738889Sjdp		  size = sizeof_leb128 (value, fragP->fr_subtype);
246838889Sjdp		  growth = size - fragP->fr_offset;
246938889Sjdp		  fragP->fr_offset = size;
247038889Sjdp		}
247138889Sjdp		break;
247238889Sjdp
247338889Sjdp	      case rs_cfa:
247438889Sjdp		growth = eh_frame_relax_frag (fragP);
247538889Sjdp		break;
247638889Sjdp
247777298Sobrien	      case rs_dwarf2dbg:
247877298Sobrien		growth = dwarf2dbg_relax_frag (fragP);
247977298Sobrien		break;
248077298Sobrien
248133965Sjdp	      default:
248233965Sjdp		BAD_CASE (fragP->fr_type);
248333965Sjdp		break;
248433965Sjdp	      }
248533965Sjdp	    if (growth)
248633965Sjdp	      {
248733965Sjdp		stretch += growth;
248878828Sobrien		stretched = 1;
248933965Sjdp	      }
249077298Sobrien	  }			/* For each frag in the segment.  */
249133965Sjdp      }
249277298Sobrien    while (stretched);		/* Until nothing further to relax.  */
249377298Sobrien  }				/* do_relax  */
249433965Sjdp
249589857Sobrien  ret = 0;
249689857Sobrien  for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
249789857Sobrien    if (fragP->last_fr_address != fragP->fr_address)
249889857Sobrien      {
249989857Sobrien	fragP->last_fr_address = fragP->fr_address;
250089857Sobrien	ret = 1;
250189857Sobrien      }
250289857Sobrien  return ret;
250377298Sobrien}
250433965Sjdp
250533965Sjdp#if defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS))
250633965Sjdp
250733965Sjdp/* fixup_segment()
250833965Sjdp
250933965Sjdp   Go through all the fixS's in a segment and see which ones can be
251033965Sjdp   handled now.  (These consist of fixS where we have since discovered
251133965Sjdp   the value of a symbol, or the address of the frag involved.)
251289857Sobrien   For each one, call md_apply_fix3 to put the fix into the frag data.
251333965Sjdp
251433965Sjdp   Result is a count of how many relocation structs will be needed to
251533965Sjdp   handle the remaining fixS's that we couldn't completely handle here.
251633965Sjdp   These will be output later by emit_relocations().  */
251733965Sjdp
251833965Sjdpstatic long
2519130561Sobrienfixup_segment (fixS *fixP, segT this_segment)
252033965Sjdp{
252133965Sjdp  long seg_reloc_count = 0;
252233965Sjdp  valueT add_number;
252333965Sjdp  fragS *fragP;
252433965Sjdp  segT add_symbol_segment = absolute_section;
252533965Sjdp
2526130561Sobrien  if (fixP != NULL && abs_section_sym == NULL)
2527130561Sobrien    {
2528130561Sobrien#ifndef BFD_ASSEMBLER
2529130561Sobrien      abs_section_sym = &abs_symbol;
2530130561Sobrien#else
2531130561Sobrien      abs_section_sym = section_symbol (absolute_section);
2532130561Sobrien#endif
2533130561Sobrien    }
2534130561Sobrien
253533965Sjdp  /* If the linker is doing the relaxing, we must not do any fixups.
253633965Sjdp
2537130561Sobrien     Well, strictly speaking that's not true -- we could do any that
2538130561Sobrien     are PC-relative and don't cross regions that could change size.
2539130561Sobrien     And for the i960 we might be able to turn callx/callj into bal
2540130561Sobrien     anyways in cases where we know the maximum displacement.  */
2541130561Sobrien  if (linkrelax && TC_LINKRELAX_FIXUP (this_segment))
254233965Sjdp    {
254333965Sjdp      for (; fixP; fixP = fixP->fx_next)
2544130561Sobrien	if (!fixP->fx_done)
2545130561Sobrien	  {
2546130561Sobrien	    if (fixP->fx_addsy == NULL)
2547130561Sobrien	      {
2548130561Sobrien		/* There was no symbol required by this relocation.
2549130561Sobrien		   However, BFD doesn't really handle relocations
2550130561Sobrien		   without symbols well. So fake up a local symbol in
2551130561Sobrien		   the absolute section.  */
2552130561Sobrien		fixP->fx_addsy = abs_section_sym;
2553130561Sobrien	      }
2554130561Sobrien	    symbol_mark_used_in_reloc (fixP->fx_addsy);
2555130561Sobrien	    if (fixP->fx_subsy != NULL)
2556130561Sobrien	      symbol_mark_used_in_reloc (fixP->fx_subsy);
2557130561Sobrien	    seg_reloc_count++;
2558130561Sobrien	  }
255933965Sjdp      TC_ADJUST_RELOC_COUNT (fixP, seg_reloc_count);
256033965Sjdp      return seg_reloc_count;
256133965Sjdp    }
256233965Sjdp
256333965Sjdp  for (; fixP; fixP = fixP->fx_next)
256433965Sjdp    {
256533965Sjdp#ifdef DEBUG5
256633965Sjdp      fprintf (stderr, "\nprocessing fixup:\n");
256733965Sjdp      print_fixup (fixP);
256833965Sjdp#endif
256933965Sjdp
257033965Sjdp      fragP = fixP->fx_frag;
257133965Sjdp      know (fragP);
257233965Sjdp#ifdef TC_VALIDATE_FIX
2573130561Sobrien      TC_VALIDATE_FIX (fixP, this_segment, skip);
257433965Sjdp#endif
257533965Sjdp      add_number = fixP->fx_offset;
257633965Sjdp
2577130561Sobrien      if (fixP->fx_addsy != NULL
2578130561Sobrien	  && symbol_mri_common_p (fixP->fx_addsy))
257933965Sjdp	{
2580130561Sobrien	  know (fixP->fx_addsy->sy_value.X_op == O_symbol);
2581130561Sobrien	  add_number += S_GET_VALUE (fixP->fx_addsy);
258233965Sjdp	  fixP->fx_offset = add_number;
2583130561Sobrien	  fixP->fx_addsy
2584130561Sobrien	    = symbol_get_value_expression (fixP->fx_addsy)->X_add_symbol;
258533965Sjdp	}
258633965Sjdp
2587130561Sobrien      if (fixP->fx_addsy != NULL)
2588130561Sobrien	add_symbol_segment = S_GET_SEGMENT (fixP->fx_addsy);
258933965Sjdp
2590130561Sobrien      if (fixP->fx_subsy != NULL)
259133965Sjdp	{
2592130561Sobrien	  segT sub_symbol_segment;
2593130561Sobrien	  resolve_symbol_value (fixP->fx_subsy);
2594130561Sobrien	  sub_symbol_segment = S_GET_SEGMENT (fixP->fx_subsy);
2595130561Sobrien	  if (fixP->fx_addsy != NULL
2596130561Sobrien	      && sub_symbol_segment == add_symbol_segment
2597130561Sobrien	      && !TC_FORCE_RELOCATION_SUB_SAME (fixP, add_symbol_segment))
259833965Sjdp	    {
2599130561Sobrien	      add_number += S_GET_VALUE (fixP->fx_addsy);
2600130561Sobrien	      add_number -= S_GET_VALUE (fixP->fx_subsy);
2601130561Sobrien	      fixP->fx_offset = add_number;
2602130561Sobrien	      fixP->fx_addsy = NULL;
2603130561Sobrien	      fixP->fx_subsy = NULL;
260489857Sobrien#ifdef TC_M68K
2605130561Sobrien	      /* See the comment below about 68k weirdness.  */
2606130561Sobrien	      fixP->fx_pcrel = 0;
260789857Sobrien#endif
260833965Sjdp	    }
2609130561Sobrien	  else if (sub_symbol_segment == absolute_section
2610130561Sobrien		   && !TC_FORCE_RELOCATION_SUB_ABS (fixP))
261133965Sjdp	    {
2612130561Sobrien	      add_number -= S_GET_VALUE (fixP->fx_subsy);
2613130561Sobrien	      fixP->fx_offset = add_number;
2614130561Sobrien	      fixP->fx_subsy = NULL;
2615130561Sobrien	    }
2616130561Sobrien	  else if (sub_symbol_segment == this_segment
2617130561Sobrien		   && !TC_FORCE_RELOCATION_SUB_LOCAL (fixP))
2618130561Sobrien	    {
2619130561Sobrien	      add_number -= S_GET_VALUE (fixP->fx_subsy);
2620130561Sobrien	      fixP->fx_offset = (add_number + fixP->fx_dot_value
2621130561Sobrien				 + fixP->fx_frag->fr_address);
262233965Sjdp
2623130561Sobrien	      /* Make it pc-relative.  If the back-end code has not
2624130561Sobrien		 selected a pc-relative reloc, cancel the adjustment
2625130561Sobrien		 we do later on all pc-relative relocs.  */
2626130561Sobrien	      if (0
262789857Sobrien#ifdef TC_M68K
2628130561Sobrien		  /* Do this for m68k even if it's already described
2629130561Sobrien		     as pc-relative.  On the m68k, an operand of
2630130561Sobrien		     "pc@(foo-.-2)" should address "foo" in a
2631130561Sobrien		     pc-relative mode.  */
2632130561Sobrien		  || 1
263389857Sobrien#endif
2634130561Sobrien		  || !fixP->fx_pcrel)
2635130561Sobrien		add_number += MD_PCREL_FROM_SECTION (fixP, this_segment);
2636130561Sobrien	      fixP->fx_subsy = NULL;
2637130561Sobrien	      fixP->fx_pcrel = 1;
263833965Sjdp	    }
2639130561Sobrien	  else if (!TC_VALIDATE_FIX_SUB (fixP))
2640130561Sobrien	    {
2641130561Sobrien	      as_bad_where (fixP->fx_file, fixP->fx_line,
2642130561Sobrien			    _("can't resolve `%s' {%s section} - `%s' {%s section}"),
2643130561Sobrien			    fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : "0",
2644130561Sobrien			    segment_name (add_symbol_segment),
2645130561Sobrien			    S_GET_NAME (fixP->fx_subsy),
2646130561Sobrien			    segment_name (sub_symbol_segment));
2647130561Sobrien	    }
264833965Sjdp	}
264933965Sjdp
2650130561Sobrien      if (fixP->fx_addsy)
265133965Sjdp	{
2652130561Sobrien	  if (add_symbol_segment == this_segment
2653130561Sobrien	      && !TC_FORCE_RELOCATION_LOCAL (fixP))
265433965Sjdp	    {
265577298Sobrien	      /* This fixup was made when the symbol's segment was
265677298Sobrien		 SEG_UNKNOWN, but it is now in the local segment.
265777298Sobrien		 So we know how to do the address without relocation.  */
2658130561Sobrien	      add_number += S_GET_VALUE (fixP->fx_addsy);
2659130561Sobrien	      fixP->fx_offset = add_number;
2660130561Sobrien	      if (fixP->fx_pcrel)
2661130561Sobrien		add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment);
2662130561Sobrien	      fixP->fx_addsy = NULL;
2663130561Sobrien	      fixP->fx_pcrel = 0;
266433965Sjdp	    }
2665130561Sobrien	  else if (add_symbol_segment == absolute_section
2666130561Sobrien		   && !TC_FORCE_RELOCATION_ABS (fixP))
266733965Sjdp	    {
2668130561Sobrien	      add_number += S_GET_VALUE (fixP->fx_addsy);
2669130561Sobrien	      fixP->fx_offset = add_number;
2670130561Sobrien	      fixP->fx_addsy = NULL;
2671130561Sobrien	    }
2672130561Sobrien	  else if (add_symbol_segment != undefined_section
267333965Sjdp#ifdef BFD_ASSEMBLER
2674130561Sobrien		   && ! bfd_is_com_section (add_symbol_segment)
267533965Sjdp#endif
2676130561Sobrien		   && MD_APPLY_SYM_VALUE (fixP))
2677130561Sobrien	    add_number += S_GET_VALUE (fixP->fx_addsy);
267833965Sjdp	}
267933965Sjdp
2680130561Sobrien      if (fixP->fx_pcrel)
268133965Sjdp	{
2682130561Sobrien	  add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment);
2683130561Sobrien	  if (!fixP->fx_done && fixP->fx_addsy == NULL)
268433965Sjdp	    {
2685130561Sobrien	      /* There was no symbol required by this relocation.
2686130561Sobrien		 However, BFD doesn't really handle relocations
2687130561Sobrien		 without symbols well. So fake up a local symbol in
2688130561Sobrien		 the absolute section.  */
2689130561Sobrien	      fixP->fx_addsy = abs_section_sym;
269033965Sjdp	    }
269133965Sjdp	}
269233965Sjdp
269360484Sobrien      if (!fixP->fx_done)
2694130561Sobrien	md_apply_fix3 (fixP, &add_number, this_segment);
269560484Sobrien
2696130561Sobrien      if (!fixP->fx_done)
269733965Sjdp	{
2698130561Sobrien	  ++seg_reloc_count;
2699130561Sobrien	  if (fixP->fx_addsy == NULL)
2700130561Sobrien	    fixP->fx_addsy = abs_section_sym;
2701130561Sobrien	  symbol_mark_used_in_reloc (fixP->fx_addsy);
2702130561Sobrien	  if (fixP->fx_subsy != NULL)
2703130561Sobrien	    symbol_mark_used_in_reloc (fixP->fx_subsy);
2704130561Sobrien	}
2705130561Sobrien
2706130561Sobrien      if (!fixP->fx_bit_fixP && !fixP->fx_no_overflow && fixP->fx_size != 0)
2707130561Sobrien	{
2708130561Sobrien	  if (fixP->fx_size < sizeof (valueT))
270933965Sjdp	    {
271060484Sobrien	      valueT mask;
271133965Sjdp
271233965Sjdp	      mask = 0;
271377298Sobrien	      mask--;		/* Set all bits to one.  */
2714130561Sobrien	      mask <<= fixP->fx_size * 8 - (fixP->fx_signed ? 1 : 0);
271560484Sobrien	      if ((add_number & mask) != 0 && (add_number & mask) != mask)
271633965Sjdp		{
271733965Sjdp		  char buf[50], buf2[50];
2718130561Sobrien		  sprint_value (buf, fragP->fr_address + fixP->fx_where);
271933965Sjdp		  if (add_number > 1000)
272033965Sjdp		    sprint_value (buf2, add_number);
272133965Sjdp		  else
272233965Sjdp		    sprintf (buf2, "%ld", (long) add_number);
272333965Sjdp		  as_bad_where (fixP->fx_file, fixP->fx_line,
272489857Sobrien				_("value of %s too large for field of %d bytes at %s"),
2725130561Sobrien				buf2, fixP->fx_size, buf);
272677298Sobrien		} /* Generic error checking.  */
272733965Sjdp	    }
272833965Sjdp#ifdef WARN_SIGNED_OVERFLOW_WORD
272933965Sjdp	  /* Warn if a .word value is too large when treated as a signed
273033965Sjdp	     number.  We already know it is not too negative.  This is to
273133965Sjdp	     catch over-large switches generated by gcc on the 68k.  */
273233965Sjdp	  if (!flag_signed_overflow_ok
2733130561Sobrien	      && fixP->fx_size == 2
273433965Sjdp	      && add_number > 0x7fff)
273533965Sjdp	    as_bad_where (fixP->fx_file, fixP->fx_line,
273689857Sobrien			  _("signed .word overflow; switch may be too large; %ld at 0x%lx"),
273733965Sjdp			  (long) add_number,
2738130561Sobrien			  (long) (fragP->fr_address + fixP->fx_where));
273933965Sjdp#endif
274077298Sobrien	}			/* Not a bit fix.  */
274133965Sjdp
274233965Sjdp#ifdef TC_VALIDATE_FIX
274360484Sobrien    skip:  ATTRIBUTE_UNUSED_LABEL
274460484Sobrien      ;
274533965Sjdp#endif
274633965Sjdp#ifdef DEBUG5
274733965Sjdp      fprintf (stderr, "result:\n");
274833965Sjdp      print_fixup (fixP);
274933965Sjdp#endif
275077298Sobrien    }				/* For each fixS in this segment.  */
275133965Sjdp
275233965Sjdp  TC_ADJUST_RELOC_COUNT (fixP, seg_reloc_count);
275333965Sjdp  return seg_reloc_count;
275433965Sjdp}
275533965Sjdp
275633965Sjdp#endif /* defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS)) */
275733965Sjdp
275833965Sjdpvoid
2759130561Sobriennumber_to_chars_bigendian (char *buf, valueT val, int n)
276033965Sjdp{
276194536Sobrien  if (n <= 0)
276233965Sjdp    abort ();
276333965Sjdp  while (n--)
276433965Sjdp    {
276533965Sjdp      buf[n] = val & 0xff;
276633965Sjdp      val >>= 8;
276733965Sjdp    }
276833965Sjdp}
276933965Sjdp
277033965Sjdpvoid
2771130561Sobriennumber_to_chars_littleendian (char *buf, valueT val, int n)
277233965Sjdp{
277394536Sobrien  if (n <= 0)
277433965Sjdp    abort ();
277533965Sjdp  while (n--)
277633965Sjdp    {
277733965Sjdp      *buf++ = val & 0xff;
277833965Sjdp      val >>= 8;
277933965Sjdp    }
278033965Sjdp}
278133965Sjdp
278233965Sjdpvoid
2783130561Sobrienwrite_print_statistics (FILE *file)
278433965Sjdp{
278560484Sobrien  fprintf (file, "fixups: %d\n", n_fixups);
278633965Sjdp}
278733965Sjdp
278877298Sobrien/* For debugging.  */
278933965Sjdpextern int indent_level;
279033965Sjdp
279133965Sjdpvoid
2792130561Sobrienprint_fixup (fixS *fixp)
279333965Sjdp{
279433965Sjdp  indent_level = 1;
279533965Sjdp  fprintf (stderr, "fix %lx %s:%d", (long) fixp, fixp->fx_file, fixp->fx_line);
279633965Sjdp  if (fixp->fx_pcrel)
279733965Sjdp    fprintf (stderr, " pcrel");
279833965Sjdp  if (fixp->fx_pcrel_adjust)
279933965Sjdp    fprintf (stderr, " pcrel_adjust=%d", fixp->fx_pcrel_adjust);
280033965Sjdp  if (fixp->fx_im_disp)
280133965Sjdp    {
280233965Sjdp#ifdef TC_NS32K
280333965Sjdp      fprintf (stderr, " im_disp=%d", fixp->fx_im_disp);
280433965Sjdp#else
280533965Sjdp      fprintf (stderr, " im_disp");
280633965Sjdp#endif
280733965Sjdp    }
280833965Sjdp  if (fixp->fx_tcbit)
280933965Sjdp    fprintf (stderr, " tcbit");
281033965Sjdp  if (fixp->fx_done)
281133965Sjdp    fprintf (stderr, " done");
281233965Sjdp  fprintf (stderr, "\n    size=%d frag=%lx where=%ld offset=%lx addnumber=%lx",
281333965Sjdp	   fixp->fx_size, (long) fixp->fx_frag, (long) fixp->fx_where,
281433965Sjdp	   (long) fixp->fx_offset, (long) fixp->fx_addnumber);
281533965Sjdp#ifdef BFD_ASSEMBLER
281633965Sjdp  fprintf (stderr, "\n    %s (%d)", bfd_get_reloc_code_name (fixp->fx_r_type),
281733965Sjdp	   fixp->fx_r_type);
281833965Sjdp#else
281933965Sjdp#ifdef NEED_FX_R_TYPE
282033965Sjdp  fprintf (stderr, " r_type=%d", fixp->fx_r_type);
282133965Sjdp#endif
282233965Sjdp#endif
282333965Sjdp  if (fixp->fx_addsy)
282433965Sjdp    {
282533965Sjdp      fprintf (stderr, "\n   +<");
282633965Sjdp      print_symbol_value_1 (stderr, fixp->fx_addsy);
282733965Sjdp      fprintf (stderr, ">");
282833965Sjdp    }
282933965Sjdp  if (fixp->fx_subsy)
283033965Sjdp    {
283133965Sjdp      fprintf (stderr, "\n   -<");
283233965Sjdp      print_symbol_value_1 (stderr, fixp->fx_subsy);
283333965Sjdp      fprintf (stderr, ">");
283433965Sjdp    }
283533965Sjdp  fprintf (stderr, "\n");
283638889Sjdp#ifdef TC_FIX_DATA_PRINT
283738889Sjdp  TC_FIX_DATA_PRINT (stderr, fixp);
283838889Sjdp#endif
283933965Sjdp}
2840