write.c revision 60484
133965Sjdp/* write.c - emit .o file
260484Sobrien   Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999
333965Sjdp   Free Software Foundation, Inc.
433965Sjdp
533965Sjdp   This file is part of GAS, the GNU Assembler.
633965Sjdp
733965Sjdp   GAS is free software; you can redistribute it and/or modify
833965Sjdp   it under the terms of the GNU General Public License as published by
933965Sjdp   the Free Software Foundation; either version 2, or (at your option)
1033965Sjdp   any later version.
1133965Sjdp
1233965Sjdp   GAS is distributed in the hope that it will be useful,
1333965Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1433965Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1533965Sjdp   GNU General Public License for more details.
1633965Sjdp
1733965Sjdp   You should have received a copy of the GNU General Public License
1833965Sjdp   along with GAS; see the file COPYING.  If not, write to the Free
1933965Sjdp   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2033965Sjdp   02111-1307, USA.  */
2133965Sjdp
2233965Sjdp/* This thing should be set up to do byteordering correctly.  But... */
2333965Sjdp
2433965Sjdp#include "as.h"
2533965Sjdp#include "subsegs.h"
2633965Sjdp#include "obstack.h"
2733965Sjdp#include "output-file.h"
2833965Sjdp
2933965Sjdp/* This looks like a good idea.  Let's try turning it on always, for now.  */
3033965Sjdp#undef  BFD_FAST_SECTION_FILL
3133965Sjdp#define BFD_FAST_SECTION_FILL
3233965Sjdp
3333965Sjdp/* The NOP_OPCODE is for the alignment fill value.  Fill it with a nop
3433965Sjdp   instruction so that the disassembler does not choke on it.  */
3533965Sjdp#ifndef NOP_OPCODE
3633965Sjdp#define NOP_OPCODE 0x00
3733965Sjdp#endif
3833965Sjdp
3933965Sjdp#ifndef TC_ADJUST_RELOC_COUNT
4033965Sjdp#define TC_ADJUST_RELOC_COUNT(FIXP,COUNT)
4133965Sjdp#endif
4233965Sjdp
4333965Sjdp#ifndef TC_FORCE_RELOCATION
4433965Sjdp#define TC_FORCE_RELOCATION(FIXP) 0
4533965Sjdp#endif
4633965Sjdp
4733965Sjdp#ifndef TC_FORCE_RELOCATION_SECTION
4833965Sjdp#define TC_FORCE_RELOCATION_SECTION(FIXP,SEG) TC_FORCE_RELOCATION(FIXP)
4933965Sjdp#endif
5033965Sjdp
5133965Sjdp#ifndef	MD_PCREL_FROM_SECTION
5233965Sjdp#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from(FIXP)
5333965Sjdp#endif
5433965Sjdp
5533965Sjdp#ifndef WORKING_DOT_WORD
5633965Sjdpextern CONST int md_short_jump_size;
5733965Sjdpextern CONST int md_long_jump_size;
5833965Sjdp#endif
5933965Sjdp
6033965Sjdpint symbol_table_frozen;
6133965Sjdpvoid print_fixup PARAMS ((fixS *));
6233965Sjdp
6333965Sjdp#ifdef BFD_ASSEMBLER
6433965Sjdpstatic void renumber_sections PARAMS ((bfd *, asection *, PTR));
6533965Sjdp
6633965Sjdp/* We generally attach relocs to frag chains.  However, after we have
6733965Sjdp   chained these all together into a segment, any relocs we add after
6833965Sjdp   that must be attached to a segment.  This will include relocs added
6933965Sjdp   in md_estimate_size_for_relax, for example.  */
7033965Sjdpstatic int frags_chained = 0;
7133965Sjdp#endif
7233965Sjdp
7333965Sjdp#ifndef BFD_ASSEMBLER
7433965Sjdp
7533965Sjdp#ifndef MANY_SEGMENTS
7633965Sjdpstruct frag *text_frag_root;
7733965Sjdpstruct frag *data_frag_root;
7833965Sjdpstruct frag *bss_frag_root;
7933965Sjdp
8033965Sjdpstruct frag *text_last_frag;	/* Last frag in segment. */
8133965Sjdpstruct frag *data_last_frag;	/* Last frag in segment. */
8233965Sjdpstatic struct frag *bss_last_frag;	/* Last frag in segment. */
8333965Sjdp#endif
8433965Sjdp
8533965Sjdp#ifndef BFD
8633965Sjdpstatic object_headers headers;
8733965Sjdp#endif
8833965Sjdp
8933965Sjdplong string_byte_count;
9033965Sjdpchar *next_object_file_charP;	/* Tracks object file bytes. */
9133965Sjdp
9233965Sjdp#ifndef OBJ_VMS
9333965Sjdpint magic_number_for_object_file = DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE;
9433965Sjdp#endif
9533965Sjdp
9633965Sjdp#endif /* BFD_ASSEMBLER */
9733965Sjdp
9833965Sjdpstatic int n_fixups;
9933965Sjdp
10033965Sjdp#ifdef BFD_ASSEMBLER
10133965Sjdpstatic fixS *fix_new_internal PARAMS ((fragS *, int where, int size,
10233965Sjdp				       symbolS *add, symbolS *sub,
10333965Sjdp				       offsetT offset, int pcrel,
10433965Sjdp				       bfd_reloc_code_real_type r_type));
10533965Sjdp#else
10633965Sjdpstatic fixS *fix_new_internal PARAMS ((fragS *, int where, int size,
10733965Sjdp				       symbolS *add, symbolS *sub,
10833965Sjdp				       offsetT offset, int pcrel,
10933965Sjdp				       int r_type));
11033965Sjdp#endif
11133965Sjdp#if defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS))
11233965Sjdpstatic long fixup_segment PARAMS ((fixS * fixP, segT this_segment_type));
11333965Sjdp#endif
11433965Sjdpstatic relax_addressT relax_align PARAMS ((relax_addressT addr, int align));
11533965Sjdp#if defined (BFD_ASSEMBLER) || ! defined (BFD)
11633965Sjdpstatic fragS *chain_frchains_together_1 PARAMS ((segT, struct frchain *));
11733965Sjdp#endif
11833965Sjdp#ifdef BFD_ASSEMBLER
11933965Sjdpstatic void chain_frchains_together PARAMS ((bfd *, segT, PTR));
12033965Sjdpstatic void cvt_frag_to_fill PARAMS ((segT, fragS *));
12133965Sjdpstatic void relax_and_size_seg PARAMS ((bfd *, asection *, PTR));
12233965Sjdpstatic void adjust_reloc_syms PARAMS ((bfd *, asection *, PTR));
12333965Sjdpstatic void write_relocs PARAMS ((bfd *, asection *, PTR));
12433965Sjdpstatic void write_contents PARAMS ((bfd *, asection *, PTR));
12533965Sjdpstatic void set_symtab PARAMS ((void));
12633965Sjdp#endif
12733965Sjdp#if defined (BFD_ASSEMBLER) || (! defined (BFD) && ! defined (OBJ_AOUT))
12833965Sjdpstatic void merge_data_into_text PARAMS ((void));
12933965Sjdp#endif
13033965Sjdp#if ! defined (BFD_ASSEMBLER) && ! defined (BFD)
13133965Sjdpstatic void cvt_frag_to_fill PARAMS ((object_headers *, segT, fragS *));
13233965Sjdpstatic void remove_subsegs PARAMS ((frchainS *, int, fragS **, fragS **));
13333965Sjdpstatic void relax_and_size_all_segments PARAMS ((void));
13433965Sjdp#endif
13533965Sjdp
13633965Sjdp/*
13733965Sjdp *			fix_new()
13833965Sjdp *
13933965Sjdp * Create a fixS in obstack 'notes'.
14033965Sjdp */
14133965Sjdpstatic fixS *
14233965Sjdpfix_new_internal (frag, where, size, add_symbol, sub_symbol, offset, pcrel,
14333965Sjdp		  r_type)
14433965Sjdp     fragS *frag;		/* Which frag? */
14533965Sjdp     int where;			/* Where in that frag? */
14633965Sjdp     int size;			/* 1, 2, or 4 usually. */
14733965Sjdp     symbolS *add_symbol;	/* X_add_symbol. */
14833965Sjdp     symbolS *sub_symbol;	/* X_op_symbol. */
14933965Sjdp     offsetT offset;		/* X_add_number. */
15033965Sjdp     int pcrel;			/* TRUE if PC-relative relocation. */
15133965Sjdp#ifdef BFD_ASSEMBLER
15233965Sjdp     bfd_reloc_code_real_type r_type; /* Relocation type */
15333965Sjdp#else
15433965Sjdp     int r_type;		/* Relocation type */
15533965Sjdp#endif
15633965Sjdp{
15733965Sjdp  fixS *fixP;
15833965Sjdp
15933965Sjdp  n_fixups++;
16033965Sjdp
16133965Sjdp  fixP = (fixS *) obstack_alloc (&notes, sizeof (fixS));
16233965Sjdp
16333965Sjdp  fixP->fx_frag = frag;
16433965Sjdp  fixP->fx_where = where;
16533965Sjdp  fixP->fx_size = size;
16633965Sjdp  /* We've made fx_size a narrow field; check that it's wide enough.  */
16733965Sjdp  if (fixP->fx_size != size)
16833965Sjdp    {
16960484Sobrien      as_bad (_("field fx_size too small to hold %d"), size);
17033965Sjdp      abort ();
17133965Sjdp    }
17233965Sjdp  fixP->fx_addsy = add_symbol;
17333965Sjdp  fixP->fx_subsy = sub_symbol;
17433965Sjdp  fixP->fx_offset = offset;
17533965Sjdp  fixP->fx_pcrel = pcrel;
17633965Sjdp  fixP->fx_plt = 0;
17733965Sjdp#if defined(NEED_FX_R_TYPE) || defined (BFD_ASSEMBLER)
17833965Sjdp  fixP->fx_r_type = r_type;
17933965Sjdp#endif
18033965Sjdp  fixP->fx_im_disp = 0;
18133965Sjdp  fixP->fx_pcrel_adjust = 0;
18233965Sjdp  fixP->fx_bit_fixP = 0;
18333965Sjdp  fixP->fx_addnumber = 0;
18433965Sjdp  fixP->fx_tcbit = 0;
18533965Sjdp  fixP->fx_done = 0;
18633965Sjdp  fixP->fx_no_overflow = 0;
18733965Sjdp  fixP->fx_signed = 0;
18833965Sjdp
18960484Sobrien#ifdef USING_CGEN
19060484Sobrien  fixP->fx_cgen.insn = NULL;
19160484Sobrien  fixP->fx_cgen.opinfo = 0;
19260484Sobrien#endif
19360484Sobrien
19433965Sjdp#ifdef TC_FIX_TYPE
19533965Sjdp  TC_INIT_FIX_DATA(fixP);
19633965Sjdp#endif
19733965Sjdp
19833965Sjdp  as_where (&fixP->fx_file, &fixP->fx_line);
19933965Sjdp
20033965Sjdp  /* Usually, we want relocs sorted numerically, but while
20133965Sjdp     comparing to older versions of gas that have relocs
20233965Sjdp     reverse sorted, it is convenient to have this compile
20333965Sjdp     time option.  xoxorich. */
20433965Sjdp
20533965Sjdp  {
20633965Sjdp
20733965Sjdp#ifdef BFD_ASSEMBLER
20833965Sjdp    fixS **seg_fix_rootP = (frags_chained
20933965Sjdp			    ? &seg_info (now_seg)->fix_root
21033965Sjdp			    : &frchain_now->fix_root);
21133965Sjdp    fixS **seg_fix_tailP = (frags_chained
21233965Sjdp			    ? &seg_info (now_seg)->fix_tail
21333965Sjdp			    : &frchain_now->fix_tail);
21433965Sjdp#endif
21533965Sjdp
21633965Sjdp#ifdef REVERSE_SORT_RELOCS
21733965Sjdp
21833965Sjdp    fixP->fx_next = *seg_fix_rootP;
21933965Sjdp    *seg_fix_rootP = fixP;
22033965Sjdp
22133965Sjdp#else /* REVERSE_SORT_RELOCS */
22233965Sjdp
22333965Sjdp    fixP->fx_next = NULL;
22433965Sjdp
22533965Sjdp    if (*seg_fix_tailP)
22633965Sjdp      (*seg_fix_tailP)->fx_next = fixP;
22733965Sjdp    else
22833965Sjdp      *seg_fix_rootP = fixP;
22933965Sjdp    *seg_fix_tailP = fixP;
23033965Sjdp
23133965Sjdp#endif /* REVERSE_SORT_RELOCS */
23233965Sjdp
23333965Sjdp  }
23433965Sjdp
23533965Sjdp  return fixP;
23633965Sjdp}
23733965Sjdp
23833965Sjdp/* Create a fixup relative to a symbol (plus a constant).  */
23933965Sjdp
24033965SjdpfixS *
24133965Sjdpfix_new (frag, where, size, add_symbol, offset, pcrel, r_type)
24233965Sjdp     fragS *frag;		/* Which frag? */
24333965Sjdp     int where;			/* Where in that frag? */
24433965Sjdp     int size;			/* 1, 2, or 4 usually. */
24533965Sjdp     symbolS *add_symbol;	/* X_add_symbol. */
24633965Sjdp     offsetT offset;		/* X_add_number. */
24733965Sjdp     int pcrel;			/* TRUE if PC-relative relocation. */
24833965Sjdp#ifdef BFD_ASSEMBLER
24933965Sjdp     bfd_reloc_code_real_type r_type; /* Relocation type */
25033965Sjdp#else
25133965Sjdp     int r_type;		/* Relocation type */
25233965Sjdp#endif
25333965Sjdp{
25433965Sjdp  return fix_new_internal (frag, where, size, add_symbol,
25533965Sjdp			   (symbolS *) NULL, offset, pcrel, r_type);
25633965Sjdp}
25733965Sjdp
25833965Sjdp/* Create a fixup for an expression.  Currently we only support fixups
25933965Sjdp   for difference expressions.  That is itself more than most object
26033965Sjdp   file formats support anyhow.  */
26133965Sjdp
26233965SjdpfixS *
26333965Sjdpfix_new_exp (frag, where, size, exp, pcrel, r_type)
26433965Sjdp     fragS *frag;		/* Which frag? */
26533965Sjdp     int where;			/* Where in that frag? */
26633965Sjdp     int size;			/* 1, 2, or 4 usually. */
26733965Sjdp     expressionS *exp;		/* Expression.  */
26833965Sjdp     int pcrel;			/* TRUE if PC-relative relocation. */
26933965Sjdp#ifdef BFD_ASSEMBLER
27033965Sjdp     bfd_reloc_code_real_type r_type; /* Relocation type */
27133965Sjdp#else
27233965Sjdp     int r_type;		/* Relocation type */
27333965Sjdp#endif
27433965Sjdp{
27533965Sjdp  symbolS *add = NULL;
27633965Sjdp  symbolS *sub = NULL;
27733965Sjdp  offsetT off = 0;
27833965Sjdp
27933965Sjdp  switch (exp->X_op)
28033965Sjdp    {
28133965Sjdp    case O_absent:
28233965Sjdp      break;
28333965Sjdp
28433965Sjdp    case O_add:
28533965Sjdp      /* This comes up when _GLOBAL_OFFSET_TABLE_+(.-L0) is read, if
28633965Sjdp	 the difference expression cannot immediately be reduced.  */
28733965Sjdp      {
28833965Sjdp	symbolS *stmp = make_expr_symbol (exp);
28933965Sjdp	exp->X_op = O_symbol;
29033965Sjdp	exp->X_op_symbol = 0;
29133965Sjdp	exp->X_add_symbol = stmp;
29233965Sjdp	exp->X_add_number = 0;
29333965Sjdp	return fix_new_exp (frag, where, size, exp, pcrel, r_type);
29433965Sjdp      }
29533965Sjdp
29633965Sjdp    case O_symbol_rva:
29733965Sjdp      add = exp->X_add_symbol;
29833965Sjdp      off = exp->X_add_number;
29933965Sjdp
30033965Sjdp#if defined(BFD_ASSEMBLER)
30133965Sjdp      r_type = BFD_RELOC_RVA;
30233965Sjdp#else
30333965Sjdp#if defined(TC_RVA_RELOC)
30433965Sjdp      r_type = TC_RVA_RELOC;
30533965Sjdp#else
30660484Sobrien      as_fatal(_("rva not supported"));
30733965Sjdp#endif
30833965Sjdp#endif
30933965Sjdp      break;
31033965Sjdp
31133965Sjdp    case O_uminus:
31233965Sjdp      sub = exp->X_add_symbol;
31333965Sjdp      off = exp->X_add_number;
31433965Sjdp      break;
31533965Sjdp
31633965Sjdp    case O_subtract:
31733965Sjdp      sub = exp->X_op_symbol;
31833965Sjdp      /* Fall through.  */
31933965Sjdp    case O_symbol:
32033965Sjdp      add = exp->X_add_symbol;
32133965Sjdp      /* Fall through.   */
32233965Sjdp    case O_constant:
32333965Sjdp      off = exp->X_add_number;
32433965Sjdp      break;
32533965Sjdp
32633965Sjdp    default:
32733965Sjdp      add = make_expr_symbol (exp);
32833965Sjdp      break;
32933965Sjdp    }
33033965Sjdp
33133965Sjdp  return fix_new_internal (frag, where, size, add, sub, off,
33233965Sjdp			   pcrel, r_type);
33333965Sjdp}
33433965Sjdp
33533965Sjdp/* Append a string onto another string, bumping the pointer along.  */
33633965Sjdpvoid
33733965Sjdpappend (charPP, fromP, length)
33833965Sjdp     char **charPP;
33933965Sjdp     char *fromP;
34033965Sjdp     unsigned long length;
34133965Sjdp{
34233965Sjdp  /* Don't trust memcpy() of 0 chars. */
34333965Sjdp  if (length == 0)
34433965Sjdp    return;
34533965Sjdp
34633965Sjdp  memcpy (*charPP, fromP, length);
34733965Sjdp  *charPP += length;
34833965Sjdp}
34933965Sjdp
35033965Sjdp#ifndef BFD_ASSEMBLER
35133965Sjdpint section_alignment[SEG_MAXIMUM_ORDINAL];
35233965Sjdp#endif
35333965Sjdp
35433965Sjdp/*
35533965Sjdp * This routine records the largest alignment seen for each segment.
35633965Sjdp * If the beginning of the segment is aligned on the worst-case
35733965Sjdp * boundary, all of the other alignments within it will work.  At
35833965Sjdp * least one object format really uses this info.
35933965Sjdp */
36033965Sjdpvoid
36133965Sjdprecord_alignment (seg, align)
36233965Sjdp     /* Segment to which alignment pertains */
36333965Sjdp     segT seg;
36433965Sjdp     /* Alignment, as a power of 2 (e.g., 1 => 2-byte boundary, 2 => 4-byte
36533965Sjdp	boundary, etc.)  */
36633965Sjdp     int align;
36733965Sjdp{
36833965Sjdp  if (seg == absolute_section)
36933965Sjdp    return;
37033965Sjdp#ifdef BFD_ASSEMBLER
37138889Sjdp  if ((unsigned int) align > bfd_get_section_alignment (stdoutput, seg))
37233965Sjdp    bfd_set_section_alignment (stdoutput, seg, align);
37333965Sjdp#else
37433965Sjdp  if (align > section_alignment[(int) seg])
37533965Sjdp    section_alignment[(int) seg] = align;
37633965Sjdp#endif
37733965Sjdp}
37833965Sjdp
37933965Sjdp#ifdef BFD_ASSEMBLER
38033965Sjdp
38133965Sjdp/* Reset the section indices after removing the gas created sections.  */
38233965Sjdp
38333965Sjdpstatic void
38433965Sjdprenumber_sections (abfd, sec, countparg)
38560484Sobrien     bfd *abfd ATTRIBUTE_UNUSED;
38633965Sjdp     asection *sec;
38733965Sjdp     PTR countparg;
38833965Sjdp{
38933965Sjdp  int *countp = (int *) countparg;
39033965Sjdp
39133965Sjdp  sec->index = *countp;
39233965Sjdp  ++*countp;
39333965Sjdp}
39433965Sjdp
39533965Sjdp#endif /* defined (BFD_ASSEMBLER) */
39633965Sjdp
39733965Sjdp#if defined (BFD_ASSEMBLER) || ! defined (BFD)
39833965Sjdp
39933965Sjdpstatic fragS *
40033965Sjdpchain_frchains_together_1 (section, frchp)
40133965Sjdp     segT section;
40233965Sjdp     struct frchain *frchp;
40333965Sjdp{
40433965Sjdp  fragS dummy, *prev_frag = &dummy;
40533965Sjdp#ifdef BFD_ASSEMBLER
40633965Sjdp  fixS fix_dummy, *prev_fix = &fix_dummy;
40733965Sjdp#endif
40833965Sjdp
40933965Sjdp  for (; frchp && frchp->frch_seg == section; frchp = frchp->frch_next)
41033965Sjdp    {
41133965Sjdp      prev_frag->fr_next = frchp->frch_root;
41233965Sjdp      prev_frag = frchp->frch_last;
41333965Sjdp      assert (prev_frag->fr_type != 0);
41433965Sjdp#ifdef BFD_ASSEMBLER
41533965Sjdp      if (frchp->fix_root != (fixS *) NULL)
41633965Sjdp	{
41733965Sjdp	  if (seg_info (section)->fix_root == (fixS *) NULL)
41833965Sjdp	    seg_info (section)->fix_root = frchp->fix_root;
41933965Sjdp	  prev_fix->fx_next = frchp->fix_root;
42033965Sjdp	  seg_info (section)->fix_tail = frchp->fix_tail;
42133965Sjdp	  prev_fix = frchp->fix_tail;
42233965Sjdp	}
42333965Sjdp#endif
42433965Sjdp    }
42533965Sjdp  assert (prev_frag->fr_type != 0);
42633965Sjdp  prev_frag->fr_next = 0;
42733965Sjdp  return prev_frag;
42833965Sjdp}
42933965Sjdp
43033965Sjdp#endif
43133965Sjdp
43233965Sjdp#ifdef BFD_ASSEMBLER
43333965Sjdp
43433965Sjdpstatic void
43533965Sjdpchain_frchains_together (abfd, section, xxx)
43660484Sobrien     bfd *abfd ATTRIBUTE_UNUSED;
43733965Sjdp     segT section;
43860484Sobrien     PTR xxx ATTRIBUTE_UNUSED;
43933965Sjdp{
44033965Sjdp  segment_info_type *info;
44133965Sjdp
44233965Sjdp  /* BFD may have introduced its own sections without using
44333965Sjdp     subseg_new, so it is possible that seg_info is NULL.  */
44433965Sjdp  info = seg_info (section);
44533965Sjdp  if (info != (segment_info_type *) NULL)
44633965Sjdp   info->frchainP->frch_last
44733965Sjdp     = chain_frchains_together_1 (section, info->frchainP);
44833965Sjdp
44933965Sjdp  /* Now that we've chained the frags together, we must add new fixups
45033965Sjdp     to the segment, not to the frag chain.  */
45133965Sjdp  frags_chained = 1;
45233965Sjdp}
45333965Sjdp
45433965Sjdp#endif
45533965Sjdp
45633965Sjdp#if !defined (BFD) && !defined (BFD_ASSEMBLER)
45733965Sjdp
45833965Sjdpstatic void
45933965Sjdpremove_subsegs (head, seg, root, last)
46033965Sjdp     frchainS *head;
46133965Sjdp     int seg;
46233965Sjdp     fragS **root;
46333965Sjdp     fragS **last;
46433965Sjdp{
46533965Sjdp  *root = head->frch_root;
46633965Sjdp  *last = chain_frchains_together_1 (seg, head);
46733965Sjdp}
46833965Sjdp
46933965Sjdp#endif /* BFD */
47033965Sjdp
47133965Sjdp#if defined (BFD_ASSEMBLER) || !defined (BFD)
47233965Sjdp
47333965Sjdp#ifdef BFD_ASSEMBLER
47433965Sjdpstatic void
47533965Sjdpcvt_frag_to_fill (sec, fragP)
47633965Sjdp     segT sec;
47733965Sjdp     fragS *fragP;
47833965Sjdp#else
47933965Sjdpstatic void
48033965Sjdpcvt_frag_to_fill (headersP, sec, fragP)
48133965Sjdp     object_headers *headersP;
48233965Sjdp     segT sec;
48333965Sjdp     fragS *fragP;
48433965Sjdp#endif
48533965Sjdp{
48633965Sjdp  switch (fragP->fr_type)
48733965Sjdp    {
48833965Sjdp    case rs_align:
48933965Sjdp    case rs_align_code:
49033965Sjdp    case rs_org:
49133965Sjdp    case rs_space:
49233965Sjdp#ifdef HANDLE_ALIGN
49333965Sjdp      HANDLE_ALIGN (fragP);
49433965Sjdp#endif
49533965Sjdp      know (fragP->fr_next != NULL);
49633965Sjdp      fragP->fr_offset = (fragP->fr_next->fr_address
49733965Sjdp			  - fragP->fr_address
49833965Sjdp			  - fragP->fr_fix) / fragP->fr_var;
49933965Sjdp      if (fragP->fr_offset < 0)
50033965Sjdp	{
50160484Sobrien	  as_bad_where (fragP->fr_file, fragP->fr_line,
50260484Sobrien			_("attempt to .org/.space backwards? (%ld)"),
50360484Sobrien			(long) fragP->fr_offset);
50433965Sjdp	}
50533965Sjdp      fragP->fr_type = rs_fill;
50633965Sjdp      break;
50733965Sjdp
50833965Sjdp    case rs_fill:
50933965Sjdp      break;
51033965Sjdp
51138889Sjdp    case rs_leb128:
51238889Sjdp      {
51338889Sjdp	valueT value = S_GET_VALUE (fragP->fr_symbol);
51438889Sjdp	int size;
51538889Sjdp
51638889Sjdp	size = output_leb128 (fragP->fr_literal + fragP->fr_fix, value,
51738889Sjdp			      fragP->fr_subtype);
51838889Sjdp
51938889Sjdp	fragP->fr_fix += size;
52038889Sjdp	fragP->fr_type = rs_fill;
52138889Sjdp	fragP->fr_var = 0;
52238889Sjdp	fragP->fr_offset = 0;
52338889Sjdp	fragP->fr_symbol = NULL;
52438889Sjdp      }
52538889Sjdp      break;
52638889Sjdp
52738889Sjdp    case rs_cfa:
52838889Sjdp      eh_frame_convert_frag (fragP);
52938889Sjdp      break;
53038889Sjdp
53133965Sjdp    case rs_machine_dependent:
53233965Sjdp#ifdef BFD_ASSEMBLER
53333965Sjdp      md_convert_frag (stdoutput, sec, fragP);
53433965Sjdp#else
53533965Sjdp      md_convert_frag (headersP, sec, fragP);
53633965Sjdp#endif
53733965Sjdp
53838889Sjdp      assert (fragP->fr_next == NULL
53938889Sjdp	      || ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
54038889Sjdp		  == fragP->fr_fix));
54133965Sjdp
54233965Sjdp      /*
54333965Sjdp       * After md_convert_frag, we make the frag into a ".space 0".
54433965Sjdp       * Md_convert_frag() should set up any fixSs and constants
54533965Sjdp       * required.
54633965Sjdp       */
54733965Sjdp      frag_wane (fragP);
54833965Sjdp      break;
54933965Sjdp
55033965Sjdp#ifndef WORKING_DOT_WORD
55133965Sjdp    case rs_broken_word:
55233965Sjdp      {
55333965Sjdp	struct broken_word *lie;
55433965Sjdp
55533965Sjdp	if (fragP->fr_subtype)
55633965Sjdp	  {
55733965Sjdp	    fragP->fr_fix += md_short_jump_size;
55833965Sjdp	    for (lie = (struct broken_word *) (fragP->fr_symbol);
55933965Sjdp		 lie && lie->dispfrag == fragP;
56033965Sjdp		 lie = lie->next_broken_word)
56133965Sjdp	      if (lie->added == 1)
56233965Sjdp		fragP->fr_fix += md_long_jump_size;
56333965Sjdp	  }
56433965Sjdp	frag_wane (fragP);
56533965Sjdp      }
56633965Sjdp      break;
56733965Sjdp#endif
56833965Sjdp
56933965Sjdp    default:
57033965Sjdp      BAD_CASE (fragP->fr_type);
57133965Sjdp      break;
57233965Sjdp    }
57333965Sjdp}
57433965Sjdp
57533965Sjdp#endif /* defined (BFD_ASSEMBLER) || !defined (BFD) */
57633965Sjdp
57733965Sjdp#ifdef BFD_ASSEMBLER
57833965Sjdpstatic void
57933965Sjdprelax_and_size_seg (abfd, sec, xxx)
58033965Sjdp     bfd *abfd;
58133965Sjdp     asection *sec;
58260484Sobrien     PTR xxx ATTRIBUTE_UNUSED;
58333965Sjdp{
58433965Sjdp  flagword flags;
58533965Sjdp  fragS *fragp;
58633965Sjdp  segment_info_type *seginfo;
58733965Sjdp  int x;
58833965Sjdp  valueT size, newsize;
58933965Sjdp
59033965Sjdp  subseg_change (sec, 0);
59133965Sjdp
59233965Sjdp  flags = bfd_get_section_flags (abfd, sec);
59333965Sjdp
59433965Sjdp  seginfo = seg_info (sec);
59533965Sjdp  if (seginfo && seginfo->frchainP)
59633965Sjdp    {
59733965Sjdp      relax_segment (seginfo->frchainP->frch_root, sec);
59833965Sjdp      for (fragp = seginfo->frchainP->frch_root; fragp; fragp = fragp->fr_next)
59933965Sjdp	cvt_frag_to_fill (sec, fragp);
60033965Sjdp      for (fragp = seginfo->frchainP->frch_root;
60133965Sjdp	   fragp->fr_next;
60233965Sjdp	   fragp = fragp->fr_next)
60333965Sjdp	/* walk to last elt */;
60433965Sjdp      size = fragp->fr_address + fragp->fr_fix;
60533965Sjdp    }
60633965Sjdp  else
60733965Sjdp    size = 0;
60833965Sjdp
60933965Sjdp  if (size > 0 && ! seginfo->bss)
61033965Sjdp    flags |= SEC_HAS_CONTENTS;
61133965Sjdp
61233965Sjdp  /* @@ This is just an approximation.  */
61333965Sjdp  if (seginfo && seginfo->fix_root)
61433965Sjdp    flags |= SEC_RELOC;
61533965Sjdp  else
61633965Sjdp    flags &= ~SEC_RELOC;
61733965Sjdp  x = bfd_set_section_flags (abfd, sec, flags);
61833965Sjdp  assert (x == true);
61933965Sjdp
62033965Sjdp  newsize = md_section_align (sec, size);
62133965Sjdp  x = bfd_set_section_size (abfd, sec, newsize);
62233965Sjdp  assert (x == true);
62333965Sjdp
62433965Sjdp  /* If the size had to be rounded up, add some padding in the last
62533965Sjdp     non-empty frag.  */
62633965Sjdp  assert (newsize >= size);
62733965Sjdp  if (size != newsize)
62833965Sjdp    {
62933965Sjdp      fragS *last = seginfo->frchainP->frch_last;
63033965Sjdp      fragp = seginfo->frchainP->frch_root;
63133965Sjdp      while (fragp->fr_next != last)
63233965Sjdp	fragp = fragp->fr_next;
63333965Sjdp      last->fr_address = size;
63433965Sjdp      fragp->fr_offset += newsize - size;
63533965Sjdp    }
63633965Sjdp
63733965Sjdp#ifdef tc_frob_section
63833965Sjdp  tc_frob_section (sec);
63933965Sjdp#endif
64033965Sjdp#ifdef obj_frob_section
64133965Sjdp  obj_frob_section (sec);
64233965Sjdp#endif
64333965Sjdp}
64433965Sjdp
64533965Sjdp#ifdef DEBUG2
64633965Sjdpstatic void
64733965Sjdpdump_section_relocs (abfd, sec, stream_)
64860484Sobrien     bfd *abfd ATTRIBUTE_UNUSED;
64933965Sjdp     asection *sec;
65033965Sjdp     char *stream_;
65133965Sjdp{
65233965Sjdp  FILE *stream = (FILE *) stream_;
65333965Sjdp  segment_info_type *seginfo = seg_info (sec);
65433965Sjdp  fixS *fixp = seginfo->fix_root;
65533965Sjdp
65633965Sjdp  if (!fixp)
65733965Sjdp    return;
65833965Sjdp
65933965Sjdp  fprintf (stream, "sec %s relocs:\n", sec->name);
66033965Sjdp  while (fixp)
66133965Sjdp    {
66233965Sjdp      symbolS *s = fixp->fx_addsy;
66360484Sobrien
66460484Sobrien      fprintf (stream, "  %08lx: type %d ", (unsigned long) fixp,
66560484Sobrien	       (int) fixp->fx_r_type);
66660484Sobrien      if (s == NULL)
66760484Sobrien	fprintf (stream, "no sym\n");
66860484Sobrien      else
66933965Sjdp	{
67060484Sobrien	  print_symbol_value_1 (stream, s);
67160484Sobrien	  fprintf (stream, "\n");
67233965Sjdp	}
67333965Sjdp      fixp = fixp->fx_next;
67433965Sjdp    }
67533965Sjdp}
67633965Sjdp#else
67733965Sjdp#define dump_section_relocs(ABFD,SEC,STREAM)	((void) 0)
67833965Sjdp#endif
67933965Sjdp
68033965Sjdp#ifndef EMIT_SECTION_SYMBOLS
68133965Sjdp#define EMIT_SECTION_SYMBOLS 1
68233965Sjdp#endif
68333965Sjdp
68433965Sjdpstatic void
68533965Sjdpadjust_reloc_syms (abfd, sec, xxx)
68660484Sobrien     bfd *abfd ATTRIBUTE_UNUSED;
68733965Sjdp     asection *sec;
68860484Sobrien     PTR xxx ATTRIBUTE_UNUSED;
68933965Sjdp{
69033965Sjdp  segment_info_type *seginfo = seg_info (sec);
69133965Sjdp  fixS *fixp;
69233965Sjdp
69333965Sjdp  if (seginfo == NULL)
69433965Sjdp    return;
69533965Sjdp
69633965Sjdp  dump_section_relocs (abfd, sec, stderr);
69733965Sjdp
69833965Sjdp  for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
69933965Sjdp    if (fixp->fx_done)
70033965Sjdp      /* ignore it */;
70133965Sjdp    else if (fixp->fx_addsy)
70233965Sjdp      {
70333965Sjdp	symbolS *sym;
70433965Sjdp	asection *symsec;
70533965Sjdp
70633965Sjdp#ifdef DEBUG5
70733965Sjdp	fprintf (stderr, "\n\nadjusting fixup:\n");
70833965Sjdp	print_fixup (fixp);
70933965Sjdp#endif
71033965Sjdp
71133965Sjdp	sym = fixp->fx_addsy;
71233965Sjdp
71333965Sjdp	/* All symbols should have already been resolved at this
71433965Sjdp	   point.  It is possible to see unresolved expression
71533965Sjdp	   symbols, though, since they are not in the regular symbol
71633965Sjdp	   table.  */
71760484Sobrien	if (sym != NULL)
71838889Sjdp	  resolve_symbol_value (sym, 1);
71960484Sobrien
72060484Sobrien	if (fixp->fx_subsy != NULL)
72138889Sjdp	  resolve_symbol_value (fixp->fx_subsy, 1);
72233965Sjdp
72333965Sjdp	/* If this symbol is equated to an undefined symbol, convert
72433965Sjdp           the fixup to being against that symbol.  */
72560484Sobrien	if (sym != NULL && symbol_equated_p (sym)
72633965Sjdp	    && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
72733965Sjdp	  {
72860484Sobrien	    fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number;
72960484Sobrien	    sym = symbol_get_value_expression (sym)->X_add_symbol;
73033965Sjdp	    fixp->fx_addsy = sym;
73133965Sjdp	  }
73233965Sjdp
73360484Sobrien	if (sym != NULL && symbol_mri_common_p (sym))
73433965Sjdp	  {
73533965Sjdp	    /* These symbols are handled specially in fixup_segment.  */
73633965Sjdp	    goto done;
73733965Sjdp	  }
73833965Sjdp
73960484Sobrien	symsec = S_GET_SEGMENT (sym);
74060484Sobrien
74160484Sobrien	if (symsec == NULL)
74260484Sobrien	  abort ();
74360484Sobrien
74433965Sjdp	if (bfd_is_abs_section (symsec))
74533965Sjdp	  {
74633965Sjdp	    /* The fixup_segment routine will not use this symbol in a
74733965Sjdp               relocation unless TC_FORCE_RELOCATION returns 1.  */
74833965Sjdp	    if (TC_FORCE_RELOCATION (fixp))
74933965Sjdp	      {
75060484Sobrien		symbol_mark_used_in_reloc (fixp->fx_addsy);
75133965Sjdp#ifdef UNDEFINED_DIFFERENCE_OK
75233965Sjdp		if (fixp->fx_subsy != NULL)
75360484Sobrien		  symbol_mark_used_in_reloc (fixp->fx_subsy);
75433965Sjdp#endif
75533965Sjdp	      }
75633965Sjdp	    goto done;
75733965Sjdp	  }
75833965Sjdp
75933965Sjdp	/* If it's one of these sections, assume the symbol is
76033965Sjdp	   definitely going to be output.  The code in
76133965Sjdp	   md_estimate_size_before_relax in tc-mips.c uses this test
76233965Sjdp	   as well, so if you change this code you should look at that
76333965Sjdp	   code.  */
76433965Sjdp	if (bfd_is_und_section (symsec)
76533965Sjdp	    || bfd_is_com_section (symsec))
76633965Sjdp	  {
76760484Sobrien	    symbol_mark_used_in_reloc (fixp->fx_addsy);
76833965Sjdp#ifdef UNDEFINED_DIFFERENCE_OK
76933965Sjdp	    /* We have the difference of an undefined symbol and some
77033965Sjdp	       other symbol.  Make sure to mark the other symbol as used
77133965Sjdp	       in a relocation so that it will always be output.  */
77233965Sjdp	    if (fixp->fx_subsy)
77360484Sobrien	      symbol_mark_used_in_reloc (fixp->fx_subsy);
77433965Sjdp#endif
77533965Sjdp	    goto done;
77633965Sjdp	  }
77733965Sjdp
77860484Sobrien	/* Don't try to reduce relocs which refer to non-local symbols
77960484Sobrien           in .linkonce sections.  It can lead to confusion when a
78060484Sobrien           debugging section refers to a .linkonce section.  I hope
78160484Sobrien           this will always be correct.  */
78260484Sobrien	if (symsec != sec && ! S_IS_LOCAL (sym))
78333965Sjdp	  {
78433965Sjdp	    boolean linkonce;
78533965Sjdp
78633965Sjdp	    linkonce = false;
78733965Sjdp#ifdef BFD_ASSEMBLER
78833965Sjdp	    if ((bfd_get_section_flags (stdoutput, symsec) & SEC_LINK_ONCE)
78933965Sjdp		!= 0)
79033965Sjdp	      linkonce = true;
79133965Sjdp#endif
79233965Sjdp#ifdef OBJ_ELF
79333965Sjdp	    /* The GNU toolchain uses an extension for ELF: a section
79433965Sjdp               beginning with the magic string .gnu.linkonce is a
79533965Sjdp               linkonce section.  */
79633965Sjdp	    if (strncmp (segment_name (symsec), ".gnu.linkonce",
79733965Sjdp			 sizeof ".gnu.linkonce" - 1) == 0)
79833965Sjdp	      linkonce = true;
79933965Sjdp#endif
80033965Sjdp
80133965Sjdp	    if (linkonce)
80233965Sjdp	      {
80360484Sobrien		symbol_mark_used_in_reloc (fixp->fx_addsy);
80433965Sjdp#ifdef UNDEFINED_DIFFERENCE_OK
80533965Sjdp		if (fixp->fx_subsy != NULL)
80660484Sobrien		  symbol_mark_used_in_reloc (fixp->fx_subsy);
80733965Sjdp#endif
80833965Sjdp		goto done;
80933965Sjdp	      }
81033965Sjdp	  }
81133965Sjdp
81233965Sjdp	/* Since we're reducing to section symbols, don't attempt to reduce
81333965Sjdp	   anything that's already using one.  */
81460484Sobrien	if (symbol_section_p (sym))
81533965Sjdp	  {
81660484Sobrien	    symbol_mark_used_in_reloc (fixp->fx_addsy);
81733965Sjdp	    goto done;
81833965Sjdp	  }
81933965Sjdp
82060484Sobrien#ifdef BFD_ASSEMBLER
82160484Sobrien	/* We can never adjust a reloc against a weak symbol.  If we
82260484Sobrien           did, and the weak symbol was overridden by a real symbol
82360484Sobrien           somewhere else, then our relocation would be pointing at
82460484Sobrien           the wrong area of memory.  */
82560484Sobrien	if (S_IS_WEAK (sym))
82660484Sobrien	  {
82760484Sobrien	    symbol_mark_used_in_reloc (fixp->fx_addsy);
82860484Sobrien	    goto done;
82960484Sobrien	  }
83060484Sobrien#endif
83160484Sobrien
83233965Sjdp	/* Is there some other reason we can't adjust this one?  (E.g.,
83333965Sjdp	   call/bal links in i960-bout symbols.)  */
83433965Sjdp#ifdef obj_fix_adjustable
83533965Sjdp	if (! obj_fix_adjustable (fixp))
83633965Sjdp	  {
83760484Sobrien	    symbol_mark_used_in_reloc (fixp->fx_addsy);
83833965Sjdp	    goto done;
83933965Sjdp	  }
84033965Sjdp#endif
84133965Sjdp
84233965Sjdp	/* Is there some other (target cpu dependent) reason we can't adjust
84333965Sjdp	   this one?  (E.g. relocations involving function addresses on
84433965Sjdp	   the PA.  */
84533965Sjdp#ifdef tc_fix_adjustable
84633965Sjdp	if (! tc_fix_adjustable (fixp))
84733965Sjdp	  {
84860484Sobrien	    symbol_mark_used_in_reloc (fixp->fx_addsy);
84933965Sjdp	    goto done;
85033965Sjdp	  }
85133965Sjdp#endif
85233965Sjdp
85333965Sjdp	/* If the section symbol isn't going to be output, the relocs
85433965Sjdp	   at least should still work.  If not, figure out what to do
85533965Sjdp	   when we run into that case.
85633965Sjdp
85733965Sjdp	   We refetch the segment when calling section_symbol, rather
85833965Sjdp	   than using symsec, because S_GET_VALUE may wind up changing
85933965Sjdp	   the section when it calls resolve_symbol_value. */
86033965Sjdp	fixp->fx_offset += S_GET_VALUE (sym);
86133965Sjdp	fixp->fx_addsy = section_symbol (S_GET_SEGMENT (sym));
86260484Sobrien	symbol_mark_used_in_reloc (fixp->fx_addsy);
86360484Sobrien#ifdef DEBUG5
86460484Sobrien	fprintf (stderr, "\nadjusted fixup:\n");
86560484Sobrien	print_fixup (fixp);
86660484Sobrien#endif
86733965Sjdp
86833965Sjdp      done:
86933965Sjdp	;
87033965Sjdp      }
87133965Sjdp#if 1/*def RELOC_REQUIRES_SYMBOL*/
87233965Sjdp    else
87333965Sjdp      {
87433965Sjdp	/* There was no symbol required by this relocation.  However,
87533965Sjdp	   BFD doesn't really handle relocations without symbols well.
87633965Sjdp	   (At least, the COFF support doesn't.)  So for now we fake up
87733965Sjdp	   a local symbol in the absolute section.  */
87833965Sjdp
87933965Sjdp	fixp->fx_addsy = section_symbol (absolute_section);
88033965Sjdp/*	fixp->fx_addsy->sy_used_in_reloc = 1; */
88133965Sjdp      }
88233965Sjdp#endif
88333965Sjdp
88433965Sjdp  dump_section_relocs (abfd, sec, stderr);
88533965Sjdp}
88633965Sjdp
88733965Sjdpstatic void
88833965Sjdpwrite_relocs (abfd, sec, xxx)
88933965Sjdp     bfd *abfd;
89033965Sjdp     asection *sec;
89160484Sobrien     PTR xxx ATTRIBUTE_UNUSED;
89233965Sjdp{
89333965Sjdp  segment_info_type *seginfo = seg_info (sec);
89433965Sjdp  int i;
89533965Sjdp  unsigned int n;
89633965Sjdp  arelent **relocs;
89733965Sjdp  fixS *fixp;
89833965Sjdp  char *err;
89933965Sjdp
90033965Sjdp  /* If seginfo is NULL, we did not create this section; don't do
90133965Sjdp     anything with it.  */
90233965Sjdp  if (seginfo == NULL)
90333965Sjdp    return;
90433965Sjdp
90533965Sjdp  fixup_segment (seginfo->fix_root, sec);
90633965Sjdp
90733965Sjdp  n = 0;
90833965Sjdp  for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
90933965Sjdp    n++;
91033965Sjdp
91133965Sjdp#ifndef RELOC_EXPANSION_POSSIBLE
91233965Sjdp  /* Set up reloc information as well.  */
91333965Sjdp  relocs = (arelent **) xmalloc (n * sizeof (arelent *));
91433965Sjdp  memset ((char*)relocs, 0, n * sizeof (arelent*));
91533965Sjdp
91633965Sjdp  i = 0;
91733965Sjdp  for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
91833965Sjdp    {
91933965Sjdp      arelent *reloc;
92033965Sjdp      bfd_reloc_status_type s;
92133965Sjdp      symbolS *sym;
92233965Sjdp
92333965Sjdp      if (fixp->fx_done)
92433965Sjdp	{
92533965Sjdp	  n--;
92633965Sjdp	  continue;
92733965Sjdp	}
92833965Sjdp
92933965Sjdp      /* If this is an undefined symbol which was equated to another
93033965Sjdp         symbol, then use generate the reloc against the latter symbol
93133965Sjdp         rather than the former.  */
93233965Sjdp      sym = fixp->fx_addsy;
93360484Sobrien      while (symbol_equated_p (sym)
93433965Sjdp	     && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
93533965Sjdp	{
93633965Sjdp	  symbolS *n;
93733965Sjdp
93833965Sjdp	  /* We must avoid looping, as that can occur with a badly
93933965Sjdp	     written program.  */
94060484Sobrien	  n = symbol_get_value_expression (sym)->X_add_symbol;
94133965Sjdp	  if (n == sym)
94233965Sjdp	    break;
94360484Sobrien	  fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number;
94433965Sjdp	  sym = n;
94533965Sjdp	}
94633965Sjdp      fixp->fx_addsy = sym;
94733965Sjdp
94833965Sjdp      reloc = tc_gen_reloc (sec, fixp);
94933965Sjdp      if (!reloc)
95033965Sjdp	{
95133965Sjdp	  n--;
95233965Sjdp	  continue;
95333965Sjdp	}
95433965Sjdp
95533965Sjdp#if 0
95633965Sjdp      /* This test is triggered inappropriately for the SH.  */
95733965Sjdp      if (fixp->fx_where + fixp->fx_size
95833965Sjdp	  > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
95933965Sjdp	abort ();
96033965Sjdp#endif
96133965Sjdp
96233965Sjdp      s = bfd_install_relocation (stdoutput, reloc,
96333965Sjdp				  fixp->fx_frag->fr_literal,
96433965Sjdp				  fixp->fx_frag->fr_address,
96533965Sjdp				  sec, &err);
96633965Sjdp      switch (s)
96733965Sjdp	{
96833965Sjdp	case bfd_reloc_ok:
96933965Sjdp	  break;
97033965Sjdp	case bfd_reloc_overflow:
97160484Sobrien	  as_bad_where (fixp->fx_file, fixp->fx_line, _("relocation overflow"));
97233965Sjdp	  break;
97360484Sobrien	case bfd_reloc_outofrange:
97460484Sobrien	  as_bad_where (fixp->fx_file, fixp->fx_line, _("relocation out of range"));
97560484Sobrien	  break;
97633965Sjdp	default:
97760484Sobrien	  as_fatal (_("%s:%u: bad return from bfd_install_relocation: %x"),
97860484Sobrien		    fixp->fx_file, fixp->fx_line, s);
97933965Sjdp	}
98033965Sjdp      relocs[i++] = reloc;
98133965Sjdp    }
98233965Sjdp#else
98333965Sjdp  n = n * MAX_RELOC_EXPANSION;
98433965Sjdp  /* Set up reloc information as well.  */
98533965Sjdp  relocs = (arelent **) xmalloc (n * sizeof (arelent *));
98633965Sjdp
98733965Sjdp  i = 0;
98833965Sjdp  for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
98933965Sjdp    {
99033965Sjdp      arelent **reloc;
99133965Sjdp      char *data;
99233965Sjdp      bfd_reloc_status_type s;
99333965Sjdp      symbolS *sym;
99433965Sjdp      int j;
99533965Sjdp
99633965Sjdp      if (fixp->fx_done)
99733965Sjdp	{
99833965Sjdp	  n--;
99933965Sjdp	  continue;
100033965Sjdp	}
100133965Sjdp
100233965Sjdp      /* If this is an undefined symbol which was equated to another
100333965Sjdp         symbol, then use generate the reloc against the latter symbol
100433965Sjdp         rather than the former.  */
100533965Sjdp      sym = fixp->fx_addsy;
100660484Sobrien      while (symbol_equated_p (sym)
100733965Sjdp	     && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
100860484Sobrien	sym = symbol_get_value_expression (sym)->X_add_symbol;
100933965Sjdp      fixp->fx_addsy = sym;
101033965Sjdp
101133965Sjdp      reloc = tc_gen_reloc (sec, fixp);
101233965Sjdp
101333965Sjdp      for (j = 0; reloc[j]; j++)
101433965Sjdp	{
101533965Sjdp          relocs[i++] = reloc[j];
101633965Sjdp          assert(i <= n);
101733965Sjdp	}
101833965Sjdp      data = fixp->fx_frag->fr_literal + fixp->fx_where;
101933965Sjdp      if (fixp->fx_where + fixp->fx_size
102033965Sjdp	  > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
102133965Sjdp	as_bad_where (fixp->fx_file, fixp->fx_line,
102260484Sobrien		      _("internal error: fixup not contained within frag"));
102333965Sjdp      for (j = 0; reloc[j]; j++)
102433965Sjdp        {
102533965Sjdp	  s = bfd_install_relocation (stdoutput, reloc[j],
102633965Sjdp				      fixp->fx_frag->fr_literal,
102733965Sjdp				      fixp->fx_frag->fr_address,
102833965Sjdp				      sec, &err);
102933965Sjdp          switch (s)
103033965Sjdp	    {
103133965Sjdp	    case bfd_reloc_ok:
103233965Sjdp	      break;
103333965Sjdp	    case bfd_reloc_overflow:
103433965Sjdp	      as_bad_where (fixp->fx_file, fixp->fx_line,
103560484Sobrien			    _("relocation overflow"));
103633965Sjdp	      break;
103733965Sjdp	    default:
103860484Sobrien	      as_fatal (_("%s:%u: bad return from bfd_install_relocation"),
103933965Sjdp			fixp->fx_file, fixp->fx_line);
104033965Sjdp	    }
104133965Sjdp        }
104233965Sjdp    }
104333965Sjdp  n = i;
104433965Sjdp#endif
104533965Sjdp
104633965Sjdp#ifdef DEBUG4
104733965Sjdp  {
104833965Sjdp    int i, j, nsyms;
104933965Sjdp    asymbol **sympp;
105033965Sjdp    sympp = bfd_get_outsymbols (stdoutput);
105133965Sjdp    nsyms = bfd_get_symcount (stdoutput);
105233965Sjdp    for (i = 0; i < n; i++)
105333965Sjdp      if (((*relocs[i]->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0)
105433965Sjdp	{
105533965Sjdp	  for (j = 0; j < nsyms; j++)
105633965Sjdp	    if (sympp[j] == *relocs[i]->sym_ptr_ptr)
105733965Sjdp	      break;
105833965Sjdp	  if (j == nsyms)
105933965Sjdp	    abort ();
106033965Sjdp	}
106133965Sjdp  }
106233965Sjdp#endif
106333965Sjdp
106433965Sjdp  if (n)
106533965Sjdp    bfd_set_reloc (stdoutput, sec, relocs, n);
106633965Sjdp  else
106733965Sjdp    bfd_set_section_flags (abfd, sec,
106833965Sjdp			   (bfd_get_section_flags (abfd, sec)
106933965Sjdp			    & (flagword) ~SEC_RELOC));
107033965Sjdp
107160484Sobrien#ifdef SET_SECTION_RELOCS
107260484Sobrien  SET_SECTION_RELOCS (sec, relocs, n);
107360484Sobrien#endif
107460484Sobrien
107533965Sjdp#ifdef DEBUG3
107633965Sjdp  {
107733965Sjdp    int i;
107833965Sjdp    arelent *r;
107933965Sjdp    asymbol *s;
108033965Sjdp    fprintf (stderr, "relocs for sec %s\n", sec->name);
108133965Sjdp    for (i = 0; i < n; i++)
108233965Sjdp      {
108333965Sjdp	r = relocs[i];
108433965Sjdp	s = *r->sym_ptr_ptr;
108533965Sjdp	fprintf (stderr, "  reloc %2d @%08x off %4x : sym %-10s addend %x\n",
108633965Sjdp		 i, r, r->address, s->name, r->addend);
108733965Sjdp      }
108833965Sjdp  }
108933965Sjdp#endif
109033965Sjdp}
109133965Sjdp
109233965Sjdpstatic void
109333965Sjdpwrite_contents (abfd, sec, xxx)
109460484Sobrien     bfd *abfd ATTRIBUTE_UNUSED;
109533965Sjdp     asection *sec;
109660484Sobrien     PTR xxx ATTRIBUTE_UNUSED;
109733965Sjdp{
109833965Sjdp  segment_info_type *seginfo = seg_info (sec);
109933965Sjdp  unsigned long offset = 0;
110033965Sjdp  fragS *f;
110133965Sjdp
110233965Sjdp  /* Write out the frags.  */
110333965Sjdp  if (seginfo == NULL
110433965Sjdp      || ! (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS))
110533965Sjdp    return;
110633965Sjdp
110733965Sjdp  for (f = seginfo->frchainP->frch_root;
110833965Sjdp       f;
110933965Sjdp       f = f->fr_next)
111033965Sjdp    {
111133965Sjdp      int x;
111233965Sjdp      unsigned long fill_size;
111333965Sjdp      char *fill_literal;
111433965Sjdp      long count;
111533965Sjdp
111633965Sjdp      assert (f->fr_type == rs_fill);
111733965Sjdp      if (f->fr_fix)
111833965Sjdp	{
111933965Sjdp	  x = bfd_set_section_contents (stdoutput, sec,
112033965Sjdp					f->fr_literal, (file_ptr) offset,
112133965Sjdp					(bfd_size_type) f->fr_fix);
112233965Sjdp	  if (x == false)
112333965Sjdp	    {
112433965Sjdp	      bfd_perror (stdoutput->filename);
112560484Sobrien	      as_perror (_("FATAL: Can't write %s"), stdoutput->filename);
112633965Sjdp	      exit (EXIT_FAILURE);
112733965Sjdp	    }
112833965Sjdp	  offset += f->fr_fix;
112933965Sjdp	}
113033965Sjdp      fill_literal = f->fr_literal + f->fr_fix;
113133965Sjdp      fill_size = f->fr_var;
113233965Sjdp      count = f->fr_offset;
113333965Sjdp      assert (count >= 0);
113433965Sjdp      if (fill_size && count)
113533965Sjdp	{
113633965Sjdp	  char buf[256];
113733965Sjdp	  if (fill_size > sizeof(buf))
113833965Sjdp	    {
113933965Sjdp	      /* Do it the old way. Can this ever happen? */
114033965Sjdp	      while (count--)
114133965Sjdp		{
114233965Sjdp		  x = bfd_set_section_contents (stdoutput, sec,
114333965Sjdp						fill_literal,
114433965Sjdp						(file_ptr) offset,
114533965Sjdp						(bfd_size_type) fill_size);
114633965Sjdp		  if (x == false)
114733965Sjdp		    {
114833965Sjdp		      bfd_perror (stdoutput->filename);
114960484Sobrien		      as_perror (_("FATAL: Can't write %s"), stdoutput->filename);
115033965Sjdp		      exit (EXIT_FAILURE);
115133965Sjdp		    }
115233965Sjdp		  offset += fill_size;
115333965Sjdp		}
115433965Sjdp	    }
115533965Sjdp	  else
115633965Sjdp	    {
115733965Sjdp	      /* Build a buffer full of fill objects and output it as
115833965Sjdp		 often as necessary. This saves on the overhead of
115933965Sjdp		 potentially lots of bfd_set_section_contents calls.  */
116033965Sjdp	      int n_per_buf, i;
116133965Sjdp	      if (fill_size == 1)
116233965Sjdp		{
116333965Sjdp		  n_per_buf = sizeof (buf);
116433965Sjdp		  memset (buf, *fill_literal, n_per_buf);
116533965Sjdp		}
116633965Sjdp	      else
116733965Sjdp		{
116833965Sjdp		  char *bufp;
116933965Sjdp		  n_per_buf = sizeof(buf)/fill_size;
117033965Sjdp		  for (i = n_per_buf, bufp = buf; i; i--, bufp += fill_size)
117133965Sjdp		    memcpy(bufp, fill_literal, fill_size);
117233965Sjdp		}
117333965Sjdp	      for (; count > 0; count -= n_per_buf)
117433965Sjdp		{
117533965Sjdp		  n_per_buf = n_per_buf > count ? count : n_per_buf;
117633965Sjdp		  x = bfd_set_section_contents (stdoutput, sec,
117733965Sjdp						buf, (file_ptr) offset,
117833965Sjdp						(bfd_size_type) n_per_buf * fill_size);
117933965Sjdp		  if (x != true)
118060484Sobrien		    as_fatal (_("Cannot write to output file."));
118133965Sjdp		  offset += n_per_buf * fill_size;
118233965Sjdp		}
118333965Sjdp	    }
118433965Sjdp	}
118533965Sjdp    }
118633965Sjdp}
118733965Sjdp#endif
118833965Sjdp
118933965Sjdp#if defined(BFD_ASSEMBLER) || (!defined (BFD) && !defined(OBJ_AOUT))
119033965Sjdpstatic void
119133965Sjdpmerge_data_into_text ()
119233965Sjdp{
119333965Sjdp#if defined(BFD_ASSEMBLER) || defined(MANY_SEGMENTS)
119433965Sjdp  seg_info (text_section)->frchainP->frch_last->fr_next =
119533965Sjdp    seg_info (data_section)->frchainP->frch_root;
119633965Sjdp  seg_info (text_section)->frchainP->frch_last =
119733965Sjdp    seg_info (data_section)->frchainP->frch_last;
119833965Sjdp  seg_info (data_section)->frchainP = 0;
119933965Sjdp#else
120033965Sjdp  fixS *tmp;
120133965Sjdp
120233965Sjdp  text_last_frag->fr_next = data_frag_root;
120333965Sjdp  text_last_frag = data_last_frag;
120433965Sjdp  data_last_frag = NULL;
120533965Sjdp  data_frag_root = NULL;
120633965Sjdp  if (text_fix_root)
120733965Sjdp    {
120833965Sjdp      for (tmp = text_fix_root; tmp->fx_next; tmp = tmp->fx_next);;
120933965Sjdp      tmp->fx_next = data_fix_root;
121033965Sjdp      text_fix_tail = data_fix_tail;
121133965Sjdp    }
121233965Sjdp  else
121333965Sjdp    text_fix_root = data_fix_root;
121433965Sjdp  data_fix_root = NULL;
121533965Sjdp#endif
121633965Sjdp}
121733965Sjdp#endif /* BFD_ASSEMBLER || (! BFD && ! OBJ_AOUT) */
121833965Sjdp
121933965Sjdp#if !defined (BFD_ASSEMBLER) && !defined (BFD)
122033965Sjdpstatic void
122133965Sjdprelax_and_size_all_segments ()
122233965Sjdp{
122333965Sjdp  fragS *fragP;
122433965Sjdp
122533965Sjdp  relax_segment (text_frag_root, SEG_TEXT);
122633965Sjdp  relax_segment (data_frag_root, SEG_DATA);
122733965Sjdp  relax_segment (bss_frag_root, SEG_BSS);
122833965Sjdp  /*
122933965Sjdp   * Now the addresses of frags are correct within the segment.
123033965Sjdp   */
123133965Sjdp
123233965Sjdp  know (text_last_frag->fr_type == rs_fill && text_last_frag->fr_offset == 0);
123333965Sjdp  H_SET_TEXT_SIZE (&headers, text_last_frag->fr_address);
123433965Sjdp  text_last_frag->fr_address = H_GET_TEXT_SIZE (&headers);
123533965Sjdp
123633965Sjdp  /*
123733965Sjdp   * Join the 2 segments into 1 huge segment.
123833965Sjdp   * To do this, re-compute every rn_address in the SEG_DATA frags.
123933965Sjdp   * Then join the data frags after the text frags.
124033965Sjdp   *
124133965Sjdp   * Determine a_data [length of data segment].
124233965Sjdp   */
124333965Sjdp  if (data_frag_root)
124433965Sjdp    {
124533965Sjdp      register relax_addressT slide;
124633965Sjdp
124733965Sjdp      know ((text_last_frag->fr_type == rs_fill) && (text_last_frag->fr_offset == 0));
124833965Sjdp
124933965Sjdp      H_SET_DATA_SIZE (&headers, data_last_frag->fr_address);
125033965Sjdp      data_last_frag->fr_address = H_GET_DATA_SIZE (&headers);
125133965Sjdp      slide = H_GET_TEXT_SIZE (&headers);	/* & in file of the data segment. */
125233965Sjdp#ifdef OBJ_BOUT
125333965Sjdp#define RoundUp(N,S) (((N)+(S)-1)&-(S))
125433965Sjdp      /* For b.out: If the data section has a strict alignment
125533965Sjdp	 requirement, its load address in the .o file will be
125633965Sjdp	 rounded up from the size of the text section.  These
125733965Sjdp	 two values are *not* the same!  Similarly for the bss
125833965Sjdp	 section....  */
125933965Sjdp      slide = RoundUp (slide, 1 << section_alignment[SEG_DATA]);
126033965Sjdp#endif
126133965Sjdp
126233965Sjdp      for (fragP = data_frag_root; fragP; fragP = fragP->fr_next)
126333965Sjdp	{
126433965Sjdp	  fragP->fr_address += slide;
126533965Sjdp	}			/* for each data frag */
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  {
127833965Sjdp    long 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  }
128633965Sjdp#else /* ! OBJ_BOUT */
128733965Sjdp  bss_address_frag.fr_address = (H_GET_TEXT_SIZE (&headers) +
128833965Sjdp				 H_GET_DATA_SIZE (&headers));
128933965Sjdp
129033965Sjdp#endif /* ! OBJ_BOUT */
129133965Sjdp
129233965Sjdp  /* 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)
129833965Sjdp	{
129933965Sjdp	  fragP->fr_address += slide;
130033965Sjdp	}			/* for each bss frag */
130133965Sjdp    }
130233965Sjdp
130333965Sjdp  if (bss_last_frag)
130433965Sjdp    H_SET_BSS_SIZE (&headers,
130533965Sjdp		    bss_last_frag->fr_address - bss_frag_root->fr_address);
130633965Sjdp  else
130733965Sjdp    H_SET_BSS_SIZE (&headers, 0);
130833965Sjdp}
130933965Sjdp#endif /* ! BFD_ASSEMBLER && ! BFD */
131033965Sjdp
131133965Sjdp#if defined (BFD_ASSEMBLER) || !defined (BFD)
131233965Sjdp
131333965Sjdp#ifdef BFD_ASSEMBLER
131433965Sjdpstatic void
131533965Sjdpset_symtab ()
131633965Sjdp{
131733965Sjdp  int nsyms;
131833965Sjdp  asymbol **asympp;
131933965Sjdp  symbolS *symp;
132033965Sjdp  boolean result;
132133965Sjdp  extern PTR bfd_alloc PARAMS ((bfd *, size_t));
132233965Sjdp
132333965Sjdp  /* Count symbols.  We can't rely on a count made by the loop in
132433965Sjdp     write_object_file, because *_frob_file may add a new symbol or
132533965Sjdp     two.  */
132633965Sjdp  nsyms = 0;
132733965Sjdp  for (symp = symbol_rootP; symp; symp = symbol_next (symp))
132833965Sjdp    nsyms++;
132933965Sjdp
133033965Sjdp  if (nsyms)
133133965Sjdp    {
133233965Sjdp      int i;
133333965Sjdp
133433965Sjdp      asympp = (asymbol **) bfd_alloc (stdoutput,
133533965Sjdp				       nsyms * sizeof (asymbol *));
133633965Sjdp      symp = symbol_rootP;
133733965Sjdp      for (i = 0; i < nsyms; i++, symp = symbol_next (symp))
133833965Sjdp	{
133960484Sobrien	  asympp[i] = symbol_get_bfdsym (symp);
134060484Sobrien	  symbol_mark_written (symp);
134133965Sjdp	}
134233965Sjdp    }
134333965Sjdp  else
134433965Sjdp    asympp = 0;
134533965Sjdp  result = bfd_set_symtab (stdoutput, asympp, nsyms);
134633965Sjdp  assert (result == true);
134733965Sjdp  symbol_table_frozen = 1;
134833965Sjdp}
134933965Sjdp#endif
135033965Sjdp
135138889Sjdp/* Finish the subsegments.  After every sub-segment, we fake an
135238889Sjdp   ".align ...".  This conforms to BSD4.2 brane-damage.  We then fake
135338889Sjdp   ".fill 0" because that is the kind of frag that requires least
135438889Sjdp   thought.  ".align" frags like to have a following frag since that
135538889Sjdp   makes calculating their intended length trivial.  */
135638889Sjdp
135738889Sjdp#ifndef SUB_SEGMENT_ALIGN
135838889Sjdp#ifdef BFD_ASSEMBLER
135938889Sjdp#define SUB_SEGMENT_ALIGN(SEG) (0)
136038889Sjdp#else
136138889Sjdp#define SUB_SEGMENT_ALIGN(SEG) (2)
136238889Sjdp#endif
136338889Sjdp#endif
136438889Sjdp
136533965Sjdpvoid
136638889Sjdpsubsegs_finish ()
136738889Sjdp{
136838889Sjdp  struct frchain *frchainP;
136938889Sjdp
137038889Sjdp  for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next)
137138889Sjdp    {
137238889Sjdp      subseg_set (frchainP->frch_seg, frchainP->frch_subseg);
137338889Sjdp
137460484Sobrien      /* This now gets called even if we had errors.  In that case,
137560484Sobrien         any alignment is meaningless, and, moreover, will look weird
137660484Sobrien         if we are generating a listing.  */
137760484Sobrien      frag_align (had_errors () ? 0 : SUB_SEGMENT_ALIGN (now_seg),
137860484Sobrien		  subseg_text_p (now_seg) ? NOP_OPCODE : 0,
137960484Sobrien		  0);
138060484Sobrien
138138889Sjdp      /* frag_align will have left a new frag.
138238889Sjdp	 Use this last frag for an empty ".fill".
138338889Sjdp
138438889Sjdp	 For this segment ...
138538889Sjdp	 Create a last frag. Do not leave a "being filled in frag".  */
138638889Sjdp
138738889Sjdp      frag_wane (frag_now);
138838889Sjdp      frag_now->fr_fix = 0;
138938889Sjdp      know (frag_now->fr_next == NULL);
139038889Sjdp    }
139138889Sjdp}
139238889Sjdp
139338889Sjdp/* Write the object file.  */
139438889Sjdp
139538889Sjdpvoid
139633965Sjdpwrite_object_file ()
139733965Sjdp{
139833965Sjdp#if ! defined (BFD_ASSEMBLER) || ! defined (WORKING_DOT_WORD)
139933965Sjdp  fragS *fragP;			/* Track along all frags. */
140033965Sjdp#endif
140133965Sjdp
140233965Sjdp  /* Do we really want to write it?  */
140333965Sjdp  {
140433965Sjdp    int n_warns, n_errs;
140533965Sjdp    n_warns = had_warnings ();
140633965Sjdp    n_errs = had_errors ();
140733965Sjdp    /* The -Z flag indicates that an object file should be generated,
140833965Sjdp       regardless of warnings and errors.  */
140933965Sjdp    if (flag_always_generate_output)
141033965Sjdp      {
141133965Sjdp	if (n_warns || n_errs)
141260484Sobrien	  as_warn (_("%d error%s, %d warning%s, generating bad object file.\n"),
141333965Sjdp		   n_errs, n_errs == 1 ? "" : "s",
141433965Sjdp		   n_warns, n_warns == 1 ? "" : "s");
141533965Sjdp      }
141633965Sjdp    else
141733965Sjdp      {
141833965Sjdp	if (n_errs)
141960484Sobrien	  as_fatal (_("%d error%s, %d warning%s, no object file generated.\n"),
142033965Sjdp		    n_errs, n_errs == 1 ? "" : "s",
142133965Sjdp		    n_warns, n_warns == 1 ? "" : "s");
142233965Sjdp      }
142333965Sjdp  }
142433965Sjdp
142533965Sjdp#ifdef	OBJ_VMS
142633965Sjdp  /* Under VMS we try to be compatible with VAX-11 "C".  Thus, we call
142733965Sjdp     a routine to check for the definition of the procedure "_main",
142833965Sjdp     and if so -- fix it up so that it can be program entry point. */
142933965Sjdp  vms_check_for_main ();
143033965Sjdp#endif /* OBJ_VMS */
143133965Sjdp
143233965Sjdp  /* From now on, we don't care about sub-segments.  Build one frag chain
143333965Sjdp     for each segment. Linked thru fr_next.  */
143433965Sjdp
143533965Sjdp#ifdef BFD_ASSEMBLER
143633965Sjdp  /* Remove the sections created by gas for its own purposes.  */
143733965Sjdp  {
143833965Sjdp    asection **seclist, *sec;
143933965Sjdp    int i;
144033965Sjdp
144133965Sjdp    seclist = &stdoutput->sections;
144233965Sjdp    while (seclist && *seclist)
144333965Sjdp      {
144433965Sjdp	sec = *seclist;
144533965Sjdp	while (sec == reg_section || sec == expr_section)
144633965Sjdp	  {
144733965Sjdp	    sec = sec->next;
144833965Sjdp	    *seclist = sec;
144933965Sjdp	    stdoutput->section_count--;
145033965Sjdp	    if (!sec)
145133965Sjdp	      break;
145233965Sjdp	  }
145333965Sjdp	if (*seclist)
145433965Sjdp	  seclist = &(*seclist)->next;
145533965Sjdp      }
145633965Sjdp    i = 0;
145733965Sjdp    bfd_map_over_sections (stdoutput, renumber_sections, &i);
145833965Sjdp  }
145933965Sjdp
146033965Sjdp  bfd_map_over_sections (stdoutput, chain_frchains_together, (char *) 0);
146133965Sjdp#else
146233965Sjdp  remove_subsegs (frchain_root, SEG_TEXT, &text_frag_root, &text_last_frag);
146333965Sjdp  remove_subsegs (data0_frchainP, SEG_DATA, &data_frag_root, &data_last_frag);
146433965Sjdp  remove_subsegs (bss0_frchainP, SEG_BSS, &bss_frag_root, &bss_last_frag);
146533965Sjdp#endif
146633965Sjdp
146733965Sjdp  /* We have two segments. If user gave -R flag, then we must put the
146833965Sjdp     data frags into the text segment. Do this before relaxing so
146933965Sjdp     we know to take advantage of -R and make shorter addresses.  */
147033965Sjdp#if !defined (OBJ_AOUT) || defined (BFD_ASSEMBLER)
147133965Sjdp  if (flag_readonly_data_in_text)
147233965Sjdp    {
147333965Sjdp      merge_data_into_text ();
147433965Sjdp    }
147533965Sjdp#endif
147633965Sjdp
147733965Sjdp#ifdef BFD_ASSEMBLER
147833965Sjdp  bfd_map_over_sections (stdoutput, relax_and_size_seg, (char *) 0);
147933965Sjdp#else
148033965Sjdp  relax_and_size_all_segments ();
148133965Sjdp#endif /* BFD_ASSEMBLER */
148233965Sjdp
148333965Sjdp#ifndef BFD_ASSEMBLER
148433965Sjdp  /*
148533965Sjdp   *
148633965Sjdp   * Crawl the symbol chain.
148733965Sjdp   *
148833965Sjdp   * For each symbol whose value depends on a frag, take the address of
148933965Sjdp   * that frag and subsume it into the value of the symbol.
149033965Sjdp   * After this, there is just one way to lookup a symbol value.
149133965Sjdp   * Values are left in their final state for object file emission.
149233965Sjdp   * We adjust the values of 'L' local symbols, even if we do
149333965Sjdp   * not intend to emit them to the object file, because their values
149433965Sjdp   * are needed for fix-ups.
149533965Sjdp   *
149633965Sjdp   * Unless we saw a -L flag, remove all symbols that begin with 'L'
149733965Sjdp   * from the symbol chain.  (They are still pointed to by the fixes.)
149833965Sjdp   *
149933965Sjdp   * Count the remaining symbols.
150033965Sjdp   * Assign a symbol number to each symbol.
150133965Sjdp   * Count the number of string-table chars we will emit.
150233965Sjdp   * Put this info into the headers as appropriate.
150333965Sjdp   *
150433965Sjdp   */
150533965Sjdp  know (zero_address_frag.fr_address == 0);
150633965Sjdp  string_byte_count = sizeof (string_byte_count);
150733965Sjdp
150833965Sjdp  obj_crawl_symbol_chain (&headers);
150933965Sjdp
151033965Sjdp  if (string_byte_count == sizeof (string_byte_count))
151133965Sjdp    string_byte_count = 0;
151233965Sjdp
151333965Sjdp  H_SET_STRING_SIZE (&headers, string_byte_count);
151433965Sjdp
151533965Sjdp  /*
151633965Sjdp   * Addresses of frags now reflect addresses we use in the object file.
151733965Sjdp   * Symbol values are correct.
151833965Sjdp   * Scan the frags, converting any ".org"s and ".align"s to ".fill"s.
151933965Sjdp   * Also converting any machine-dependent frags using md_convert_frag();
152033965Sjdp   */
152133965Sjdp  subseg_change (SEG_TEXT, 0);
152233965Sjdp
152333965Sjdp  for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
152433965Sjdp    {
152538889Sjdp      /* At this point we have linked all the frags into a single
152638889Sjdp         chain.  However, cvt_frag_to_fill may call md_convert_frag
152738889Sjdp         which may call fix_new.  We need to ensure that fix_new adds
152838889Sjdp         the fixup to the right section.  */
152938889Sjdp      if (fragP == data_frag_root)
153038889Sjdp	subseg_change (SEG_DATA, 0);
153138889Sjdp
153233965Sjdp      cvt_frag_to_fill (&headers, SEG_TEXT, fragP);
153333965Sjdp
153433965Sjdp      /* Some assert macros don't work with # directives mixed in.  */
153533965Sjdp#ifndef NDEBUG
153633965Sjdp      if (!(fragP->fr_next == NULL
153733965Sjdp#ifdef OBJ_BOUT
153833965Sjdp	    || fragP->fr_next == data_frag_root
153933965Sjdp#endif
154033965Sjdp	    || ((fragP->fr_next->fr_address - fragP->fr_address)
154133965Sjdp		== (fragP->fr_fix + fragP->fr_offset * fragP->fr_var))))
154233965Sjdp	abort ();
154333965Sjdp#endif
154433965Sjdp    }
154533965Sjdp#endif /* ! BFD_ASSEMBLER */
154633965Sjdp
154733965Sjdp#ifndef WORKING_DOT_WORD
154833965Sjdp  {
154933965Sjdp    struct broken_word *lie;
155033965Sjdp    struct broken_word **prevP;
155133965Sjdp
155233965Sjdp    prevP = &broken_words;
155333965Sjdp    for (lie = broken_words; lie; lie = lie->next_broken_word)
155433965Sjdp      if (!lie->added)
155533965Sjdp	{
155633965Sjdp	  expressionS exp;
155733965Sjdp
155860484Sobrien	  subseg_change (lie->seg, lie->subseg);
155933965Sjdp	  exp.X_op = O_subtract;
156033965Sjdp	  exp.X_add_symbol = lie->add;
156133965Sjdp	  exp.X_op_symbol = lie->sub;
156233965Sjdp	  exp.X_add_number = lie->addnum;
156333965Sjdp#ifdef BFD_ASSEMBLER
156433965Sjdp#ifdef TC_CONS_FIX_NEW
156533965Sjdp	  TC_CONS_FIX_NEW (lie->frag,
156633965Sjdp		       lie->word_goes_here - lie->frag->fr_literal,
156733965Sjdp		       2, &exp);
156833965Sjdp#else
156933965Sjdp	  fix_new_exp (lie->frag,
157033965Sjdp		       lie->word_goes_here - lie->frag->fr_literal,
157133965Sjdp		       2, &exp, 0, BFD_RELOC_16);
157233965Sjdp#endif
157333965Sjdp#else
157433965Sjdp#if defined(TC_SPARC) || defined(TC_A29K) || defined(NEED_FX_R_TYPE)
157533965Sjdp	  fix_new_exp (lie->frag,
157633965Sjdp		       lie->word_goes_here - lie->frag->fr_literal,
157733965Sjdp		       2, &exp, 0, NO_RELOC);
157833965Sjdp#else
157933965Sjdp#ifdef TC_NS32K
158033965Sjdp	  fix_new_ns32k_exp (lie->frag,
158133965Sjdp			     lie->word_goes_here - lie->frag->fr_literal,
158233965Sjdp			     2, &exp, 0, 0, 2, 0, 0);
158333965Sjdp#else
158433965Sjdp	  fix_new_exp (lie->frag,
158533965Sjdp		       lie->word_goes_here - lie->frag->fr_literal,
158633965Sjdp		       2, &exp, 0, 0);
158733965Sjdp#endif /* TC_NS32K */
158833965Sjdp#endif /* TC_SPARC|TC_A29K|NEED_FX_R_TYPE */
158933965Sjdp#endif /* BFD_ASSEMBLER */
159033965Sjdp	  *prevP = lie->next_broken_word;
159133965Sjdp	}
159233965Sjdp      else
159333965Sjdp	prevP = &(lie->next_broken_word);
159433965Sjdp
159533965Sjdp    for (lie = broken_words; lie;)
159633965Sjdp      {
159733965Sjdp	struct broken_word *untruth;
159833965Sjdp	char *table_ptr;
159933965Sjdp	addressT table_addr;
160033965Sjdp	addressT from_addr, to_addr;
160133965Sjdp	int n, m;
160233965Sjdp
160360484Sobrien	subseg_change (lie->seg, lie->subseg);
160433965Sjdp	fragP = lie->dispfrag;
160533965Sjdp
160633965Sjdp	/* Find out how many broken_words go here.  */
160733965Sjdp	n = 0;
160833965Sjdp	for (untruth = lie; untruth && untruth->dispfrag == fragP; untruth = untruth->next_broken_word)
160933965Sjdp	  if (untruth->added == 1)
161033965Sjdp	    n++;
161133965Sjdp
161233965Sjdp	table_ptr = lie->dispfrag->fr_opcode;
161333965Sjdp	table_addr = lie->dispfrag->fr_address + (table_ptr - lie->dispfrag->fr_literal);
161433965Sjdp	/* Create the jump around the long jumps.  This is a short
161533965Sjdp	   jump from table_ptr+0 to table_ptr+n*long_jump_size.  */
161633965Sjdp	from_addr = table_addr;
161733965Sjdp	to_addr = table_addr + md_short_jump_size + n * md_long_jump_size;
161833965Sjdp	md_create_short_jump (table_ptr, from_addr, to_addr, lie->dispfrag, lie->add);
161933965Sjdp	table_ptr += md_short_jump_size;
162033965Sjdp	table_addr += md_short_jump_size;
162133965Sjdp
162233965Sjdp	for (m = 0; lie && lie->dispfrag == fragP; m++, lie = lie->next_broken_word)
162333965Sjdp	  {
162433965Sjdp	    if (lie->added == 2)
162533965Sjdp	      continue;
162633965Sjdp	    /* Patch the jump table */
162733965Sjdp	    /* This is the offset from ??? to table_ptr+0 */
162833965Sjdp	    to_addr = table_addr - S_GET_VALUE (lie->sub);
162933965Sjdp#ifdef BFD_ASSEMBLER
163060484Sobrien	    to_addr -= symbol_get_frag (lie->sub)->fr_address;
163133965Sjdp#endif
163233965Sjdp	    md_number_to_chars (lie->word_goes_here, to_addr, 2);
163333965Sjdp	    for (untruth = lie->next_broken_word; untruth && untruth->dispfrag == fragP; untruth = untruth->next_broken_word)
163433965Sjdp	      {
163533965Sjdp		if (untruth->use_jump == lie)
163633965Sjdp		  md_number_to_chars (untruth->word_goes_here, to_addr, 2);
163733965Sjdp	      }
163833965Sjdp
163933965Sjdp	    /* Install the long jump */
164033965Sjdp	    /* this is a long jump from table_ptr+0 to the final target */
164133965Sjdp	    from_addr = table_addr;
164233965Sjdp	    to_addr = S_GET_VALUE (lie->add) + lie->addnum;
164333965Sjdp#ifdef BFD_ASSEMBLER
164460484Sobrien	    to_addr += symbol_get_frag (lie->add)->fr_address;
164533965Sjdp#endif
164633965Sjdp	    md_create_long_jump (table_ptr, from_addr, to_addr, lie->dispfrag, lie->add);
164733965Sjdp	    table_ptr += md_long_jump_size;
164833965Sjdp	    table_addr += md_long_jump_size;
164933965Sjdp	  }
165033965Sjdp      }
165133965Sjdp  }
165233965Sjdp#endif /* not WORKING_DOT_WORD */
165333965Sjdp
165433965Sjdp#ifndef BFD_ASSEMBLER
165533965Sjdp#ifndef	OBJ_VMS
165633965Sjdp  {				/* not vms */
165733965Sjdp    char *the_object_file;
165833965Sjdp    long object_file_size;
165933965Sjdp    /*
166033965Sjdp     * Scan every FixS performing fixups. We had to wait until now to do
166133965Sjdp     * this because md_convert_frag() may have made some fixSs.
166233965Sjdp     */
166333965Sjdp    int trsize, drsize;
166433965Sjdp
166533965Sjdp    subseg_change (SEG_TEXT, 0);
166633965Sjdp    trsize = md_reloc_size * fixup_segment (text_fix_root, SEG_TEXT);
166733965Sjdp    subseg_change (SEG_DATA, 0);
166833965Sjdp    drsize = md_reloc_size * fixup_segment (data_fix_root, SEG_DATA);
166933965Sjdp    H_SET_RELOCATION_SIZE (&headers, trsize, drsize);
167033965Sjdp
167133965Sjdp    /* FIXME move this stuff into the pre-write-hook */
167233965Sjdp    H_SET_MAGIC_NUMBER (&headers, magic_number_for_object_file);
167333965Sjdp    H_SET_ENTRY_POINT (&headers, 0);
167433965Sjdp
167533965Sjdp    obj_pre_write_hook (&headers);	/* extra coff stuff */
167633965Sjdp
167733965Sjdp    object_file_size = H_GET_FILE_SIZE (&headers);
167833965Sjdp    next_object_file_charP = the_object_file = xmalloc (object_file_size);
167933965Sjdp
168033965Sjdp    output_file_create (out_file_name);
168133965Sjdp
168233965Sjdp    obj_header_append (&next_object_file_charP, &headers);
168333965Sjdp
168433965Sjdp    know ((next_object_file_charP - the_object_file) == H_GET_HEADER_SIZE (&headers));
168533965Sjdp
168633965Sjdp    /*
168733965Sjdp     * Emit code.
168833965Sjdp     */
168933965Sjdp    for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
169033965Sjdp      {
169133965Sjdp	register long count;
169233965Sjdp	register char *fill_literal;
169333965Sjdp	register long fill_size;
169433965Sjdp
169533965Sjdp	PROGRESS (1);
169633965Sjdp	know (fragP->fr_type == rs_fill);
169733965Sjdp	append (&next_object_file_charP, fragP->fr_literal, (unsigned long) fragP->fr_fix);
169833965Sjdp	fill_literal = fragP->fr_literal + fragP->fr_fix;
169933965Sjdp	fill_size = fragP->fr_var;
170033965Sjdp	know (fragP->fr_offset >= 0);
170133965Sjdp
170233965Sjdp	for (count = fragP->fr_offset; count; count--)
170333965Sjdp	  {
170433965Sjdp	    append (&next_object_file_charP, fill_literal, (unsigned long) fill_size);
170533965Sjdp	  }			/* for each  */
170633965Sjdp
170733965Sjdp      }				/* for each code frag. */
170833965Sjdp
170933965Sjdp    know ((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE (&headers) + H_GET_TEXT_SIZE (&headers) + H_GET_DATA_SIZE (&headers)));
171033965Sjdp
171133965Sjdp    /*
171233965Sjdp     * Emit relocations.
171333965Sjdp     */
171433965Sjdp    obj_emit_relocations (&next_object_file_charP, text_fix_root, (relax_addressT) 0);
171533965Sjdp    know ((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE (&headers) + H_GET_TEXT_SIZE (&headers) + H_GET_DATA_SIZE (&headers) + H_GET_TEXT_RELOCATION_SIZE (&headers)));
171633965Sjdp#ifdef TC_I960
171733965Sjdp    /* Make addresses in data relocation directives relative to beginning of
171833965Sjdp     * first data fragment, not end of last text fragment:  alignment of the
171933965Sjdp     * start of the data segment may place a gap between the segments.
172033965Sjdp     */
172133965Sjdp    obj_emit_relocations (&next_object_file_charP, data_fix_root, data0_frchainP->frch_root->fr_address);
172233965Sjdp#else /* TC_I960 */
172333965Sjdp    obj_emit_relocations (&next_object_file_charP, data_fix_root, text_last_frag->fr_address);
172433965Sjdp#endif /* TC_I960 */
172533965Sjdp
172633965Sjdp    know ((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE (&headers) + H_GET_TEXT_SIZE (&headers) + H_GET_DATA_SIZE (&headers) + H_GET_TEXT_RELOCATION_SIZE (&headers) + H_GET_DATA_RELOCATION_SIZE (&headers)));
172733965Sjdp
172833965Sjdp    /*
172933965Sjdp     * Emit line number entries.
173033965Sjdp     */
173133965Sjdp    OBJ_EMIT_LINENO (&next_object_file_charP, lineno_rootP, the_object_file);
173233965Sjdp    know ((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE (&headers) + H_GET_TEXT_SIZE (&headers) + H_GET_DATA_SIZE (&headers) + H_GET_TEXT_RELOCATION_SIZE (&headers) + H_GET_DATA_RELOCATION_SIZE (&headers) + H_GET_LINENO_SIZE (&headers)));
173333965Sjdp
173433965Sjdp    /*
173533965Sjdp     * Emit symbols.
173633965Sjdp     */
173733965Sjdp    obj_emit_symbols (&next_object_file_charP, symbol_rootP);
173833965Sjdp    know ((next_object_file_charP - the_object_file) == (H_GET_HEADER_SIZE (&headers) + H_GET_TEXT_SIZE (&headers) + H_GET_DATA_SIZE (&headers) + H_GET_TEXT_RELOCATION_SIZE (&headers) + H_GET_DATA_RELOCATION_SIZE (&headers) + H_GET_LINENO_SIZE (&headers) + H_GET_SYMBOL_TABLE_SIZE (&headers)));
173933965Sjdp
174033965Sjdp    /*
174133965Sjdp     * Emit strings.
174233965Sjdp     */
174333965Sjdp
174433965Sjdp    if (string_byte_count > 0)
174533965Sjdp      {
174633965Sjdp	obj_emit_strings (&next_object_file_charP);
174733965Sjdp      }				/* only if we have a string table */
174833965Sjdp
174933965Sjdp#ifdef BFD_HEADERS
175033965Sjdp    bfd_seek (stdoutput, 0, 0);
175133965Sjdp    bfd_write (the_object_file, 1, object_file_size, stdoutput);
175233965Sjdp#else
175333965Sjdp
175433965Sjdp    /* Write the data to the file */
175533965Sjdp    output_file_append (the_object_file, object_file_size, out_file_name);
175633965Sjdp    free (the_object_file);
175733965Sjdp#endif
175833965Sjdp  }				/* non vms output */
175933965Sjdp#else /* OBJ_VMS */
176033965Sjdp  /*
176133965Sjdp   *	Now do the VMS-dependent part of writing the object file
176233965Sjdp   */
176333965Sjdp  vms_write_object_file (H_GET_TEXT_SIZE (&headers),
176433965Sjdp			 H_GET_DATA_SIZE (&headers),
176533965Sjdp			 H_GET_BSS_SIZE (&headers),
176633965Sjdp			 text_frag_root, data_frag_root);
176733965Sjdp#endif /* OBJ_VMS */
176833965Sjdp#else /* BFD_ASSEMBLER */
176933965Sjdp
177033965Sjdp  /* Resolve symbol values.  This needs to be done before processing
177133965Sjdp     the relocations.  */
177233965Sjdp  if (symbol_rootP)
177333965Sjdp    {
177433965Sjdp      symbolS *symp;
177533965Sjdp
177633965Sjdp      for (symp = symbol_rootP; symp; symp = symbol_next (symp))
177760484Sobrien	resolve_symbol_value (symp, 1);
177833965Sjdp    }
177960484Sobrien  resolve_local_symbol_values ();
178033965Sjdp
178133965Sjdp  PROGRESS (1);
178233965Sjdp
178333965Sjdp#ifdef tc_frob_file_before_adjust
178433965Sjdp  tc_frob_file_before_adjust ();
178533965Sjdp#endif
178633965Sjdp#ifdef obj_frob_file_before_adjust
178733965Sjdp  obj_frob_file_before_adjust ();
178833965Sjdp#endif
178933965Sjdp
179033965Sjdp  bfd_map_over_sections (stdoutput, adjust_reloc_syms, (char *)0);
179133965Sjdp
179233965Sjdp  /* Set up symbol table, and write it out.  */
179333965Sjdp  if (symbol_rootP)
179433965Sjdp    {
179533965Sjdp      symbolS *symp;
179633965Sjdp
179733965Sjdp      for (symp = symbol_rootP; symp; symp = symbol_next (symp))
179833965Sjdp	{
179933965Sjdp	  int punt = 0;
180033965Sjdp	  const char *name;
180133965Sjdp
180260484Sobrien	  if (symbol_mri_common_p (symp))
180333965Sjdp	    {
180433965Sjdp	      if (S_IS_EXTERNAL (symp))
180560484Sobrien		as_bad (_("%s: global symbols not supported in common sections"),
180633965Sjdp			S_GET_NAME (symp));
180733965Sjdp	      symbol_remove (symp, &symbol_rootP, &symbol_lastP);
180833965Sjdp	      continue;
180933965Sjdp	    }
181033965Sjdp
181133965Sjdp	  name = S_GET_NAME (symp);
181233965Sjdp	  if (name)
181333965Sjdp	    {
181433965Sjdp	      const char *name2 = decode_local_label_name ((char *)S_GET_NAME (symp));
181533965Sjdp	      /* They only differ if `name' is a fb or dollar local
181633965Sjdp		 label name.  */
181733965Sjdp	      if (name2 != name && ! S_IS_DEFINED (symp))
181860484Sobrien		as_bad (_("local label %s is not defined"), name2);
181933965Sjdp	    }
182033965Sjdp
182133965Sjdp	  /* Do it again, because adjust_reloc_syms might introduce
182233965Sjdp	     more symbols.  They'll probably only be section symbols,
182333965Sjdp	     but they'll still need to have the values computed.  */
182460484Sobrien	  resolve_symbol_value (symp, 1);
182533965Sjdp
182633965Sjdp	  /* Skip symbols which were equated to undefined or common
182733965Sjdp             symbols.  */
182860484Sobrien	  if (symbol_equated_p (symp)
182933965Sjdp	      && (! S_IS_DEFINED (symp) || S_IS_COMMON (symp)))
183033965Sjdp	    {
183133965Sjdp	      symbol_remove (symp, &symbol_rootP, &symbol_lastP);
183233965Sjdp	      continue;
183333965Sjdp	    }
183433965Sjdp
183533965Sjdp	  /* So far, common symbols have been treated like undefined symbols.
183633965Sjdp	     Put them in the common section now.  */
183733965Sjdp	  if (S_IS_DEFINED (symp) == 0
183833965Sjdp	      && S_GET_VALUE (symp) != 0)
183933965Sjdp	    S_SET_SEGMENT (symp, bfd_com_section_ptr);
184033965Sjdp#if 0
184133965Sjdp	  printf ("symbol `%s'\n\t@%x: value=%d flags=%x seg=%s\n",
184233965Sjdp		  S_GET_NAME (symp), symp,
184333965Sjdp		  S_GET_VALUE (symp),
184460484Sobrien		  symbol_get_bfdsym (symp)->flags,
184560484Sobrien		  segment_name (S_GET_SEGMENT (symp)));
184633965Sjdp#endif
184733965Sjdp
184833965Sjdp#ifdef obj_frob_symbol
184933965Sjdp	  obj_frob_symbol (symp, punt);
185033965Sjdp#endif
185133965Sjdp#ifdef tc_frob_symbol
185260484Sobrien	  if (! punt || symbol_used_in_reloc_p (symp))
185333965Sjdp	    tc_frob_symbol (symp, punt);
185433965Sjdp#endif
185533965Sjdp
185633965Sjdp	  /* If we don't want to keep this symbol, splice it out of
185733965Sjdp	     the chain now.  If EMIT_SECTION_SYMBOLS is 0, we never
185833965Sjdp	     want section symbols.  Otherwise, we skip local symbols
185933965Sjdp	     and symbols that the frob_symbol macros told us to punt,
186033965Sjdp	     but we keep such symbols if they are used in relocs.  */
186133965Sjdp	  if ((! EMIT_SECTION_SYMBOLS
186260484Sobrien	       && symbol_section_p (symp))
186333965Sjdp	      /* Note that S_IS_EXTERN and S_IS_LOCAL are not always
186433965Sjdp		 opposites.  Sometimes the former checks flags and the
186533965Sjdp		 latter examines the name...  */
186633965Sjdp	      || (!S_IS_EXTERN (symp)
186733965Sjdp		  && (S_IS_LOCAL (symp) || punt)
186860484Sobrien		  && ! symbol_used_in_reloc_p (symp)))
186933965Sjdp	    {
187033965Sjdp	      symbol_remove (symp, &symbol_rootP, &symbol_lastP);
187133965Sjdp	      /* After symbol_remove, symbol_next(symp) still returns
187233965Sjdp		 the one that came after it in the chain.  So we don't
187333965Sjdp		 need to do any extra cleanup work here.  */
187433965Sjdp
187533965Sjdp	      continue;
187633965Sjdp	    }
187733965Sjdp
187833965Sjdp	  /* Make sure we really got a value for the symbol.  */
187960484Sobrien	  if (! symbol_resolved_p (symp))
188033965Sjdp	    {
188160484Sobrien	      as_bad (_("can't resolve value for symbol \"%s\""),
188233965Sjdp		      S_GET_NAME (symp));
188360484Sobrien	      symbol_mark_resolved (symp);
188433965Sjdp	    }
188533965Sjdp
188633965Sjdp	  /* Set the value into the BFD symbol.  Up til now the value
188733965Sjdp	     has only been kept in the gas symbolS struct.  */
188860484Sobrien	  symbol_get_bfdsym (symp)->value = S_GET_VALUE (symp);
188933965Sjdp	}
189033965Sjdp    }
189133965Sjdp
189233965Sjdp  PROGRESS (1);
189333965Sjdp
189433965Sjdp  /* Now do any format-specific adjustments to the symbol table, such
189533965Sjdp     as adding file symbols.  */
189633965Sjdp#ifdef tc_adjust_symtab
189733965Sjdp  tc_adjust_symtab ();
189833965Sjdp#endif
189933965Sjdp#ifdef obj_adjust_symtab
190033965Sjdp  obj_adjust_symtab ();
190133965Sjdp#endif
190233965Sjdp
190333965Sjdp  /* Now that all the sizes are known, and contents correct, we can
190433965Sjdp     start writing to the file.  */
190533965Sjdp  set_symtab ();
190633965Sjdp
190733965Sjdp  /* If *_frob_file changes the symbol value at this point, it is
190833965Sjdp     responsible for moving the changed value into symp->bsym->value
190933965Sjdp     as well.  Hopefully all symbol value changing can be done in
191033965Sjdp     *_frob_symbol.  */
191133965Sjdp#ifdef tc_frob_file
191233965Sjdp  tc_frob_file ();
191333965Sjdp#endif
191433965Sjdp#ifdef obj_frob_file
191533965Sjdp  obj_frob_file ();
191633965Sjdp#endif
191733965Sjdp
191833965Sjdp  bfd_map_over_sections (stdoutput, write_relocs, (char *) 0);
191933965Sjdp
192033965Sjdp#ifdef tc_frob_file_after_relocs
192133965Sjdp  tc_frob_file_after_relocs ();
192233965Sjdp#endif
192333965Sjdp#ifdef obj_frob_file_after_relocs
192433965Sjdp  obj_frob_file_after_relocs ();
192533965Sjdp#endif
192633965Sjdp
192733965Sjdp  bfd_map_over_sections (stdoutput, write_contents, (char *) 0);
192833965Sjdp#endif /* BFD_ASSEMBLER */
192933965Sjdp}
193033965Sjdp#endif /* ! BFD */
193133965Sjdp
193233965Sjdp/*
193333965Sjdp *			relax_segment()
193433965Sjdp *
193533965Sjdp * Now we have a segment, not a crowd of sub-segments, we can make fr_address
193633965Sjdp * values.
193733965Sjdp *
193833965Sjdp * Relax the frags.
193933965Sjdp *
194033965Sjdp * After this, all frags in this segment have addresses that are correct
194133965Sjdp * within the segment. Since segments live in different file addresses,
194233965Sjdp * these frag addresses may not be the same as final object-file addresses.
194333965Sjdp */
194433965Sjdp
194533965Sjdp#ifdef TC_GENERIC_RELAX_TABLE
194633965Sjdp
194733965Sjdpstatic int is_dnrange PARAMS ((fragS *, fragS *));
194833965Sjdp
194933965Sjdp/* Subroutines of relax_segment.  */
195033965Sjdpstatic int
195133965Sjdpis_dnrange (f1, f2)
195233965Sjdp     fragS *f1;
195333965Sjdp     fragS *f2;
195433965Sjdp{
195533965Sjdp  for (; f1; f1 = f1->fr_next)
195633965Sjdp    if (f1->fr_next == f2)
195733965Sjdp      return 1;
195833965Sjdp  return 0;
195933965Sjdp}
196033965Sjdp
196133965Sjdp/* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE.  */
196233965Sjdp
196333965Sjdplong
196433965Sjdprelax_frag (fragP, stretch)
196533965Sjdp     fragS *fragP;
196633965Sjdp     long stretch;
196733965Sjdp{
196833965Sjdp  const relax_typeS *this_type;
196933965Sjdp  const relax_typeS *start_type;
197033965Sjdp  relax_substateT next_state;
197133965Sjdp  relax_substateT this_state;
197233965Sjdp  long aim, target, growth;
197333965Sjdp  symbolS *symbolP = fragP->fr_symbol;
197433965Sjdp  long offset = fragP->fr_offset;
197533965Sjdp  /* Recompute was_address by undoing "+= stretch" done by relax_segment.  */
197633965Sjdp  unsigned long was_address = fragP->fr_address - stretch;
197733965Sjdp  unsigned long address = fragP->fr_address;
197833965Sjdp  const relax_typeS *table = TC_GENERIC_RELAX_TABLE;
197933965Sjdp
198033965Sjdp  this_state = fragP->fr_subtype;
198133965Sjdp  start_type = this_type = table + this_state;
198233965Sjdp  target = offset;
198333965Sjdp
198433965Sjdp  if (symbolP)
198533965Sjdp    {
198633965Sjdp#ifndef DIFF_EXPR_OK
198733965Sjdp#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
198833965Sjdp      know ((S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
198933965Sjdp	    || (S_GET_SEGMENT (symbolP) == SEG_DATA)
199033965Sjdp	    || (S_GET_SEGMENT (symbolP) == SEG_BSS)
199133965Sjdp	    || (S_GET_SEGMENT (symbolP) == SEG_TEXT));
199233965Sjdp#endif
199333965Sjdp      know (symbolP->sy_frag);
199433965Sjdp#endif
199533965Sjdp      know (!(S_GET_SEGMENT (symbolP) == absolute_section)
199633965Sjdp	    || symbolP->sy_frag == &zero_address_frag);
199760484Sobrien      target +=	S_GET_VALUE (symbolP) + symbol_get_frag (symbolP)->fr_address;
199833965Sjdp
199933965Sjdp      /* If frag has yet to be reached on this pass,
200033965Sjdp	 assume it will move by STRETCH just as we did.
200133965Sjdp	 If this is not so, it will be because some frag
200233965Sjdp	 between grows, and that will force another pass.
200333965Sjdp
200433965Sjdp	 Beware zero-length frags.
200533965Sjdp
200633965Sjdp	 There should be a faster way to do this.  */
200733965Sjdp
200860484Sobrien      if (symbol_get_frag (symbolP)->fr_address >= was_address
200960484Sobrien	  && is_dnrange (fragP, symbol_get_frag (symbolP)))
201033965Sjdp	{
201133965Sjdp	  target += stretch;
201233965Sjdp	}
201333965Sjdp    }
201433965Sjdp
201533965Sjdp  aim = target - address - fragP->fr_fix;
201633965Sjdp#ifdef TC_PCREL_ADJUST
201733965Sjdp  /* Currently only the ns32k family needs this */
201833965Sjdp  aim += TC_PCREL_ADJUST(fragP);
201933965Sjdp/*#else*/
202033965Sjdp  /* This machine doesn't want to use pcrel_adjust.
202133965Sjdp     In that case, pcrel_adjust should be zero.  */
202233965Sjdp/*  assert (fragP->fr_targ.ns32k.pcrel_adjust == 0);*/
202333965Sjdp#endif
202433965Sjdp#ifdef md_prepare_relax_scan /* formerly called M68K_AIM_KLUDGE */
202533965Sjdp  md_prepare_relax_scan (fragP, address, aim, this_state, this_type);
202633965Sjdp#endif
202733965Sjdp
202833965Sjdp  if (aim < 0)
202933965Sjdp    {
203033965Sjdp      /* Look backwards. */
203133965Sjdp      for (next_state = this_type->rlx_more; next_state;)
203233965Sjdp	if (aim >= this_type->rlx_backward)
203333965Sjdp	  next_state = 0;
203433965Sjdp	else
203533965Sjdp	  {
203633965Sjdp	    /* Grow to next state. */
203733965Sjdp	    this_state = next_state;
203833965Sjdp	    this_type = table + this_state;
203933965Sjdp	    next_state = this_type->rlx_more;
204033965Sjdp	  }
204133965Sjdp    }
204233965Sjdp  else
204333965Sjdp    {
204433965Sjdp      /* Look forwards. */
204533965Sjdp      for (next_state = this_type->rlx_more; next_state;)
204633965Sjdp	if (aim <= this_type->rlx_forward)
204733965Sjdp	  next_state = 0;
204833965Sjdp	else
204933965Sjdp	  {
205033965Sjdp	    /* Grow to next state. */
205133965Sjdp	    this_state = next_state;
205233965Sjdp	    this_type = table + this_state;
205333965Sjdp	    next_state = this_type->rlx_more;
205433965Sjdp	  }
205533965Sjdp    }
205633965Sjdp
205733965Sjdp  growth = this_type->rlx_length - start_type->rlx_length;
205833965Sjdp  if (growth != 0)
205933965Sjdp    fragP->fr_subtype = this_state;
206033965Sjdp  return growth;
206133965Sjdp}
206233965Sjdp
206333965Sjdp#endif /* defined (TC_GENERIC_RELAX_TABLE) */
206433965Sjdp
206533965Sjdp/* Relax_align. Advance location counter to next address that has 'alignment'
206633965Sjdp   lowest order bits all 0s, return size of adjustment made.  */
206733965Sjdpstatic relax_addressT
206833965Sjdprelax_align (address, alignment)
206933965Sjdp     register relax_addressT address;	/* Address now. */
207033965Sjdp     register int alignment;	/* Alignment (binary). */
207133965Sjdp{
207233965Sjdp  relax_addressT mask;
207333965Sjdp  relax_addressT new_address;
207433965Sjdp
207533965Sjdp  mask = ~((~0) << alignment);
207633965Sjdp  new_address = (address + mask) & (~mask);
207733965Sjdp#ifdef LINKER_RELAXING_SHRINKS_ONLY
207833965Sjdp  if (linkrelax)
207933965Sjdp    /* We must provide lots of padding, so the linker can discard it
208033965Sjdp       when needed.  The linker will not add extra space, ever.  */
208133965Sjdp    new_address += (1 << alignment);
208233965Sjdp#endif
208333965Sjdp  return (new_address - address);
208433965Sjdp}
208533965Sjdp
208633965Sjdpvoid
208733965Sjdprelax_segment (segment_frag_root, segment)
208833965Sjdp     struct frag *segment_frag_root;
208933965Sjdp     segT segment;
209033965Sjdp{
209133965Sjdp  register struct frag *fragP;
209233965Sjdp  register relax_addressT address;
209333965Sjdp#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
209433965Sjdp  know (segment == SEG_DATA || segment == SEG_TEXT || segment == SEG_BSS);
209533965Sjdp#endif
209633965Sjdp  /* In case md_estimate_size_before_relax() wants to make fixSs. */
209733965Sjdp  subseg_change (segment, 0);
209833965Sjdp
209933965Sjdp  /* For each frag in segment: count and store  (a 1st guess of)
210033965Sjdp     fr_address.  */
210133965Sjdp  address = 0;
210233965Sjdp  for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
210333965Sjdp    {
210433965Sjdp      fragP->fr_address = address;
210533965Sjdp      address += fragP->fr_fix;
210633965Sjdp
210733965Sjdp      switch (fragP->fr_type)
210833965Sjdp	{
210933965Sjdp	case rs_fill:
211033965Sjdp	  address += fragP->fr_offset * fragP->fr_var;
211133965Sjdp	  break;
211233965Sjdp
211333965Sjdp	case rs_align:
211433965Sjdp	case rs_align_code:
211533965Sjdp	  {
211633965Sjdp	    addressT offset = relax_align (address, (int) fragP->fr_offset);
211733965Sjdp
211833965Sjdp	    if (fragP->fr_subtype != 0 && offset > fragP->fr_subtype)
211933965Sjdp	      offset = 0;
212033965Sjdp
212133965Sjdp	    if (offset % fragP->fr_var != 0)
212233965Sjdp	      {
212360484Sobrien		as_bad (_("alignment padding (%lu bytes) not a multiple of %ld"),
212433965Sjdp			(unsigned long) offset, (long) fragP->fr_var);
212533965Sjdp		offset -= (offset % fragP->fr_var);
212633965Sjdp	      }
212733965Sjdp
212833965Sjdp	    address += offset;
212933965Sjdp	  }
213033965Sjdp	  break;
213133965Sjdp
213233965Sjdp	case rs_org:
213333965Sjdp	case rs_space:
213433965Sjdp	  /* Assume .org is nugatory. It will grow with 1st relax.  */
213533965Sjdp	  break;
213633965Sjdp
213733965Sjdp	case rs_machine_dependent:
213833965Sjdp	  address += md_estimate_size_before_relax (fragP, segment);
213933965Sjdp	  break;
214033965Sjdp
214133965Sjdp#ifndef WORKING_DOT_WORD
214233965Sjdp	  /* Broken words don't concern us yet */
214333965Sjdp	case rs_broken_word:
214433965Sjdp	  break;
214533965Sjdp#endif
214633965Sjdp
214738889Sjdp	case rs_leb128:
214838889Sjdp	  /* Initial guess is always 1; doing otherwise can result in
214938889Sjdp	     stable solutions that are larger than the minimum.  */
215038889Sjdp	  address += fragP->fr_offset = 1;
215138889Sjdp	  break;
215238889Sjdp
215338889Sjdp	case rs_cfa:
215438889Sjdp	  address += eh_frame_estimate_size_before_relax (fragP);
215538889Sjdp	  break;
215638889Sjdp
215733965Sjdp	default:
215833965Sjdp	  BAD_CASE (fragP->fr_type);
215933965Sjdp	  break;
216033965Sjdp	}			/* switch(fr_type) */
216133965Sjdp    }				/* for each frag in the segment */
216233965Sjdp
216333965Sjdp  /* Do relax().  */
216433965Sjdp  {
216533965Sjdp    long stretch;	/* May be any size, 0 or negative. */
216633965Sjdp    /* Cumulative number of addresses we have */
216733965Sjdp    /* relaxed this pass. */
216833965Sjdp    /* We may have relaxed more than one address. */
216933965Sjdp    long stretched;	/* Have we stretched on this pass? */
217033965Sjdp    /* This is 'cuz stretch may be zero, when, in fact some piece of code
217133965Sjdp       grew, and another shrank.  If a branch instruction doesn't fit anymore,
217233965Sjdp       we could be scrod.  */
217333965Sjdp
217433965Sjdp    do
217533965Sjdp      {
217633965Sjdp	stretch = stretched = 0;
217733965Sjdp	for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next)
217833965Sjdp	  {
217933965Sjdp	    long growth = 0;
218033965Sjdp	    addressT was_address;
218133965Sjdp	    offsetT offset;
218233965Sjdp	    symbolS *symbolP;
218333965Sjdp
218433965Sjdp	    was_address = fragP->fr_address;
218533965Sjdp	    address = fragP->fr_address += stretch;
218633965Sjdp	    symbolP = fragP->fr_symbol;
218733965Sjdp	    offset = fragP->fr_offset;
218833965Sjdp
218933965Sjdp	    switch (fragP->fr_type)
219033965Sjdp	      {
219133965Sjdp	      case rs_fill:	/* .fill never relaxes. */
219233965Sjdp		growth = 0;
219333965Sjdp		break;
219433965Sjdp
219533965Sjdp#ifndef WORKING_DOT_WORD
219633965Sjdp		/* JF:  This is RMS's idea.  I do *NOT* want to be blamed
219733965Sjdp		   for it I do not want to write it.  I do not want to have
219833965Sjdp		   anything to do with it.  This is not the proper way to
219933965Sjdp		   implement this misfeature.  */
220033965Sjdp	      case rs_broken_word:
220133965Sjdp		{
220233965Sjdp		  struct broken_word *lie;
220333965Sjdp		  struct broken_word *untruth;
220433965Sjdp
220533965Sjdp		  /* Yes this is ugly (storing the broken_word pointer
220633965Sjdp		     in the symbol slot).  Still, this whole chunk of
220733965Sjdp		     code is ugly, and I don't feel like doing anything
220833965Sjdp		     about it.  Think of it as stubbornness in action.  */
220933965Sjdp		  growth = 0;
221033965Sjdp		  for (lie = (struct broken_word *) (fragP->fr_symbol);
221133965Sjdp		       lie && lie->dispfrag == fragP;
221233965Sjdp		       lie = lie->next_broken_word)
221333965Sjdp		    {
221433965Sjdp
221533965Sjdp		      if (lie->added)
221633965Sjdp			continue;
221733965Sjdp
221860484Sobrien		      offset = (symbol_get_frag (lie->add)->fr_address
221933965Sjdp				+ S_GET_VALUE (lie->add)
222033965Sjdp				+ lie->addnum
222160484Sobrien				- (symbol_get_frag (lie->sub)->fr_address
222233965Sjdp				   + S_GET_VALUE (lie->sub)));
222333965Sjdp		      if (offset <= -32768 || offset >= 32767)
222433965Sjdp			{
222533965Sjdp			  if (flag_warn_displacement)
222633965Sjdp			    {
222733965Sjdp			      char buf[50];
222833965Sjdp			      sprint_value (buf, (addressT) lie->addnum);
222960484Sobrien			      as_warn (_(".word %s-%s+%s didn't fit"),
223033965Sjdp				       S_GET_NAME (lie->add),
223133965Sjdp				       S_GET_NAME (lie->sub),
223233965Sjdp				       buf);
223333965Sjdp			    }
223433965Sjdp			  lie->added = 1;
223533965Sjdp			  if (fragP->fr_subtype == 0)
223633965Sjdp			    {
223733965Sjdp			      fragP->fr_subtype++;
223833965Sjdp			      growth += md_short_jump_size;
223933965Sjdp			    }
224033965Sjdp			  for (untruth = lie->next_broken_word;
224133965Sjdp			       untruth && untruth->dispfrag == lie->dispfrag;
224233965Sjdp			       untruth = untruth->next_broken_word)
224360484Sobrien			    if ((symbol_get_frag (untruth->add)
224460484Sobrien				 == symbol_get_frag (lie->add))
224560484Sobrien				&& (S_GET_VALUE (untruth->add)
224660484Sobrien				    == S_GET_VALUE (lie->add)))
224733965Sjdp			      {
224833965Sjdp				untruth->added = 2;
224933965Sjdp				untruth->use_jump = lie;
225033965Sjdp			      }
225133965Sjdp			  growth += md_long_jump_size;
225233965Sjdp			}
225333965Sjdp		    }
225433965Sjdp
225533965Sjdp		  break;
225633965Sjdp		}		/* case rs_broken_word */
225733965Sjdp#endif
225833965Sjdp	      case rs_align:
225933965Sjdp	      case rs_align_code:
226033965Sjdp		{
226133965Sjdp		  addressT oldoff, newoff;
226233965Sjdp
226333965Sjdp		  oldoff = relax_align (was_address + fragP->fr_fix,
226433965Sjdp					(int) offset);
226533965Sjdp		  newoff = relax_align (address + fragP->fr_fix,
226633965Sjdp					(int) offset);
226733965Sjdp
226833965Sjdp		  if (fragP->fr_subtype != 0)
226933965Sjdp		    {
227033965Sjdp		      if (oldoff > fragP->fr_subtype)
227133965Sjdp			oldoff = 0;
227233965Sjdp		      if (newoff > fragP->fr_subtype)
227333965Sjdp			newoff = 0;
227433965Sjdp		    }
227533965Sjdp
227633965Sjdp		  growth = newoff - oldoff;
227733965Sjdp		}
227833965Sjdp		break;
227933965Sjdp
228033965Sjdp	      case rs_org:
228133965Sjdp		{
228233965Sjdp		  long target = offset;
228333965Sjdp		  long after;
228433965Sjdp
228533965Sjdp		  if (symbolP)
228633965Sjdp		    {
228733965Sjdp#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
228833965Sjdp		      know ((S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
228933965Sjdp			    || (S_GET_SEGMENT (symbolP) == SEG_DATA)
229033965Sjdp			    || (S_GET_SEGMENT (symbolP) == SEG_TEXT)
229133965Sjdp			    || S_GET_SEGMENT (symbolP) == SEG_BSS);
229233965Sjdp		      know (symbolP->sy_frag);
229333965Sjdp		      know (!(S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
229433965Sjdp			    || (symbolP->sy_frag == &zero_address_frag));
229533965Sjdp#endif
229660484Sobrien		      target += (S_GET_VALUE (symbolP)
229760484Sobrien				 + symbol_get_frag (symbolP)->fr_address);
229833965Sjdp		    }		/* if we have a symbol */
229933965Sjdp
230033965Sjdp		  know (fragP->fr_next);
230133965Sjdp		  after = fragP->fr_next->fr_address;
230233965Sjdp		  growth = target - after;
230333965Sjdp		  if (growth < 0)
230433965Sjdp		    {
230533965Sjdp		      /* Growth may be negative, but variable part of frag
230633965Sjdp			 cannot have fewer than 0 chars.  That is, we can't
230733965Sjdp			 .org backwards. */
230860484Sobrien		      as_bad_where (fragP->fr_file, fragP->fr_line,
230960484Sobrien				    _("attempt to .org backwards ignored"));
231060484Sobrien
231160484Sobrien		      /* We've issued an error message.  Change the
231260484Sobrien                         frag to avoid cascading errors.  */
231360484Sobrien		      fragP->fr_type = rs_align;
231460484Sobrien		      fragP->fr_subtype = 0;
231560484Sobrien		      fragP->fr_offset = 0;
231660484Sobrien		      fragP->fr_fix = after - address;
231760484Sobrien		      growth = stretch;
231833965Sjdp		    }
231933965Sjdp
232033965Sjdp		  growth -= stretch;	/* This is an absolute growth factor */
232133965Sjdp		  break;
232233965Sjdp		}
232333965Sjdp
232433965Sjdp	      case rs_space:
232533965Sjdp		if (symbolP)
232633965Sjdp		  {
232733965Sjdp		    growth = S_GET_VALUE (symbolP);
232860484Sobrien		    if (symbol_get_frag (symbolP) != &zero_address_frag
232933965Sjdp			|| S_IS_COMMON (symbolP)
233033965Sjdp			|| ! S_IS_DEFINED (symbolP))
233133965Sjdp		      as_bad_where (fragP->fr_file, fragP->fr_line,
233260484Sobrien				    _(".space specifies non-absolute value"));
233333965Sjdp		    fragP->fr_symbol = 0;
233433965Sjdp		    if (growth < 0)
233533965Sjdp		      {
233660484Sobrien			as_warn (_(".space or .fill with negative value, ignored"));
233733965Sjdp			growth = 0;
233833965Sjdp		      }
233933965Sjdp		  }
234033965Sjdp		else
234133965Sjdp		  growth = 0;
234233965Sjdp		break;
234333965Sjdp
234433965Sjdp	      case rs_machine_dependent:
234533965Sjdp#ifdef md_relax_frag
234633965Sjdp		growth = md_relax_frag (fragP, stretch);
234733965Sjdp#else
234833965Sjdp#ifdef TC_GENERIC_RELAX_TABLE
234933965Sjdp		/* The default way to relax a frag is to look through
235033965Sjdp		   TC_GENERIC_RELAX_TABLE.  */
235133965Sjdp		growth = relax_frag (fragP, stretch);
235233965Sjdp#endif /* TC_GENERIC_RELAX_TABLE */
235333965Sjdp#endif
235433965Sjdp		break;
235533965Sjdp
235638889Sjdp	      case rs_leb128:
235738889Sjdp		{
235838889Sjdp		  valueT value;
235938889Sjdp		  int size;
236038889Sjdp
236138889Sjdp		  value = resolve_symbol_value (fragP->fr_symbol, 0);
236238889Sjdp		  size = sizeof_leb128 (value, fragP->fr_subtype);
236338889Sjdp		  growth = size - fragP->fr_offset;
236438889Sjdp		  fragP->fr_offset = size;
236538889Sjdp		}
236638889Sjdp		break;
236738889Sjdp
236838889Sjdp	      case rs_cfa:
236938889Sjdp		growth = eh_frame_relax_frag (fragP);
237038889Sjdp		break;
237138889Sjdp
237233965Sjdp	      default:
237333965Sjdp		BAD_CASE (fragP->fr_type);
237433965Sjdp		break;
237533965Sjdp	      }
237633965Sjdp	    if (growth)
237733965Sjdp	      {
237833965Sjdp		stretch += growth;
237933965Sjdp		stretched++;
238033965Sjdp	      }
238133965Sjdp	  }			/* For each frag in the segment. */
238233965Sjdp      }
238333965Sjdp    while (stretched);		/* Until nothing further to relax. */
238433965Sjdp  }				/* do_relax */
238533965Sjdp
238633965Sjdp  /*
238733965Sjdp   * We now have valid fr_address'es for each frag.
238833965Sjdp   */
238933965Sjdp
239033965Sjdp  /*
239133965Sjdp   * All fr_address's are correct, relative to their own segment.
239233965Sjdp   * We have made all the fixS we will ever make.
239333965Sjdp   */
239433965Sjdp}				/* relax_segment() */
239533965Sjdp
239633965Sjdp#if defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS))
239733965Sjdp
239833965Sjdp#ifndef TC_RELOC_RTSYM_LOC_FIXUP
239933965Sjdp#define TC_RELOC_RTSYM_LOC_FIXUP(X) (1)
240033965Sjdp#endif
240133965Sjdp
240233965Sjdp/* fixup_segment()
240333965Sjdp
240433965Sjdp   Go through all the fixS's in a segment and see which ones can be
240533965Sjdp   handled now.  (These consist of fixS where we have since discovered
240633965Sjdp   the value of a symbol, or the address of the frag involved.)
240733965Sjdp   For each one, call md_apply_fix to put the fix into the frag data.
240833965Sjdp
240933965Sjdp   Result is a count of how many relocation structs will be needed to
241033965Sjdp   handle the remaining fixS's that we couldn't completely handle here.
241133965Sjdp   These will be output later by emit_relocations().  */
241233965Sjdp
241333965Sjdpstatic long
241433965Sjdpfixup_segment (fixP, this_segment_type)
241533965Sjdp     register fixS *fixP;
241633965Sjdp     segT this_segment_type;	/* N_TYPE bits for segment. */
241733965Sjdp{
241833965Sjdp  long seg_reloc_count = 0;
241933965Sjdp  symbolS *add_symbolP;
242033965Sjdp  symbolS *sub_symbolP;
242133965Sjdp  valueT add_number;
242233965Sjdp  int size;
242333965Sjdp  char *place;
242433965Sjdp  long where;
242533965Sjdp  int pcrel, plt;
242633965Sjdp  fragS *fragP;
242733965Sjdp  segT add_symbol_segment = absolute_section;
242833965Sjdp
242933965Sjdp  /* If the linker is doing the relaxing, we must not do any fixups.
243033965Sjdp
243133965Sjdp     Well, strictly speaking that's not true -- we could do any that are
243233965Sjdp     PC-relative and don't cross regions that could change size.  And for the
243333965Sjdp     i960 (the only machine for which we've got a relaxing linker right now),
243433965Sjdp     we might be able to turn callx/callj into bal anyways in cases where we
243533965Sjdp     know the maximum displacement.  */
243633965Sjdp  if (linkrelax)
243733965Sjdp    {
243833965Sjdp      for (; fixP; fixP = fixP->fx_next)
243933965Sjdp	seg_reloc_count++;
244033965Sjdp      TC_ADJUST_RELOC_COUNT (fixP, seg_reloc_count);
244133965Sjdp      return seg_reloc_count;
244233965Sjdp    }
244333965Sjdp
244433965Sjdp  for (; fixP; fixP = fixP->fx_next)
244533965Sjdp    {
244660484Sobrien
244733965Sjdp#ifdef DEBUG5
244833965Sjdp      fprintf (stderr, "\nprocessing fixup:\n");
244933965Sjdp      print_fixup (fixP);
245033965Sjdp#endif
245133965Sjdp
245260484Sobrien
245333965Sjdp      fragP = fixP->fx_frag;
245433965Sjdp      know (fragP);
245533965Sjdp      where = fixP->fx_where;
245633965Sjdp      place = fragP->fr_literal + where;
245733965Sjdp      size = fixP->fx_size;
245833965Sjdp      add_symbolP = fixP->fx_addsy;
245933965Sjdp#ifdef TC_VALIDATE_FIX
246033965Sjdp      TC_VALIDATE_FIX (fixP, this_segment_type, skip);
246133965Sjdp#endif
246233965Sjdp      sub_symbolP = fixP->fx_subsy;
246333965Sjdp      add_number = fixP->fx_offset;
246433965Sjdp      pcrel = fixP->fx_pcrel;
246533965Sjdp      plt = fixP->fx_plt;
246633965Sjdp
246733965Sjdp      if (add_symbolP != NULL
246860484Sobrien	  && symbol_mri_common_p (add_symbolP))
246933965Sjdp	{
247033965Sjdp	  know (add_symbolP->sy_value.X_op == O_symbol);
247133965Sjdp	  add_number += S_GET_VALUE (add_symbolP);
247233965Sjdp	  fixP->fx_offset = add_number;
247360484Sobrien	  add_symbolP = fixP->fx_addsy =
247460484Sobrien	    symbol_get_value_expression (add_symbolP)->X_add_symbol;
247533965Sjdp	}
247633965Sjdp
247733965Sjdp      if (add_symbolP)
247833965Sjdp	add_symbol_segment = S_GET_SEGMENT (add_symbolP);
247933965Sjdp
248033965Sjdp      if (sub_symbolP)
248133965Sjdp	{
248238889Sjdp	  resolve_symbol_value (sub_symbolP, 1);
248333965Sjdp	  if (add_symbolP == NULL || add_symbol_segment == absolute_section)
248433965Sjdp	    {
248533965Sjdp	      if (add_symbolP != NULL)
248633965Sjdp		{
248733965Sjdp		  add_number += S_GET_VALUE (add_symbolP);
248833965Sjdp		  add_symbolP = NULL;
248933965Sjdp		  fixP->fx_addsy = NULL;
249033965Sjdp		}
249133965Sjdp
249233965Sjdp	      /* It's just -sym */
249333965Sjdp	      if (S_GET_SEGMENT (sub_symbolP) == absolute_section)
249433965Sjdp		{
249533965Sjdp		  add_number -= S_GET_VALUE (sub_symbolP);
249633965Sjdp		  fixP->fx_subsy = NULL;
249733965Sjdp		}
249833965Sjdp	      else if (pcrel
249933965Sjdp		       && S_GET_SEGMENT (sub_symbolP) == this_segment_type)
250033965Sjdp		{
250133965Sjdp		  /* Should try converting to a constant.  */
250233965Sjdp		  goto bad_sub_reloc;
250333965Sjdp		}
250433965Sjdp	      else
250533965Sjdp	      bad_sub_reloc:
250633965Sjdp		as_bad_where (fixP->fx_file, fixP->fx_line,
250760484Sobrien			      _("Negative of non-absolute symbol %s"),
250833965Sjdp			      S_GET_NAME (sub_symbolP));
250933965Sjdp	    }
251033965Sjdp	  else if (S_GET_SEGMENT (sub_symbolP) == add_symbol_segment
251133965Sjdp		   && SEG_NORMAL (add_symbol_segment))
251233965Sjdp	    {
251333965Sjdp	      /* Difference of 2 symbols from same segment.
251433965Sjdp		 Can't make difference of 2 undefineds: 'value' means
251533965Sjdp		 something different for N_UNDF. */
251633965Sjdp#ifdef TC_I960
251733965Sjdp	      /* Makes no sense to use the difference of 2 arbitrary symbols
251833965Sjdp		 as the target of a call instruction.  */
251933965Sjdp	      if (fixP->fx_tcbit)
252033965Sjdp		as_bad_where (fixP->fx_file, fixP->fx_line,
252160484Sobrien			      _("callj to difference of 2 symbols"));
252233965Sjdp#endif /* TC_I960 */
252333965Sjdp	      add_number += S_GET_VALUE (add_symbolP) -
252433965Sjdp		S_GET_VALUE (sub_symbolP);
252533965Sjdp
252633965Sjdp	      add_symbolP = NULL;
252733965Sjdp	      pcrel = 0;	/* No further pcrel processing. */
252833965Sjdp
252933965Sjdp	      /* Let the target machine make the final determination
253033965Sjdp		 as to whether or not a relocation will be needed to
253133965Sjdp		 handle this fixup.  */
253233965Sjdp	      if (!TC_FORCE_RELOCATION_SECTION (fixP, this_segment_type))
253333965Sjdp		{
253433965Sjdp		  fixP->fx_pcrel = 0;
253533965Sjdp		  fixP->fx_addsy = NULL;
253633965Sjdp		  fixP->fx_subsy = NULL;
253733965Sjdp		}
253833965Sjdp	    }
253933965Sjdp	  else
254033965Sjdp	    {
254133965Sjdp	      /* Different segments in subtraction. */
254233965Sjdp	      know (!(S_IS_EXTERNAL (sub_symbolP)
254333965Sjdp		      && (S_GET_SEGMENT (sub_symbolP) == absolute_section)));
254433965Sjdp
254533965Sjdp	      if ((S_GET_SEGMENT (sub_symbolP) == absolute_section))
254633965Sjdp		add_number -= S_GET_VALUE (sub_symbolP);
254733965Sjdp
254833965Sjdp#ifdef DIFF_EXPR_OK
254933965Sjdp	      else if (S_GET_SEGMENT (sub_symbolP) == this_segment_type
255033965Sjdp#if 0 /* Do this even if it's already described as pc-relative.  For example,
255133965Sjdp	 on the m68k, an operand of "pc@(foo-.-2)" should address "foo" in a
255233965Sjdp	 pc-relative mode.  */
255333965Sjdp		       && pcrel
255433965Sjdp#endif
255533965Sjdp		       )
255633965Sjdp		{
255733965Sjdp		  /* Make it pc-relative.  */
255833965Sjdp		  add_number += (MD_PCREL_FROM_SECTION (fixP, this_segment_type)
255933965Sjdp				 - S_GET_VALUE (sub_symbolP));
256033965Sjdp		  pcrel = 1;
256133965Sjdp		  fixP->fx_pcrel = 1;
256233965Sjdp		  sub_symbolP = 0;
256333965Sjdp		  fixP->fx_subsy = 0;
256433965Sjdp		}
256533965Sjdp#endif
256633965Sjdp#ifdef UNDEFINED_DIFFERENCE_OK
256733965Sjdp	      /* The PA needs this for PIC code generation.  We basically
256833965Sjdp		 don't want to do anything if we have the difference of two
256933965Sjdp		 symbols at this point.  */
257033965Sjdp	      else if (1)
257133965Sjdp		{
257233965Sjdp		  /* Leave it alone.  */
257333965Sjdp		}
257433965Sjdp#endif
257533965Sjdp#ifdef BFD_ASSEMBLER
257633965Sjdp	      else if (fixP->fx_r_type == BFD_RELOC_GPREL32
257733965Sjdp		       || fixP->fx_r_type == BFD_RELOC_GPREL16)
257833965Sjdp		{
257933965Sjdp		  /* Leave it alone.  */
258033965Sjdp		}
258133965Sjdp#endif
258233965Sjdp	      else
258333965Sjdp		{
258433965Sjdp		  char buf[50];
258533965Sjdp		  sprint_value (buf, fragP->fr_address + where);
258633965Sjdp		  as_bad_where (fixP->fx_file, fixP->fx_line,
258760484Sobrien				_("Subtraction of two symbols in different sections \"%s\" {%s section} - \"%s\" {%s section} at file address %s."),
258860484Sobrien				S_GET_NAME (add_symbolP),
258960484Sobrien				segment_name (S_GET_SEGMENT (add_symbolP)),
259060484Sobrien				S_GET_NAME (sub_symbolP),
259133965Sjdp				segment_name (S_GET_SEGMENT (sub_symbolP)),
259260484Sobrien				buf);
259333965Sjdp		}
259433965Sjdp	    }
259533965Sjdp	}
259633965Sjdp
259733965Sjdp      if (add_symbolP)
259833965Sjdp	{
259933965Sjdp	  if (add_symbol_segment == this_segment_type && pcrel && !plt
260033965Sjdp	      && TC_RELOC_RTSYM_LOC_FIXUP (fixP))
260133965Sjdp	    {
260233965Sjdp	      /*
260333965Sjdp	       * This fixup was made when the symbol's segment was
260433965Sjdp	       * SEG_UNKNOWN, but it is now in the local segment.
260533965Sjdp	       * So we know how to do the address without relocation.
260633965Sjdp	       */
260733965Sjdp#ifdef TC_I960
260833965Sjdp	      /* reloc_callj() may replace a 'call' with a 'calls' or a
260933965Sjdp		 'bal', in which cases it modifies *fixP as appropriate.
261033965Sjdp		 In the case of a 'calls', no further work is required,
261133965Sjdp		 and *fixP has been set up to make the rest of the code
261233965Sjdp		 below a no-op. */
261333965Sjdp	      reloc_callj (fixP);
261433965Sjdp#endif /* TC_I960 */
261533965Sjdp
261633965Sjdp	      add_number += S_GET_VALUE (add_symbolP);
261733965Sjdp	      add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment_type);
261833965Sjdp	      pcrel = 0;	/* Lie. Don't want further pcrel processing. */
261933965Sjdp
262033965Sjdp	      /* Let the target machine make the final determination
262133965Sjdp		 as to whether or not a relocation will be needed to
262233965Sjdp		 handle this fixup.  */
262333965Sjdp	      if (!TC_FORCE_RELOCATION (fixP))
262433965Sjdp		{
262533965Sjdp		  fixP->fx_pcrel = 0;
262633965Sjdp		  fixP->fx_addsy = NULL;
262733965Sjdp		}
262833965Sjdp	    }
262933965Sjdp	  else
263033965Sjdp	    {
263133965Sjdp	      if (add_symbol_segment == absolute_section
263233965Sjdp		  && ! pcrel)
263333965Sjdp		{
263433965Sjdp#ifdef TC_I960
263533965Sjdp		  /* See comment about reloc_callj() above.  */
263633965Sjdp		  reloc_callj (fixP);
263733965Sjdp#endif /* TC_I960 */
263833965Sjdp		  add_number += S_GET_VALUE (add_symbolP);
263933965Sjdp
264033965Sjdp		  /* Let the target machine make the final determination
264133965Sjdp		     as to whether or not a relocation will be needed to
264233965Sjdp		     handle this fixup.  */
264333965Sjdp
264433965Sjdp		  if (!TC_FORCE_RELOCATION (fixP))
264533965Sjdp		    {
264633965Sjdp		      fixP->fx_addsy = NULL;
264733965Sjdp		      add_symbolP = NULL;
264833965Sjdp		    }
264933965Sjdp		}
265033965Sjdp	      else if (add_symbol_segment == undefined_section
265133965Sjdp#ifdef BFD_ASSEMBLER
265233965Sjdp		       || bfd_is_com_section (add_symbol_segment)
265333965Sjdp#endif
265433965Sjdp		       )
265533965Sjdp		{
265633965Sjdp#ifdef TC_I960
265733965Sjdp		  if ((int) fixP->fx_bit_fixP == 13)
265833965Sjdp		    {
265933965Sjdp		      /* This is a COBR instruction.  They have only a
266033965Sjdp		       * 13-bit displacement and are only to be used
266133965Sjdp		       * for local branches: flag as error, don't generate
266233965Sjdp		       * relocation.
266333965Sjdp		       */
266433965Sjdp		      as_bad_where (fixP->fx_file, fixP->fx_line,
266560484Sobrien				    _("can't use COBR format with external label"));
266633965Sjdp		      fixP->fx_addsy = NULL;
266733965Sjdp		      fixP->fx_done = 1;
266833965Sjdp		      continue;
266933965Sjdp		    }		/* COBR */
267033965Sjdp#endif /* TC_I960 */
267133965Sjdp
267233965Sjdp#ifdef OBJ_COFF
267333965Sjdp#ifdef TE_I386AIX
267433965Sjdp		  if (S_IS_COMMON (add_symbolP))
267533965Sjdp		    add_number += S_GET_VALUE (add_symbolP);
267633965Sjdp#endif /* TE_I386AIX */
267733965Sjdp#endif /* OBJ_COFF */
267833965Sjdp		  ++seg_reloc_count;
267933965Sjdp		}
268033965Sjdp	      else
268133965Sjdp		{
268233965Sjdp		  seg_reloc_count++;
268338889Sjdp#if !(defined (TC_V850) && defined (OBJ_ELF))
268433965Sjdp#if !(defined (TC_M68K) && defined (OBJ_ELF))
268560484Sobrien#if !(defined (TC_ARM)  && defined (OBJ_ELF))
268660484Sobrien#if !(defined (TC_I960) && defined (OBJ_ELF))
268738889Sjdp#if !defined (TC_I386) || !(defined (OBJ_ELF) || defined (OBJ_COFF)) || defined (TE_PE)
268833965Sjdp		  add_number += S_GET_VALUE (add_symbolP);
268933965Sjdp#endif
269033965Sjdp#endif
269138889Sjdp#endif
269260484Sobrien#endif
269360484Sobrien#endif
269433965Sjdp		}
269533965Sjdp	    }
269633965Sjdp	}
269733965Sjdp
269833965Sjdp      if (pcrel)
269933965Sjdp	{
270033965Sjdp	  add_number -= MD_PCREL_FROM_SECTION (fixP, this_segment_type);
270133965Sjdp	  if (add_symbolP == 0)
270233965Sjdp	    {
270333965Sjdp#ifndef BFD_ASSEMBLER
270433965Sjdp	      fixP->fx_addsy = &abs_symbol;
270533965Sjdp#else
270633965Sjdp	      fixP->fx_addsy = section_symbol (absolute_section);
270733965Sjdp#endif
270860484Sobrien	      symbol_mark_used_in_reloc (fixP->fx_addsy);
270933965Sjdp	      ++seg_reloc_count;
271033965Sjdp	    }
271133965Sjdp	}
271233965Sjdp
271360484Sobrien      if (!fixP->fx_done)
271460484Sobrien	{
271560484Sobrien#ifdef MD_APPLY_FIX3
271660484Sobrien	  md_apply_fix3 (fixP, &add_number, this_segment_type);
271760484Sobrien#else
271860484Sobrien#ifdef BFD_ASSEMBLER
271960484Sobrien	  md_apply_fix (fixP, &add_number);
272060484Sobrien#else
272160484Sobrien	  md_apply_fix (fixP, add_number);
272260484Sobrien#endif
272360484Sobrien#endif
272460484Sobrien
272560484Sobrien#ifndef TC_HANDLES_FX_DONE
272660484Sobrien	  /* If the tc-* files haven't been converted, assume it's handling
272760484Sobrien	     it the old way, where a null fx_addsy means that the fix has
272860484Sobrien	     been applied completely, and no further work is needed.  */
272960484Sobrien	  if (fixP->fx_addsy == 0 && fixP->fx_pcrel == 0)
273060484Sobrien	    fixP->fx_done = 1;
273160484Sobrien#endif
273260484Sobrien	}
273360484Sobrien
273433965Sjdp      if (!fixP->fx_bit_fixP && !fixP->fx_no_overflow && size > 0)
273533965Sjdp	{
273638889Sjdp	  if ((size_t) size < sizeof (valueT))
273733965Sjdp	    {
273860484Sobrien	      valueT mask;
273933965Sjdp
274033965Sjdp	      mask = 0;
274160484Sobrien	      mask--;		/* set all bits to one */
274260484Sobrien	      mask <<= size * 8 - (fixP->fx_signed ? 1 : 0);
274360484Sobrien	      if ((add_number & mask) != 0 && (add_number & mask) != mask)
274433965Sjdp		{
274533965Sjdp		  char buf[50], buf2[50];
274633965Sjdp		  sprint_value (buf, fragP->fr_address + where);
274733965Sjdp		  if (add_number > 1000)
274833965Sjdp		    sprint_value (buf2, add_number);
274933965Sjdp		  else
275033965Sjdp		    sprintf (buf2, "%ld", (long) add_number);
275133965Sjdp		  as_bad_where (fixP->fx_file, fixP->fx_line,
275260484Sobrien				_("Value of %s too large for field of %d bytes at %s"),
275333965Sjdp				buf2, size, buf);
275433965Sjdp		} /* generic error checking */
275533965Sjdp	    }
275633965Sjdp#ifdef WARN_SIGNED_OVERFLOW_WORD
275733965Sjdp	  /* Warn if a .word value is too large when treated as a signed
275833965Sjdp	     number.  We already know it is not too negative.  This is to
275933965Sjdp	     catch over-large switches generated by gcc on the 68k.  */
276033965Sjdp	  if (!flag_signed_overflow_ok
276133965Sjdp	      && size == 2
276233965Sjdp	      && add_number > 0x7fff)
276333965Sjdp	    as_bad_where (fixP->fx_file, fixP->fx_line,
276460484Sobrien			  _("Signed .word overflow; switch may be too large; %ld at 0x%lx"),
276533965Sjdp			  (long) add_number,
276633965Sjdp			  (unsigned long) (fragP->fr_address + where));
276733965Sjdp#endif
276833965Sjdp	}			/* not a bit fix */
276933965Sjdp
277033965Sjdp#ifdef TC_VALIDATE_FIX
277160484Sobrien    skip:  ATTRIBUTE_UNUSED_LABEL
277260484Sobrien      ;
277333965Sjdp#endif
277433965Sjdp#ifdef DEBUG5
277533965Sjdp      fprintf (stderr, "result:\n");
277633965Sjdp      print_fixup (fixP);
277733965Sjdp#endif
277833965Sjdp    }				/* For each fixS in this segment. */
277933965Sjdp
278033965Sjdp  TC_ADJUST_RELOC_COUNT (fixP, seg_reloc_count);
278133965Sjdp  return seg_reloc_count;
278233965Sjdp}
278333965Sjdp
278433965Sjdp#endif /* defined (BFD_ASSEMBLER) || (!defined (BFD) && !defined (OBJ_VMS)) */
278533965Sjdp
278633965Sjdpvoid
278733965Sjdpnumber_to_chars_bigendian (buf, val, n)
278833965Sjdp     char *buf;
278933965Sjdp     valueT val;
279033965Sjdp     int n;
279133965Sjdp{
279238889Sjdp  if ((size_t) n > sizeof (val) || n <= 0)
279333965Sjdp    abort ();
279433965Sjdp  while (n--)
279533965Sjdp    {
279633965Sjdp      buf[n] = val & 0xff;
279733965Sjdp      val >>= 8;
279833965Sjdp    }
279933965Sjdp}
280033965Sjdp
280133965Sjdpvoid
280233965Sjdpnumber_to_chars_littleendian (buf, val, n)
280333965Sjdp     char *buf;
280433965Sjdp     valueT val;
280533965Sjdp     int n;
280633965Sjdp{
280738889Sjdp  if ((size_t) n > sizeof (val) || n <= 0)
280833965Sjdp    abort ();
280933965Sjdp  while (n--)
281033965Sjdp    {
281133965Sjdp      *buf++ = val & 0xff;
281233965Sjdp      val >>= 8;
281333965Sjdp    }
281433965Sjdp}
281533965Sjdp
281633965Sjdpvoid
281733965Sjdpwrite_print_statistics (file)
281833965Sjdp     FILE *file;
281933965Sjdp{
282060484Sobrien  fprintf (file, "fixups: %d\n", n_fixups);
282133965Sjdp}
282233965Sjdp
282333965Sjdp/* for debugging */
282433965Sjdpextern int indent_level;
282533965Sjdp
282633965Sjdpvoid
282733965Sjdpprint_fixup (fixp)
282833965Sjdp     fixS *fixp;
282933965Sjdp{
283033965Sjdp  indent_level = 1;
283133965Sjdp  fprintf (stderr, "fix %lx %s:%d", (long) fixp, fixp->fx_file, fixp->fx_line);
283233965Sjdp  if (fixp->fx_pcrel)
283333965Sjdp    fprintf (stderr, " pcrel");
283433965Sjdp  if (fixp->fx_pcrel_adjust)
283533965Sjdp    fprintf (stderr, " pcrel_adjust=%d", fixp->fx_pcrel_adjust);
283633965Sjdp  if (fixp->fx_im_disp)
283733965Sjdp    {
283833965Sjdp#ifdef TC_NS32K
283933965Sjdp      fprintf (stderr, " im_disp=%d", fixp->fx_im_disp);
284033965Sjdp#else
284133965Sjdp      fprintf (stderr, " im_disp");
284233965Sjdp#endif
284333965Sjdp    }
284433965Sjdp  if (fixp->fx_tcbit)
284533965Sjdp    fprintf (stderr, " tcbit");
284633965Sjdp  if (fixp->fx_done)
284733965Sjdp    fprintf (stderr, " done");
284833965Sjdp  fprintf (stderr, "\n    size=%d frag=%lx where=%ld offset=%lx addnumber=%lx",
284933965Sjdp	   fixp->fx_size, (long) fixp->fx_frag, (long) fixp->fx_where,
285033965Sjdp	   (long) fixp->fx_offset, (long) fixp->fx_addnumber);
285133965Sjdp#ifdef BFD_ASSEMBLER
285233965Sjdp  fprintf (stderr, "\n    %s (%d)", bfd_get_reloc_code_name (fixp->fx_r_type),
285333965Sjdp	   fixp->fx_r_type);
285433965Sjdp#else
285533965Sjdp#ifdef NEED_FX_R_TYPE
285633965Sjdp  fprintf (stderr, " r_type=%d", fixp->fx_r_type);
285733965Sjdp#endif
285833965Sjdp#endif
285933965Sjdp  if (fixp->fx_addsy)
286033965Sjdp    {
286133965Sjdp      fprintf (stderr, "\n   +<");
286233965Sjdp      print_symbol_value_1 (stderr, fixp->fx_addsy);
286333965Sjdp      fprintf (stderr, ">");
286433965Sjdp    }
286533965Sjdp  if (fixp->fx_subsy)
286633965Sjdp    {
286733965Sjdp      fprintf (stderr, "\n   -<");
286833965Sjdp      print_symbol_value_1 (stderr, fixp->fx_subsy);
286933965Sjdp      fprintf (stderr, ">");
287033965Sjdp    }
287133965Sjdp  fprintf (stderr, "\n");
287238889Sjdp#ifdef TC_FIX_DATA_PRINT
287338889Sjdp  TC_FIX_DATA_PRINT (stderr, fixp);
287438889Sjdp#endif
287533965Sjdp}
287633965Sjdp
287733965Sjdp/* end of write.c */
2878